From e25a267e812e918a78577c919ad426afe57b3b1f Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 14 Sep 2024 20:30:14 +0000 Subject: [PATCH 001/522] Fix the fts5 xInstToken() API for prefix queries that do not use prefix-indexes. This is experimental. FossilOrigin-Name: 97c2824f471e7e622c4a166947a6e8162cae891345101539829a6fcec83373fe --- ext/fts5/fts5_expr.c | 18 +++-- ext/fts5/fts5_index.c | 19 ++++-- ext/fts5/test/fts5origintext.test | 11 +++- ext/fts5/test/fts5tokendata.test | 105 ++++++++++++++++++++++++++++++ manifest | 22 ++++--- manifest.uuid | 2 +- 6 files changed, 148 insertions(+), 29 deletions(-) create mode 100644 ext/fts5/test/fts5tokendata.test diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index cd44b96bda..0124a1cc93 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -3046,7 +3046,7 @@ static int fts5ExprPopulatePoslistsCb( int rc = sqlite3Fts5PoslistWriterAppend( &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff ); - if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){ + if( rc==SQLITE_OK && (pExpr->pConfig->bTokendata || pT->bPrefix) ){ int iCol = p->iOff>>32; int iTokOff = p->iOff & 0x7FFFFFFF; rc = sqlite3Fts5IndexIterWriteTokendata( @@ -3239,15 +3239,13 @@ int sqlite3Fts5ExprInstToken( return SQLITE_RANGE; } pTerm = &pPhrase->aTerm[iToken]; - if( pTerm->bPrefix==0 ){ - if( pExpr->pConfig->bTokendata ){ - rc = sqlite3Fts5IterToken( - pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut - ); - }else{ - *ppOut = pTerm->pTerm; - *pnOut = pTerm->nFullTerm; - } + if( pExpr->pConfig->bTokendata || pTerm->bPrefix ){ + rc = sqlite3Fts5IterToken( + pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut + ); + }else{ + *ppOut = pTerm->pTerm; + *pnOut = pTerm->nFullTerm; } return rc; } diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 4363305a56..ded1ec59cf 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6571,12 +6571,13 @@ int sqlite3Fts5IndexWrite( static int fts5IsTokendataPrefix( Fts5Buffer *pBuf, const u8 *pToken, - int nToken + int nToken, + int bPrefix ){ return ( pBuf->n>=nToken && 0==memcmp(pBuf->p, pToken, nToken) - && (pBuf->n==nToken || pBuf->p[nToken]==0x00) + && (bPrefix || pBuf->n==nToken || pBuf->p[nToken]==0x00) ); } @@ -6879,7 +6880,8 @@ static Fts5Iter *fts5SetupTokendataIter( Fts5Index *p, /* FTS index to query */ const u8 *pToken, /* Buffer containing query term */ int nToken, /* Size of buffer pToken in bytes */ - Fts5Colset *pColset /* Colset to filter on */ + Fts5Colset *pColset, /* Colset to filter on */ + int bPrefix /* True to match any prefix */ ){ Fts5Iter *pRet = 0; Fts5TokenDataIter *pSet = 0; @@ -6961,7 +6963,7 @@ static Fts5Iter *fts5SetupTokendataIter( pSmall = 0; for(ii=0; iinSeg; ii++){ Fts5SegIter *pII = &pNew->aSeg[ii]; - if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken) ){ + if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken, bPrefix) ){ fts5SegIterSetEOF(pII); } if( pII->pLeaf && (!pSmall || fts5BufferCompare(pSmall, &pII->term)>0) ){ @@ -7037,6 +7039,9 @@ int sqlite3Fts5IndexQuery( int bTokendata = pConfig->bTokendata; if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); + /* The NOTOKENDATA flag is set when it is known that tokendata data will + ** not be required. e.g. for queries performed as part of an + ** integrity-check, or by the fts5vocab module. */ if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){ bTokendata = 0; } @@ -7066,9 +7071,9 @@ int sqlite3Fts5IndexQuery( } } - if( bTokendata && iIdx==0 ){ - buf.p[0] = '0'; - pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset); + if( (bTokendata && iIdx==0) || iIdx>pConfig->nPrefix ){ + buf.p[0] = FTS5_MAIN_PREFIX; + pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset, iIdx>0); }else if( iIdx<=pConfig->nPrefix ){ /* Straight index lookup */ Fts5Structure *pStruct = fts5StructureRead(p); diff --git a/ext/fts5/test/fts5origintext.test b/ext/fts5/test/fts5origintext.test index 8e975fa17c..9741f786e8 100644 --- a/ext/fts5/test/fts5origintext.test +++ b/ext/fts5/test/fts5origintext.test @@ -166,6 +166,13 @@ do_execsql_test 3.3.3 { SELECT rowid FROM ft2('HELLO') } {1 2 3} do_execsql_test 3.3.4 { SELECT rowid FROM ft2('hello*') } {1 2 3 10} +do_execsql_test 3.3.5.1 { SELECT rowid FROM ft2('HELLO') ORDER BY rowid DESC} { + 3 2 1 +} +do_execsql_test 3.3.5.2 { SELECT rowid FROM ft2('HELLO') ORDER BY +rowid DESC} { + 3 2 1 +} + #------------------------------------------------------------------------- # reset_db @@ -285,11 +292,11 @@ do_execsql_test 6.1 { do_execsql_test 6.2 { SELECT rowid, tokens(ft) FROM ft('on*'); -} {1 {{}} 2 {{} {}}} +} {1 one.One 2 {one one.One}} do_execsql_test 6.3 { SELECT rowid, tokens(ft) FROM ft('Three*'); -} {1 {{}} 2 {{}}} +} {1 three.Three 2 three.Three} fts5_aux_test_functions db do_catchsql_test 6.4 { diff --git a/ext/fts5/test/fts5tokendata.test b/ext/fts5/test/fts5tokendata.test new file mode 100644 index 0000000000..7f75f4fa8e --- /dev/null +++ b/ext/fts5/test/fts5tokendata.test @@ -0,0 +1,105 @@ +# 2014 Jan 08 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Tests focused on phrase queries. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5tokendata + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +foreach_detail_mode $testprefix { + + sqlite3_fts5_register_origintext db + fts5_aux_test_functions db + proc b {x} { string map [list "\0" "."] $x } + db func b b + + do_execsql_test 1.0 { + CREATE VIRTUAL TABLE ft USING fts5(a, b, tokendata=1, + tokenize="origintext unicode61", detail=%DETAIL% + ); + CREATE VIRTUAL TABLE vocab USING fts5vocab(ft, instance); + } + + do_execsql_test 1.1 { + INSERT INTO ft(rowid, a, b) VALUES + (1, 'Pedagog Pedal Pedant', 'Peculier Day Today'), + (2, 'Pedant pedantic pecked', 'Peck Penalize Pen'); + + INSERT INTO ft(rowid, a, b) VALUES + (3, 'Penalty Pence Penciled', 'One Two Three'), + (4, 'Pedant Pedal Pedant', 'Peculier Day Today'); + } + + do_execsql_test 1.2 { + SELECT DISTINCT b(term) FROM vocab + } { + day.Day one.One peck.Peck pecked peculier.Peculier pedagog.Pedagog + pedal.Pedal pedant.Pedant pedantic pen.Pen penalize.Penalize + penalty.Penalty pence.Pence penciled.Penciled three.Three + today.Today two.Two + } + + do_execsql_test 1.3.1 { + SELECT rowid FROM ft('pe*') + } { + 1 2 3 4 + } + + do_execsql_test 1.3.2 { + SELECT rowid FROM ft('pe*') ORDER BY rowid DESC + } { + 4 3 2 1 + } + + if {"%DETAIL%"!="none"} { + do_execsql_test 1.3.3 { + SELECT rowid FROM ft WHERE a MATCH 'pe*' ORDER BY rowid DESC + } { + 4 3 2 1 + } + } + + do_execsql_test 1.4 { + SELECT rowid, b( fts5_test_insttoken(ft, 0, 0) ) FROM ft('pedant') + } { + 1 pedant.Pedant + 2 pedant.Pedant + 4 pedant.Pedant + } + + do_execsql_test 1.5 { + SELECT rowid, b( fts5_test_insttoken(ft, 0, 0) ) FROM ft('pe*') + } { + 1 pedagog.Pedagog + 2 pedant.Pedant + 3 penalty.Penalty + 4 pedant.Pedant + } + + do_execsql_test 1.6 { + SELECT rowid, fts5_test_poslist(ft) FROM ft('pe*') + } { + 1 {0.0.0 0.0.1 0.0.2 0.1.0} + 2 {0.0.0 0.0.1 0.0.2 0.1.0 0.1.1 0.1.2} + 3 {0.0.0 0.0.1 0.0.2} + 4 {0.0.0 0.0.1 0.0.2 0.1.0} + } +} + +finish_test + diff --git a/manifest b/manifest index 3a6304a539..3fc85c61ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\ssubsequent\schanges\sto\ssqlite-rsync\sthat\swere\saccidentally\smissed\sby\nthe\sprior\scheck-in. -D 2024-09-14T16:52:45.740 +C Fix\sthe\sfts5\sxInstToken()\sAPI\sfor\sprefix\squeries\sthat\sdo\snot\suse\sprefix-indexes.\sThis\sis\sexperimental. +D 2024-09-14T20:30:14.441 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -97,9 +97,9 @@ F ext/fts5/fts5Int.h 93aba03ca417f403b07b2ab6f50aa0e0c1b8b031917a9026b81520e7047 F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 F ext/fts5/fts5_config.c da21548ddbc1a457cb42545f527065221ede8ada6a734891b8c34317a7a9506b -F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33 +F ext/fts5/fts5_expr.c 1f60d81aa4703435f98f46bbb41fb2a2efa898423fec070a2b3f7a02f177ac64 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c 571483823193f09439356741669aa8c81da838ae6f5e1bfa7517f7ee2fb3addd +F ext/fts5/fts5_index.c aadd271f3c2048418298377908dd09d496753a5c7da84161a9c86ca8c1e78e9a F ext/fts5/fts5_main.c 4503498d3453e29a3cd89dacaba029011e89cb8c481a6241611d106e7a369bd4 F ext/fts5/fts5_storage.c 3332497823c3d171cf56379f2bd8c971ce15a19aadacff961106462022c92470 F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe @@ -201,7 +201,7 @@ F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618 F ext/fts5/test/fts5optimize.test 264b9101721c17d06d1d174feb743fda3ddc89fad41dee980fef821428258e47 F ext/fts5/test/fts5optimize2.test 795d4ae5f66a7239cf8d5aef4c2ea96aeb8bcd907bd9be0cfe22064fc71a44ed F ext/fts5/test/fts5optimize3.test 1653029284e10e0715246819893ba30565c4ead0d0fc470adae92c353ea857d3 -F ext/fts5/test/fts5origintext.test 2015f69bc8abd111152a8e66211fd2d45026378001e07c054159aa4f84e6691d +F ext/fts5/test/fts5origintext.test 63d5b0dc00f0104add8960da0705a70bffd4d86b6feb6ddbb38bff21141d42f0 F ext/fts5/test/fts5origintext2.test f4505ff79bf7369f2b8b10b9cef7476049d844e20b37f29cad3a8b8d5ac6f9ba F ext/fts5/test/fts5origintext3.test 45c33cf0c91a9ca0e36d298462db3edc7c8fe45fd185649a9dbfd66bb670058b F ext/fts5/test/fts5origintext4.test 0d3ef0a8038f471dbc83001c34fe5f7ae39b571bfc209670771eb28bc0fc50e8 @@ -234,6 +234,7 @@ F ext/fts5/test/fts5synonym.test becc8cea6cfc958a50b30c572c68cbfdf7455971d0fe988 F ext/fts5/test/fts5synonym2.test 58f357b997cf2fedeeb9d0de4db9f880fa96fa2fe27a743bfe7d7b96895bdd87 F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 +F ext/fts5/test/fts5tokendata.test 7cad79af82e8e81b7a36b450087233d2fca051bb0d584421afc375d6dd26d6f6 F ext/fts5/test/fts5tokenizer.test 7937cec672b148223fff8746d21d3e7ed0965fd7caf35ccdc888a005bb452f98 F ext/fts5/test/fts5tokenizer2.test ddb8b10fbe4b84b2a75812671f127774c1d2e3e2bf82d2e0e4f0bb1cd8a2b2d6 F ext/fts5/test/fts5tokenizer3.test eea778f7bb7024c3e904e28915f9d53286141671b138722148be22a9c758bdc3 @@ -2213,8 +2214,11 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b7a8ce4c8c5fc6a3b4744d412d96f99d2452eb4086ad84472511da3b4d6afec6 129aca54f6b791c222b51f3eb01569e1e569269860e153b005140eb65af378b9 -R 3fe2d7eb1050bd322cb4e381c1c28c99 -U drh -Z 5104838c8e0c55c4caf222e0f2dc7147 +P 50762ba0783a04e0dcd9456a1ae17d875b0a9272f2f09854a23d9d5253761e9f +R 7d932f341b9d462f57fdca7d1de99fb1 +T *branch * fts5-tokendata-prefix +T *sym-fts5-tokendata-prefix * +T -sym-trunk * +U dan +Z 82ecce364e38343eb4f3cc0cc45881c8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e011175dd4..77dd09f207 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50762ba0783a04e0dcd9456a1ae17d875b0a9272f2f09854a23d9d5253761e9f +97c2824f471e7e622c4a166947a6e8162cae891345101539829a6fcec83373fe From 6219872845bb1cf0e83a70596510e3b32db47251 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 24 Sep 2024 21:08:49 +0000 Subject: [PATCH 002/522] Initial pristine autosetup bits. FossilOrigin-Name: dfb1e7f0cce9bc79c43eee7208cad0e2df562b2bc9705d3a36fd78f86c75495b --- auto.def | 10 + autosetup/LICENSE | 35 + autosetup/README.autosetup | 11 + autosetup/autosetup | 2534 +++ autosetup/autosetup-config.guess | 1815 +++ autosetup/autosetup-config.sub | 2354 +++ autosetup/autosetup-find-tclsh | 16 + autosetup/autosetup-test-tclsh | 20 + autosetup/cc-db.tcl | 15 + autosetup/cc-lib.tcl | 187 + autosetup/cc-shared.tcl | 113 + autosetup/cc.tcl | 756 + autosetup/default.auto | 25 + autosetup/jimsh0.c | 24442 +++++++++++++++++++++++++++++ autosetup/pkg-config.tcl | 168 + autosetup/system.tcl | 412 + autosetup/tmake.auto | 73 + autosetup/tmake.tcl | 52 + configure | 14081 +---------------- manifest | 35 +- manifest.uuid | 2 +- 21 files changed, 33071 insertions(+), 14085 deletions(-) create mode 100644 auto.def create mode 100644 autosetup/LICENSE create mode 100644 autosetup/README.autosetup create mode 100755 autosetup/autosetup create mode 100755 autosetup/autosetup-config.guess create mode 100755 autosetup/autosetup-config.sub create mode 100755 autosetup/autosetup-find-tclsh create mode 100644 autosetup/autosetup-test-tclsh create mode 100644 autosetup/cc-db.tcl create mode 100644 autosetup/cc-lib.tcl create mode 100644 autosetup/cc-shared.tcl create mode 100644 autosetup/cc.tcl create mode 100644 autosetup/default.auto create mode 100644 autosetup/jimsh0.c create mode 100644 autosetup/pkg-config.tcl create mode 100644 autosetup/system.tcl create mode 100644 autosetup/tmake.auto create mode 100644 autosetup/tmake.tcl diff --git a/auto.def b/auto.def new file mode 100644 index 0000000000..bed7e333f9 --- /dev/null +++ b/auto.def @@ -0,0 +1,10 @@ +# Initial auto.def created by 'autosetup --init=make' + +use cc + +# Add any user options here +options { +} + +make-config-header config.h +make-template Makefile.in diff --git a/autosetup/LICENSE b/autosetup/LICENSE new file mode 100644 index 0000000000..4fe636c9d9 --- /dev/null +++ b/autosetup/LICENSE @@ -0,0 +1,35 @@ +Unless explicitly stated, all files which form part of autosetup +are released under the following license: + +--------------------------------------------------------------------- +autosetup - A build environment "autoconfigurator" + +Copyright (c) 2010-2011, WorkWare Systems + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE WORKWARE SYSTEMS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WORKWARE +SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation +are those of the authors and should not be interpreted as representing +official policies, either expressed or implied, of WorkWare Systems. diff --git a/autosetup/README.autosetup b/autosetup/README.autosetup new file mode 100644 index 0000000000..3952980480 --- /dev/null +++ b/autosetup/README.autosetup @@ -0,0 +1,11 @@ +README.autosetup created by autosetup v0.7.2 + +This is the autosetup directory for a local install of autosetup. +It contains autosetup, support files and loadable modules. + +*.tcl files in this directory are optional modules which +can be loaded with the 'use' directive. + +*.auto files in this directory are auto-loaded. + +For more information, see https://msteveb.github.io/autosetup/ diff --git a/autosetup/autosetup b/autosetup/autosetup new file mode 100755 index 0000000000..e041e77a3a --- /dev/null +++ b/autosetup/autosetup @@ -0,0 +1,2534 @@ +#!/bin/sh +# Copyright (c) 2006-2011 WorkWare Systems http://www.workware.net.au/ +# All rights reserved +# vim:se syntax=tcl: +# \ +dir=`dirname "$0"`; exec "`$dir/autosetup-find-tclsh`" "$0" "$@" + +# Note that the version has a trailing + on unreleased versions +set autosetup(version) 0.7.2 + +# Can be set to 1 to debug early-init problems +set autosetup(debug) [expr {"--debug" in $argv}] + +################################################################## +# +# Main flow of control, option handling +# +proc main {argv} { + global autosetup define + + # There are 3 potential directories involved: + # 1. The directory containing autosetup (this script) + # 2. The directory containing auto.def + # 3. The current directory + + # From this we need to determine: + # a. The path to this script (and related support files) + # b. The path to auto.def + # c. The build directory, where output files are created + + # This is also complicated by the fact that autosetup may + # have been run via the configure wrapper ([getenv WRAPPER] is set) + + # Here are the rules. + # a. This script is $::argv0 + # => dir, prog, exe, libdir + # b. auto.def is in the directory containing the configure wrapper, + # otherwise it is in the current directory. + # => srcdir, autodef + # c. The build directory is the current directory + # => builddir, [pwd] + + # 'misc' is needed before we can do anything, so set a temporary libdir + # in case this is the development version + set autosetup(libdir) [file dirname $::argv0]/lib + use misc + + # (a) + set autosetup(dir) [realdir [file dirname [realpath $::argv0]]] + set autosetup(prog) [file join $autosetup(dir) [file tail $::argv0]] + set autosetup(exe) [getenv WRAPPER $autosetup(prog)] + if {$autosetup(installed)} { + set autosetup(libdir) $autosetup(dir) + } else { + set autosetup(libdir) [file join $autosetup(dir) lib] + } + autosetup_add_dep $autosetup(prog) + + # (b) + if {[getenv WRAPPER ""] eq ""} { + # Invoked directly + set autosetup(srcdir) [pwd] + } else { + # Invoked via the configure wrapper + set autosetup(srcdir) [file-normalize [file dirname $autosetup(exe)]] + } + set autosetup(autodef) [relative-path $autosetup(srcdir)/auto.def] + + # (c) + set autosetup(builddir) [pwd] + + set autosetup(argv) $argv + set autosetup(cmdline) {} + # options is a list of known options + set autosetup(options) {} + # optset is a dictionary of option values set by the user based on getopt + set autosetup(optset) {} + # optdefault is a dictionary of default values + set autosetup(optdefault) {} + # options-defaults is a dictionary of overrides for default values for options + set autosetup(options-defaults) {} + set autosetup(optionhelp) {} + set autosetup(showhelp) 0 + + use util + + # Parse options + use getopt + + # At the is point we don't know what is a valid option + # We simply parse anything that looks like an option + set autosetup(getopt) [getopt argv] + + #"=Core Options:" + options-add { + help:=all => "display help and options. Optional: module name, such as --help=system" + licence license => "display the autosetup license" + version => "display the version of autosetup" + ref:=text manual:=text + reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'" + debug => "display debugging output as autosetup runs" + install:=. => "install autosetup to the current or given directory" + } + if {$autosetup(installed)} { + # hidden options so we can produce a nice error + options-add { + sysinstall:path + } + } else { + options-add { + sysinstall:path => "install standalone autosetup to the given directory (e.g.: /usr/local)" + } + } + options-add { + force init:=help => "create initial auto.def, etc. Use --init=help for known types" + # Undocumented options + option-checking=1 + nopager + quiet + timing + conf: + } + + if {[opt-bool version]} { + puts $autosetup(version) + exit 0 + } + + # autosetup --conf=alternate-auto.def + if {[opt-str conf o]} { + set autosetup(autodef) $o + } + + # Debugging output (set this early) + incr autosetup(debug) [opt-bool debug] + incr autosetup(force) [opt-bool force] + incr autosetup(msg-quiet) [opt-bool quiet] + incr autosetup(msg-timing) [opt-bool timing] + + # If the local module exists, source it now to allow for + # project-local customisations + if {[file exists $autosetup(libdir)/local.tcl]} { + use local + } + + # Now any auto-load modules + autosetup_load_auto_modules + + if {[opt-str help o]} { + incr autosetup(showhelp) + use help + autosetup_help $o + } + + if {[opt-bool licence license]} { + use help + autosetup_show_license + exit 0 + } + + if {[opt-str {manual ref reference} o]} { + use help + autosetup_reference $o + } + + # Allow combining --install and --init + set earlyexit 0 + if {[opt-str install o]} { + use install + autosetup_install $o + incr earlyexit + } + + if {[opt-str init o]} { + use init + autosetup_init $o + incr earlyexit + } + + if {$earlyexit} { + exit 0 + } + if {[opt-str sysinstall o]} { + use install + autosetup_install $o 1 + exit 0 + } + + if {![file exists $autosetup(autodef)]} { + # Check for invalid option first + options {} + user-error "No auto.def found in \"$autosetup(srcdir)\" (use [file tail $::autosetup(exe)] --init to create one)" + } + + # Parse extra arguments into autosetup(cmdline) + foreach arg $argv { + if {[regexp {([^=]*)=(.*)} $arg -> n v]} { + dict set autosetup(cmdline) $n $v + define $n $v + } else { + user-error "Unexpected parameter: $arg" + } + } + + autosetup_add_dep $autosetup(autodef) + + # Add $argv to CONFIGURE_OPTS + define-append-argv CONFIGURE_OPTS {*}$autosetup(argv) + # Set up AUTOREMAKE to reconfigure with the same args + define-append-argv AUTOREMAKE {*}$autosetup(exe) {*}$autosetup(argv) + + # Log how we were invoked + configlog "Invoked as: [getenv WRAPPER $::argv0] [quote-argv $autosetup(argv)]" + configlog "Tclsh: [info nameofexecutable]" + + # Load auto.def as module "auto.def" + autosetup_load_module auto.def source $autosetup(autodef) + + # Could warn here if options {} was not specified + + show-notices + + if {$autosetup(debug)} { + msg-result "Writing all defines to config.log" + configlog "================ defines ======================" + foreach n [lsort [array names define]] { + configlog "define $n $define($n)" + } + } + + exit 0 +} + +# @section Option Handling + +# @opt-bool ?-nodefault? option ... +# +# Check each of the named, boolean options and if any have been explicitly enabled +# or disabled by the user, return 1 or 0 accordingly. +# +# If the option was specified more than once, the last value wins. +# e.g. With '--enable-foo --disable-foo', '[opt-bool foo]' will return 0 +# +# If no value was specified by the user, returns the default value for the +# first option. If '-nodefault' is given, this behaviour changes and +# -1 is returned instead. +# +proc opt-bool {args} { + set nodefault 0 + if {[lindex $args 0] eq "-nodefault"} { + set nodefault 1 + set args [lrange $args 1 end] + } + option-check-names {*}$args + + foreach opt $args { + if {[dict exists $::autosetup(optset) $opt]} { + return [dict get $::autosetup(optset) $opt] + } + } + + if {$nodefault} { + return -1 + } + # Default value is the default for the first option + return [dict get $::autosetup(optdefault) [lindex $args 0]] +} + +# @opt-val optionlist ?default=""? +# +# Returns a list containing all the values given for the non-boolean options in '$optionlist'. +# There will be one entry in the list for each option given by the user, including if the +# same option was used multiple times. +# +# If no options were set, '$default' is returned (exactly, not as a list). +# +# Note: For most use cases, 'opt-str' should be preferred. +# +proc opt-val {names {default ""}} { + option-check-names {*}$names + + foreach opt $names { + if {[dict exists $::autosetup(optset) $opt]} { + lappend result {*}[dict get $::autosetup(optset) $opt] + } + } + if {[info exists result]} { + return $result + } + return $default +} + +# @opt-str optionlist varname ?default? +# +# Sets '$varname' in the callers scope to the value for one of the given options. +# +# For the list of options given in '$optionlist', if any value is set for any option, +# the option value is taken to be the *last* value of the last option (in the order given). +# +# If no option was given, and a default was specified with 'options-defaults', +# that value is used. +# +# If no 'options-defaults' value was given and '$default' was given, it is used. +# +# If none of the above provided a value, no value is set. +# +# The return value depends on whether '$default' was specified. +# If it was, the option value is returned. +# If it was not, 1 is returns if a value was set, or 0 if not. +# +# Typical usage is as follows: +# +## if {[opt-str {myopt altname} o]} { +## do something with $o +## } +# +# Or: +## define myname [opt-str {myopt altname} o "/usr/local"] +# +proc opt-str {names varname args} { + global autosetup + + option-check-names {*}$names + upvar $varname value + + if {[llength $args]} { + # A default was given, so always return the string value of the option + set default [lindex $args 0] + set retopt 1 + } else { + # No default, so return 0 or 1 to indicate if a value was found + set retopt 0 + } + + foreach opt $names { + if {[dict exists $::autosetup(optset) $opt]} { + set result [lindex [dict get $::autosetup(optset) $opt] end] + } + } + + if {![info exists result]} { + # No user-specified value. Has options-defaults been set? + foreach opt $names { + if {[dict exists $::autosetup(optdefault) $opt]} { + set result [dict get $autosetup(optdefault) $opt] + } + } + } + + if {[info exists result]} { + set value $result + if {$retopt} { + return $value + } + return 1 + } + + if {$retopt} { + set value $default + return $value + } + + return 0 +} + +proc option-check-names {args} { + foreach o $args { + if {$o ni $::autosetup(options)} { + autosetup-error "Request for undeclared option --$o" + } + } +} + +# Parse the option definition in $opts and update +# ::autosetup(setoptions) and ::autosetup(optionhelp) appropriately +# +proc options-add {opts} { + global autosetup + + # First weed out comment lines + set realopts {} + foreach line [split $opts \n] { + if {![string match "#*" [string trimleft $line]]} { + append realopts $line \n + } + } + set opts $realopts + + for {set i 0} {$i < [llength $opts]} {incr i} { + set opt [lindex $opts $i] + if {[string match =* $opt]} { + # This is a special heading + lappend autosetup(optionhelp) [list $opt $autosetup(module)] + continue + } + unset -nocomplain defaultvalue equal value + + #puts "i=$i, opt=$opt" + regexp {^([^:=]*)(:)?(=)?(.*)$} $opt -> name colon equal value + if {$name in $autosetup(options)} { + autosetup-error "Option $name already specified" + } + + #puts "$opt => $name $colon $equal $value" + + # Find the corresponding value in the user options + # and set the default if necessary + if {[string match "-*" $opt]} { + # This is a documentation-only option, like "-C " + set opthelp $opt + } elseif {$colon eq ""} { + # Boolean option + lappend autosetup(options) $name + + # Check for override + if {[dict exists $autosetup(options-defaults) $name]} { + # A default was specified with options-defaults, so use it + set value [dict get $autosetup(options-defaults) $name] + } + + if {$value eq "1"} { + set opthelp "--disable-$name" + } else { + set opthelp "--$name" + } + + # Set the default + if {$value eq ""} { + set value 0 + } + set defaultvalue $value + dict set autosetup(optdefault) $name $defaultvalue + + if {[dict exists $autosetup(getopt) $name]} { + # The option was specified by the user. Look at the last value. + lassign [lindex [dict get $autosetup(getopt) $name] end] type setvalue + if {$type eq "str"} { + # Can we convert the value to a boolean? + if {$setvalue in {1 enabled yes}} { + set setvalue 1 + } elseif {$setvalue in {0 disabled no}} { + set setvalue 0 + } else { + user-error "Boolean option $name given as --$name=$setvalue" + } + } + dict set autosetup(optset) $name $setvalue + #puts "Found boolean option --$name=$setvalue" + } + } else { + # String option. + lappend autosetup(options) $name + + if {$equal ne "="} { + # Was the option given as "name:value=default"? + # If so, set $value to the display name and $defaultvalue to the default + # (This is the preferred way to set a default value for a string option) + if {[regexp {^([^=]+)=(.*)$} $value -> value defaultvalue]} { + dict set autosetup(optdefault) $name $defaultvalue + } + } + + # Maybe override the default value + if {[dict exists $autosetup(options-defaults) $name]} { + # A default was specified with options-defaults, so use it + set defaultvalue [dict get $autosetup(options-defaults) $name] + dict set autosetup(optdefault) $name $defaultvalue + } elseif {![info exists defaultvalue]} { + # No default value was given by value=default or options-defaults + # so use the value as the default when the plain option with no + # value is given (.e.g. just --opt instead of --opt=value) + set defaultvalue $value + } + + if {$equal eq "="} { + # String option with optional value + set opthelp "--$name?=$value?" + } else { + # String option with required value + set opthelp "--$name=$value" + } + + # Get the values specified by the user + if {[dict exists $autosetup(getopt) $name]} { + set listvalue {} + + foreach pair [dict get $autosetup(getopt) $name] { + lassign $pair type setvalue + if {$type eq "bool" && $setvalue} { + if {$equal ne "="} { + user-error "Option --$name requires a value" + } + # If given as a boolean, use the default value + set setvalue $defaultvalue + } + lappend listvalue $setvalue + } + + #puts "Found string option --$name=$listvalue" + dict set autosetup(optset) $name $listvalue + } + } + + # Now create the help for this option if appropriate + if {[lindex $opts $i+1] eq "=>"} { + set desc [lindex $opts $i+2] + if {[info exists defaultvalue]} { + set desc [string map [list @default@ $defaultvalue] $desc] + } + # A multi-line description + lappend autosetup(optionhelp) [list $opthelp $autosetup(module) $desc] + incr i 2 + } + } +} + +# @module-options optionlist +# +# Deprecated. Simply use 'options' from within a module. +proc module-options {opts} { + options $opts +} + +proc max {a b} { + expr {$a > $b ? $a : $b} +} + +proc options-wrap-desc {text length firstprefix nextprefix initial} { + set len $initial + set space $firstprefix + foreach word [split $text] { + set word [string trim $word] + if {$word == ""} { + continue + } + if {$len && [string length $space$word] + $len >= $length} { + puts "" + set len 0 + set space $nextprefix + } + incr len [string length $space$word] + puts -nonewline $space$word + set space " " + } + if {$len} { + puts "" + } +} + +# Display options (from $autosetup(optionhelp)) for modules that match +# glob pattern $what +proc options-show {what} { + set local 0 + # Determine the max option width + set max 0 + foreach help $::autosetup(optionhelp) { + lassign $help opt module desc + if {![string match $what $module]} { + continue + } + if {[string match =* $opt] || [string match \n* $desc]} { + continue + } + set max [max $max [string length $opt]] + } + set indent [string repeat " " [expr {$max+4}]] + set cols [getenv COLUMNS 80] + catch { + lassign [exec stty size] rows cols + } + incr cols -1 + # Now output + foreach help $::autosetup(optionhelp) { + lassign $help opt module desc + if {![string match $what $module]} { + continue + } + if {$local == 0 && $module eq "auto.def"} { + puts "Local Options:" + incr local + } + if {[string match =* $opt]} { + # Output a special heading line" + puts [string range $opt 1 end] + continue + } + puts -nonewline " [format %-${max}s $opt]" + if {[string match \n* $desc]} { + # Output a pre-formatted help description as-is + puts $desc + } else { + options-wrap-desc [string trim $desc] $cols " " $indent [expr {$max+2}] + } + } +} + +# @options optionspec +# +# Specifies configuration-time options which may be selected by the user +# and checked with 'opt-str' and 'opt-bool'. '$optionspec' contains a series +# of options specifications separated by newlines, as follows: +# +# A boolean option is of the form: +# +## name[=0|1] => "Description of this boolean option" +# +# The default is 'name=0', meaning that the option is disabled by default. +# If 'name=1' is used to make the option enabled by default, the description should reflect +# that with text like "Disable support for ...". +# +# An argument option (one which takes a parameter) is of one of the following forms: +# +## name:value => "Description of this option" +## name:value=default => "Description of this option with a default value" +## name:=value => "Description of this option with an optional value" +# +# If the 'name:value' form is used, the value must be provided with the option (as '--name=myvalue'). +# If the 'name:value=default' form is used, the option has the given default value even if not +# specified by the user. +# If the 'name:=value' form is used, the value is optional and the given value is used +# if it is not provided. +# +# The description may contain '@default@', in which case it will be replaced with the default +# value for the option (taking into account defaults specified with 'options-defaults'. +# +# Undocumented options are also supported by omitting the '=> description'. +# These options are not displayed with '--help' and can be useful for internal options or as aliases. +# +# For example, '--disable-lfs' is an alias for '--disable=largefile': +# +## lfs=1 largefile=1 => "Disable large file support" +# +proc options {optlist} { + global autosetup + + options-add $optlist + + if {$autosetup(showhelp)} { + # If --help, stop now to show help + return -code break + } + + if {$autosetup(module) eq "auto.def"} { + # Check for invalid options + if {[opt-bool option-checking]} { + foreach o [dict keys $::autosetup(getopt)] { + if {$o ni $::autosetup(options)} { + user-error "Unknown option --$o" + } + } + } + } +} + +# @options-defaults dictionary +# +# Specifies a dictionary of options and a new default value for each of those options. +# Use before any 'use' statements in 'auto.def' to change the defaults for +# subsequently included modules. +proc options-defaults {dict} { + foreach {n v} $dict { + dict set ::autosetup(options-defaults) $n $v + } +} + +proc config_guess {} { + if {[file-isexec $::autosetup(dir)/autosetup-config.guess]} { + if {[catch {exec-with-stderr sh $::autosetup(dir)/autosetup-config.guess} alias]} { + user-error $alias + } + return $alias + } else { + configlog "No autosetup-config.guess, so using uname" + string tolower [exec uname -p]-unknown-[exec uname -s][exec uname -r] + } +} + +proc config_sub {alias} { + if {[file-isexec $::autosetup(dir)/autosetup-config.sub]} { + if {[catch {exec-with-stderr sh $::autosetup(dir)/autosetup-config.sub $alias} alias]} { + user-error $alias + } + } + return $alias +} + +# @section Variable Definitions (defines) + +# @define name ?value=1? +# +# Defines the named variable to the given value. +# These (name, value) pairs represent the results of the configuration check +# and are available to be subsequently checked, modified and substituted. +# +proc define {name {value 1}} { + set ::define($name) $value + #dputs "$name <= $value" +} + +# @define-push {name ...} script +# +# Save the values of the given defines, evaluation the script, then restore. +# For example, to avoid updating AS_FLAGS and AS_CXXFLAGS: +## define-push {AS_CFLAGS AS_CXXFLAGS} { +## cc-check-flags -Wno-error +## } +proc define-push {names script} { + array set unset {} + foreach name $names { + if {[is-defined $name]} { + set save($name) [get-define $name] + } else { + set unset($name) 1 + } + } + uplevel 1 $script + array set ::define [array get save] + foreach name [array names unset] { + unset -nocomplain ::define($name) + } +} + +# @undefine name +# +# Undefine the named variable. +# +proc undefine {name} { + unset -nocomplain ::define($name) + #dputs "$name <= " +} + +# @define-append name value ... +# +# Appends the given value(s) to the given "defined" variable. +# If the variable is not defined or empty, it is set to '$value'. +# Otherwise the value is appended, separated by a space. +# Any extra values are similarly appended. +# +# Note that define-append is not designed to add values containing spaces. +# If values may contain spaces, consider define-append-argv instead. +# +proc define-append {name args} { + if {[get-define $name ""] ne ""} { + foreach arg $args { + if {$arg eq ""} { + continue + } + append ::define($name) " " $arg + } + } else { + set ::define($name) [join $args] + } + #dputs "$name += [join $args] => $::define($name)" +} + +# @define-append-argv name value ... +# +# Similar to define-append except designed to construct shell command +# lines, including correct handling of parameters with spaces. +# +# Each non-empty value is quoted if necessary and then appended to the given variable +# if it does not already exist. +# +proc define-append-argv {name args} { + set seen {} + set new {} + foreach val [list {*}[get-define $name ""] {*}$args] { + if {$val ne {} && ![dict exists $seen $val]} { + lappend new [quote-if-needed $val] + dict set seen $val 1 + } + } + set ::define($name) [join $new " "] + #dputs "$name += [join $args] => $::define($name)" +} + +# @get-define name ?default=0? +# +# Returns the current value of the "defined" variable, or '$default' +# if not set. +# +proc get-define {name {default 0}} { + if {[info exists ::define($name)]} { + #dputs "$name => $::define($name)" + return $::define($name) + } + #dputs "$name => $default" + return $default +} + +# @is-defined name +# +# Returns 1 if the given variable is defined. +# +proc is-defined {name} { + info exists ::define($name) +} + +# @is-define-set name +# +# Returns 1 if the given variable is defined and is set +# to a value other than "" or 0 +# +proc is-define-set {name} { + if {[get-define $name] in {0 ""}} { + return 0 + } + return 1 +} + +# @all-defines +# +# Returns a dictionary (name, value list) of all defined variables. +# +# This is suitable for use with 'dict', 'array set' or 'foreach' +# and allows for arbitrary processing of the defined variables. +# +proc all-defines {} { + array get ::define +} + +# @section Environment/Helpers + +# @get-env name default +# +# If '$name' was specified on the command line, return it. +# Otherwise if '$name' was set in the environment, return it. +# Otherwise return '$default'. +# +proc get-env {name default} { + if {[dict exists $::autosetup(cmdline) $name]} { + return [dict get $::autosetup(cmdline) $name] + } + getenv $name $default +} + +# @env-is-set name +# +# Returns 1 if '$name' was specified on the command line or in the environment. +# Note that an empty environment variable is not considered to be set. +# +proc env-is-set {name} { + if {[dict exists $::autosetup(cmdline) $name]} { + return 1 + } + if {[getenv $name ""] ne ""} { + return 1 + } + return 0 +} + +# @readfile filename ?default=""? +# +# Return the contents of the file, without the trailing newline. +# If the file doesn't exist or can't be read, returns '$default'. +# +proc readfile {filename {default_value ""}} { + set result $default_value + catch { + set f [open $filename] + set result [read -nonewline $f] + close $f + } + return $result +} + +# @writefile filename value +# +# Creates the given file containing '$value'. +# Does not add an extra newline. +# +proc writefile {filename value} { + set f [open $filename w] + puts -nonewline $f $value + close $f +} + +proc quote-if-needed {str} { + if {[string match {*[\" ]*} $str]} { + return \"[string map [list \" \\" \\ \\\\] $str]\" + } + return $str +} + +proc quote-argv {argv} { + set args {} + foreach arg $argv { + lappend args [quote-if-needed $arg] + } + join $args +} + +# @list-non-empty list +# +# Returns a copy of the given list with empty elements removed +proc list-non-empty {list} { + set result {} + foreach p $list { + if {$p ne ""} { + lappend result $p + } + } + return $result +} + +# @section Paths, Searching + +# @find-executable-path name +# +# Searches the path for an executable with the given name. +# Note that the name may include some parameters, e.g. 'cc -mbig-endian', +# in which case the parameters are ignored. +# The full path to the executable if found, or "" if not found. +# Returns 1 if found, or 0 if not. +# +proc find-executable-path {name} { + # Ignore any parameters + set name [lindex $name 0] + # The empty string is never a valid executable + if {$name ne ""} { + foreach p [split-path] { + dputs "Looking for $name in $p" + set exec [file join $p $name] + if {[file-isexec $exec]} { + dputs "Found $name -> $exec" + return $exec + } + } + } + return {} +} + +# @find-executable name +# +# Searches the path for an executable with the given name. +# Note that the name may include some parameters, e.g. 'cc -mbig-endian', +# in which case the parameters are ignored. +# Returns 1 if found, or 0 if not. +# +proc find-executable {name} { + if {[find-executable-path $name] eq {}} { + return 0 + } + return 1 +} + +# @find-an-executable ?-required? name ... +# +# Given a list of possible executable names, +# searches for one of these on the path. +# +# Returns the name found, or "" if none found. +# If the first parameter is '-required', an error is generated +# if no executable is found. +# +proc find-an-executable {args} { + set required 0 + if {[lindex $args 0] eq "-required"} { + set args [lrange $args 1 end] + incr required + } + foreach name $args { + if {[find-executable $name]} { + return $name + } + } + if {$required} { + if {[llength $args] == 1} { + user-error "failed to find: [join $args]" + } else { + user-error "failed to find one of: [join $args]" + } + } + return "" +} + +# @section Logging, Messages and Errors + +# @configlog msg +# +# Writes the given message to the configuration log, 'config.log'. +# +proc configlog {msg} { + if {![info exists ::autosetup(logfh)]} { + set ::autosetup(logfh) [open config.log w] + } + puts $::autosetup(logfh) $msg +} + +# @msg-checking msg +# +# Writes the message with no newline to stdout. +# +proc msg-checking {msg} { + if {$::autosetup(msg-quiet) == 0} { + maybe-show-timestamp + puts -nonewline $msg + set ::autosetup(msg-checking) 1 + } +} + +# @msg-result msg +# +# Writes the message to stdout. +# +proc msg-result {msg} { + if {$::autosetup(msg-quiet) == 0} { + maybe-show-timestamp + puts $msg + set ::autosetup(msg-checking) 0 + show-notices + } +} + +# @msg-quiet command ... +# +# 'msg-quiet' evaluates it's arguments as a command with output +# from 'msg-checking' and 'msg-result' suppressed. +# +# This is useful if a check needs to run a subcheck which isn't +# of interest to the user. +proc msg-quiet {args} { + incr ::autosetup(msg-quiet) + set rc [uplevel 1 $args] + incr ::autosetup(msg-quiet) -1 + return $rc +} + +# Will be overridden by 'use misc' +proc error-stacktrace {msg} { + return $msg +} + +proc error-location {msg} { + return $msg +} + +################################################################## +# +# Debugging output +# +proc dputs {msg} { + if {$::autosetup(debug)} { + puts $msg + } +} + +################################################################## +# +# User and system warnings and errors +# +# Usage errors such as wrong command line options + +# @user-error msg +# +# Indicate incorrect usage to the user, including if required components +# or features are not found. +# 'autosetup' exits with a non-zero return code. +# +proc user-error {msg} { + show-notices + puts stderr "Error: $msg" + puts stderr "Try: '[file tail $::autosetup(exe)] --help' for options" + exit 1 +} + +# @user-notice msg +# +# Output the given message to stderr. +# +proc user-notice {msg} { + lappend ::autosetup(notices) $msg +} + +# Incorrect usage in the auto.def file. Identify the location. +proc autosetup-error {msg} { + autosetup-full-error [error-location $msg] +} + +# Like autosetup-error, except $msg is the full error message. +proc autosetup-full-error {msg} { + show-notices + puts stderr $msg + exit 1 +} + +proc show-notices {} { + if {$::autosetup(msg-checking)} { + puts "" + set ::autosetup(msg-checking) 0 + } + flush stdout + if {[info exists ::autosetup(notices)]} { + puts stderr [join $::autosetup(notices) \n] + unset ::autosetup(notices) + } +} + +proc maybe-show-timestamp {} { + if {$::autosetup(msg-timing) && $::autosetup(msg-checking) == 0} { + puts -nonewline [format {[%6.2f] } [expr {([clock millis] - $::autosetup(start)) % 10000 / 1000.0}]] + } +} + +# @autosetup-require-version required +# +# Checks the current version of 'autosetup' against '$required'. +# A fatal error is generated if the current version is less than that required. +# +proc autosetup-require-version {required} { + if {[compare-versions $::autosetup(version) $required] < 0} { + user-error "autosetup version $required is required, but this is $::autosetup(version)" + } +} + +proc autosetup_version {} { + return "autosetup v$::autosetup(version)" +} + +################################################################## +# +# Directory/path handling +# + +proc realdir {dir} { + set oldpwd [pwd] + cd $dir + set pwd [pwd] + cd $oldpwd + return $pwd +} + +# Follow symlinks until we get to something which is not a symlink +proc realpath {path} { + while {1} { + if {[catch { + set path [file readlink $path] + }]} { + # Not a link + break + } + } + return $path +} + +# Convert absolute path, $path into a path relative +# to the given directory (or the current dir, if not given). +# +proc relative-path {path {pwd {}}} { + set diff 0 + set same 0 + set newf {} + set prefix {} + set path [file-normalize $path] + if {$pwd eq ""} { + set pwd [pwd] + } else { + set pwd [file-normalize $pwd] + } + + if {$path eq $pwd} { + return . + } + + # Try to make the filename relative to the current dir + foreach p [split $pwd /] f [split $path /] { + if {$p ne $f} { + incr diff + } elseif {!$diff} { + incr same + } + if {$diff} { + if {$p ne ""} { + # Add .. for sibling or parent dir + lappend prefix .. + } + if {$f ne ""} { + lappend newf $f + } + } + } + if {$same == 1 || [llength $prefix] > 3} { + return $path + } + + file join [join $prefix /] [join $newf /] +} + +# Add filename as a dependency to rerun autosetup +# The name will be normalised (converted to a full path) +# +proc autosetup_add_dep {filename} { + lappend ::autosetup(deps) [file-normalize $filename] +} + +# @section Modules Support + +################################################################## +# +# Library module support +# + +# @use module ... +# +# Load the given library modules. +# e.g. 'use cc cc-shared' +# +# Note that module 'X' is implemented in either 'autosetup/X.tcl' +# or 'autosetup/X/init.tcl' +# +# The latter form is useful for a complex module which requires additional +# support file. In this form, '$::usedir' is set to the module directory +# when it is loaded. +# +proc use {args} { + global autosetup libmodule modsource + + set dirs [list $autosetup(libdir)] + if {[info exists autosetup(srcdir)]} { + lappend dirs $autosetup(srcdir)/autosetup + } + foreach m $args { + if {[info exists libmodule($m)]} { + continue + } + set libmodule($m) 1 + + if {[info exists modsource(${m}.tcl)]} { + autosetup_load_module $m eval $modsource(${m}.tcl) + } else { + set locs [list ${m}.tcl ${m}/init.tcl] + set found 0 + foreach dir $dirs { + foreach loc $locs { + set source $dir/$loc + if {[file exists $source]} { + incr found + break + } + } + if {$found} { + break + } + } + if {$found} { + # For the convenience of the "use" source, point to the directory + # it is being loaded from + set ::usedir [file dirname $source] + autosetup_load_module $m source $source + autosetup_add_dep $source + } else { + autosetup-error "use: No such module: $m" + } + } + } +} + +proc autosetup_load_auto_modules {} { + global autosetup modsource + # First load any embedded auto modules + foreach mod [array names modsource *.auto] { + autosetup_load_module $mod eval $modsource($mod) + } + # Now any external auto modules + foreach file [glob -nocomplain $autosetup(libdir)/*.auto $autosetup(libdir)/*/*.auto] { + autosetup_load_module [file tail $file] source $file + } +} + +# Load module source in the global scope by executing the given command +proc autosetup_load_module {module args} { + global autosetup + set prev $autosetup(module) + set autosetup(module) $module + + if {[catch [list uplevel #0 $args] msg opts] ni {0 2 3}} { + autosetup-full-error [error-dump $msg $opts $::autosetup(debug)] + } + set autosetup(module) $prev +} + +# Initial settings +set autosetup(exe) $::argv0 +set autosetup(istcl) 1 +set autosetup(start) [clock millis] +set autosetup(installed) 0 +set autosetup(sysinstall) 0 +set autosetup(msg-checking) 0 +set autosetup(msg-quiet) 0 +set autosetup(inittypes) {} +set autosetup(module) autosetup + +# Embedded modules are inserted below here +set autosetup(installed) 1 +set autosetup(sysinstall) 0 +# ----- @module asciidoc-formatting.tcl ----- + +set modsource(asciidoc-formatting.tcl) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides text formatting +# asciidoc format + +use formatting + +proc para {text} { + regsub -all "\[ \t\n\]+" [string trim $text] " " +} +proc title {text} { + underline [para $text] = + nl +} +proc p {text} { + puts [para $text] + nl +} +proc code {text} { + foreach line [parse_code_block $text] { + puts " $line" + } + nl +} +proc codelines {lines} { + foreach line $lines { + puts " $line" + } + nl +} +proc nl {} { + puts "" +} +proc underline {text char} { + regexp "^(\[ \t\]*)(.*)" $text -> indent words + puts $text + puts $indent[string repeat $char [string length $words]] +} +proc section {text} { + underline "[para $text]" - + nl +} +proc subsection {text} { + underline "$text" ~ + nl +} +proc bullet {text} { + puts "* [para $text]" +} +proc indent {text} { + puts " :: " + puts [para $text] +} +proc defn {first args} { + set sep "" + if {$first ne ""} { + puts "${first}::" + } else { + puts " :: " + } + set defn [string trim [join $args \n]] + regsub -all "\n\n" $defn "\n ::\n" defn + puts $defn +} +} + +# ----- @module formatting.tcl ----- + +set modsource(formatting.tcl) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides common text formatting + +# This is designed for documentation which looks like: +# code {...} +# or +# code { +# ... +# ... +# } +# In the second case, we need to work out the indenting +# and strip it from all lines but preserve the remaining indenting. +# Note that all lines need to be indented with the same initial +# spaces/tabs. +# +# Returns a list of lines with the indenting removed. +# +proc parse_code_block {text} { + # If the text begins with newline, take the following text, + # otherwise just return the original + if {![regexp "^\n(.*)" $text -> text]} { + return [list [string trim $text]] + } + + # And trip spaces off the end + set text [string trimright $text] + + set min 100 + # Examine each line to determine the minimum indent + foreach line [split $text \n] { + if {$line eq ""} { + # Ignore empty lines for the indent calculation + continue + } + regexp "^(\[ \t\]*)" $line -> indent + set len [string length $indent] + if {$len < $min} { + set min $len + } + } + + # Now make a list of lines with this indent removed + set lines {} + foreach line [split $text \n] { + lappend lines [string range $line $min end] + } + + # Return the result + return $lines +} +} + +# ----- @module getopt.tcl ----- + +set modsource(getopt.tcl) { +# Copyright (c) 2006 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Simple getopt module + +# Parse everything out of the argv list which looks like an option +# Everything which doesn't look like an option, or is after --, is left unchanged +# Understands --enable-xxx as a synonym for --xxx to enable the boolean option xxx. +# Understands --disable-xxx to disable the boolean option xxx. +# +# The returned value is a dictionary keyed by option name +# Each value is a list of {type value} ... where type is "bool" or "str". +# The value for a boolean option is 0 or 1. The value of a string option is the value given. +proc getopt {argvname} { + upvar $argvname argv + set nargv {} + + set opts {} + + for {set i 0} {$i < [llength $argv]} {incr i} { + set arg [lindex $argv $i] + + #dputs arg=$arg + + if {$arg eq "--"} { + # End of options + incr i + lappend nargv {*}[lrange $argv $i end] + break + } + + if {[regexp {^--([^=][^=]+)=(.*)$} $arg -> name value]} { + # --name=value + dict lappend opts $name [list str $value] + } elseif {[regexp {^--(enable-|disable-)?([^=]*)$} $arg -> prefix name]} { + if {$prefix in {enable- ""}} { + set value 1 + } else { + set value 0 + } + dict lappend opts $name [list bool $value] + } else { + lappend nargv $arg + } + } + + #puts "getopt: argv=[join $argv] => [join $nargv]" + #array set getopt $opts + #parray getopt + + set argv $nargv + + return $opts +} +} + +# ----- @module help.tcl ----- + +set modsource(help.tcl) { +# Copyright (c) 2010 WorkWare Systems http://workware.net.au/ +# All rights reserved + +# Module which provides usage, help and the command reference + +proc autosetup_help {what} { + use_pager + + puts "Usage: [file tail $::autosetup(exe)] \[options\] \[settings\]\n" + puts "This is [autosetup_version], a build environment \"autoconfigurator\"" + puts "See the documentation online at https://msteveb.github.io/autosetup/\n" + + if {$what in {all local}} { + # Need to load auto.def now + if {[file exists $::autosetup(autodef)]} { + # Load auto.def as module "auto.def" + autosetup_load_module auto.def source $::autosetup(autodef) + } + if {$what eq "all"} { + set what * + } else { + set what auto.def + } + } else { + use $what + puts "Options for module $what:" + } + options-show $what + exit 0 +} + +proc autosetup_show_license {} { + global modsource autosetup + use_pager + + if {[info exists modsource(LICENSE)]} { + puts $modsource(LICENSE) + return + } + foreach dir [list $autosetup(libdir) $autosetup(srcdir)] { + set path [file join $dir LICENSE] + if {[file exists $path]} { + puts [readfile $path] + return + } + } + puts "LICENSE not found" +} + +# If not already paged and stdout is a tty, pipe the output through the pager +# This is done by reinvoking autosetup with --nopager added +proc use_pager {} { + if {![opt-bool nopager] && [getenv PAGER ""] ne "" && [isatty? stdin] && [isatty? stdout]} { + if {[catch { + exec [info nameofexecutable] $::argv0 --nopager {*}$::argv |& {*}[getenv PAGER] >@stdout <@stdin 2>@stderr + } msg opts] == 1} { + if {[dict get $opts -errorcode] eq "NONE"} { + # an internal/exec error + puts stderr $msg + exit 1 + } + } + exit 0 + } +} + +# Outputs the autosetup references in one of several formats +proc autosetup_reference {{type text}} { + + use_pager + + switch -glob -- $type { + wiki {use wiki-formatting} + ascii* {use asciidoc-formatting} + md - markdown {use markdown-formatting} + default {use text-formatting} + } + + title "[autosetup_version] -- Command Reference" + + section {Introduction} + + p { + See https://msteveb.github.io/autosetup/ for the online documentation for 'autosetup'. + This documentation can also be accessed locally with `autosetup --ref`. + } + + p { + 'autosetup' provides a number of built-in commands which + are documented below. These may be used from 'auto.def' to test + for features, define variables, create files from templates and + other similar actions. + } + + automf_command_reference + + exit 0 +} + +proc autosetup_output_block {type lines} { + if {[llength $lines]} { + switch $type { + section { + section $lines + } + subsection { + subsection $lines + } + code { + codelines $lines + } + p { + p [join $lines] + } + list { + foreach line $lines { + bullet $line + } + nl + } + } + } +} + +# Generate a command reference from inline documentation +proc automf_command_reference {} { + lappend files $::autosetup(prog) + lappend files {*}[lsort [glob -nocomplain $::autosetup(libdir)/*.tcl]] + + # We want to process all non-module files before module files + # and then modules in alphabetical order. + # So examine all files and extract docs into doc($modulename) and doc(_core_) + # + # Each entry is a list of {type data} where $type is one of: section, subsection, code, list, p + # and $data is a string for section, subsection or a list of text lines for other types. + + # XXX: Should commands be in alphabetical order too? Currently they are in file order. + + set doc(_core_) {} + lappend doc(_core_) [list section "Core Commands"] + + foreach file $files { + set modulename [file rootname [file tail $file]] + set current _core_ + set f [open $file] + while {![eof $f]} { + set line [gets $f] + + if {[regexp {^#.*@section (.*)$} $line -> section]} { + lappend doc($current) [list section $section] + continue + } + + # Find embedded module names + if {[regexp {^#.*@module ([^ ]*)} $line -> modulename]} { + continue + } + + # Find lines starting with "# @*" and continuing through the remaining comment lines + if {![regexp {^# @(.*)} $line -> cmd]} { + continue + } + + # Synopsis or command? + if {$cmd eq "synopsis:"} { + set current $modulename + lappend doc($current) [list section "Module: $modulename"] + } else { + lappend doc($current) [list subsection $cmd] + } + + set lines {} + set type p + + # Now the description + while {![eof $f]} { + set line [gets $f] + + if {![regexp {^#(#)? ?(.*)} $line -> hash cmd]} { + break + } + if {$hash eq "#"} { + set t code + } elseif {[regexp {^- (.*)} $cmd -> cmd]} { + set t list + } else { + set t p + } + + #puts "hash=$hash, oldhash=$oldhash, lines=[llength $lines], cmd=$cmd" + + if {$t ne $type || $cmd eq ""} { + # Finish the current block + lappend doc($current) [list $type $lines] + set lines {} + set type $t + } + if {$cmd ne ""} { + lappend lines $cmd + } + } + + lappend doc($current) [list $type $lines] + } + close $f + } + + # Now format and output the results + + # _core_ will sort first + foreach module [lsort [array names doc]] { + foreach item $doc($module) { + autosetup_output_block {*}$item + } + } +} +} + +# ----- @module init.tcl ----- + +set modsource(init.tcl) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module to help create auto.def and configure + +proc autosetup_init {type} { + set help 0 + if {$type in {? help}} { + incr help + } elseif {![dict exists $::autosetup(inittypes) $type]} { + puts "Unknown type, --init=$type" + incr help + } + if {$help} { + puts "Use one of the following types (e.g. --init=make)\n" + foreach type [lsort [dict keys $::autosetup(inittypes)]] { + lassign [dict get $::autosetup(inittypes) $type] desc + # XXX: Use the options-show code to wrap the description + puts [format "%-10s %s" $type $desc] + } + return + } + lassign [dict get $::autosetup(inittypes) $type] desc script + + puts "Initialising $type: $desc\n" + + # All initialisations happens in the top level srcdir + cd $::autosetup(srcdir) + + uplevel #0 $script +} + +proc autosetup_add_init_type {type desc script} { + dict set ::autosetup(inittypes) $type [list $desc $script] +} + +# This is for in creating build-system init scripts +# +# If the file doesn't exist, create it containing $contents +# If the file does exist, only overwrite if --force is specified. +# +proc autosetup_check_create {filename contents} { + if {[file exists $filename]} { + if {!$::autosetup(force)} { + puts "I see $filename already exists." + return + } else { + puts "I will overwrite the existing $filename because you used --force." + } + } else { + puts "I don't see $filename, so I will create it." + } + writefile $filename $contents +} +} + +# ----- @module install.tcl ----- + +set modsource(install.tcl) { +# Copyright (c) 2006-2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which can install autosetup + +# autosetup(installed)=1 means that autosetup is not running from source +# autosetup(sysinstall)=1 means that autosetup is running from a sysinstall version +# shared=1 means that we are trying to do a sysinstall. This is only possible from the development source. + +proc autosetup_install {dir {shared 0}} { + global autosetup + if {$shared} { + if {$autosetup(installed) || $autosetup(sysinstall)} { + user-error "Can only --sysinstall from development sources" + } + } elseif {$autosetup(installed) && !$autosetup(sysinstall)} { + user-error "Can't --install from project install" + } + + if {$autosetup(sysinstall)} { + # This is the sysinstall version, so install just uses references + cd $dir + + puts "[autosetup_version] creating configure to use system-installed autosetup" + autosetup_create_configure 1 + puts "Creating autosetup/README.autosetup" + file mkdir autosetup + autosetup_install_readme autosetup/README.autosetup 1 + return + } + + if {[catch { + if {$shared} { + set target $dir/bin/autosetup + set installedas $target + } else { + if {$dir eq "."} { + set installedas autosetup + } else { + set installedas $dir/autosetup + } + cd $dir + file mkdir autosetup + set target autosetup/autosetup + } + set targetdir [file dirname $target] + file mkdir $targetdir + + set f [open $target w] + + set publicmodules {} + + # First the main script, but only up until "CUT HERE" + set in [open $autosetup(dir)/autosetup] + while {[gets $in buf] >= 0} { + if {$buf ne "##-- CUT HERE --##"} { + puts $f $buf + continue + } + + # Insert the static modules here + # i.e. those which don't contain @synopsis: + # All modules are inserted if $shared is set + puts $f "set autosetup(installed) 1" + puts $f "set autosetup(sysinstall) $shared" + foreach file [lsort [glob $autosetup(libdir)/*.{tcl,auto}]] { + set modname [file tail $file] + set ext [file ext $modname] + set buf [readfile $file] + if {!$shared} { + if {$ext eq ".auto" || [string match "*\n# @synopsis:*" $buf]} { + lappend publicmodules $file + continue + } + } + dputs "install: importing lib/[file tail $file]" + puts $f "# ----- @module $modname -----" + puts $f "\nset modsource($modname) \{" + puts $f $buf + puts $f "\}\n" + } + if {$shared} { + foreach {srcname destname} [list $autosetup(libdir)/README.autosetup-lib README.autosetup \ + $autosetup(srcdir)/LICENSE LICENSE] { + dputs "install: importing $srcname as $destname" + puts $f "\nset modsource($destname) \\\n[list [readfile $srcname]\n]\n" + } + } + } + close $in + close $f + catch {exec chmod 755 $target} + + set installfiles {autosetup-config.guess autosetup-config.sub autosetup-test-tclsh} + set removefiles {} + + if {!$shared} { + autosetup_install_readme $targetdir/README.autosetup 0 + + # Install public modules + foreach file $publicmodules { + set tail [file tail $file] + autosetup_install_file $file $targetdir/$tail + } + lappend installfiles jimsh0.c autosetup-find-tclsh LICENSE + lappend removefiles config.guess config.sub test-tclsh find-tclsh + } else { + lappend installfiles {sys-find-tclsh autosetup-find-tclsh} + } + + # Install support files + foreach fileinfo $installfiles { + if {[llength $fileinfo] == 2} { + lassign $fileinfo source dest + } else { + lassign $fileinfo source + set dest $source + } + autosetup_install_file $autosetup(dir)/$source $targetdir/$dest + } + + # Remove obsolete files + foreach file $removefiles { + if {[file exists $targetdir/$file]} { + file delete $targetdir/$file + } + } + } error]} { + user-error "Failed to install autosetup: $error" + } + if {$shared} { + set type "system" + } else { + set type "local" + } + puts "Installed $type [autosetup_version] to $installedas" + + if {!$shared} { + # Now create 'configure' if necessary + autosetup_create_configure 0 + } +} + +proc autosetup_create_configure {shared} { + if {[file exists configure]} { + if {!$::autosetup(force)} { + # Could this be an autosetup configure? + if {![string match "*\nWRAPPER=*" [readfile configure]]} { + puts "I see configure, but not created by autosetup, so I won't overwrite it." + puts "Remove it or use --force to overwrite." + return + } + } else { + puts "I will overwrite the existing configure because you used --force." + } + } else { + puts "I don't see configure, so I will create it." + } + if {$shared} { + writefile configure \ +{#!/bin/sh +WRAPPER="$0"; export WRAPPER; "autosetup" "$@" +} + } else { + writefile configure \ +{#!/bin/sh +dir="`dirname "$0"`/autosetup" +#@@INITCHECK@@# +WRAPPER="$0"; export WRAPPER; exec "`"$dir/autosetup-find-tclsh"`" "$dir/autosetup" "$@" +} + } + catch {exec chmod 755 configure} +} + +# Append the contents of $file to filehandle $f +proc autosetup_install_append {f file} { + dputs "install: include $file" + set in [open $file] + puts $f [read $in] + close $in +} + +proc autosetup_install_file {source target} { + dputs "install: $source => $target" + if {![file exists $source]} { + error "Missing installation file '$source'" + } + writefile $target [readfile $source]\n + # If possible, copy the file mode + file stat $source stat + set mode [format %o [expr {$stat(mode) & 0x1ff}]] + catch {exec chmod $mode $target} +} + +proc autosetup_install_readme {target sysinstall} { + set readme "README.autosetup created by [autosetup_version]\n\n" + if {$sysinstall} { + append readme \ +{This is the autosetup directory for a system install of autosetup. +Loadable modules can be added here. +} + } else { + append readme \ +{This is the autosetup directory for a local install of autosetup. +It contains autosetup, support files and loadable modules. +} +} + + append readme { +*.tcl files in this directory are optional modules which +can be loaded with the 'use' directive. + +*.auto files in this directory are auto-loaded. + +For more information, see https://msteveb.github.io/autosetup/ +} + dputs "install: autosetup/README.autosetup" + writefile $target $readme +} +} + +# ----- @module markdown-formatting.tcl ----- + +set modsource(markdown-formatting.tcl) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides text formatting +# markdown format (kramdown syntax) + +use formatting + +proc para {text} { + regsub -all "\[ \t\n\]+" [string trim $text] " " text + regsub -all {([^a-zA-Z])'([^']*)'} $text {\1**`\2`**} text + regsub -all {^'([^']*)'} $text {**`\1`**} text + regsub -all {(http[^ \t\n]*)} $text {[\1](\1)} text + return $text +} +proc title {text} { + underline [para $text] = + nl +} +proc p {text} { + puts [para $text] + nl +} +proc codelines {lines} { + puts "~~~~~~~~~~~~" + foreach line $lines { + puts $line + } + puts "~~~~~~~~~~~~" + nl +} +proc code {text} { + puts "~~~~~~~~~~~~" + foreach line [parse_code_block $text] { + puts $line + } + puts "~~~~~~~~~~~~" + nl +} +proc nl {} { + puts "" +} +proc underline {text char} { + regexp "^(\[ \t\]*)(.*)" $text -> indent words + puts $text + puts $indent[string repeat $char [string length $words]] +} +proc section {text} { + underline "[para $text]" - + nl +} +proc subsection {text} { + puts "### `$text`" + nl +} +proc bullet {text} { + puts "* [para $text]" +} +proc defn {first args} { + puts "^" + set defn [string trim [join $args \n]] + if {$first ne ""} { + puts "**${first}**" + puts -nonewline ": " + regsub -all "\n\n" $defn "\n: " defn + } + puts "$defn" +} +} + +# ----- @module misc.tcl ----- + +set modsource(misc.tcl) { +# Copyright (c) 2007-2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module containing misc procs useful to modules +# Largely for platform compatibility + +set autosetup(istcl) [info exists ::tcl_library] +set autosetup(iswin) [string equal windows $tcl_platform(platform)] + +if {$autosetup(iswin)} { + # mingw/windows separates $PATH with semicolons + # and doesn't have an executable bit + proc split-path {} { + split [getenv PATH .] {;} + } + proc file-isexec {exec} { + # Basic test for windows. We ignore .bat + if {[file isfile $exec] || [file isfile $exec.exe]} { + return 1 + } + return 0 + } +} else { + # unix separates $PATH with colons and has and executable bit + proc split-path {} { + split [getenv PATH .] : + } + proc file-isexec {exec} { + file executable $exec + } +} + +# Assume that exec can return stdout and stderr +proc exec-with-stderr {args} { + exec {*}$args 2>@1 +} + +if {$autosetup(istcl)} { + # Tcl doesn't have the env command + proc getenv {name args} { + if {[info exists ::env($name)]} { + return $::env($name) + } + if {[llength $args]} { + return [lindex $args 0] + } + return -code error "environment variable \"$name\" does not exist" + } + proc isatty? {channel} { + dict exists [fconfigure $channel] -xchar + } + # Jim-compatible stacktrace using info frame + proc stacktrace {} { + set stacktrace {} + # 2 to skip the current frame + for {set i 2} {$i < [info frame]} {incr i} { + set frame [info frame -$i] + if {[dict exists $frame file]} { + # We don't need proc, so use "" + lappend stacktrace "" [dict get $frame file] [dict get $frame line] + } + } + return $stacktrace + } +} else { + if {$autosetup(iswin)} { + # On Windows, backslash convert all environment variables + # (Assume that Tcl does this for us) + proc getenv {name args} { + string map {\\ /} [env $name {*}$args] + } + } else { + # Jim on unix is simple + alias getenv env + } + proc isatty? {channel} { + set tty 0 + catch { + # isatty is a recent addition to Jim Tcl + set tty [$channel isatty] + } + return $tty + } +} + +# In case 'file normalize' doesn't exist +# +proc file-normalize {path} { + if {[catch {file normalize $path} result]} { + if {$path eq ""} { + return "" + } + set oldpwd [pwd] + if {[file isdir $path]} { + cd $path + set result [pwd] + } else { + cd [file dirname $path] + set result [file join [pwd] [file tail $path]] + } + cd $oldpwd + } + return $result +} + +# If everything is working properly, the only errors which occur +# should be generated in user code (e.g. auto.def). +# By default, we only want to show the error location in user code. +# We use [info frame] to achieve this, but it works differently on Tcl and Jim. +# +# This is designed to be called for incorrect usage in auto.def, via autosetup-error +# +proc error-location {msg} { + if {$::autosetup(debug)} { + return -code error $msg + } + # Search back through the stack trace for the first error in a .def file + foreach {p f l} [stacktrace] { + if {[string match *.def $f]} { + return "[relative-path $f]:$l: Error: $msg" + } + #puts "Skipping $f:$l" + } + return $msg +} + +# If everything is working properly, the only errors which occur +# should be generated in user code (e.g. auto.def). +# By default, we only want to show the error location in user code. +# We use [info frame] to achieve this, but it works differently on Tcl and Jim. +# +# This is designed to be called for incorrect usage in auto.def, via autosetup-error +# +proc error-stacktrace {msg} { + if {$::autosetup(debug)} { + return -code error $msg + } + # Search back through the stack trace for the first error in a .def file + for {set i 1} {$i < [info level]} {incr i} { + if {$::autosetup(istcl)} { + array set info [info frame -$i] + } else { + lassign [info frame -$i] info(caller) info(file) info(line) + } + if {[string match *.def $info(file)]} { + return "[relative-path $info(file)]:$info(line): Error: $msg" + } + #puts "Skipping $info(file):$info(line)" + } + return $msg +} + +# Given the return from [catch {...} msg opts], returns an appropriate +# error message. A nice one for Jim and a less-nice one for Tcl. +# If 'fulltrace' is set, a full stack trace is provided. +# Otherwise a simple message is provided. +# +# This is designed for developer errors, e.g. in module code or auto.def code +# +# +proc error-dump {msg opts fulltrace} { + if {$::autosetup(istcl)} { + if {$fulltrace} { + return "Error: [dict get $opts -errorinfo]" + } else { + return "Error: $msg" + } + } else { + lassign $opts(-errorinfo) p f l + if {$f ne ""} { + set result "$f:$l: Error: " + } + append result "$msg\n" + if {$fulltrace} { + append result [stackdump $opts(-errorinfo)] + } + + # Remove the trailing newline + string trim $result + } +} +} + +# ----- @module text-formatting.tcl ----- + +set modsource(text-formatting.tcl) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides text formatting + +use formatting + +proc wordwrap {text length {firstprefix ""} {nextprefix ""}} { + set len 0 + set space $firstprefix + + foreach word [split $text] { + set word [string trim $word] + if {$word eq ""} { + continue + } + if {[info exists partial]} { + append partial " " $word + if {[string first $quote $word] < 0} { + # Haven't found end of quoted word + continue + } + # Finished quoted word + set word $partial + unset partial + unset quote + } else { + set quote [string index $word 0] + if {$quote in {' *}} { + if {[string first $quote $word 1] < 0} { + # Haven't found end of quoted word + # Not a whole word. + set first [string index $word 0] + # Start of quoted word + set partial $word + continue + } + } + } + + if {$len && [string length $space$word] + $len >= $length} { + puts "" + set len 0 + set space $nextprefix + } + incr len [string length $space$word] + + # Use man-page conventions for highlighting 'quoted' and *quoted* + # single words. + # Use x^Hx for *bold* and _^Hx for 'underline'. + # + # less and more will both understand this. + # Pipe through 'col -b' to remove them. + if {[regexp {^'(.*)'(.*)} $word -> quoted after]} { + set quoted [string map {~ " "} $quoted] + regsub -all . $quoted "&\b&" quoted + set word $quoted$after + } elseif {[regexp {^[*](.*)[*](.*)} $word -> quoted after]} { + set quoted [string map {~ " "} $quoted] + regsub -all . $quoted "_\b&" quoted + set word $quoted$after + } + puts -nonewline $space$word + set space " " + } + if {[info exists partial]} { + # Missing end of quote + puts -nonewline $space$partial + } + if {$len} { + puts "" + } +} +proc title {text} { + underline [string trim $text] = + nl +} +proc p {text} { + wordwrap $text 80 + nl +} +proc codelines {lines} { + foreach line $lines { + puts " $line" + } + nl +} +proc nl {} { + puts "" +} +proc underline {text char} { + regexp "^(\[ \t\]*)(.*)" $text -> indent words + puts $text + puts $indent[string repeat $char [string length $words]] +} +proc section {text} { + underline "[string trim $text]" - + nl +} +proc subsection {text} { + underline "$text" ~ + nl +} +proc bullet {text} { + wordwrap $text 76 " * " " " +} +proc indent {text} { + wordwrap $text 76 " " " " +} +proc defn {first args} { + if {$first ne ""} { + underline " $first" ~ + } + foreach p $args { + if {$p ne ""} { + indent $p + } + } +} +} + +# ----- @module util.tcl ----- + +set modsource(util.tcl) { +# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which contains miscellaneous utility functions + +# @section Utilities + +# @compare-versions version1 version2 +# +# Versions are of the form 'a.b.c' (may be any number of numeric components) +# +# Compares the two versions and returns: +## -1 if v1 < v2 +## 0 if v1 == v2 +## 1 if v1 > v2 +# +# If one version has fewer components than the other, 0 is substituted to the right. e.g. +## 0.2 < 0.3 +## 0.2.5 > 0.2 +## 1.1 == 1.1.0 +# +proc compare-versions {v1 v2} { + foreach c1 [split $v1 .] c2 [split $v2 .] { + if {$c1 eq ""} { + set c1 0 + } + if {$c2 eq ""} { + set c2 0 + } + if {$c1 < $c2} { + return -1 + } + if {$c1 > $c2} { + return 1 + } + } + return 0 +} + +# @suffix suf list +# +# Takes a list and returns a new list with '$suf' appended +# to each element +# +## suffix .c {a b c} => {a.c b.c c.c} +# +proc suffix {suf list} { + set result {} + foreach p $list { + lappend result $p$suf + } + return $result +} + +# @prefix pre list +# +# Takes a list and returns a new list with '$pre' prepended +# to each element +# +## prefix jim- {a.c b.c} => {jim-a.c jim-b.c} +# +proc prefix {pre list} { + set result {} + foreach p $list { + lappend result $pre$p + } + return $result +} + +# @lpop list +# +# Removes the last entry from the given list and returns it. +proc lpop {listname} { + upvar $listname list + set val [lindex $list end] + set list [lrange $list 0 end-1] + return $val +} +} + +# ----- @module wiki-formatting.tcl ----- + +set modsource(wiki-formatting.tcl) { +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Module which provides text formatting +# wiki.tcl.tk format output + +use formatting + +proc joinlines {text} { + set lines {} + foreach l [split [string trim $text] \n] { + lappend lines [string trim $l] + } + join $lines +} +proc p {text} { + puts [joinlines $text] + puts "" +} +proc title {text} { + puts "*** [joinlines $text] ***" + puts "" +} +proc codelines {lines} { + puts "======" + foreach line $lines { + puts " $line" + } + puts "======" +} +proc code {text} { + puts "======" + foreach line [parse_code_block $text] { + puts " $line" + } + puts "======" +} +proc nl {} { +} +proc section {text} { + puts "'''$text'''" + puts "" +} +proc subsection {text} { + puts "''$text''" + puts "" +} +proc bullet {text} { + puts " * [joinlines $text]" +} +proc indent {text} { + puts " : [joinlines $text]" +} +proc defn {first args} { + if {$first ne ""} { + indent '''$first''' + } + + foreach p $args { + p $p + } +} +} + + +################################################################## +# +# Entry/Exit +# +if {$autosetup(debug)} { + main $argv +} +if {[catch {main $argv} msg opts] == 1} { + show-notices + autosetup-full-error [error-dump $msg $opts $autosetup(debug)] + if {!$autosetup(debug)} { + puts stderr "Try: '[file tail $autosetup(exe)] --debug' for a full stack trace" + } + exit 1 +} diff --git a/autosetup/autosetup-config.guess b/autosetup/autosetup-config.guess new file mode 100755 index 0000000000..48a684601b --- /dev/null +++ b/autosetup/autosetup-config.guess @@ -0,0 +1,1815 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2024 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2024-07-27' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +# +# Please send patches to . + + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system '$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2024 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try '$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Just in case it came from the environment. +GUESS= + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c17 c99 c89 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case $UNAME_SYSTEM in +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #elif defined(__GLIBC__) + LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif + #endif + #endif + EOF + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case $UNAME_VERSION in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + GUESS=$machine-${os}${release}${abi-} + ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; + *:ekkoBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; + *:SolidBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; + macppc:MirBSD:*:*) + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; + *:MirBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; + alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case $ALPHA_CPU_TYPE in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; + Amiga*:UNIX_System_V:4.0:*) + GUESS=m68k-unknown-sysv4 + ;; + *:[Aa]miga[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; + *:[Mm]orph[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-morphos + ;; + *:OS/390:*:*) + GUESS=i370-ibm-openedition + ;; + *:z/VM:*:*) + GUESS=s390-ibm-zvmoe + ;; + *:OS400:*:*) + GUESS=powerpc-ibm-os400 + ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + GUESS=arm-unknown-riscos + ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + GUESS=hppa1.1-hitachi-hiuxmpp + ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; + NILE*:*:*:dcosx) + GUESS=pyramid-pyramid-svr4 + ;; + DRS?6000:unix:4.0:6*) + GUESS=sparc-icl-nx6 + ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; + s390x:SunOS:*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; + sun4H:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; + sun4*:SunOS:*:*) + case `/usr/bin/arch -k` in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like '4.1.3-JL'. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; + sun3*:SunOS:*:*) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in + sun3) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun4) + GUESS=sparc-sun-sunos$UNAME_RELEASE + ;; + esac + ;; + aushp:SunOS:*:*) + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; + m68k:machten:*:*) + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; + powerpc:machten:*:*) + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; + RISC*:Mach:*:*) + GUESS=mips-dec-mach_bsd4.3 + ;; + RISC*:ULTRIX:*:*) + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; + VAX*:ULTRIX*:*:*) + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; + Motorola:PowerMAX_OS:*:*) + GUESS=powerpc-motorola-powermax + ;; + Motorola:*:4.3:PL8-*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:Power_UNIX:*:*) + GUESS=powerpc-harris-powerunix + ;; + m88k:CX/UX:7*:*) + GUESS=m88k-harris-cxux7 + ;; + m88k:*:4*:R4*) + GUESS=m88k-motorola-sysv4 + ;; + m88k:*:3*:R3*) + GUESS=m88k-motorola-sysv3 + ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + GUESS=m88k-dg-dgux$UNAME_RELEASE + else + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE + fi + else + GUESS=i586-dg-dgux$UNAME_RELEASE + fi + ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + GUESS=m88k-dolphin-sysv3 + ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + GUESS=m88k-motorola-sysv3 + ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + GUESS=m88k-tektronix-sysv3 + ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + GUESS=m68k-tektronix-bsd + ;; + *:IRIX*:*:*) + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + GUESS=i386-ibm-aix + ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + + int + main () + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + GUESS=$SYSTEM_NAME + else + GUESS=rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + GUESS=rs6000-ibm-aix3.2.4 + else + GUESS=rs6000-ibm-aix3.2 + fi + ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; + *:AIX:*:*) + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + GUESS=rs6000-bull-bosx + ;; + DPX/2?00:B.O.S.:*:*) + GUESS=m68k-bull-sysv3 + ;; + 9000/[34]??:4.3bsd:1.*:*) + GUESS=m68k-hp-bsd + ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + GUESS=m68k-hp-bsd4.4 + ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int + main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; + 9000/8??:4.3bsd:*:*) + GUESS=hppa1.0-hp-bsd + ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; + hp8??:OSF1:*:*) + GUESS=hppa1.0-hp-osf + ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk + else + GUESS=$UNAME_MACHINE-unknown-osf1 + fi + ;; + parisc*:Lites*:*:*) + GUESS=hppa1.1-hp-lites + ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + GUESS=c1-convex-bsd + ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + GUESS=c34-convex-bsd + ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + GUESS=c38-convex-bsd + ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + GUESS=c4-convex-bsd + ;; + CRAY*Y-MP:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; + CRAY*T3E:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; + CRAY*SV1:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; + *:UNICOS/mp:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; + sparc*:BSD/OS:*:*) + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; + *:BSD/OS:*:*) + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; + i*:CYGWIN*:*) + GUESS=$UNAME_MACHINE-pc-cygwin + ;; + *:MINGW64*:*) + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; + *:MINGW*:*) + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; + *:MSYS*:*) + GUESS=$UNAME_MACHINE-pc-msys + ;; + i*:PW*:*) + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; + *:Interix*:*) + case $UNAME_MACHINE in + x86) + GUESS=i586-pc-interix$UNAME_RELEASE + ;; + authenticamd | genuineintel | EM64T) + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; + IA64) + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; + esac ;; + i*:UWIN*:*) + GUESS=$UNAME_MACHINE-pc-uwin + ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + GUESS=x86_64-pc-cygwin + ;; + prep*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; + *:GNU:*:*) + # the GNU system + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; + aarch64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI + ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi + else + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf + fi + fi + ;; + avr32*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + cris:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + crisv32:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + frv:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + hexagon:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:Linux:*:*) + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; + ia64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m32r*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m68*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + openrisc*:Linux:*:*) + GUESS=or1k-unknown-linux-$LIBC + ;; + or32:Linux:*:* | or1k*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + padre:Linux:*:*) + GUESS=sparc-unknown-linux-$LIBC + ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + GUESS=hppa64-unknown-linux-$LIBC + ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; + esac + ;; + ppc64:Linux:*:*) + GUESS=powerpc64-unknown-linux-$LIBC + ;; + ppc:Linux:*:*) + GUESS=powerpc-unknown-linux-$LIBC + ;; + ppc64le:Linux:*:*) + GUESS=powerpc64le-unknown-linux-$LIBC + ;; + ppcle:Linux:*:*) + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + s390:Linux:*:* | s390x:Linux:*:*) + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; + sh64*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sh*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + tile*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + vax:Linux:*:*) + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; + x86_64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac + fi + GUESS=$CPU-pc-linux-$LIBCABI + ;; + xtensa*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + GUESS=i386-sequent-sysv4 + ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; + i*86:OS/2:*:*) + # If we were able to find 'uname', then EMX Unix compatibility + # is probably installed. + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; + i*86:XTS-300:*:STOP) + GUESS=$UNAME_MACHINE-unknown-stop + ;; + i*86:atheos:*:*) + GUESS=$UNAME_MACHINE-unknown-atheos + ;; + i*86:syllable:*:*) + GUESS=$UNAME_MACHINE-pc-syllable + ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; + i*86:*DOS:*:*) + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL + fi + ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv32 + fi + ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + GUESS=i586-pc-msdosdjgpp + ;; + Intel:Mach:3*:*) + GUESS=i386-pc-mach3 + ;; + paragon:*:*:*) + GUESS=i860-intel-osf1 + ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 + fi + ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + GUESS=m68010-convergent-sysv + ;; + mc68k:UNIX:SYSTEM5:3.51m) + GUESS=m68k-convergent-sysv + ;; + M680?0:D-NIX:5.3:*) + GUESS=m68k-diab-dnix + ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; + mc68030:UNIX_System_V:4.*:*) + GUESS=m68k-atari-sysv4 + ;; + TSUNAMI:LynxOS:2.*:*) + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; + rs6000:LynxOS:2.*:*) + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; + SM[BE]S:UNIX_SV:*:*) + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; + RM*:ReliantUNIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + RM*:SINIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + GUESS=$UNAME_MACHINE-sni-sysv4 + else + GUESS=ns32k-sni-sysv + fi + ;; + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort + # says + GUESS=i586-unisys-sysv4 + ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + GUESS=hppa1.1-stratus-sysv4 + ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + GUESS=i860-stratus-sysv4 + ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=$UNAME_MACHINE-stratus-vos + ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=hppa1.1-stratus-vos + ;; + mc68*:A/UX:*:*) + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; + news*:NEWS-OS:6*:*) + GUESS=mips-sony-newsos6 + ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE + else + GUESS=mips-unknown-sysv$UNAME_RELEASE + fi + ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + GUESS=powerpc-be-beos + ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + GUESS=powerpc-apple-beos + ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + GUESS=i586-pc-beos + ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + GUESS=i586-pc-haiku + ;; + ppc:Haiku:*:*) # Haiku running on Apple PowerPC + GUESS=powerpc-apple-haiku + ;; + *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) + GUESS=$UNAME_MACHINE-unknown-haiku + ;; + SX-4:SUPER-UX:*:*) + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; + SX-5:SUPER-UX:*:*) + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; + SX-6:SUPER-UX:*:*) + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; + SX-7:SUPER-UX:*:*) + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; + SX-8:SUPER-UX:*:*) + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; + SX-8R:SUPER-UX:*:*) + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; + Power*:Rhapsody:*:*) + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; + *:Rhapsody:*:*) + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; + *:QNX:*:4*) + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; + NSE-*:NONSTOP_KERNEL:*:*) + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; + *:NonStop-UX:*:*) + GUESS=mips-compaq-nonstopux + ;; + BS2000:POSIX*:*:*) + GUESS=bs2000-siemens-sysv + ;; + DS/*:UNIX_System_V:*:*) + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "${cputype-}" = 386; then + UNAME_MACHINE=i386 + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype + fi + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; + *:TOPS-10:*:*) + GUESS=pdp10-unknown-tops10 + ;; + *:TENEX:*:*) + GUESS=pdp10-unknown-tenex + ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + GUESS=pdp10-dec-tops20 + ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + GUESS=pdp10-xkl-tops20 + ;; + *:TOPS-20:*:*) + GUESS=pdp10-unknown-tops20 + ;; + *:ITS:*:*) + GUESS=pdp10-unknown-its + ;; + SEI:*:*:SEIUX) + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; + *:DragonFly:*:*) + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; + esac ;; + *:XENIX:*:SysV) + GUESS=i386-pc-xenix + ;; + i*86:skyos:*:*) + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; + i*86:rdos:*:*) + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; + x86_64:VMkernel:*:*) + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +int +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/autosetup/autosetup-config.sub b/autosetup/autosetup-config.sub new file mode 100755 index 0000000000..4aaae46f6f --- /dev/null +++ b/autosetup/autosetup-config.sub @@ -0,0 +1,2354 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2024 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale + +timestamp='2024-05-27' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2024 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try '$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + cloudabi*-eabi* \ + | kfreebsd*-gnu* \ + | knetbsd*-gnu* \ + | kopensolaris*-gnu* \ + | linux-* \ + | managarm-* \ + | netbsd*-eabi* \ + | netbsd*-gnu* \ + | nto-qnx* \ + | os2-emx* \ + | rtmk-nova* \ + | storm-chaos* \ + | uclinux-gnu* \ + | uclinux-uclibc* \ + | windows-* ) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + case $field1-$field2 in + # Shorthands that happen to contain a single dash + convex-c[12] | convex-c3[248]) + basic_machine=$field2-convex + basic_os= + ;; + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Do not treat sunos as a manufacturer + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + # Manufacturers + 3100* \ + | 32* \ + | 3300* \ + | 3600* \ + | 7300* \ + | acorn \ + | altos* \ + | apollo \ + | apple \ + | atari \ + | att* \ + | axis \ + | be \ + | bull \ + | cbm \ + | ccur \ + | cisco \ + | commodore \ + | convergent* \ + | convex* \ + | cray \ + | crds \ + | dec* \ + | delta* \ + | dg \ + | digital \ + | dolphin \ + | encore* \ + | gould \ + | harris \ + | highlevel \ + | hitachi* \ + | hp \ + | ibm* \ + | intergraph \ + | isi* \ + | knuth \ + | masscomp \ + | microblaze* \ + | mips* \ + | motorola* \ + | ncr* \ + | news \ + | next \ + | ns \ + | oki \ + | omron* \ + | pc533* \ + | rebel \ + | rom68k \ + | rombug \ + | semi \ + | sequent* \ + | siemens \ + | sgi* \ + | siemens \ + | sim \ + | sni \ + | sony* \ + | stratus \ + | sun \ + | sun[234]* \ + | tektronix \ + | tti* \ + | ultra \ + | unicom* \ + | wec \ + | winbond \ + | wrs) + basic_machine=$field1-$field2 + basic_os= + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300) + cpu=m68k + vendor=motorola + ;; + # This used to be dpx2*, but that gets the RS6000-based + # DPX/20 and the x86-based DPX/2-100 wrong. See + # https://oldskool.silicium.org/stations/bull_dpx20.htm + # https://www.feb-patrimoine.com/english/bull_dpx2.htm + # https://www.feb-patrimoine.com/english/unix_and_bull.htm + dpx2 | dpx2[23]00 | dpx2[23]xx) + cpu=m68k + vendor=bull + ;; + dpx2100 | dpx21xx) + cpu=i386 + vendor=bull + ;; + dpx20) + cpu=rs6000 + vendor=bull + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x"$basic_os" != x +then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +obj= +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + saved_IFS=$IFS + IFS="-" read kernel os <&2 + fi + ;; + *) + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- | linux-ohos*- ) + ;; + uclinux-uclibc*- | uclinux-gnu*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) + ;; + windows*-msvc*-) + ;; + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 + exit 1 + ;; + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 + ;; + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 + ;; + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 + ;; + kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) + ;; + rtmk-nova-) + ;; + *-eabi*- | *-gnueabi*-) + ;; + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) + # Blank kernel with real OS is always fine. + ;; + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos* | *-solaris*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/autosetup/autosetup-find-tclsh b/autosetup/autosetup-find-tclsh new file mode 100755 index 0000000000..f0fd98c8ed --- /dev/null +++ b/autosetup/autosetup-find-tclsh @@ -0,0 +1,16 @@ +#!/bin/sh +# Looks for a suitable tclsh or jimsh in the PATH +# If not found, builds a bootstrap jimsh in current dir from source +# Prefer $autosetup_tclsh if is set in the environment (unless ./jimsh0 works) +# If an argument is given, use that as the test instead of autosetup-test-tclsh +d="`dirname "$0"`" +for tclsh in ./jimsh0 $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; do + { $tclsh "$d/${1-autosetup-test-tclsh}"; } 2>/dev/null && exit 0 +done +echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" +for cc in ${CC_FOR_BUILD:-cc} gcc; do + { $cc -o jimsh0 "$d/jimsh0.c"; } 2>&1 >/dev/null || continue + ./jimsh0 "$d/${1-autosetup-test-tclsh}" && exit 0 +done +echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." +echo false diff --git a/autosetup/autosetup-test-tclsh b/autosetup/autosetup-test-tclsh new file mode 100644 index 0000000000..75126d2444 --- /dev/null +++ b/autosetup/autosetup-test-tclsh @@ -0,0 +1,20 @@ +# A small Tcl script to verify that the chosen +# interpreter works. Sometimes we might e.g. pick up +# an interpreter for a different arch. +# Outputs the full path to the interpreter + +if {[catch {info version} version] == 0} { + # This is Jim Tcl + if {$version >= 0.72} { + # Ensure that regexp works + regexp (a.*?) a + puts [info nameofexecutable] + exit 0 + } +} elseif {[catch {info tclversion} version] == 0} { + if {$version >= 8.5 && ![string match 8.5a* [info patchlevel]]} { + puts [info nameofexecutable] + exit 0 + } +} +exit 1 diff --git a/autosetup/cc-db.tcl b/autosetup/cc-db.tcl new file mode 100644 index 0000000000..12f1aed2c9 --- /dev/null +++ b/autosetup/cc-db.tcl @@ -0,0 +1,15 @@ +# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# The 'cc-db' module provides a knowledge-base of system idiosyncrasies. +# In general, this module can always be included. + +use cc + +options {} + +# openbsd needs sys/types.h to detect some system headers +cc-include-needs sys/socket.h sys/types.h +cc-include-needs netinet/in.h sys/types.h diff --git a/autosetup/cc-lib.tcl b/autosetup/cc-lib.tcl new file mode 100644 index 0000000000..01a0fb3877 --- /dev/null +++ b/autosetup/cc-lib.tcl @@ -0,0 +1,187 @@ +# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# Provides a library of common tests on top of the 'cc' module. + +use cc + +# @cc-check-lfs +# +# The equivalent of the 'AC_SYS_LARGEFILE' macro. +# +# defines 'HAVE_LFS' if LFS is available, +# and defines '_FILE_OFFSET_BITS=64' if necessary +# +# Returns 1 if 'LFS' is available or 0 otherwise +# +proc cc-check-lfs {} { + cc-check-includes sys/types.h + msg-checking "Checking if -D_FILE_OFFSET_BITS=64 is needed..." + set lfs 1 + if {[msg-quiet cc-with {-includes sys/types.h} {cc-check-sizeof off_t}] == 8} { + msg-result no + } elseif {[msg-quiet cc-with {-includes sys/types.h -cflags -D_FILE_OFFSET_BITS=64} {cc-check-sizeof off_t}] == 8} { + define _FILE_OFFSET_BITS 64 + msg-result yes + } else { + set lfs 0 + msg-result none + } + define-feature lfs $lfs + return $lfs +} + +# @cc-check-endian +# +# The equivalent of the 'AC_C_BIGENDIAN' macro. +# +# defines 'HAVE_BIG_ENDIAN' if endian is known to be big, +# or 'HAVE_LITTLE_ENDIAN' if endian is known to be little. +# +# Returns 1 if determined, or 0 if not. +# +proc cc-check-endian {} { + cc-check-includes sys/types.h sys/param.h + set rc 0 + msg-checking "Checking endian..." + cc-with {-includes {sys/types.h sys/param.h}} { + if {[cctest -code { + #if !defined(BIG_ENDIAN) || !defined(BYTE_ORDER) + #error unknown + #elif BYTE_ORDER != BIG_ENDIAN + #error little + #endif + }]} { + define-feature big-endian + msg-result "big" + set rc 1 + } elseif {[cctest -code { + #if !defined(LITTLE_ENDIAN) || !defined(BYTE_ORDER) + #error unknown + #elif BYTE_ORDER != LITTLE_ENDIAN + #error big + #endif + }]} { + define-feature little-endian + msg-result "little" + set rc 1 + } else { + msg-result "unknown" + } + } + return $rc +} + +# @cc-check-flags flag ?...? +# +# Checks whether the given C/C++ compiler flags can be used. Defines feature +# names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and +# appends working flags to '-cflags' and 'AS_CFLAGS' or 'AS_CXXFLAGS'. +proc cc-check-flags {args} { + set result 1 + array set opts [cc-get-settings] + switch -exact -- $opts(-lang) { + c++ { + set lang C++ + set prefix CXXFLAG + } + c { + set lang C + set prefix CFLAG + } + default { + autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)" + } + } + foreach flag $args { + msg-checking "Checking whether the $lang compiler accepts $flag..." + if {[cctest -cflags $flag]} { + msg-result yes + define-feature $prefix$flag + cc-with [list -cflags [list $flag]] + define-append AS_${prefix}S $flag + } else { + msg-result no + set result 0 + } + } + return $result +} + +# @cc-check-standards ver ?...? +# +# Checks whether the C/C++ compiler accepts one of the specified '-std=$ver' +# options, and appends the first working one to '-cflags' and 'AS_CFLAGS' or +# 'AS_CXXFLAGS'. +proc cc-check-standards {args} { + array set opts [cc-get-settings] + foreach std $args { + if {[cc-check-flags -std=$std]} { + return $std + } + } + return "" +} + +# Checks whether $keyword is usable as alignof +proc cctest_alignof {keyword} { + msg-checking "Checking for $keyword..." + if {[cctest -code "int x = ${keyword}(char), y = ${keyword}('x');"]} then { + msg-result ok + define-feature $keyword + } else { + msg-result "not found" + } +} + +# @cc-check-c11 +# +# Checks for several C11/C++11 extensions and their alternatives. Currently +# checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'. +proc cc-check-c11 {} { + msg-checking "Checking for _Static_assert..." + if {[cctest -code { + _Static_assert(1, "static assertions are available"); + }]} then { + msg-result ok + define-feature _Static_assert + } else { + msg-result "not found" + } + + cctest_alignof _Alignof + cctest_alignof __alignof__ + cctest_alignof __alignof +} + +# @cc-check-alloca +# +# The equivalent of the 'AC_FUNC_ALLOCA' macro. +# +# Checks for the existence of 'alloca' +# defines 'HAVE_ALLOCA' and returns 1 if it exists. +proc cc-check-alloca {} { + cc-check-some-feature alloca { + cctest -includes alloca.h -code { alloca (2 * sizeof (int)); } + } +} + +# @cc-signal-return-type +# +# The equivalent of the 'AC_TYPE_SIGNAL' macro. +# +# defines 'RETSIGTYPE' to 'int' or 'void'. +proc cc-signal-return-type {} { + msg-checking "Checking return type of signal handlers..." + cc-with {-includes {sys/types.h signal.h}} { + if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} { + set type int + } else { + set type void + } + define RETSIGTYPE $type + msg-result $type + } +} diff --git a/autosetup/cc-shared.tcl b/autosetup/cc-shared.tcl new file mode 100644 index 0000000000..cbe568018e --- /dev/null +++ b/autosetup/cc-shared.tcl @@ -0,0 +1,113 @@ +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# The 'cc-shared' module provides support for shared libraries and shared objects. +# It defines the following variables: +# +## SH_CFLAGS Flags to use compiling sources destined for a shared library +## SH_LDFLAGS Flags to use linking (creating) a shared library +## SH_SOPREFIX Prefix to use to set the soname when creating a shared library +## SH_SOFULLPATH Set to 1 if the shared library soname should include the full install path +## SH_SOEXT Extension for shared libs +## SH_SOEXTVER Format for versioned shared libs - %s = version +## SHOBJ_CFLAGS Flags to use compiling sources destined for a shared object +## SHOBJ_LDFLAGS Flags to use linking a shared object, undefined symbols allowed +## SHOBJ_LDFLAGS_R - as above, but all symbols must be resolved +## SH_LINKRPATH Format for setting the rpath when linking an executable, %s = path +## SH_LINKFLAGS Flags to use linking an executable which will load shared objects +## LD_LIBRARY_PATH Environment variable which specifies path to shared libraries +## STRIPLIBFLAGS Arguments to strip a dynamic library + +options {} + +# Defaults: gcc on unix +define SHOBJ_CFLAGS -fPIC +define SHOBJ_LDFLAGS -shared +define SH_CFLAGS -fPIC +define SH_LDFLAGS -shared +define SH_LINKFLAGS -rdynamic +define SH_LINKRPATH "-Wl,-rpath -Wl,%s" +define SH_SOEXT .so +define SH_SOEXTVER .so.%s +define SH_SOPREFIX -Wl,-soname, +define LD_LIBRARY_PATH LD_LIBRARY_PATH +define STRIPLIBFLAGS --strip-unneeded + +# Note: This is a helpful reference for identifying the toolchain +# http://sourceforge.net/apps/mediawiki/predef/index.php?title=Compilers + +switch -glob -- [get-define host] { + *-*-darwin* { + define SHOBJ_CFLAGS "-dynamic -fno-common" + define SHOBJ_LDFLAGS "-bundle -undefined dynamic_lookup" + define SHOBJ_LDFLAGS_R -bundle + define SH_CFLAGS -dynamic + define SH_LDFLAGS -dynamiclib + define SH_LINKFLAGS "" + define SH_SOEXT .dylib + define SH_SOEXTVER .%s.dylib + define SH_SOPREFIX -Wl,-install_name, + define SH_SOFULLPATH + define LD_LIBRARY_PATH DYLD_LIBRARY_PATH + define STRIPLIBFLAGS -x + } + *-*-ming* - *-*-cygwin - *-*-msys { + define SHOBJ_CFLAGS "" + define SHOBJ_LDFLAGS -shared + define SH_CFLAGS "" + define SH_LDFLAGS -shared + define SH_LINKRPATH "" + define SH_LINKFLAGS "" + define SH_SOEXT .dll + define SH_SOEXTVER .dll + define SH_SOPREFIX "" + define LD_LIBRARY_PATH PATH + } + sparc* { + if {[msg-quiet cc-check-decls __SUNPRO_C]} { + msg-result "Found sun stdio compiler" + # sun stdio compiler + # XXX: These haven't been fully tested. + define SHOBJ_CFLAGS -KPIC + define SHOBJ_LDFLAGS "-G" + define SH_CFLAGS -KPIC + define SH_LINKFLAGS -Wl,-export-dynamic + define SH_SOPREFIX -Wl,-h, + } + } + *-*-solaris* { + if {[msg-quiet cc-check-decls __SUNPRO_C]} { + msg-result "Found sun stdio compiler" + # sun stdio compiler + # XXX: These haven't been fully tested. + define SHOBJ_CFLAGS -KPIC + define SHOBJ_LDFLAGS "-G" + define SH_CFLAGS -KPIC + define SH_LINKFLAGS -Wl,-export-dynamic + define SH_SOPREFIX -Wl,-h, + } + } + *-*-hpux { + # XXX: These haven't been tested + define SHOBJ_CFLAGS "+O3 +z" + define SHOBJ_LDFLAGS -b + define SH_CFLAGS +z + define SH_LINKFLAGS -Wl,+s + define LD_LIBRARY_PATH SHLIB_PATH + } + *-*-haiku { + define SHOBJ_CFLAGS "" + define SHOBJ_LDFLAGS -shared + define SH_CFLAGS "" + define SH_LDFLAGS -shared + define SH_LINKFLAGS "" + define SH_SOPREFIX "" + define LD_LIBRARY_PATH LIBRARY_PATH + } +} + +if {![is-defined SHOBJ_LDFLAGS_R]} { + define SHOBJ_LDFLAGS_R [get-define SHOBJ_LDFLAGS] +} diff --git a/autosetup/cc.tcl b/autosetup/cc.tcl new file mode 100644 index 0000000000..f45cc2ecdc --- /dev/null +++ b/autosetup/cc.tcl @@ -0,0 +1,756 @@ +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# The 'cc' module supports checking various 'features' of the C or C++ +# compiler/linker environment. Common commands are 'cc-check-includes', +# 'cc-check-types', 'cc-check-functions', 'cc-with', 'make-config-header' and 'make-template'. +# +# The following environment variables are used if set: +# +## CC - C compiler +## CXX - C++ compiler +## CPP - C preprocessor +## CCACHE - Set to "none" to disable automatic use of ccache +## CPPFLAGS - Additional C preprocessor compiler flags (C and C++), before CFLAGS, CXXFLAGS +## CFLAGS - Additional C compiler flags +## CXXFLAGS - Additional C++ compiler flags +## LDFLAGS - Additional compiler flags during linking +## LINKFLAGS - ?How is this different from LDFLAGS? +## LIBS - Additional libraries to use (for all tests) +## CROSS - Tool prefix for cross compilation +# +# The following variables are defined from the corresponding +# environment variables if set. +# +## CC_FOR_BUILD +## LD + +use system + +options {} + +# Checks for the existence of the given function by linking +# +proc cctest_function {function} { + cctest -link 1 -declare "extern void $function\(void);" -code "$function\();" +} + +# Checks for the existence of the given type by compiling +proc cctest_type {type} { + cctest -code "$type _x;" +} + +# Checks for the existence of the given type/structure member. +# e.g. "struct stat.st_mtime" +proc cctest_member {struct_member} { + # split at the first dot + regexp {^([^.]+)[.](.*)$} $struct_member -> struct member + cctest -code "static $struct _s; return sizeof(_s.$member);" +} + +# Checks for the existence of the given define by compiling +# +proc cctest_define {name} { + cctest -code "#ifndef $name\n#error not defined\n#endif" +} + +# Checks for the existence of the given name either as +# a macro (#define) or an rvalue (such as an enum) +# +proc cctest_decl {name} { + cctest -code "#ifndef $name\n(void)$name;\n#endif" +} + +# @cc-check-sizeof type ... +# +# Checks the size of the given types (between 1 and 32, inclusive). +# Defines a variable with the size determined, or 'unknown' otherwise. +# e.g. for type 'long long', defines 'SIZEOF_LONG_LONG'. +# Returns the size of the last type. +# +proc cc-check-sizeof {args} { + foreach type $args { + msg-checking "Checking for sizeof $type..." + set size unknown + # Try the most common sizes first + foreach i {4 8 1 2 16 32} { + if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} { + set size $i + break + } + } + msg-result $size + set define [feature-define-name $type SIZEOF_] + define $define $size + } + # Return the last result + get-define $define +} + +# Checks for each feature in $list by using the given script. +# +# When the script is evaluated, $each is set to the feature +# being checked, and $extra is set to any additional cctest args. +# +# Returns 1 if all features were found, or 0 otherwise. +proc cc-check-some-feature {list script} { + set ret 1 + foreach each $list { + if {![check-feature $each $script]} { + set ret 0 + } + } + return $ret +} + +# @cc-check-includes includes ... +# +# Checks that the given include files can be used. +proc cc-check-includes {args} { + cc-check-some-feature $args { + set with {} + if {[dict exists $::autosetup(cc-include-deps) $each]} { + set deps [dict keys [dict get $::autosetup(cc-include-deps) $each]] + msg-quiet cc-check-includes {*}$deps + foreach i $deps { + if {[have-feature $i]} { + lappend with $i + } + } + } + if {[llength $with]} { + cc-with [list -includes $with] { + cctest -includes $each + } + } else { + cctest -includes $each + } + } +} + +# @cc-include-needs include required ... +# +# Ensures that when checking for '$include', a check is first +# made for each '$required' file, and if found, it is included with '#include'. +proc cc-include-needs {file args} { + foreach depfile $args { + dict set ::autosetup(cc-include-deps) $file $depfile 1 + } +} + +# @cc-check-types type ... +# +# Checks that the types exist. +proc cc-check-types {args} { + cc-check-some-feature $args { + cctest_type $each + } +} + +# @cc-check-defines define ... +# +# Checks that the given preprocessor symbols are defined. +proc cc-check-defines {args} { + cc-check-some-feature $args { + cctest_define $each + } +} + +# @cc-check-decls name ... +# +# Checks that each given name is either a preprocessor symbol or rvalue +# such as an enum. Note that the define used is 'HAVE_DECL_xxx' +# rather than 'HAVE_xxx'. +proc cc-check-decls {args} { + set ret 1 + foreach name $args { + msg-checking "Checking for $name..." + set r [cctest_decl $name] + define-feature "decl $name" $r + if {$r} { + msg-result "ok" + } else { + msg-result "not found" + set ret 0 + } + } + return $ret +} + +# @cc-check-functions function ... +# +# Checks that the given functions exist (can be linked). +proc cc-check-functions {args} { + cc-check-some-feature $args { + cctest_function $each + } +} + +# @cc-check-members type.member ... +# +# Checks that the given type/structure members exist. +# A structure member is of the form 'struct stat.st_mtime'. +proc cc-check-members {args} { + cc-check-some-feature $args { + cctest_member $each + } +} + +# @cc-check-function-in-lib function libs ?otherlibs? +# +# Checks that the given function can be found in one of the libs. +# +# First checks for no library required, then checks each of the libraries +# in turn. +# +# If the function is found, the feature is defined and 'lib_$function' is defined +# to '-l$lib' where the function was found, or "" if no library required. +# In addition, '-l$lib' is prepended to the 'LIBS' define. +# +# If additional libraries may be needed for linking, they should be specified +# with '$extralibs' as '-lotherlib1 -lotherlib2'. +# These libraries are not automatically added to 'LIBS'. +# +# Returns 1 if found or 0 if not. +# +proc cc-check-function-in-lib {function libs {otherlibs {}}} { + msg-checking "Checking libs for $function..." + set found 0 + cc-with [list -libs $otherlibs] { + if {[cctest_function $function]} { + msg-result "none needed" + define lib_$function "" + incr found + } else { + foreach lib $libs { + cc-with [list -libs -l$lib] { + if {[cctest_function $function]} { + msg-result -l$lib + define lib_$function -l$lib + # prepend to LIBS + define LIBS "-l$lib [get-define LIBS]" + incr found + break + } + } + } + } + } + define-feature $function $found + if {!$found} { + msg-result "no" + } + return $found +} + +# @cc-check-tools tool ... +# +# Checks for existence of the given compiler tools, taking +# into account any cross compilation prefix. +# +# For example, when checking for 'ar', first 'AR' is checked on the command +# line and then in the environment. If not found, '${host}-ar' or +# simply 'ar' is assumed depending upon whether cross compiling. +# The path is searched for this executable, and if found 'AR' is defined +# to the executable name. +# Note that even when cross compiling, the simple 'ar' is used as a fallback, +# but a warning is generated. This is necessary for some toolchains. +# +# It is an error if the executable is not found. +# +proc cc-check-tools {args} { + foreach tool $args { + set TOOL [string toupper $tool] + set exe [get-env $TOOL [get-define cross]$tool] + if {[find-executable $exe]} { + define $TOOL $exe + continue + } + if {[find-executable $tool]} { + msg-result "Warning: Failed to find $exe, falling back to $tool which may be incorrect" + define $TOOL $tool + continue + } + user-error "Failed to find $exe" + } +} + +# @cc-check-progs prog ... +# +# Checks for existence of the given executables on the path. +# +# For example, when checking for 'grep', the path is searched for +# the executable, 'grep', and if found 'GREP' is defined as 'grep'. +# +# If the executable is not found, the variable is defined as 'false'. +# Returns 1 if all programs were found, or 0 otherwise. +# +proc cc-check-progs {args} { + set failed 0 + foreach prog $args { + set PROG [string toupper $prog] + msg-checking "Checking for $prog..." + if {![find-executable $prog]} { + msg-result no + define $PROG false + incr failed + } else { + msg-result ok + define $PROG $prog + } + } + expr {!$failed} +} + +# @cc-path-progs prog ... +# +# Like cc-check-progs, but sets the define to the full path rather +# than just the program name. +# +proc cc-path-progs {args} { + set failed 0 + foreach prog $args { + set PROG [string toupper $prog] + msg-checking "Checking for $prog..." + set path [find-executable-path $prog] + if {$path eq ""} { + msg-result no + define $PROG false + incr failed + } else { + msg-result $path + define $PROG $path + } + } + expr {!$failed} +} + +# Adds the given settings to $::autosetup(ccsettings) and +# returns the old settings. +# +proc cc-add-settings {settings} { + if {[llength $settings] % 2} { + autosetup-error "settings list is missing a value: $settings" + } + + set prev [cc-get-settings] + # workaround a bug in some versions of jimsh by forcing + # conversion of $prev to a list + llength $prev + + array set new $prev + + foreach {name value} $settings { + switch -exact -- $name { + -cflags - -includes { + # These are given as lists + lappend new($name) {*}[list-non-empty $value] + } + -declare { + lappend new($name) $value + } + -libs { + # Note that new libraries are added before previous libraries + set new($name) [list {*}[list-non-empty $value] {*}$new($name)] + } + -link - -lang - -nooutput { + set new($name) $value + } + -source - -sourcefile - -code { + # XXX: These probably are only valid directly from cctest + set new($name) $value + } + default { + autosetup-error "unknown cctest setting: $name" + } + } + } + + cc-store-settings [array get new] + + return $prev +} + +proc cc-store-settings {new} { + set ::autosetup(ccsettings) $new +} + +proc cc-get-settings {} { + return $::autosetup(ccsettings) +} + +# Similar to cc-add-settings, but each given setting +# simply replaces the existing value. +# +# Returns the previous settings +proc cc-update-settings {args} { + set prev [cc-get-settings] + cc-store-settings [dict merge $prev $args] + return $prev +} + +# @cc-with settings ?{ script }? +# +# Sets the given 'cctest' settings and then runs the tests in '$script'. +# Note that settings such as '-lang' replace the current setting, while +# those such as '-includes' are appended to the existing setting. +# +# If no script is given, the settings become the default for the remainder +# of the 'auto.def' file. +# +## cc-with {-lang c++} { +## # This will check with the C++ compiler +## cc-check-types bool +## cc-with {-includes signal.h} { +## # This will check with the C++ compiler, signal.h and any existing includes. +## ... +## } +## # back to just the C++ compiler +## } +# +# The '-libs' setting is special in that newer values are added *before* earlier ones. +# +## cc-with {-libs {-lc -lm}} { +## cc-with {-libs -ldl} { +## cctest -libs -lsocket ... +## # libs will be in this order: -lsocket -ldl -lc -lm +## } +## } +# +# If you wish to invoke something like cc-check-flags but not have -cflags updated, +# use the following idiom: +# +## cc-with {} { +## cc-check-flags ... +## } +proc cc-with {settings args} { + if {[llength $args] == 0} { + cc-add-settings $settings + } elseif {[llength $args] > 1} { + autosetup-error "usage: cc-with settings ?script?" + } else { + set save [cc-add-settings $settings] + set rc [catch {uplevel 1 [lindex $args 0]} result info] + cc-store-settings $save + if {$rc != 0} { + return -code [dict get $info -code] $result + } + return $result + } +} + +# @cctest ?settings? +# +# Low level C/C++ compiler checker. Compiles and or links a small C program +# according to the arguments and returns 1 if OK, or 0 if not. +# +# Supported settings are: +# +## -cflags cflags A list of flags to pass to the compiler +## -includes list A list of includes, e.g. {stdlib.h stdio.h} +## -declare code Code to declare before main() +## -link 1 Don't just compile, link too +## -lang c|c++ Use the C (default) or C++ compiler +## -libs liblist List of libraries to link, e.g. {-ldl -lm} +## -code code Code to compile in the body of main() +## -source code Compile a complete program. Ignore -includes, -declare and -code +## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file] +## -nooutput 1 Treat any compiler output (e.g. a warning) as an error +# +# Unless '-source' or '-sourcefile' is specified, the C program looks like: +# +## #include /* same for remaining includes in the list */ +## declare-code /* any code in -declare, verbatim */ +## int main(void) { +## code /* any code in -code, verbatim */ +## return 0; +## } +# +# And the command line looks like: +# +## CC -cflags CFLAGS CPPFLAGS conftest.c -o conftest.o +## CXX -cflags CXXFLAGS CPPFLAGS conftest.cpp -o conftest.o +# +# And if linking: +# +## CC LDFLAGS -cflags CFLAGS conftest.c -o conftest -libs LIBS +## CXX LDFLAGS -cflags CXXFLAGS conftest.c -o conftest -libs LIBS +# +# Any failures are recorded in 'config.log' +# +proc cctest {args} { + set tmp conftest__ + + # Easiest way to merge in the settings + cc-with $args { + array set opts [cc-get-settings] + } + + if {[info exists opts(-sourcefile)]} { + set opts(-source) [readfile [get-define srcdir]/$opts(-sourcefile) "#error can't find $opts(-sourcefile)"] + } + if {[info exists opts(-source)]} { + set lines $opts(-source) + } else { + foreach i $opts(-includes) { + if {$opts(-code) ne "" && ![feature-checked $i]} { + # Compiling real code with an unchecked header file + # Quickly (and silently) check for it now + + # Remove all -includes from settings before checking + set saveopts [cc-update-settings -includes {}] + msg-quiet cc-check-includes $i + cc-store-settings $saveopts + } + if {$opts(-code) eq "" || [have-feature $i]} { + lappend source "#include <$i>" + } + } + lappend source {*}$opts(-declare) + lappend source "int main(void) {" + lappend source $opts(-code) + lappend source "return 0;" + lappend source "}" + + set lines [join $source \n] + } + + # Build the command line + set cmdline {} + lappend cmdline {*}[get-define CCACHE] + switch -exact -- $opts(-lang) { + c++ { + set src conftest__.cpp + lappend cmdline {*}[get-define CXX] + set cflags [get-define CXXFLAGS] + } + c { + set src conftest__.c + lappend cmdline {*}[get-define CC] + set cflags [get-define CFLAGS] + } + default { + autosetup-error "cctest called with unknown language: $opts(-lang)" + } + } + + if {$opts(-link)} { + lappend cmdline {*}[get-define LDFLAGS] + } else { + lappend cflags {*}[get-define CPPFLAGS] + set tmp conftest__.o + lappend cmdline -c + } + lappend cmdline {*}$opts(-cflags) {*}[get-define cc-default-debug ""] {*}$cflags + lappend cmdline $src -o $tmp + if {$opts(-link)} { + lappend cmdline {*}$opts(-libs) {*}[get-define LIBS] + } + + # At this point we have the complete command line and the + # complete source to be compiled. Get the result from cache if + # we can + if {[info exists ::cc_cache($cmdline,$lines)]} { + msg-checking "(cached) " + set ok $::cc_cache($cmdline,$lines) + if {$::autosetup(debug)} { + configlog "From cache (ok=$ok): [join $cmdline]" + configlog "============" + configlog $lines + configlog "============" + } + return $ok + } + + writefile $src $lines\n + + set ok 1 + set err [catch {exec-with-stderr {*}$cmdline} result errinfo] + if {$err || ($opts(-nooutput) && [string length $result])} { + configlog "Failed: [join $cmdline]" + configlog $result + configlog "============" + configlog "The failed code was:" + configlog $lines + configlog "============" + set ok 0 + } elseif {$::autosetup(debug)} { + configlog "Compiled OK: [join $cmdline]" + configlog "============" + configlog $lines + configlog "============" + } + file delete $src + file delete $tmp + + # cache it + set ::cc_cache($cmdline,$lines) $ok + + return $ok +} + +# @make-autoconf-h outfile ?auto-patterns=HAVE_*? ?bare-patterns=SIZEOF_*? +# +# Deprecated - see 'make-config-header' +proc make-autoconf-h {file {autopatterns {HAVE_*}} {barepatterns {SIZEOF_* HAVE_DECL_*}}} { + user-notice "*** make-autoconf-h is deprecated -- use make-config-header instead" + make-config-header $file -auto $autopatterns -bare $barepatterns +} + +# @make-config-header outfile ?-auto patternlist? ?-bare patternlist? ?-none patternlist? ?-str patternlist? ... +# +# Examines all defined variables which match the given patterns +# and writes an include file, '$file', which defines each of these. +# Variables which match '-auto' are output as follows: +# - defines which have the value '0' are ignored. +# - defines which have integer values are defined as the integer value. +# - any other value is defined as a string, e.g. '"value"' +# Variables which match '-bare' are defined as-is. +# Variables which match '-str' are defined as a string, e.g. '"value"' +# Variables which match '-none' are omitted. +# +# Note that order is important. The first pattern that matches is selected. +# Default behaviour is: +# +## -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * +# +# If the file would be unchanged, it is not written. +proc make-config-header {file args} { + set guard _[string toupper [regsub -all {[^a-zA-Z0-9]} [file tail $file] _]] + file mkdir [file dirname $file] + set lines {} + lappend lines "#ifndef $guard" + lappend lines "#define $guard" + + # Add some defaults + lappend args -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* + + foreach n [lsort [dict keys [all-defines]]] { + set value [get-define $n] + set type [calc-define-output-type $n $args] + switch -exact -- $type { + -bare { + # Just output the value unchanged + } + -none { + continue + } + -str { + set value \"[string map [list \\ \\\\ \" \\\"] $value]\" + } + -auto { + # Automatically determine the type + if {$value eq "0"} { + lappend lines "/* #undef $n */" + continue + } + if {![string is integer -strict $value]} { + set value \"[string map [list \\ \\\\ \" \\\"] $value]\" + } + } + "" { + continue + } + default { + autosetup-error "Unknown type in make-config-header: $type" + } + } + lappend lines "#define $n $value" + } + lappend lines "#endif" + set buf [join $lines \n] + write-if-changed $file $buf { + msg-result "Created $file" + } +} + +proc calc-define-output-type {name spec} { + foreach {type patterns} $spec { + foreach pattern $patterns { + if {[string match $pattern $name]} { + return $type + } + } + } + return "" +} + +# Initialise some values from the environment or commandline or default settings +foreach i {LDFLAGS LIBS CPPFLAGS LINKFLAGS CFLAGS} { + lassign $i var default + define $var [get-env $var $default] +} + +if {[env-is-set CC]} { + # Set by the user, so don't try anything else + set try [list [get-env CC ""]] +} else { + # Try some reasonable options + set try [list [get-define cross]cc [get-define cross]gcc] +} +define CC [find-an-executable {*}$try] +if {[get-define CC] eq ""} { + user-error "Could not find a C compiler. Tried: [join $try ", "]" +} + +define CPP [get-env CPP "[get-define CC] -E"] + +# XXX: Could avoid looking for a C++ compiler until requested +# If CXX isn't found, it is set to the empty string. +if {[env-is-set CXX]} { + define CXX [find-an-executable -required [get-env CXX ""]] +} else { + define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++] +} + +# CXXFLAGS default to CFLAGS if not specified +define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]] + +# May need a CC_FOR_BUILD, so look for one +define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false] + +if {[get-define CC] eq ""} { + user-error "Could not find a C compiler. Tried: [join $try ", "]" +} + +# These start empty and never come from the user or environment +define AS_CFLAGS "" +define AS_CPPFLAGS "" +define AS_CXXFLAGS "" + +define CCACHE [find-an-executable [get-env CCACHE ccache]] + +# If any of these are set in the environment, propagate them to the AUTOREMAKE commandline +foreach i {CC CXX CCACHE CPP CFLAGS CXXFLAGS CXXFLAGS LDFLAGS LIBS CROSS CPPFLAGS LINKFLAGS CC_FOR_BUILD LD} { + if {[env-is-set $i]} { + # Note: If the variable is set on the command line, get-env will return that value + # so the command line will continue to override the environment + define-append-argv AUTOREMAKE $i=[get-env $i ""] + } +} + +# Initial cctest settings +cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {} -nooutput 0} +set autosetup(cc-include-deps) {} + +msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS] [get-define CPPFLAGS]" +if {[get-define CXX] ne "false"} { + msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS] [get-define CPPFLAGS]" +} +msg-result "Build C compiler...[get-define CC_FOR_BUILD]" + +# On Darwin, we prefer to use -g0 to avoid creating .dSYM directories +# but some compilers may not support it, so test here. +switch -glob -- [get-define host] { + *-*-darwin* { + if {[cctest -cflags {-g0}]} { + define cc-default-debug -g0 + } + } +} + +if {![cc-check-includes stdlib.h]} { + user-error "Compiler does not work. See config.log" +} diff --git a/autosetup/default.auto b/autosetup/default.auto new file mode 100644 index 0000000000..b36e0f8dc9 --- /dev/null +++ b/autosetup/default.auto @@ -0,0 +1,25 @@ +# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Auto-load module for 'make' build system integration + +use init + +autosetup_add_init_type make {Simple "make" build system} { + autosetup_check_create auto.def \ +{# Initial auto.def created by 'autosetup --init=make' + +use cc + +# Add any user options here +options { +} + +make-config-header config.h +make-template Makefile.in +} + + if {![file exists Makefile.in]} { + puts "Note: I don't see Makefile.in. You will probably need to create one." + } +} diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c new file mode 100644 index 0000000000..3c0e8b78a2 --- /dev/null +++ b/autosetup/jimsh0.c @@ -0,0 +1,24442 @@ +/* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ +#define JIM_TCL_COMPAT +#define JIM_ANSIC +#define JIM_REGEXP +#define HAVE_NO_AUTOCONF +#define JIM_TINY +#define _JIMAUTOCONF_H +#define TCL_LIBRARY "." +#define jim_ext_bootstrap +#define jim_ext_aio +#define jim_ext_readdir +#define jim_ext_regexp +#define jim_ext_file +#define jim_ext_glob +#define jim_ext_exec +#define jim_ext_posix +#define jim_ext_clock +#define jim_ext_array +#define jim_ext_stdlib +#define jim_ext_tclcompat +#if defined(_MSC_VER) +#define TCL_PLATFORM_OS "windows" +#define TCL_PLATFORM_PLATFORM "windows" +#define TCL_PLATFORM_PATH_SEPARATOR ";" +#define HAVE_MKDIR_ONE_ARG +#define HAVE_SYSTEM +#elif defined(__MINGW32__) +#define TCL_PLATFORM_OS "mingw" +#define TCL_PLATFORM_PLATFORM "windows" +#define TCL_PLATFORM_PATH_SEPARATOR ";" +#define HAVE_MKDIR_ONE_ARG +#define HAVE_SYSTEM +#define HAVE_SYS_TIME_H +#define HAVE_DIRENT_H +#define HAVE_UNISTD_H +#define HAVE_UMASK +#include +#ifndef S_IRWXG +#define S_IRWXG 0 +#endif +#ifndef S_IRWXO +#define S_IRWXO 0 +#endif +#else +#define TCL_PLATFORM_OS "unknown" +#define TCL_PLATFORM_PLATFORM "unix" +#define TCL_PLATFORM_PATH_SEPARATOR ":" +#ifdef _MINIX +#define vfork fork +#define _POSIX_SOURCE +#else +#define _GNU_SOURCE +#endif +#define HAVE_FORK +#define HAVE_WAITPID +#define HAVE_ISATTY +#define HAVE_MKSTEMP +#define HAVE_LINK +#define HAVE_SYS_TIME_H +#define HAVE_DIRENT_H +#define HAVE_UNISTD_H +#define HAVE_UMASK +#define HAVE_PIPE +#define _FILE_OFFSET_BITS 64 +#endif +#define JIM_VERSION 83 +#ifndef JIM_WIN32COMPAT_H +#define JIM_WIN32COMPAT_H + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(_WIN32) || defined(WIN32) + +#define HAVE_DLOPEN +void *dlopen(const char *path, int mode); +int dlclose(void *handle); +void *dlsym(void *handle, const char *symbol); +char *dlerror(void); + + +#if defined(__MINGW32__) + #define JIM_SPRINTF_DOUBLE_NEEDS_FIX +#endif + +#ifdef _MSC_VER + + +#if _MSC_VER >= 1000 + #pragma warning(disable:4146) +#endif + +#include +#define jim_wide _int64 +#ifndef LLONG_MAX + #define LLONG_MAX 9223372036854775807I64 +#endif +#ifndef LLONG_MIN + #define LLONG_MIN (-LLONG_MAX - 1I64) +#endif +#define JIM_WIDE_MIN LLONG_MIN +#define JIM_WIDE_MAX LLONG_MAX +#define JIM_WIDE_MODIFIER "I64d" +#define strcasecmp _stricmp +#define strtoull _strtoui64 + +#include + +struct timeval { + long tv_sec; + long tv_usec; +}; + +int gettimeofday(struct timeval *tv, void *unused); + +#define HAVE_OPENDIR +struct dirent { + char *d_name; +}; + +typedef struct DIR { + long handle; + struct _finddata_t info; + struct dirent result; + char *name; +} DIR; + +DIR *opendir(const char *name); +int closedir(DIR *dir); +struct dirent *readdir(DIR *dir); + +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif +#ifndef UTF8_UTIL_H +#define UTF8_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define MAX_UTF8_LEN 4 + +int utf8_fromunicode(char *p, unsigned uc); + +#ifndef JIM_UTF8 +#include + + +#define utf8_strlen(S, B) ((B) < 0 ? (int)strlen(S) : (B)) +#define utf8_strwidth(S, B) utf8_strlen((S), (B)) +#define utf8_tounicode(S, CP) (*(CP) = (unsigned char)*(S), 1) +#define utf8_getchars(CP, C) (*(CP) = (C), 1) +#define utf8_upper(C) toupper(C) +#define utf8_title(C) toupper(C) +#define utf8_lower(C) tolower(C) +#define utf8_index(C, I) (I) +#define utf8_charlen(C) 1 +#define utf8_prev_len(S, L) 1 +#define utf8_width(C) 1 + +#else + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#ifndef __JIM__H +#define __JIM__H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + + +#ifndef HAVE_NO_AUTOCONF +#endif + + + +#ifndef jim_wide +# ifdef HAVE_LONG_LONG +# define jim_wide long long +# ifndef LLONG_MAX +# define LLONG_MAX 9223372036854775807LL +# endif +# ifndef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - 1LL) +# endif +# define JIM_WIDE_MIN LLONG_MIN +# define JIM_WIDE_MAX LLONG_MAX +# else +# define jim_wide long +# define JIM_WIDE_MIN LONG_MIN +# define JIM_WIDE_MAX LONG_MAX +# endif + + +# ifdef HAVE_LONG_LONG +# define JIM_WIDE_MODIFIER "lld" +# else +# define JIM_WIDE_MODIFIER "ld" +# define strtoull strtoul +# endif +#endif + +#define UCHAR(c) ((unsigned char)(c)) + + + +#define JIM_ABI_VERSION 101 + +#define JIM_OK 0 +#define JIM_ERR 1 +#define JIM_RETURN 2 +#define JIM_BREAK 3 +#define JIM_CONTINUE 4 +#define JIM_SIGNAL 5 +#define JIM_EXIT 6 + +#define JIM_EVAL 7 + +#define JIM_MAX_CALLFRAME_DEPTH 1000 +#define JIM_MAX_EVAL_DEPTH 2000 + + +#define JIM_PRIV_FLAG_SHIFT 20 + +#define JIM_NONE 0 +#define JIM_ERRMSG 1 +#define JIM_ENUM_ABBREV 2 +#define JIM_UNSHARED 4 +#define JIM_MUSTEXIST 8 +#define JIM_NORESULT 16 + + +#define JIM_SUBST_NOVAR 1 +#define JIM_SUBST_NOCMD 2 +#define JIM_SUBST_NOESC 4 +#define JIM_SUBST_FLAG 128 + + +#define JIM_CASESENS 0 +#define JIM_NOCASE 1 +#define JIM_OPT_END 2 + + +#define JIM_PATH_LEN 1024 + + +#define JIM_NOTUSED(V) ((void) V) + +#define JIM_LIBPATH "auto_path" +#define JIM_INTERACTIVE "tcl_interactive" + + +typedef struct Jim_Stack { + int len; + int maxlen; + void **vector; +} Jim_Stack; + + +typedef struct Jim_HashEntry { + void *key; + union { + void *val; + int intval; + } u; + struct Jim_HashEntry *next; +} Jim_HashEntry; + +typedef struct Jim_HashTableType { + unsigned int (*hashFunction)(const void *key); + void *(*keyDup)(void *privdata, const void *key); + void *(*valDup)(void *privdata, const void *obj); + int (*keyCompare)(void *privdata, const void *key1, const void *key2); + void (*keyDestructor)(void *privdata, void *key); + void (*valDestructor)(void *privdata, void *obj); +} Jim_HashTableType; + +typedef struct Jim_HashTable { + Jim_HashEntry **table; + const Jim_HashTableType *type; + void *privdata; + unsigned int size; + unsigned int sizemask; + unsigned int used; + unsigned int collisions; + unsigned int uniq; +} Jim_HashTable; + +typedef struct Jim_HashTableIterator { + Jim_HashTable *ht; + Jim_HashEntry *entry, *nextEntry; + int index; +} Jim_HashTableIterator; + + +#define JIM_HT_INITIAL_SIZE 16 + + +#define Jim_FreeEntryVal(ht, entry) \ + if ((ht)->type->valDestructor) \ + (ht)->type->valDestructor((ht)->privdata, (entry)->u.val) + +#define Jim_SetHashVal(ht, entry, _val_) do { \ + if ((ht)->type->valDup) \ + (entry)->u.val = (ht)->type->valDup((ht)->privdata, (_val_)); \ + else \ + (entry)->u.val = (_val_); \ +} while(0) + +#define Jim_SetHashIntVal(ht, entry, _val_) (entry)->u.intval = (_val_) + +#define Jim_FreeEntryKey(ht, entry) \ + if ((ht)->type->keyDestructor) \ + (ht)->type->keyDestructor((ht)->privdata, (entry)->key) + +#define Jim_SetHashKey(ht, entry, _key_) do { \ + if ((ht)->type->keyDup) \ + (entry)->key = (ht)->type->keyDup((ht)->privdata, (_key_)); \ + else \ + (entry)->key = (void *)(_key_); \ +} while(0) + +#define Jim_CompareHashKeys(ht, key1, key2) \ + (((ht)->type->keyCompare) ? \ + (ht)->type->keyCompare((ht)->privdata, (key1), (key2)) : \ + (key1) == (key2)) + +#define Jim_HashKey(ht, key) ((ht)->type->hashFunction(key) + (ht)->uniq) + +#define Jim_GetHashEntryKey(he) ((he)->key) +#define Jim_GetHashEntryVal(he) ((he)->u.val) +#define Jim_GetHashEntryIntVal(he) ((he)->u.intval) +#define Jim_GetHashTableCollisions(ht) ((ht)->collisions) +#define Jim_GetHashTableSize(ht) ((ht)->size) +#define Jim_GetHashTableUsed(ht) ((ht)->used) + + +typedef struct Jim_Obj { + char *bytes; + const struct Jim_ObjType *typePtr; + int refCount; + int length; + + union { + + jim_wide wideValue; + + int intValue; + + double doubleValue; + + void *ptr; + + struct { + void *ptr1; + void *ptr2; + } twoPtrValue; + + struct { + void *ptr; + int int1; + int int2; + } ptrIntValue; + + struct { + struct Jim_VarVal *vv; + unsigned long callFrameId; + int global; + } varValue; + + struct { + struct Jim_Obj *nsObj; + struct Jim_Cmd *cmdPtr; + unsigned long procEpoch; + } cmdValue; + + struct { + struct Jim_Obj **ele; + int len; + int maxLen; + } listValue; + + struct Jim_Dict *dictValue; + + struct { + int maxLength; + int charLength; + } strValue; + + struct { + unsigned long id; + struct Jim_Reference *refPtr; + } refValue; + + struct { + struct Jim_Obj *fileNameObj; + int lineNumber; + } sourceValue; + + struct { + struct Jim_Obj *varNameObjPtr; + struct Jim_Obj *indexObjPtr; + } dictSubstValue; + struct { + int line; + int argc; + } scriptLineValue; + } internalRep; + struct Jim_Obj *prevObjPtr; + struct Jim_Obj *nextObjPtr; +} Jim_Obj; + + +#define Jim_IncrRefCount(objPtr) \ + ++(objPtr)->refCount +#define Jim_DecrRefCount(interp, objPtr) \ + if (--(objPtr)->refCount <= 0) Jim_FreeObj(interp, objPtr) +#define Jim_IsShared(objPtr) \ + ((objPtr)->refCount > 1) + +#define Jim_FreeNewObj Jim_FreeObj + + +#define Jim_FreeIntRep(i,o) \ + if ((o)->typePtr && (o)->typePtr->freeIntRepProc) \ + (o)->typePtr->freeIntRepProc(i, o) + + +#define Jim_GetIntRepPtr(o) (o)->internalRep.ptr + + +#define Jim_SetIntRepPtr(o, p) \ + (o)->internalRep.ptr = (p) + + +struct Jim_Interp; + +typedef void (Jim_FreeInternalRepProc)(struct Jim_Interp *interp, + struct Jim_Obj *objPtr); +typedef void (Jim_DupInternalRepProc)(struct Jim_Interp *interp, + struct Jim_Obj *srcPtr, Jim_Obj *dupPtr); +typedef void (Jim_UpdateStringProc)(struct Jim_Obj *objPtr); + +typedef struct Jim_ObjType { + const char *name; + Jim_FreeInternalRepProc *freeIntRepProc; + Jim_DupInternalRepProc *dupIntRepProc; + Jim_UpdateStringProc *updateStringProc; + int flags; +} Jim_ObjType; + + +#define JIM_TYPE_NONE 0 +#define JIM_TYPE_REFERENCES 1 + + + +typedef struct Jim_CallFrame { + unsigned long id; + int level; + struct Jim_HashTable vars; + struct Jim_HashTable *staticVars; + struct Jim_CallFrame *parent; + Jim_Obj *const *argv; + int argc; + Jim_Obj *procArgsObjPtr; + Jim_Obj *procBodyObjPtr; + struct Jim_CallFrame *next; + Jim_Obj *nsObj; + Jim_Obj *unused_fileNameObj; + int unused_line; + Jim_Stack *localCommands; + struct Jim_Obj *tailcallObj; + struct Jim_Cmd *tailcallCmd; +} Jim_CallFrame; + + +typedef struct Jim_EvalFrame { + Jim_CallFrame *framePtr; + int level; + int procLevel; + struct Jim_Cmd *cmd; + struct Jim_EvalFrame *parent; + Jim_Obj *const *argv; + int argc; + Jim_Obj *scriptObj; +} Jim_EvalFrame; + +typedef struct Jim_VarVal { + Jim_Obj *objPtr; + struct Jim_CallFrame *linkFramePtr; + int refCount; +} Jim_VarVal; + + +typedef int Jim_CmdProc(struct Jim_Interp *interp, int argc, + Jim_Obj *const *argv); +typedef void Jim_DelCmdProc(struct Jim_Interp *interp, void *privData); + +typedef struct Jim_Dict { + struct JimDictHashEntry { + int offset; + unsigned hash; + } *ht; + unsigned int size; + unsigned int sizemask; + unsigned int uniq; + Jim_Obj **table; + int len; + int maxLen; + unsigned int dummy; +} Jim_Dict; + +typedef struct Jim_Cmd { + int inUse; + int isproc; + struct Jim_Cmd *prevCmd; + Jim_Obj *cmdNameObj; + union { + struct { + + Jim_CmdProc *cmdProc; + Jim_DelCmdProc *delProc; + void *privData; + } native; + struct { + + Jim_Obj *argListObjPtr; + Jim_Obj *bodyObjPtr; + Jim_HashTable *staticVars; + int argListLen; + int reqArity; + int optArity; + int argsPos; + int upcall; + struct Jim_ProcArg { + Jim_Obj *nameObjPtr; + Jim_Obj *defaultObjPtr; + } *arglist; + Jim_Obj *nsObj; + } proc; + } u; +} Jim_Cmd; + + +typedef struct Jim_PrngState { + unsigned char sbox[256]; + unsigned int i, j; +} Jim_PrngState; + +typedef struct Jim_Interp { + Jim_Obj *result; + int unused_errorLine; + Jim_Obj *currentFilenameObj; + int break_level; + int maxCallFrameDepth; + int maxEvalDepth; + int evalDepth; + int returnCode; + int returnLevel; + int exitCode; + long id; + int signal_level; + jim_wide sigmask; + int (*signal_set_result)(struct Jim_Interp *interp, jim_wide sigmask); + Jim_CallFrame *framePtr; + Jim_CallFrame *topFramePtr; + struct Jim_HashTable commands; + unsigned long procEpoch; /* Incremented every time the result + of procedures names lookup caching + may no longer be valid. */ + unsigned long callFrameEpoch; /* Incremented every time a new + callframe is created. This id is used for the + 'ID' field contained in the Jim_CallFrame + structure. */ + int local; + int quitting; + int safeexpr; + Jim_Obj *liveList; + Jim_Obj *freeList; + Jim_Obj *unused_currentScriptObj; + Jim_EvalFrame topEvalFrame; + Jim_EvalFrame *evalFrame; + int procLevel; + Jim_Obj * const *unused_argv; + Jim_Obj *nullScriptObj; + Jim_Obj *emptyObj; + Jim_Obj *trueObj; + Jim_Obj *falseObj; + unsigned long referenceNextId; + struct Jim_HashTable references; + unsigned long lastCollectId; /* reference max Id of the last GC + execution. It's set to ~0 while the collection + is running as sentinel to avoid to recursive + calls via the [collect] command inside + finalizers. */ + jim_wide lastCollectTime; + Jim_Obj *stackTrace; + Jim_Obj *errorProc; + Jim_Obj *unknown; + Jim_Obj *defer; + Jim_Obj *traceCmdObj; + int unknown_called; + int errorFlag; + void *cmdPrivData; /* Used to pass the private data pointer to + a command. It is set to what the user specified + via Jim_CreateCommand(). */ + + Jim_Cmd *oldCmdCache; + int oldCmdCacheSize; + struct Jim_CallFrame *freeFramesList; + struct Jim_HashTable assocData; + Jim_PrngState *prngState; + struct Jim_HashTable packages; + Jim_Stack *loadHandles; +} Jim_Interp; + +#define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l)) +#define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval)) + +#define Jim_SetResultBool(i,b) Jim_SetResultInt(i, b) +#define Jim_SetEmptyResult(i) Jim_SetResult(i, (i)->emptyObj) +#define Jim_GetResult(i) ((i)->result) +#define Jim_CmdPrivData(i) ((i)->cmdPrivData) + +#define Jim_SetResult(i,o) do { \ + Jim_Obj *_resultObjPtr_ = (o); \ + Jim_IncrRefCount(_resultObjPtr_); \ + Jim_DecrRefCount(i,(i)->result); \ + (i)->result = _resultObjPtr_; \ +} while(0) + + +#define Jim_GetId(i) (++(i)->id) + + +#define JIM_REFERENCE_TAGLEN 7 /* The tag is fixed-length, because the reference + string representation must be fixed length. */ +typedef struct Jim_Reference { + Jim_Obj *objPtr; + Jim_Obj *finalizerCmdNamePtr; + char tag[JIM_REFERENCE_TAGLEN+1]; +} Jim_Reference; + + +#define Jim_NewEmptyStringObj(i) Jim_NewStringObj(i, "", 0) +#define Jim_FreeHashTableIterator(iter) Jim_Free(iter) + +#define JIM_EXPORT extern + + + +JIM_EXPORT void *(*Jim_Allocator)(void *ptr, size_t size); + +#define Jim_Free(P) Jim_Allocator((P), 0) +#define Jim_Realloc(P, S) Jim_Allocator((P), (S)) +#define Jim_Alloc(S) Jim_Allocator(NULL, (S)) +JIM_EXPORT char * Jim_StrDup (const char *s); +JIM_EXPORT char *Jim_StrDupLen(const char *s, int l); + + +JIM_EXPORT char **Jim_GetEnviron(void); +JIM_EXPORT void Jim_SetEnviron(char **env); +JIM_EXPORT int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file); +#ifndef CLOCK_REALTIME +# define CLOCK_REALTIME 0 +#endif +#ifndef CLOCK_MONOTONIC +# define CLOCK_MONOTONIC 1 +#endif +#ifndef CLOCK_MONOTONIC_RAW +# define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC +#endif +JIM_EXPORT jim_wide Jim_GetTimeUsec(unsigned type); + + +JIM_EXPORT int Jim_Eval(Jim_Interp *interp, const char *script); + + +JIM_EXPORT int Jim_EvalSource(Jim_Interp *interp, const char *filename, int lineno, const char *script); + +#define Jim_Eval_Named(I, S, F, L) Jim_EvalSource((I), (F), (L), (S)) + +JIM_EXPORT int Jim_EvalGlobal(Jim_Interp *interp, const char *script); +JIM_EXPORT int Jim_EvalFile(Jim_Interp *interp, const char *filename); +JIM_EXPORT int Jim_EvalFileGlobal(Jim_Interp *interp, const char *filename); +JIM_EXPORT int Jim_EvalObj (Jim_Interp *interp, Jim_Obj *scriptObjPtr); +JIM_EXPORT int Jim_EvalObjVector (Jim_Interp *interp, int objc, + Jim_Obj *const *objv); +JIM_EXPORT int Jim_EvalObjList(Jim_Interp *interp, Jim_Obj *listObj); +JIM_EXPORT int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix, + int objc, Jim_Obj *const *objv); +#define Jim_EvalPrefix(i, p, oc, ov) Jim_EvalObjPrefix((i), Jim_NewStringObj((i), (p), -1), (oc), (ov)) +JIM_EXPORT int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj); +JIM_EXPORT int Jim_SubstObj (Jim_Interp *interp, Jim_Obj *substObjPtr, + Jim_Obj **resObjPtrPtr, int flags); + + +JIM_EXPORT Jim_Obj *Jim_GetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, + int *lineptr); + +JIM_EXPORT void Jim_SetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *fileNameObj, int lineNumber); + + + +JIM_EXPORT void Jim_InitStack(Jim_Stack *stack); +JIM_EXPORT void Jim_FreeStack(Jim_Stack *stack); +JIM_EXPORT int Jim_StackLen(Jim_Stack *stack); +JIM_EXPORT void Jim_StackPush(Jim_Stack *stack, void *element); +JIM_EXPORT void * Jim_StackPop(Jim_Stack *stack); +JIM_EXPORT void * Jim_StackPeek(Jim_Stack *stack); +JIM_EXPORT void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc)(void *ptr)); + + +JIM_EXPORT int Jim_InitHashTable (Jim_HashTable *ht, + const Jim_HashTableType *type, void *privdata); +JIM_EXPORT void Jim_ExpandHashTable (Jim_HashTable *ht, + unsigned int size); +JIM_EXPORT int Jim_AddHashEntry (Jim_HashTable *ht, const void *key, + void *val); +JIM_EXPORT int Jim_ReplaceHashEntry (Jim_HashTable *ht, + const void *key, void *val); +JIM_EXPORT int Jim_DeleteHashEntry (Jim_HashTable *ht, + const void *key); +JIM_EXPORT int Jim_FreeHashTable (Jim_HashTable *ht); +JIM_EXPORT Jim_HashEntry * Jim_FindHashEntry (Jim_HashTable *ht, + const void *key); +JIM_EXPORT Jim_HashTableIterator *Jim_GetHashTableIterator + (Jim_HashTable *ht); +JIM_EXPORT Jim_HashEntry * Jim_NextHashEntry + (Jim_HashTableIterator *iter); + + +JIM_EXPORT Jim_Obj * Jim_NewObj (Jim_Interp *interp); +JIM_EXPORT void Jim_FreeObj (Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT void Jim_InvalidateStringRep (Jim_Obj *objPtr); +JIM_EXPORT Jim_Obj * Jim_DuplicateObj (Jim_Interp *interp, + Jim_Obj *objPtr); +JIM_EXPORT const char * Jim_GetString(Jim_Obj *objPtr, + int *lenPtr); +JIM_EXPORT const char *Jim_String(Jim_Obj *objPtr); +JIM_EXPORT int Jim_Length(Jim_Obj *objPtr); + + +JIM_EXPORT Jim_Obj * Jim_NewStringObj (Jim_Interp *interp, + const char *s, int len); +JIM_EXPORT Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, + const char *s, int charlen); +JIM_EXPORT Jim_Obj * Jim_NewStringObjNoAlloc (Jim_Interp *interp, + char *s, int len); +JIM_EXPORT void Jim_AppendString (Jim_Interp *interp, Jim_Obj *objPtr, + const char *str, int len); +JIM_EXPORT void Jim_AppendObj (Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *appendObjPtr); +JIM_EXPORT void Jim_AppendStrings (Jim_Interp *interp, + Jim_Obj *objPtr, ...); +JIM_EXPORT int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr); +JIM_EXPORT int Jim_StringMatchObj (Jim_Interp *interp, Jim_Obj *patternObjPtr, + Jim_Obj *objPtr, int nocase); +JIM_EXPORT Jim_Obj * Jim_StringRangeObj (Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, + Jim_Obj *lastObjPtr); +JIM_EXPORT Jim_Obj * Jim_FormatString (Jim_Interp *interp, + Jim_Obj *fmtObjPtr, int objc, Jim_Obj *const *objv); +JIM_EXPORT Jim_Obj * Jim_ScanString (Jim_Interp *interp, Jim_Obj *strObjPtr, + Jim_Obj *fmtObjPtr, int flags); +JIM_EXPORT int Jim_CompareStringImmediate (Jim_Interp *interp, + Jim_Obj *objPtr, const char *str); +JIM_EXPORT int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, + Jim_Obj *secondObjPtr, int nocase); +JIM_EXPORT int Jim_Utf8Length(Jim_Interp *interp, Jim_Obj *objPtr); + + +JIM_EXPORT Jim_Obj * Jim_NewReference (Jim_Interp *interp, + Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr); +JIM_EXPORT Jim_Reference * Jim_GetReference (Jim_Interp *interp, + Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetFinalizer (Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *cmdNamePtr); +JIM_EXPORT int Jim_GetFinalizer (Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj **cmdNamePtrPtr); + + +JIM_EXPORT Jim_Interp * Jim_CreateInterp (void); +JIM_EXPORT void Jim_FreeInterp (Jim_Interp *i); +JIM_EXPORT int Jim_GetExitCode (Jim_Interp *interp); +JIM_EXPORT const char *Jim_ReturnCode(int code); +JIM_EXPORT void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...); + + +JIM_EXPORT void Jim_RegisterCoreCommands (Jim_Interp *interp); +JIM_EXPORT int Jim_CreateCommand (Jim_Interp *interp, + const char *cmdName, Jim_CmdProc *cmdProc, void *privData, + Jim_DelCmdProc *delProc); +JIM_EXPORT int Jim_DeleteCommand (Jim_Interp *interp, + Jim_Obj *cmdNameObj); +JIM_EXPORT int Jim_RenameCommand (Jim_Interp *interp, + Jim_Obj *oldNameObj, Jim_Obj *newNameObj); +JIM_EXPORT Jim_Cmd * Jim_GetCommand (Jim_Interp *interp, + Jim_Obj *objPtr, int flags); +JIM_EXPORT int Jim_SetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr); +JIM_EXPORT int Jim_SetVariableStr (Jim_Interp *interp, + const char *name, Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetGlobalVariableStr (Jim_Interp *interp, + const char *name, Jim_Obj *objPtr); +JIM_EXPORT int Jim_SetVariableStrWithStr (Jim_Interp *interp, + const char *name, const char *val); +JIM_EXPORT int Jim_SetVariableLink (Jim_Interp *interp, + Jim_Obj *nameObjPtr, Jim_Obj *targetNameObjPtr, + Jim_CallFrame *targetCallFrame); +JIM_EXPORT Jim_Obj * Jim_MakeGlobalNamespaceName(Jim_Interp *interp, + Jim_Obj *nameObjPtr); +JIM_EXPORT Jim_Obj * Jim_GetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); +JIM_EXPORT Jim_Obj * Jim_GetGlobalVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); +JIM_EXPORT Jim_Obj * Jim_GetVariableStr (Jim_Interp *interp, + const char *name, int flags); +JIM_EXPORT Jim_Obj * Jim_GetGlobalVariableStr (Jim_Interp *interp, + const char *name, int flags); +JIM_EXPORT int Jim_UnsetVariable (Jim_Interp *interp, + Jim_Obj *nameObjPtr, int flags); + + +JIM_EXPORT Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, + Jim_Obj *levelObjPtr); + + +JIM_EXPORT int Jim_Collect (Jim_Interp *interp); +JIM_EXPORT void Jim_CollectIfNeeded (Jim_Interp *interp); + + +JIM_EXPORT int Jim_GetIndex (Jim_Interp *interp, Jim_Obj *objPtr, + int *indexPtr); + + +JIM_EXPORT Jim_Obj * Jim_NewListObj (Jim_Interp *interp, + Jim_Obj *const *elements, int len); +JIM_EXPORT void Jim_ListInsertElements (Jim_Interp *interp, + Jim_Obj *listPtr, int listindex, int objc, Jim_Obj *const *objVec); +JIM_EXPORT void Jim_ListAppendElement (Jim_Interp *interp, + Jim_Obj *listPtr, Jim_Obj *objPtr); +JIM_EXPORT void Jim_ListAppendList (Jim_Interp *interp, + Jim_Obj *listPtr, Jim_Obj *appendListPtr); +JIM_EXPORT int Jim_ListLength (Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT int Jim_ListIndex (Jim_Interp *interp, Jim_Obj *listPrt, + int listindex, Jim_Obj **objPtrPtr, int seterr); +JIM_EXPORT Jim_Obj *Jim_ListGetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx); +JIM_EXPORT int Jim_SetListIndex (Jim_Interp *interp, + Jim_Obj *varNamePtr, Jim_Obj *const *indexv, int indexc, + Jim_Obj *newObjPtr); +JIM_EXPORT Jim_Obj * Jim_ConcatObj (Jim_Interp *interp, int objc, + Jim_Obj *const *objv); +JIM_EXPORT Jim_Obj *Jim_ListJoin(Jim_Interp *interp, + Jim_Obj *listObjPtr, const char *joinStr, int joinStrLen); + + +JIM_EXPORT Jim_Obj * Jim_NewDictObj (Jim_Interp *interp, + Jim_Obj *const *elements, int len); +JIM_EXPORT int Jim_DictKey (Jim_Interp *interp, Jim_Obj *dictPtr, + Jim_Obj *keyPtr, Jim_Obj **objPtrPtr, int flags); +JIM_EXPORT int Jim_DictKeysVector (Jim_Interp *interp, + Jim_Obj *dictPtr, Jim_Obj *const *keyv, int keyc, + Jim_Obj **objPtrPtr, int flags); +JIM_EXPORT int Jim_SetDictKeysVector (Jim_Interp *interp, + Jim_Obj *varNamePtr, Jim_Obj *const *keyv, int keyc, + Jim_Obj *newObjPtr, int flags); +JIM_EXPORT Jim_Obj **Jim_DictPairs(Jim_Interp *interp, + Jim_Obj *dictPtr, int *len); +JIM_EXPORT int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr); + +#define JIM_DICTMATCH_KEYS 0x0001 +#define JIM_DICTMATCH_VALUES 0x002 + +JIM_EXPORT int Jim_DictMatchTypes(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj, int match_type, int return_types); +JIM_EXPORT int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr); +JIM_EXPORT Jim_Obj *Jim_DictMerge(Jim_Interp *interp, int objc, Jim_Obj *const *objv); + + +JIM_EXPORT int Jim_GetReturnCode (Jim_Interp *interp, Jim_Obj *objPtr, + int *intPtr); + + +JIM_EXPORT int Jim_EvalExpression (Jim_Interp *interp, + Jim_Obj *exprObjPtr); +JIM_EXPORT int Jim_GetBoolFromExpr (Jim_Interp *interp, + Jim_Obj *exprObjPtr, int *boolPtr); + + +JIM_EXPORT int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, + int *booleanPtr); + + +JIM_EXPORT int Jim_GetWide (Jim_Interp *interp, Jim_Obj *objPtr, + jim_wide *widePtr); +JIM_EXPORT int Jim_GetWideExpr(Jim_Interp *interp, Jim_Obj *objPtr, + jim_wide *widePtr); +JIM_EXPORT int Jim_GetLong (Jim_Interp *interp, Jim_Obj *objPtr, + long *longPtr); +#define Jim_NewWideObj Jim_NewIntObj +JIM_EXPORT Jim_Obj * Jim_NewIntObj (Jim_Interp *interp, + jim_wide wideValue); + + +JIM_EXPORT int Jim_GetDouble(Jim_Interp *interp, Jim_Obj *objPtr, + double *doublePtr); +JIM_EXPORT void Jim_SetDouble(Jim_Interp *interp, Jim_Obj *objPtr, + double doubleValue); +JIM_EXPORT Jim_Obj * Jim_NewDoubleObj(Jim_Interp *interp, double doubleValue); + + +JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc, + Jim_Obj *const *argv, const char *msg); +JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr, + const char * const *tablePtr, int *indexPtr, const char *name, int flags); +JIM_EXPORT int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, + const char *const *tablePtr); +JIM_EXPORT int Jim_ScriptIsComplete(Jim_Interp *interp, + Jim_Obj *scriptObj, char *stateCharPtr); + +JIM_EXPORT int Jim_FindByName(const char *name, const char * const array[], size_t len); + + +typedef void (Jim_InterpDeleteProc)(Jim_Interp *interp, void *data); +JIM_EXPORT void * Jim_GetAssocData(Jim_Interp *interp, const char *key); +JIM_EXPORT int Jim_SetAssocData(Jim_Interp *interp, const char *key, + Jim_InterpDeleteProc *delProc, void *data); +JIM_EXPORT int Jim_DeleteAssocData(Jim_Interp *interp, const char *key); +JIM_EXPORT int Jim_CheckAbiVersion(Jim_Interp *interp, int abi_version); + + + + +JIM_EXPORT int Jim_PackageProvide (Jim_Interp *interp, + const char *name, const char *ver, int flags); +JIM_EXPORT int Jim_PackageRequire (Jim_Interp *interp, + const char *name, int flags); +#define Jim_PackageProvideCheck(INTERP, NAME) \ + if (Jim_CheckAbiVersion(INTERP, JIM_ABI_VERSION) == JIM_ERR || Jim_PackageProvide(INTERP, NAME, "1.0", JIM_ERRMSG)) \ + return JIM_ERR + + +JIM_EXPORT void Jim_MakeErrorMessage (Jim_Interp *interp); + + +JIM_EXPORT int Jim_InteractivePrompt (Jim_Interp *interp); +JIM_EXPORT void Jim_HistoryLoad(const char *filename); +JIM_EXPORT void Jim_HistorySave(const char *filename); +JIM_EXPORT char *Jim_HistoryGetline(Jim_Interp *interp, const char *prompt); +JIM_EXPORT void Jim_HistorySetCompletion(Jim_Interp *interp, Jim_Obj *completionCommandObj); +JIM_EXPORT void Jim_HistorySetHints(Jim_Interp *interp, Jim_Obj *hintsCommandObj); +JIM_EXPORT void Jim_HistoryAdd(const char *line); +JIM_EXPORT void Jim_HistoryShow(void); +JIM_EXPORT void Jim_HistorySetMaxLen(int length); +JIM_EXPORT int Jim_HistoryGetMaxLen(void); + + +JIM_EXPORT int Jim_InitStaticExtensions(Jim_Interp *interp); +JIM_EXPORT int Jim_StringToWide(const char *str, jim_wide *widePtr, int base); +JIM_EXPORT int Jim_IsBigEndian(void); + +#define Jim_CheckSignal(i) ((i)->signal_level && (i)->sigmask) +JIM_EXPORT void Jim_SignalSetIgnored(jim_wide mask); + + +JIM_EXPORT int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName); +JIM_EXPORT void Jim_FreeLoadHandles(Jim_Interp *interp); + + +JIM_EXPORT int Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command); + + +JIM_EXPORT int Jim_IsDict(Jim_Obj *objPtr); +JIM_EXPORT int Jim_IsList(Jim_Obj *objPtr); + +#ifdef __cplusplus +} +#endif + +#endif + +#ifndef JIM_SUBCMD_H +#define JIM_SUBCMD_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define JIM_MODFLAG_HIDDEN 0x0001 +#define JIM_MODFLAG_FULLARGV 0x0002 + + + +typedef int jim_subcmd_function(Jim_Interp *interp, int argc, Jim_Obj *const *argv); + +typedef struct { + const char *cmd; + const char *args; + jim_subcmd_function *function; + short minargs; + short maxargs; + unsigned short flags; +} jim_subcmd_type; + +#define JIM_DEF_SUBCMD(name, args, minargs, maxargs) { name, args, NULL, minargs, maxargs } +#define JIM_DEF_SUBCMD_HIDDEN(name, args, minargs, maxargs) { name, args, NULL, minargs, maxargs, JIM_MODFLAG_HIDDEN } + +const jim_subcmd_type * +Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int argc, Jim_Obj *const *argv); + +int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); + +int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type *ct, int argc, Jim_Obj *const *argv); + +void Jim_SubCmdArgError(Jim_Interp *interp, const jim_subcmd_type *ct, Jim_Obj *subcmd); + +#ifdef __cplusplus +} +#endif + +#endif +#ifndef JIMREGEXP_H +#define JIMREGEXP_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct { + int rm_so; + int rm_eo; +} regmatch_t; + + +typedef struct regexp { + + int re_nsub; + + + int cflags; + int err; + int regstart; + int reganch; + int regmust; + int regmlen; + int *program; + + + const char *regparse; + int p; + int proglen; + + + int eflags; + const char *start; + const char *reginput; + const char *regbol; + + + regmatch_t *pmatch; + int nmatch; +} regexp; + +typedef regexp regex_t; + +#define REG_EXTENDED 0 +#define REG_NEWLINE 1 +#define REG_ICASE 2 + +#define REG_NOTBOL 16 + +enum { + REG_NOERROR, + REG_NOMATCH, + REG_BADPAT, + REG_ERR_NULL_ARGUMENT, + REG_ERR_UNKNOWN, + REG_ERR_TOO_BIG, + REG_ERR_NOMEM, + REG_ERR_TOO_MANY_PAREN, + REG_ERR_UNMATCHED_PAREN, + REG_ERR_UNMATCHED_BRACES, + REG_ERR_BAD_COUNT, + REG_ERR_JUNK_ON_END, + REG_ERR_OPERAND_COULD_BE_EMPTY, + REG_ERR_NESTED_COUNT, + REG_ERR_INTERNAL, + REG_ERR_COUNT_FOLLOWS_NOTHING, + REG_ERR_INVALID_ESCAPE, + REG_ERR_CORRUPTED, + REG_ERR_NULL_CHAR, + REG_ERR_UNMATCHED_BRACKET, + REG_ERR_NUM +}; + +int jim_regcomp(regex_t *preg, const char *regex, int cflags); +int jim_regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); +size_t jim_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); +void jim_regfree(regex_t *preg); + +#ifdef __cplusplus +} +#endif + +#endif +#ifndef JIM_SIGNAL_H +#define JIM_SIGNAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +const char *Jim_SignalId(int sig); + +#ifdef __cplusplus +} +#endif + +#endif +#ifndef JIMIOCOMPAT_H +#define JIMIOCOMPAT_H + + +#include +#include +#include + + +void Jim_SetResultErrno(Jim_Interp *interp, const char *msg); + +int Jim_OpenForWrite(const char *filename, int append); + +int Jim_OpenForRead(const char *filename); + +#if defined(__MINGW32__) + #ifndef STRICT + #define STRICT + #endif + #define WIN32_LEAN_AND_MEAN + #include + #include + #include + #include + + typedef HANDLE phandle_t; + #define JIM_BAD_PHANDLE INVALID_HANDLE_VALUE + + + #define WIFEXITED(STATUS) (((STATUS) & 0xff00) == 0) + #define WEXITSTATUS(STATUS) ((STATUS) & 0x00ff) + #define WIFSIGNALED(STATUS) (((STATUS) & 0xff00) != 0) + #define WTERMSIG(STATUS) (((STATUS) >> 8) & 0xff) + #define WNOHANG 1 + + int Jim_Errno(void); + + long waitpid(phandle_t phandle, int *status, int nohang); + + phandle_t JimWaitPid(long processid, int *status, int nohang); + + long JimProcessPid(phandle_t phandle); + + #define HAVE_PIPE + #define pipe(P) _pipe((P), 0, O_NOINHERIT) + + typedef struct __stat64 jim_stat_t; + #define Jim_Stat _stat64 + #define Jim_FileStat _fstat64 + #define Jim_Lseek _lseeki64 + +#else + #if defined(HAVE_STAT64) + typedef struct stat64 jim_stat_t; + #define Jim_Stat stat64 + #if defined(HAVE_FSTAT64) + #define Jim_FileStat fstat64 + #endif + #if defined(HAVE_LSTAT64) + #define Jim_LinkStat lstat64 + #endif + #else + typedef struct stat jim_stat_t; + #define Jim_Stat stat + #if defined(HAVE_FSTAT) + #define Jim_FileStat fstat + #endif + #if defined(HAVE_LSTAT) + #define Jim_LinkStat lstat + #endif + #endif + #if defined(HAVE_LSEEK64) + #define Jim_Lseek lseek64 + #else + #define Jim_Lseek lseek + #endif + + #if defined(HAVE_UNISTD_H) + #include + #include + #include + + typedef int phandle_t; + #define Jim_Errno() errno + #define JIM_BAD_PHANDLE -1 + #define JimProcessPid(PIDTYPE) (PIDTYPE) + #define JimWaitPid waitpid + + #ifndef HAVE_EXECVPE + #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV) + #endif + #endif +#endif + +#ifndef O_TEXT +#define O_TEXT 0 +#endif + + +int Jim_FileStoreStatData(Jim_Interp *interp, Jim_Obj *varName, const jim_stat_t *sb); + +#endif +int Jim_bootstrapInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "bootstrap", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "bootstrap.tcl", 1, +"\n" +"proc package {cmd args} {\n" +" if {$cmd eq \"require\"} {\n" +" foreach path $::auto_path {\n" +" lassign $args pkg\n" +" set pkgpath $path/$pkg.tcl\n" +" if {$path eq \".\"} {\n" +" set pkgpath $pkg.tcl\n" +" }\n" +" if {[file exists $pkgpath]} {\n" +" tailcall uplevel #0 [list source $pkgpath]\n" +" }\n" +" }\n" +" }\n" +"}\n" +"set tcl_platform(bootstrap) 1\n" +); +} +int Jim_initjimshInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "initjimsh", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "initjimsh.tcl", 1, +"\n" +"\n" +"\n" +"proc _jimsh_init {} {\n" +" rename _jimsh_init {}\n" +" global jim::exe jim::argv0 tcl_interactive auto_path tcl_platform\n" +"\n" +"\n" +" if {[exists jim::argv0]} {\n" +" if {[string match \"*/*\" $jim::argv0]} {\n" +" set jim::exe [file join [pwd] $jim::argv0]\n" +" } else {\n" +" foreach path [split [env PATH \"\"] $tcl_platform(pathSeparator)] {\n" +" set exec [file join [pwd] [string map {\\\\ /} $path] $jim::argv0]\n" +" if {[file executable $exec]} {\n" +" set jim::exe $exec\n" +" break\n" +" }\n" +" }\n" +" }\n" +" }\n" +"\n" +"\n" +" lappend p {*}[split [env JIMLIB {}] $tcl_platform(pathSeparator)]\n" +" if {[exists jim::exe]} {\n" +" lappend p [file dirname $jim::exe]\n" +" }\n" +" lappend p {*}$auto_path\n" +" set auto_path $p\n" +"\n" +" if {$tcl_interactive && [env HOME {}] ne \"\"} {\n" +" foreach src {.jimrc jimrc.tcl} {\n" +" if {[file exists [env HOME]/$src]} {\n" +" uplevel #0 source [env HOME]/$src\n" +" break\n" +" }\n" +" }\n" +" }\n" +" return \"\"\n" +"}\n" +"\n" +"if {$tcl_platform(platform) eq \"windows\"} {\n" +" set jim::argv0 [string map {\\\\ /} $jim::argv0]\n" +"}\n" +"\n" +"\n" +"set tcl::autocomplete_commands {array clock debug dict file history info namespace package signal socket string tcl::prefix zlib}\n" +"\n" +"\n" +"\n" +"proc tcl::autocomplete {prefix} {\n" +" if {[set space [string first \" \" $prefix]] != -1} {\n" +" set cmd [string range $prefix 0 $space-1]\n" +" if {$cmd in $::tcl::autocomplete_commands || [info channel $cmd] ne \"\"} {\n" +" set arg [string range $prefix $space+1 end]\n" +"\n" +" return [lmap p [$cmd -commands] {\n" +" if {![string match \"${arg}*\" $p]} continue\n" +" function \"$cmd $p\"\n" +" }]\n" +" }\n" +" }\n" +"\n" +" if {[string match \"source *\" $prefix]} {\n" +" set path [string range $prefix 7 end]\n" +" return [lmap p [glob -nocomplain \"${path}*\"] {\n" +" function \"source $p\"\n" +" }]\n" +" }\n" +"\n" +" return [lmap p [lsort [info commands $prefix*]] {\n" +" if {[string match \"* *\" $p]} {\n" +" continue\n" +" }\n" +" function $p\n" +" }]\n" +"}\n" +"\n" +"\n" +"set tcl::stdhint_commands {array clock debug dict file history info namespace package signal string zlib}\n" +"\n" +"set tcl::stdhint_cols {\n" +" none {0}\n" +" black {30}\n" +" red {31}\n" +" green {32}\n" +" yellow {33}\n" +" blue {34}\n" +" purple {35}\n" +" cyan {36}\n" +" normal {37}\n" +" grey {30 1}\n" +" gray {30 1}\n" +" lred {31 1}\n" +" lgreen {32 1}\n" +" lyellow {33 1}\n" +" lblue {34 1}\n" +" lpurple {35 1}\n" +" lcyan {36 1}\n" +" white {37 1}\n" +"}\n" +"\n" +"\n" +"set tcl::stdhint_col $tcl::stdhint_cols(lcyan)\n" +"\n" +"\n" +"proc tcl::stdhint {string} {\n" +" set result \"\"\n" +" if {[llength $string] >= 2} {\n" +" lassign $string cmd arg\n" +" if {$cmd in $::tcl::stdhint_commands || [info channel $cmd] ne \"\"} {\n" +" catch {\n" +" set help [$cmd -help $arg]\n" +" if {[string match \"Usage: $cmd *\" $help]} {\n" +" set n [llength $string]\n" +" set subcmd [lindex $help $n]\n" +" incr n\n" +" set hint [join [lrange $help $n end]]\n" +" set prefix \"\"\n" +" if {![string match \"* \" $string]} {\n" +" if {$n == 3 && $subcmd ne $arg} {\n" +"\n" +" set prefix \"[string range $subcmd [string length $arg] end] \"\n" +" } else {\n" +" set prefix \" \"\n" +" }\n" +" }\n" +" set result [list $prefix$hint {*}$::tcl::stdhint_col]\n" +" }\n" +" }\n" +" }\n" +" }\n" +" return $result\n" +"}\n" +"\n" +"_jimsh_init\n" +); +} +int Jim_globInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "glob", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "glob.tcl", 1, +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"package require readdir\n" +"\n" +"\n" +"proc glob.globdir {dir pattern} {\n" +" if {[file exists $dir/$pattern]} {\n" +"\n" +" return [list $pattern]\n" +" }\n" +"\n" +" set result {}\n" +" set files [readdir $dir]\n" +" lappend files . ..\n" +"\n" +" foreach name $files {\n" +" if {[string match $pattern $name]} {\n" +"\n" +" if {[string index $name 0] eq \".\" && [string index $pattern 0] ne \".\"} {\n" +" continue\n" +" }\n" +" lappend result $name\n" +" }\n" +" }\n" +"\n" +" return $result\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"proc glob.explode {pattern} {\n" +" set oldexp {}\n" +" set newexp {\"\"}\n" +"\n" +" while 1 {\n" +" set oldexp $newexp\n" +" set newexp {}\n" +" set ob [string first \\{ $pattern]\n" +" set cb [string first \\} $pattern]\n" +"\n" +" if {$ob < $cb && $ob != -1} {\n" +" set mid [string range $pattern 0 $ob-1]\n" +" set subexp [lassign [glob.explode [string range $pattern $ob+1 end]] pattern]\n" +" if {$pattern eq \"\"} {\n" +" error \"unmatched open brace in glob pattern\"\n" +" }\n" +" set pattern [string range $pattern 1 end]\n" +"\n" +" foreach subs $subexp {\n" +" foreach sub [split $subs ,] {\n" +" foreach old $oldexp {\n" +" lappend newexp $old$mid$sub\n" +" }\n" +" }\n" +" }\n" +" } elseif {$cb != -1} {\n" +" set suf [string range $pattern 0 $cb-1]\n" +" set rest [string range $pattern $cb end]\n" +" break\n" +" } else {\n" +" set suf $pattern\n" +" set rest \"\"\n" +" break\n" +" }\n" +" }\n" +"\n" +" foreach old $oldexp {\n" +" lappend newexp $old$suf\n" +" }\n" +" list $rest {*}$newexp\n" +"}\n" +"\n" +"\n" +"\n" +"proc glob.glob {base pattern} {\n" +" set dir [file dirname $pattern]\n" +" if {$pattern eq $dir || $pattern eq \"\"} {\n" +" return [list [file join $base $dir] $pattern]\n" +" } elseif {$pattern eq [file tail $pattern]} {\n" +" set dir \"\"\n" +" }\n" +"\n" +"\n" +" set dirlist [glob.glob $base $dir]\n" +" set pattern [file tail $pattern]\n" +"\n" +"\n" +" set result {}\n" +" foreach {realdir dir} $dirlist {\n" +" if {![file isdir $realdir]} {\n" +" continue\n" +" }\n" +" if {[string index $dir end] ne \"/\" && $dir ne \"\"} {\n" +" append dir /\n" +" }\n" +" foreach name [glob.globdir $realdir $pattern] {\n" +" lappend result [file join $realdir $name] $dir$name\n" +" }\n" +" }\n" +" return $result\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"proc glob {args} {\n" +" set nocomplain 0\n" +" set base \"\"\n" +" set tails 0\n" +"\n" +" set n 0\n" +" foreach arg $args {\n" +" if {[info exists param]} {\n" +" set $param $arg\n" +" unset param\n" +" incr n\n" +" continue\n" +" }\n" +" switch -glob -- $arg {\n" +" -d* {\n" +" set switch $arg\n" +" set param base\n" +" }\n" +" -n* {\n" +" set nocomplain 1\n" +" }\n" +" -ta* {\n" +" set tails 1\n" +" }\n" +" -- {\n" +" incr n\n" +" break\n" +" }\n" +" -* {\n" +" return -code error \"bad option \\\"$arg\\\": must be -directory, -nocomplain, -tails, or --\"\n" +" }\n" +" * {\n" +" break\n" +" }\n" +" }\n" +" incr n\n" +" }\n" +" if {[info exists param]} {\n" +" return -code error \"missing argument to \\\"$switch\\\"\"\n" +" }\n" +" if {[llength $args] <= $n} {\n" +" return -code error \"wrong # args: should be \\\"glob ?options? pattern ?pattern ...?\\\"\"\n" +" }\n" +"\n" +" set args [lrange $args $n end]\n" +"\n" +" set result {}\n" +" foreach pattern $args {\n" +" set escpattern [string map {\n" +" \\\\\\\\ \\x01 \\\\\\{ \\x02 \\\\\\} \\x03 \\\\, \\x04\n" +" } $pattern]\n" +" set patexps [lassign [glob.explode $escpattern] rest]\n" +" if {$rest ne \"\"} {\n" +" return -code error \"unmatched close brace in glob pattern\"\n" +" }\n" +" foreach patexp $patexps {\n" +" set patexp [string map {\n" +" \\x01 \\\\\\\\ \\x02 \\{ \\x03 \\} \\x04 ,\n" +" } $patexp]\n" +" foreach {realname name} [glob.glob $base $patexp] {\n" +" incr n\n" +" if {$tails} {\n" +" lappend result $name\n" +" } else {\n" +" lappend result [file join $base $name]\n" +" }\n" +" }\n" +" }\n" +" }\n" +"\n" +" if {!$nocomplain && [llength $result] == 0} {\n" +" set s $(([llength $args] > 1) ? \"s\" : \"\")\n" +" return -code error \"no files matched glob pattern$s \\\"[join $args]\\\"\"\n" +" }\n" +"\n" +" return $result\n" +"}\n" +); +} +int Jim_stdlibInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "stdlib", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "stdlib.tcl", 1, +"\n" +"\n" +"if {![exists -command ref]} {\n" +"\n" +" proc ref {args} {{count 0}} {\n" +" format %08x [incr count]\n" +" }\n" +"}\n" +"\n" +"\n" +"proc lambda {arglist args} {\n" +" tailcall proc [ref {} function lambda.finalizer] $arglist {*}$args\n" +"}\n" +"\n" +"proc lambda.finalizer {name val} {\n" +" rename $name {}\n" +"}\n" +"\n" +"\n" +"proc curry {args} {\n" +" alias [ref {} function lambda.finalizer] {*}$args\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"proc function {value} {\n" +" return $value\n" +"}\n" +"\n" +"\n" +"proc stackdump {stacktrace} {\n" +" set lines {}\n" +" lappend lines \"Traceback (most recent call last):\"\n" +" foreach {cmd l f p} [lreverse $stacktrace] {\n" +" set line {}\n" +" if {$f ne \"\"} {\n" +" append line \" File \\\"$f\\\", line $l\"\n" +" }\n" +" if {$p ne \"\"} {\n" +" append line \", in $p\"\n" +" }\n" +" if {$line ne \"\"} {\n" +" lappend lines $line\n" +" if {$cmd ne \"\"} {\n" +" set nl [string first \\n $cmd 1]\n" +" if {$nl >= 0} {\n" +" set cmd [string range $cmd 0 $nl-1]...\n" +" }\n" +" lappend lines \" $cmd\"\n" +" }\n" +" }\n" +" }\n" +" if {[llength $lines] > 1} {\n" +" return [join $lines \\n]\n" +" }\n" +"}\n" +"\n" +"\n" +"\n" +"proc defer {script} {\n" +" upvar jim::defer v\n" +" lappend v $script\n" +"}\n" +"\n" +"\n" +"\n" +"proc errorInfo {msg {stacktrace \"\"}} {\n" +" if {$stacktrace eq \"\"} {\n" +"\n" +" set stacktrace [info stacktrace]\n" +" }\n" +" lassign $stacktrace p f l cmd\n" +" if {$f ne \"\"} {\n" +" set result \"$f:$l: Error: \"\n" +" }\n" +" append result \"$msg\\n\"\n" +" append result [stackdump $stacktrace]\n" +"\n" +"\n" +" string trim $result\n" +"}\n" +"\n" +"\n" +"\n" +"proc {info nameofexecutable} {} {\n" +" if {[exists ::jim::exe]} {\n" +" return $::jim::exe\n" +" }\n" +"}\n" +"\n" +"\n" +"proc {dict update} {&varName args script} {\n" +" set keys {}\n" +" foreach {n v} $args {\n" +" upvar $v var_$v\n" +" if {[dict exists $varName $n]} {\n" +" set var_$v [dict get $varName $n]\n" +" }\n" +" }\n" +" catch {uplevel 1 $script} msg opts\n" +" if {[info exists varName]} {\n" +" foreach {n v} $args {\n" +" if {[info exists var_$v]} {\n" +" dict set varName $n [set var_$v]\n" +" } else {\n" +" dict unset varName $n\n" +" }\n" +" }\n" +" }\n" +" return {*}$opts $msg\n" +"}\n" +"\n" +"proc {dict replace} {dictionary {args {key value}}} {\n" +" if {[llength ${key value}] % 2} {\n" +" tailcall {dict replace}\n" +" }\n" +" tailcall dict merge $dictionary ${key value}\n" +"}\n" +"\n" +"\n" +"proc {dict lappend} {varName key {args value}} {\n" +" upvar $varName dict\n" +" if {[exists dict] && [dict exists $dict $key]} {\n" +" set list [dict get $dict $key]\n" +" }\n" +" lappend list {*}$value\n" +" dict set dict $key $list\n" +"}\n" +"\n" +"\n" +"proc {dict append} {varName key {args value}} {\n" +" upvar $varName dict\n" +" if {[exists dict] && [dict exists $dict $key]} {\n" +" set str [dict get $dict $key]\n" +" }\n" +" append str {*}$value\n" +" dict set dict $key $str\n" +"}\n" +"\n" +"\n" +"proc {dict incr} {varName key {increment 1}} {\n" +" upvar $varName dict\n" +" if {[exists dict] && [dict exists $dict $key]} {\n" +" set value [dict get $dict $key]\n" +" }\n" +" incr value $increment\n" +" dict set dict $key $value\n" +"}\n" +"\n" +"\n" +"proc {dict remove} {dictionary {args key}} {\n" +" foreach k $key {\n" +" dict unset dictionary $k\n" +" }\n" +" return $dictionary\n" +"}\n" +"\n" +"\n" +"proc {dict for} {vars dictionary script} {\n" +" if {[llength $vars] != 2} {\n" +" return -code error \"must have exactly two variable names\"\n" +" }\n" +" dict size $dictionary\n" +" tailcall foreach $vars $dictionary $script\n" +"}\n" +); +} +int Jim_tclcompatInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "tclcompat", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + return Jim_EvalSource(interp, "tclcompat.tcl", 1, +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"set env [env]\n" +"\n" +"\n" +"if {[exists -command stdout]} {\n" +"\n" +" foreach p {gets flush close eof seek tell} {\n" +" proc $p {chan args} {p} {\n" +" tailcall $chan $p {*}$args\n" +" }\n" +" }\n" +" unset p\n" +"\n" +"\n" +"\n" +" proc puts {{-nonewline {}} {chan stdout} msg} {\n" +" if {${-nonewline} ni {-nonewline {}}} {\n" +" tailcall ${-nonewline} puts $msg\n" +" }\n" +" tailcall $chan puts {*}${-nonewline} $msg\n" +" }\n" +"\n" +"\n" +"\n" +"\n" +"\n" +" proc read {{-nonewline {}} chan} {\n" +" if {${-nonewline} ni {-nonewline {}}} {\n" +" tailcall ${-nonewline} read {*}${chan}\n" +" }\n" +" tailcall $chan read {*}${-nonewline}\n" +" }\n" +"\n" +" proc fconfigure {f args} {\n" +" foreach {n v} $args {\n" +" switch -glob -- $n {\n" +" -bl* {\n" +" $f ndelay $(!$v)\n" +" }\n" +" -bu* {\n" +" $f buffering $v\n" +" }\n" +" -tr* {\n" +"\n" +" }\n" +" default {\n" +" return -code error \"fconfigure: unknown option $n\"\n" +" }\n" +" }\n" +" }\n" +" }\n" +"}\n" +"\n" +"\n" +"proc fileevent {args} {\n" +" tailcall {*}$args\n" +"}\n" +"\n" +"\n" +"\n" +"proc parray {arrayname {pattern *} {puts puts}} {\n" +" upvar $arrayname a\n" +"\n" +" set max 0\n" +" foreach name [array names a $pattern]] {\n" +" if {[string length $name] > $max} {\n" +" set max [string length $name]\n" +" }\n" +" }\n" +" incr max [string length $arrayname]\n" +" incr max 2\n" +" foreach name [lsort [array names a $pattern]] {\n" +" $puts [format \"%-${max}s = %s\" $arrayname\\($name\\) $a($name)]\n" +" }\n" +"}\n" +"\n" +"\n" +"proc {file copy} {{force {}} source target} {\n" +" try {\n" +" if {$force ni {{} -force}} {\n" +" error \"bad option \\\"$force\\\": should be -force\"\n" +" }\n" +"\n" +" set in [open $source rb]\n" +"\n" +" if {[file exists $target]} {\n" +" if {$force eq \"\"} {\n" +" error \"error copying \\\"$source\\\" to \\\"$target\\\": file already exists\"\n" +" }\n" +"\n" +" if {$source eq $target} {\n" +" return\n" +" }\n" +"\n" +"\n" +" file stat $source ss\n" +" file stat $target ts\n" +" if {$ss(dev) == $ts(dev) && $ss(ino) == $ts(ino) && $ss(ino)} {\n" +" return\n" +" }\n" +" }\n" +" set out [open $target wb]\n" +" $in copyto $out\n" +" $out close\n" +" } on error {msg opts} {\n" +" incr opts(-level)\n" +" return {*}$opts $msg\n" +" } finally {\n" +" catch {$in close}\n" +" }\n" +"}\n" +"\n" +"\n" +"\n" +"proc popen {cmd {mode r}} {\n" +" lassign [pipe] r w\n" +" try {\n" +" if {[string match \"w*\" $mode]} {\n" +" lappend cmd <@$r &\n" +" set pids [exec {*}$cmd]\n" +" $r close\n" +" set f $w\n" +" } else {\n" +" lappend cmd >@$w &\n" +" set pids [exec {*}$cmd]\n" +" $w close\n" +" set f $r\n" +" }\n" +" lambda {cmd args} {f pids} {\n" +" if {$cmd eq \"pid\"} {\n" +" return $pids\n" +" }\n" +" if {$cmd eq \"getfd\"} {\n" +" $f getfd\n" +" }\n" +" if {$cmd eq \"close\"} {\n" +" $f close\n" +"\n" +" set retopts {}\n" +" foreach p $pids {\n" +" lassign [wait $p] status - rc\n" +" if {$status eq \"CHILDSTATUS\"} {\n" +" if {$rc == 0} {\n" +" continue\n" +" }\n" +" set msg \"child process exited abnormally\"\n" +" } else {\n" +" set msg \"child killed: received signal\"\n" +" }\n" +" set retopts [list -code error -errorcode [list $status $p $rc] $msg]\n" +" }\n" +" return {*}$retopts\n" +" }\n" +" tailcall $f $cmd {*}$args\n" +" }\n" +" } on error {error opts} {\n" +" $r close\n" +" $w close\n" +" error $error\n" +" }\n" +"}\n" +"\n" +"\n" +"local proc pid {{channelId {}}} {\n" +" if {$channelId eq \"\"} {\n" +" tailcall upcall pid\n" +" }\n" +" if {[catch {$channelId tell}]} {\n" +" return -code error \"can not find channel named \\\"$channelId\\\"\"\n" +" }\n" +" if {[catch {$channelId pid} pids]} {\n" +" return \"\"\n" +" }\n" +" return $pids\n" +"}\n" +"\n" +"\n" +"\n" +"proc throw {code {msg \"\"}} {\n" +" return -code $code $msg\n" +"}\n" +"\n" +"\n" +"proc {file delete force} {path} {\n" +" foreach e [readdir $path] {\n" +" file delete -force $path/$e\n" +" }\n" +" file delete $path\n" +"}\n" +); +} + + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#include +#endif +#ifdef HAVE_UTIL_H +#include +#endif +#ifdef HAVE_PTY_H +#include +#endif + + +#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_SELECT) && defined(HAVE_NETINET_IN_H) && defined(HAVE_NETDB_H) && defined(HAVE_ARPA_INET_H) +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_UN_H +#include +#endif +#define HAVE_SOCKETS +#elif defined (__MINGW32__) + +#endif + +#if defined(JIM_SSL) +#include +#include +#endif + +#ifdef HAVE_TERMIOS_H +#endif + + +#define AIO_CMD_LEN 32 +#define AIO_BUF_LEN 256 +#define AIO_WBUF_FULL_SIZE (64 * 1024) + +#define AIO_KEEPOPEN 1 +#define AIO_NODELETE 2 +#define AIO_EOF 4 +#define AIO_WBUF_NONE 8 +#define AIO_NONBLOCK 16 + +enum wbuftype { + WBUF_OPT_NONE, + WBUF_OPT_LINE, + WBUF_OPT_FULL, +}; + +#if defined(JIM_IPV6) +#define IPV6 1 +#else +#define IPV6 0 +#ifndef PF_INET6 +#define PF_INET6 0 +#endif +#endif +#if defined(HAVE_SYS_UN_H) && defined(PF_UNIX) +#define UNIX_SOCKETS 1 +#else +#define UNIX_SOCKETS 0 +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN JIM_PATH_LEN +#endif + + + + +static int JimReadableTimeout(int fd, long ms) +{ +#ifdef HAVE_SELECT + int retval; + struct timeval tv; + fd_set rfds; + + FD_ZERO(&rfds); + + FD_SET(fd, &rfds); + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) * 1000; + + retval = select(fd + 1, &rfds, NULL, NULL, ms == 0 ? NULL : &tv); + + if (retval > 0) { + return JIM_OK; + } + return JIM_ERR; +#else + return JIM_OK; +#endif +} + + +struct AioFile; + +typedef struct { + int (*writer)(struct AioFile *af, const char *buf, int len); + int (*reader)(struct AioFile *af, char *buf, int len, int pending); + int (*error)(const struct AioFile *af); + const char *(*strerror)(struct AioFile *af); + int (*verify)(struct AioFile *af); +} JimAioFopsType; + +typedef struct AioFile +{ + Jim_Obj *filename; + int wbuft; + int flags; + long timeout; + int fd; + int addr_family; + void *ssl; + const JimAioFopsType *fops; + Jim_Obj *readbuf; + Jim_Obj *writebuf; +} AioFile; + +static int stdio_writer(struct AioFile *af, const char *buf, int len) +{ + return write(af->fd, buf, len); +} + +static int stdio_reader(struct AioFile *af, char *buf, int len, int nb) +{ + if (nb || af->timeout == 0 || JimReadableTimeout(af->fd, af->timeout) == JIM_OK) { + + int ret; + + errno = 0; + ret = read(af->fd, buf, len); + if (ret <= 0 && errno != EAGAIN && errno != EINTR) { + af->flags |= AIO_EOF; + } + return ret; + } + errno = ETIMEDOUT; + return -1; +} + +static int stdio_error(const AioFile *af) +{ + if (af->flags & AIO_EOF) { + return JIM_OK; + } + + switch (errno) { + case EAGAIN: + case EINTR: + case ETIMEDOUT: +#ifdef ECONNRESET + case ECONNRESET: +#endif +#ifdef ECONNABORTED + case ECONNABORTED: +#endif + return JIM_OK; + default: + return JIM_ERR; + } +} + +static const char *stdio_strerror(struct AioFile *af) +{ + return strerror(errno); +} + +static const JimAioFopsType stdio_fops = { + stdio_writer, + stdio_reader, + stdio_error, + stdio_strerror, + NULL, +}; + + +static void aio_set_nonblocking(AioFile *af, int nb) +{ +#ifdef O_NDELAY + int old = !!(af->flags & AIO_NONBLOCK); + if (old != nb) { + int fmode = fcntl(af->fd, F_GETFL); + if (nb) { + fmode |= O_NDELAY; + af->flags |= AIO_NONBLOCK; + } + else { + fmode &= ~O_NDELAY; + af->flags &= ~AIO_NONBLOCK; + } + (void)fcntl(af->fd, F_SETFL, fmode); + } +#endif +} + +static int aio_start_nonblocking(AioFile *af) +{ + int old = !!(af->flags & AIO_NONBLOCK); + if (af->timeout) { + aio_set_nonblocking(af, 1); + } + return old; +} + +static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +static AioFile *JimMakeChannel(Jim_Interp *interp, int fd, Jim_Obj *filename, + const char *hdlfmt, int family, int flags); + + +static const char *JimAioErrorString(AioFile *af) +{ + if (af && af->fops) + return af->fops->strerror(af); + + return strerror(errno); +} + +static void JimAioSetError(Jim_Interp *interp, Jim_Obj *name) +{ + AioFile *af = Jim_CmdPrivData(interp); + + if (name) { + Jim_SetResultFormatted(interp, "%#s: %s", name, JimAioErrorString(af)); + } + else { + Jim_SetResultString(interp, JimAioErrorString(af), -1); + } +} + +static int aio_eof(AioFile *af) +{ + return af->flags & AIO_EOF; +} + +static int JimCheckStreamError(Jim_Interp *interp, AioFile *af) +{ + int ret = 0; + if (!aio_eof(af)) { + ret = af->fops->error(af); + if (ret) { + JimAioSetError(interp, af->filename); + } + } + return ret; +} + +static void aio_consume(Jim_Obj *objPtr, int n) +{ + assert(objPtr->bytes); + assert(n <= objPtr->length); + + + memmove(objPtr->bytes, objPtr->bytes + n, objPtr->length - n + 1); + objPtr->length -= n; +} + + +static int aio_autoflush(Jim_Interp *interp, void *clientData, int mask); + +static int aio_flush(Jim_Interp *interp, AioFile *af) +{ + int len; + const char *pt = Jim_GetString(af->writebuf, &len); + if (len) { + int ret = af->fops->writer(af, pt, len); + if (ret > 0) { + + aio_consume(af->writebuf, ret); + } + if (ret < 0) { + return JimCheckStreamError(interp, af); + } + if (Jim_Length(af->writebuf)) { +#ifdef jim_ext_eventloop + void *handler = Jim_FindFileHandler(interp, af->fd, JIM_EVENT_WRITABLE); + if (handler == NULL) { + Jim_CreateFileHandler(interp, af->fd, JIM_EVENT_WRITABLE, aio_autoflush, af, NULL); + return JIM_OK; + } + else if (handler == af) { + + return JIM_OK; + } +#endif + + Jim_SetResultString(interp, "send buffer is full", -1); + return JIM_ERR; + } + } + return JIM_OK; +} + +static int aio_autoflush(Jim_Interp *interp, void *clientData, int mask) +{ + AioFile *af = clientData; + + aio_flush(interp, af); + if (Jim_Length(af->writebuf) == 0) { + + return -1; + } + return 0; +} + +static int aio_read_len(Jim_Interp *interp, AioFile *af, int nb, char *buf, size_t buflen, int neededLen) +{ + if (!af->readbuf) { + af->readbuf = Jim_NewStringObj(interp, NULL, 0); + } + + if (neededLen >= 0) { + neededLen -= Jim_Length(af->readbuf); + if (neededLen <= 0) { + return JIM_OK; + } + } + + while (neededLen && !aio_eof(af)) { + int retval; + int readlen; + + if (neededLen == -1) { + readlen = AIO_BUF_LEN; + } + else { + readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen); + } + retval = af->fops->reader(af, buf, readlen, nb); + if (retval > 0) { + Jim_AppendString(interp, af->readbuf, buf, retval); + if (neededLen != -1) { + neededLen -= retval; + } + continue; + } + if (JimCheckStreamError(interp, af)) { + return JIM_ERR; + } + break; + } + + return JIM_OK; +} + +static Jim_Obj *aio_read_consume(Jim_Interp *interp, AioFile *af, int neededLen) +{ + Jim_Obj *objPtr = NULL; + + if (neededLen < 0 || af->readbuf == NULL || Jim_Length(af->readbuf) <= neededLen) { + objPtr = af->readbuf; + af->readbuf = NULL; + } + else if (af->readbuf) { + + int len; + const char *pt = Jim_GetString(af->readbuf, &len); + + objPtr = Jim_NewStringObj(interp, pt, neededLen); + aio_consume(af->readbuf, neededLen); + } + + return objPtr; +} + +static void JimAioDelProc(Jim_Interp *interp, void *privData) +{ + AioFile *af = privData; + + JIM_NOTUSED(interp); + + + aio_flush(interp, af); + Jim_DecrRefCount(interp, af->writebuf); + +#if UNIX_SOCKETS + if (af->addr_family == PF_UNIX && (af->flags & AIO_NODELETE) == 0) { + + Jim_Obj *filenameObj = aio_sockname(interp, af->fd); + if (filenameObj) { + if (Jim_Length(filenameObj)) { + remove(Jim_String(filenameObj)); + } + Jim_FreeNewObj(interp, filenameObj); + } + } +#endif + + Jim_DecrRefCount(interp, af->filename); + +#ifdef jim_ext_eventloop + + Jim_DeleteFileHandler(interp, af->fd, JIM_EVENT_READABLE | JIM_EVENT_WRITABLE | JIM_EVENT_EXCEPTION); +#endif + +#if defined(JIM_SSL) + if (af->ssl != NULL) { + SSL_free(af->ssl); + } +#endif + if (!(af->flags & AIO_KEEPOPEN)) { + close(af->fd); + } + if (af->readbuf) { + Jim_FreeNewObj(interp, af->readbuf); + } + + Jim_Free(af); +} + +static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int nonewline = 0; + jim_wide neededLen = -1; + static const char * const options[] = { "-pending", "-nonewline", NULL }; + enum { OPT_PENDING, OPT_NONEWLINE }; + int option; + int nb; + Jim_Obj *objPtr; + char buf[AIO_BUF_LEN]; + + if (argc) { + if (*Jim_String(argv[0]) == '-') { + if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_PENDING: + + break; + case OPT_NONEWLINE: + nonewline++; + break; + } + } + else { + if (Jim_GetWide(interp, argv[0], &neededLen) != JIM_OK) + return JIM_ERR; + if (neededLen < 0) { + Jim_SetResultString(interp, "invalid parameter: negative len", -1); + return JIM_ERR; + } + } + argc--; + argv++; + } + if (argc) { + return -1; + } + + + nb = aio_start_nonblocking(af); + + if (aio_read_len(interp, af, nb, buf, sizeof(buf), neededLen) != JIM_OK) { + aio_set_nonblocking(af, nb); + return JIM_ERR; + } + objPtr = aio_read_consume(interp, af, neededLen); + + aio_set_nonblocking(af, nb); + + if (objPtr) { + if (nonewline) { + int len; + const char *s = Jim_GetString(objPtr, &len); + + if (len > 0 && s[len - 1] == '\n') { + objPtr->length--; + objPtr->bytes[objPtr->length] = '\0'; + } + } + Jim_SetResult(interp, objPtr); + } + else { + Jim_SetEmptyResult(interp); + } + return JIM_OK; +} + +int Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) +{ + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG); + + + if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) { + return ((AioFile *) cmdPtr->u.native.privData)->fd; + } + Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command); + return -1; +} + +static int aio_cmd_getfd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + + aio_flush(interp, af); + + Jim_SetResultInt(interp, af->fd); + + return JIM_OK; +} + +static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + jim_wide count = 0; + jim_wide maxlen = JIM_WIDE_MAX; + + char buf[AIO_BUF_LEN]; + + char *bufp = buf; + int buflen = sizeof(buf); + int ok = 1; + Jim_Obj *objv[4]; + + if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &maxlen) != JIM_OK) { + return JIM_ERR; + } + } + + objv[0] = argv[0]; + objv[1] = Jim_NewStringObj(interp, "flush", -1); + if (Jim_EvalObjVector(interp, 2, objv) != JIM_OK) { + Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", argv[0]); + return JIM_ERR; + } + + + objv[0] = argv[0]; + objv[1] = Jim_NewStringObj(interp, "puts", -1); + objv[2] = Jim_NewStringObj(interp, "-nonewline", -1); + Jim_IncrRefCount(objv[1]); + Jim_IncrRefCount(objv[2]); + + while (count < maxlen) { + jim_wide len = maxlen - count; + if (len > buflen) { + len = buflen; + } + if (aio_read_len(interp, af, 0, bufp, buflen, len) != JIM_OK) { + ok = 0; + break; + } + objv[3] = aio_read_consume(interp, af, len); + count += Jim_Length(objv[3]); + if (Jim_EvalObjVector(interp, 4, objv) != JIM_OK) { + ok = 0; + break; + } + if (aio_eof(af)) { + break; + } + if (count >= 16384 && bufp == buf) { + + buflen = 65536; + bufp = Jim_Alloc(buflen); + } + } + + if (bufp != buf) { + Jim_Free(bufp); + } + + Jim_DecrRefCount(interp, objv[1]); + Jim_DecrRefCount(interp, objv[2]); + + if (!ok) { + return JIM_ERR; + } + + Jim_SetResultInt(interp, count); + + return JIM_OK; +} + +static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + char buf[AIO_BUF_LEN]; + Jim_Obj *objPtr = NULL; + int len; + int nb; + char *nl = NULL; + int offset = 0; + + errno = 0; + + + nb = aio_start_nonblocking(af); + + if (!af->readbuf) { + af->readbuf = Jim_NewStringObj(interp, NULL, 0); + } + + while (!aio_eof(af)) { + const char *pt = Jim_GetString(af->readbuf, &len); + nl = memchr(pt + offset, '\n', len - offset); + if (nl) { + + objPtr = Jim_NewStringObj(interp, pt, nl - pt); + + aio_consume(af->readbuf, nl - pt + 1); + break; + } + + offset = len; + len = af->fops->reader(af, buf, AIO_BUF_LEN, nb); + if (len <= 0) { + break; + } + Jim_AppendString(interp, af->readbuf, buf, len); + } + + aio_set_nonblocking(af, nb); + + if (!nl && aio_eof(af)) { + + objPtr = af->readbuf; + af->readbuf = NULL; + } + else if (!objPtr) { + objPtr = Jim_NewStringObj(interp, NULL, 0); + } + + if (argc) { + if (Jim_SetVariable(interp, argv[0], objPtr) != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + + len = Jim_Length(objPtr); + + if (!nl && len == 0) { + + len = -1; + } + Jim_SetResultInt(interp, len); + } + else { + Jim_SetResult(interp, objPtr); + } + return JIM_OK; +} + +static int aio_cmd_puts(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int wlen; + const char *wdata; + Jim_Obj *strObj; + int wnow = 0; + int nl = 1; + + if (argc == 2) { + if (!Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { + return -1; + } + strObj = argv[1]; + nl = 0; + } + else { + strObj = argv[0]; + } + + Jim_AppendObj(interp, af->writebuf, strObj); + if (nl) { + Jim_AppendString(interp, af->writebuf, "\n", 1); + } + + + wdata = Jim_GetString(af->writebuf, &wlen); + switch (af->wbuft) { + case WBUF_OPT_NONE: + + wnow = 1; + break; + + case WBUF_OPT_LINE: + + if (nl || memchr(wdata, '\n', wlen) != NULL) { + wnow = 1; + } + break; + + case WBUF_OPT_FULL: + if (wlen >= AIO_WBUF_FULL_SIZE) { + wnow = 1; + } + break; + } + + if (wnow) { + return aio_flush(interp, af); + } + return JIM_OK; +} + +static int aio_cmd_isatty(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef HAVE_ISATTY + AioFile *af = Jim_CmdPrivData(interp); + Jim_SetResultInt(interp, isatty(af->fd)); +#else + Jim_SetResultInt(interp, 0); +#endif + + return JIM_OK; +} + + +static int aio_cmd_flush(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + return aio_flush(interp, af); +} + +static int aio_cmd_eof(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResultInt(interp, !!aio_eof(af)); + return JIM_OK; +} + +static int aio_cmd_close(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + if (argc == 3) { + int option = -1; +#if defined(HAVE_SOCKETS) + static const char * const options[] = { "r", "w", "-nodelete", NULL }; + enum { OPT_R, OPT_W, OPT_NODELETE }; + + if (Jim_GetEnum(interp, argv[2], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } +#endif + switch (option) { +#if defined(HAVE_SHUTDOWN) + case OPT_R: + case OPT_W: + if (shutdown(af->fd, option == OPT_R ? SHUT_RD : SHUT_WR) == 0) { + return JIM_OK; + } + JimAioSetError(interp, NULL); + return JIM_ERR; +#endif +#if UNIX_SOCKETS + case OPT_NODELETE: + if (af->addr_family == PF_UNIX) { + af->flags |= AIO_NODELETE; + break; + } + +#endif + default: + Jim_SetResultString(interp, "not supported", -1); + return JIM_ERR; + } + } + + + af->flags &= ~AIO_KEEPOPEN; + + return Jim_DeleteCommand(interp, argv[0]); +} + +static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + int orig = SEEK_SET; + jim_wide offset; + + if (argc == 2) { + if (Jim_CompareStringImmediate(interp, argv[1], "start")) + orig = SEEK_SET; + else if (Jim_CompareStringImmediate(interp, argv[1], "current")) + orig = SEEK_CUR; + else if (Jim_CompareStringImmediate(interp, argv[1], "end")) + orig = SEEK_END; + else { + return -1; + } + } + if (Jim_GetWide(interp, argv[0], &offset) != JIM_OK) { + return JIM_ERR; + } + if (orig != SEEK_CUR || offset != 0) { + + aio_flush(interp, af); + } + if (Jim_Lseek(af->fd, offset, orig) == -1) { + JimAioSetError(interp, af->filename); + return JIM_ERR; + } + if (af->readbuf) { + Jim_FreeNewObj(interp, af->readbuf); + af->readbuf = NULL; + } + af->flags &= ~AIO_EOF; + return JIM_OK; +} + +static int aio_cmd_tell(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResultInt(interp, Jim_Lseek(af->fd, 0, SEEK_CUR)); + return JIM_OK; +} + +static int aio_cmd_filename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + Jim_SetResult(interp, af->filename); + return JIM_OK; +} + +#ifdef O_NDELAY +static int aio_cmd_ndelay(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + if (argc) { + long nb; + + if (Jim_GetLong(interp, argv[0], &nb) != JIM_OK) { + return JIM_ERR; + } + aio_set_nonblocking(af, nb); + } + Jim_SetResultInt(interp, (af->flags & AIO_NONBLOCK) ? 1 : 0); + return JIM_OK; +} +#endif + + +#ifdef HAVE_FSYNC +static int aio_cmd_sync(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + if (aio_flush(interp, af) != JIM_OK) { + return JIM_ERR; + } + fsync(af->fd); + return JIM_OK; +} +#endif + +static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + static const char * const options[] = { + "none", + "line", + "full", + NULL + }; + + if (Jim_GetEnum(interp, argv[0], options, &af->wbuft, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + + if (af->wbuft == WBUF_OPT_NONE) { + return aio_flush(interp, af); + } + + return JIM_OK; +} + +static int aio_cmd_timeout(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef HAVE_SELECT + AioFile *af = Jim_CmdPrivData(interp); + if (argc == 1) { + if (Jim_GetLong(interp, argv[0], &af->timeout) != JIM_OK) { + return JIM_ERR; + } + } + Jim_SetResultInt(interp, af->timeout); + return JIM_OK; +#else + Jim_SetResultString(interp, "timeout not supported", -1); + return JIM_ERR; +#endif +} + +#ifdef jim_ext_eventloop +static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, + int argc, Jim_Obj * const *argv) +{ + if (argc == 0) { + + Jim_Obj *objPtr = Jim_FindFileHandler(interp, af->fd, mask); + if (objPtr) { + Jim_SetResult(interp, objPtr); + } + return JIM_OK; + } + + + Jim_DeleteFileHandler(interp, af->fd, mask); + + + if (Jim_Length(argv[0])) { + Jim_CreateScriptFileHandler(interp, af->fd, mask, argv[0]); + } + + return JIM_OK; +} + +static int aio_cmd_readable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_READABLE, argc, argv); +} + +static int aio_cmd_writable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_WRITABLE, argc, argv); +} + +static int aio_cmd_onexception(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + return aio_eventinfo(interp, af, JIM_EVENT_EXCEPTION, argc, argv); +} +#endif + +#if defined(jim_ext_file) && defined(Jim_FileStat) +static int aio_cmd_stat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + AioFile *af = Jim_CmdPrivData(interp); + + if (Jim_FileStat(af->fd, &sb) == -1) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + return Jim_FileStoreStatData(interp, argc == 0 ? NULL : argv[0], &sb); +} +#endif + + + + +static const jim_subcmd_type aio_command_table[] = { + { "read", + "?-nonewline|len?", + aio_cmd_read, + 0, + 2, + + }, + { "copyto", + "handle ?size?", + aio_cmd_copy, + 1, + 2, + + }, + { "getfd", + NULL, + aio_cmd_getfd, + 0, + 0, + + }, + { "gets", + "?var?", + aio_cmd_gets, + 0, + 1, + + }, + { "puts", + "?-nonewline? str", + aio_cmd_puts, + 1, + 2, + + }, + { "isatty", + NULL, + aio_cmd_isatty, + 0, + 0, + + }, + { "flush", + NULL, + aio_cmd_flush, + 0, + 0, + + }, + { "eof", + NULL, + aio_cmd_eof, + 0, + 0, + + }, + { "close", + "?r(ead)|w(rite)?", + aio_cmd_close, + 0, + 1, + JIM_MODFLAG_FULLARGV, + + }, + { "seek", + "offset ?start|current|end", + aio_cmd_seek, + 1, + 2, + + }, + { "tell", + NULL, + aio_cmd_tell, + 0, + 0, + + }, + { "filename", + NULL, + aio_cmd_filename, + 0, + 0, + + }, +#ifdef O_NDELAY + { "ndelay", + "?0|1?", + aio_cmd_ndelay, + 0, + 1, + + }, +#endif +#ifdef HAVE_FSYNC + { "sync", + NULL, + aio_cmd_sync, + 0, + 0, + + }, +#endif + { "buffering", + "none|line|full", + aio_cmd_buffering, + 1, + 1, + + }, +#if defined(jim_ext_file) && defined(Jim_FileStat) + { "stat", + "?var?", + aio_cmd_stat, + 0, + 1, + + }, +#endif +#ifdef jim_ext_eventloop + { "readable", + "?readable-script?", + aio_cmd_readable, + 0, + 1, + + }, + { "writable", + "?writable-script?", + aio_cmd_writable, + 0, + 1, + + }, + { "onexception", + "?exception-script?", + aio_cmd_onexception, + 0, + 1, + + }, + { "timeout", + "?ms?", + aio_cmd_timeout, + 0, + 1, + + }, +#endif + { NULL } +}; + +static int JimAioSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, aio_command_table, argc, argv), argc, argv); +} + +static int parse_posix_open_mode(Jim_Interp *interp, Jim_Obj *modeObj) +{ + int i; + int flags = 0; + #ifndef O_NOCTTY + + #define O_NOCTTY 0 + #endif + static const char * const modetypes[] = { + "RDONLY", "WRONLY", "RDWR", "APPEND", "BINARY", "CREAT", "EXCL", "NOCTTY", "TRUNC", NULL + }; + static const int modeflags[] = { + O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, 0, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, + }; + + for (i = 0; i < Jim_ListLength(interp, modeObj); i++) { + int opt; + Jim_Obj *objPtr = Jim_ListGetIndex(interp, modeObj, i); + if (Jim_GetEnum(interp, objPtr, modetypes, &opt, "access mode", JIM_ERRMSG) != JIM_OK) { + return -1; + } + flags |= modeflags[opt]; + } + return flags; +} + +static int parse_open_mode(Jim_Interp *interp, Jim_Obj *filenameObj, Jim_Obj *modeObj) +{ + + int flags; + const char *mode = Jim_String(modeObj); + if (*mode == 'R' || *mode == 'W') { + return parse_posix_open_mode(interp, modeObj); + } + if (*mode == 'r') { + flags = O_RDONLY; + } + else if (*mode == 'w') { + flags = O_WRONLY | O_CREAT | O_TRUNC; + } + else if (*mode == 'a') { + flags = O_WRONLY | O_CREAT | O_APPEND; + } + else { + Jim_SetResultFormatted(interp, "%s: invalid open mode '%s'", Jim_String(filenameObj), mode); + return -1; + } + mode++; + + if (*mode == 'b') { +#ifdef O_BINARY + flags |= O_BINARY; +#endif + mode++; + } + + if (*mode == 't') { +#ifdef O_TEXT + flags |= O_TEXT; +#endif + mode++; + } + + if (*mode == '+') { + mode++; + + flags &= ~(O_RDONLY | O_WRONLY); + flags |= O_RDWR; + } + + if (*mode == 'x') { + mode++; +#ifdef O_EXCL + flags |= O_EXCL; +#endif + } + + if (*mode == 'F') { + mode++; +#ifdef O_LARGEFILE + flags |= O_LARGEFILE; +#endif + } + + if (*mode == 'e') { + + mode++; + } + return flags; +} + +static int JimAioOpenCommand(Jim_Interp *interp, int argc, + Jim_Obj *const *argv) +{ + int openflags; + const char *filename; + int fd = -1; + int n = 0; + int flags = 0; + + if (argc > 2 && Jim_CompareStringImmediate(interp, argv[2], "-noclose")) { + flags = AIO_KEEPOPEN; + n++; + } + if (argc < 2 || argc > 3 + n) { + Jim_WrongNumArgs(interp, 1, argv, "filename ?-noclose? ?mode?"); + return JIM_ERR; + } + + filename = Jim_String(argv[1]); + +#ifdef jim_ext_tclcompat + { + + + if (*filename == '|') { + Jim_Obj *evalObj[3]; + int i = 0; + + evalObj[i++] = Jim_NewStringObj(interp, "::popen", -1); + evalObj[i++] = Jim_NewStringObj(interp, filename + 1, -1); + if (argc == 3 + n) { + evalObj[i++] = argv[2 + n]; + } + + return Jim_EvalObjVector(interp, i, evalObj); + } + } +#endif + if (argc == 3 + n) { + openflags = parse_open_mode(interp, argv[1], argv[2 + n]); + if (openflags == -1) { + return JIM_ERR; + } + } + else { + openflags = O_RDONLY; + } + fd = open(filename, openflags, 0666); + if (fd < 0) { + JimAioSetError(interp, argv[1]); + return JIM_ERR; + } + + return JimMakeChannel(interp, fd, argv[1], "aio.handle%ld", 0, flags) ? JIM_OK : JIM_ERR; +} + + +static AioFile *JimMakeChannel(Jim_Interp *interp, int fd, Jim_Obj *filename, + const char *hdlfmt, int family, int flags) +{ + AioFile *af; + char buf[AIO_CMD_LEN]; + Jim_Obj *cmdname; + + snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp)); + cmdname = Jim_NewStringObj(interp, buf, -1); + if (!filename) { + filename = cmdname; + } + Jim_IncrRefCount(filename); + + + af = Jim_Alloc(sizeof(*af)); + memset(af, 0, sizeof(*af)); + af->filename = filename; + af->fd = fd; + af->addr_family = family; + af->fops = &stdio_fops; + af->ssl = NULL; + if (flags & AIO_WBUF_NONE) { + af->wbuft = WBUF_OPT_NONE; + } + else { +#ifdef HAVE_ISATTY + af->wbuft = isatty(af->fd) ? WBUF_OPT_LINE : WBUF_OPT_FULL; +#else + af->wbuft = WBUF_OPT_FULL; +#endif + } + +#ifdef FD_CLOEXEC + if ((flags & AIO_KEEPOPEN) == 0) { + (void)fcntl(af->fd, F_SETFD, FD_CLOEXEC); + } +#endif + aio_set_nonblocking(af, !!(flags & AIO_NONBLOCK)); + + af->flags |= flags; + + af->writebuf = Jim_NewStringObj(interp, NULL, 0); + Jim_IncrRefCount(af->writebuf); + + Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc); + + Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, cmdname)); + + return af; +} + +#if defined(HAVE_PIPE) || (defined(HAVE_SOCKETPAIR) && UNIX_SOCKETS) || defined(HAVE_OPENPTY) +static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, + const char *hdlfmt, int family, int flags) +{ + if (JimMakeChannel(interp, p[0], filename, hdlfmt, family, flags)) { + Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); + if (JimMakeChannel(interp, p[1], filename, hdlfmt, family, flags)) { + Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + } + + + close(p[0]); + close(p[1]); + JimAioSetError(interp, NULL); + return JIM_ERR; +} +#endif + +#ifdef HAVE_PIPE +static int JimCreatePipe(Jim_Interp *interp, Jim_Obj *filenameObj, int flags) +{ + int p[2]; + + if (pipe(p) != 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + + return JimMakeChannelPair(interp, p, filenameObj, "aio.pipe%ld", 0, flags); +} + + +static int JimAioPipeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + return JimCreatePipe(interp, argv[0], 0); +} +#endif + +#ifdef HAVE_OPENPTY +static int JimAioOpenPtyCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int p[2]; + char path[MAXPATHLEN]; + + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + + if (openpty(&p[0], &p[1], path, NULL, NULL) != 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + + + return JimMakeChannelPair(interp, p, Jim_NewStringObj(interp, path, -1), "aio.pty%ld", 0, 0); + return JimMakeChannelPair(interp, p, Jim_NewStringObj(interp, path, -1), "aio.pty%ld", 0, 0); +} +#endif + + + +int Jim_aioInit(Jim_Interp *interp) +{ + if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG)) + return JIM_ERR; + +#if defined(JIM_SSL) + Jim_CreateCommand(interp, "load_ssl_certs", JimAioLoadSSLCertsCommand, NULL, NULL); +#endif + + Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL); +#ifdef HAVE_SOCKETS + Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL); +#endif +#ifdef HAVE_PIPE + Jim_CreateCommand(interp, "pipe", JimAioPipeCommand, NULL, NULL); +#endif + + + JimMakeChannel(interp, fileno(stdin), NULL, "stdin", 0, AIO_KEEPOPEN); + JimMakeChannel(interp, fileno(stdout), NULL, "stdout", 0, AIO_KEEPOPEN); + JimMakeChannel(interp, fileno(stderr), NULL, "stderr", 0, AIO_KEEPOPEN | AIO_WBUF_NONE); + + return JIM_OK; +} + +#include +#include +#include + + +#ifdef HAVE_DIRENT_H +#include +#endif + +int Jim_ReaddirCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *dirPath; + DIR *dirPtr; + struct dirent *entryPtr; + int nocomplain = 0; + + if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "-nocomplain")) { + nocomplain = 1; + } + if (argc != 2 && !nocomplain) { + Jim_WrongNumArgs(interp, 1, argv, "?-nocomplain? dirPath"); + return JIM_ERR; + } + + dirPath = Jim_String(argv[1 + nocomplain]); + + dirPtr = opendir(dirPath); + if (dirPtr == NULL) { + if (nocomplain) { + return JIM_OK; + } + Jim_SetResultString(interp, strerror(errno), -1); + return JIM_ERR; + } + else { + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + while ((entryPtr = readdir(dirPtr)) != NULL) { + if (entryPtr->d_name[0] == '.') { + if (entryPtr->d_name[1] == '\0') { + continue; + } + if ((entryPtr->d_name[1] == '.') && (entryPtr->d_name[2] == '\0')) + continue; + } + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, entryPtr->d_name, -1)); + } + closedir(dirPtr); + + Jim_SetResult(interp, listObj); + + return JIM_OK; + } +} + +int Jim_readdirInit(Jim_Interp *interp) +{ + Jim_PackageProvideCheck(interp, "readdir"); + Jim_CreateCommand(interp, "readdir", Jim_ReaddirCmd, NULL, NULL); + return JIM_OK; +} + +#include +#include + +#if defined(JIM_REGEXP) +#else + #include + #define jim_regcomp regcomp + #define jim_regexec regexec + #define jim_regerror regerror + #define jim_regfree regfree +#endif + +static void FreeRegexpInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + jim_regfree(objPtr->internalRep.ptrIntValue.ptr); + Jim_Free(objPtr->internalRep.ptrIntValue.ptr); +} + +static const Jim_ObjType regexpObjType = { + "regexp", + FreeRegexpInternalRep, + NULL, + NULL, + JIM_TYPE_NONE +}; + +static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned flags) +{ + regex_t *compre; + const char *pattern; + int ret; + + + if (objPtr->typePtr == ®expObjType && + objPtr->internalRep.ptrIntValue.ptr && objPtr->internalRep.ptrIntValue.int1 == flags) { + + return objPtr->internalRep.ptrIntValue.ptr; + } + + + + + pattern = Jim_String(objPtr); + compre = Jim_Alloc(sizeof(regex_t)); + + if ((ret = jim_regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) { + char buf[100]; + + jim_regerror(ret, compre, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "couldn't compile regular expression pattern: %s", buf); + jim_regfree(compre); + Jim_Free(compre); + return NULL; + } + + Jim_FreeIntRep(interp, objPtr); + + objPtr->typePtr = ®expObjType; + objPtr->internalRep.ptrIntValue.int1 = flags; + objPtr->internalRep.ptrIntValue.ptr = compre; + + return compre; +} + +int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int opt_indices = 0; + int opt_all = 0; + int opt_inline = 0; + regex_t *regex; + int match, i, j; + int offset = 0; + regmatch_t *pmatch = NULL; + int source_len; + int result = JIM_OK; + const char *pattern; + const char *source_str; + int num_matches = 0; + int num_vars; + Jim_Obj *resultListObj = NULL; + int regcomp_flags = 0; + int eflags = 0; + int option; + enum { + OPT_INDICES, OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_INLINE, OPT_START, OPT_END + }; + static const char * const options[] = { + "-indices", "-nocase", "-line", "-all", "-inline", "-start", "--", NULL + }; + + if (argc < 3) { + wrongNumArgs: + Jim_WrongNumArgs(interp, 1, argv, + "?-switch ...? exp string ?matchVar? ?subMatchVar ...?"); + return JIM_ERR; + } + + for (i = 1; i < argc; i++) { + const char *opt = Jim_String(argv[i]); + + if (*opt != '-') { + break; + } + if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + if (option == OPT_END) { + i++; + break; + } + switch (option) { + case OPT_INDICES: + opt_indices = 1; + break; + + case OPT_NOCASE: + regcomp_flags |= REG_ICASE; + break; + + case OPT_LINE: + regcomp_flags |= REG_NEWLINE; + break; + + case OPT_ALL: + opt_all = 1; + break; + + case OPT_INLINE: + opt_inline = 1; + break; + + case OPT_START: + if (++i == argc) { + goto wrongNumArgs; + } + if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { + return JIM_ERR; + } + break; + } + } + if (argc - i < 2) { + goto wrongNumArgs; + } + + regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); + if (!regex) { + return JIM_ERR; + } + + pattern = Jim_String(argv[i]); + source_str = Jim_GetString(argv[i + 1], &source_len); + + num_vars = argc - i - 2; + + if (opt_inline) { + if (num_vars) { + Jim_SetResultString(interp, "regexp match variables not allowed when using -inline", + -1); + result = JIM_ERR; + goto done; + } + num_vars = regex->re_nsub + 1; + } + + pmatch = Jim_Alloc((num_vars + 1) * sizeof(*pmatch)); + + if (offset) { + if (offset < 0) { + offset += source_len + 1; + } + if (offset > source_len) { + source_str += source_len; + } + else if (offset > 0) { + source_str += utf8_index(source_str, offset); + } + eflags |= REG_NOTBOL; + } + + if (opt_inline) { + resultListObj = Jim_NewListObj(interp, NULL, 0); + } + + next_match: + match = jim_regexec(regex, source_str, num_vars + 1, pmatch, eflags); + if (match >= REG_BADPAT) { + char buf[100]; + + jim_regerror(match, regex, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf); + result = JIM_ERR; + goto done; + } + + if (match == REG_NOMATCH) { + goto done; + } + + num_matches++; + + if (opt_all && !opt_inline) { + + goto try_next_match; + } + + + j = 0; + for (i += 2; opt_inline ? j < num_vars : i < argc; i++, j++) { + Jim_Obj *resultObj; + + if (opt_indices) { + resultObj = Jim_NewListObj(interp, NULL, 0); + } + else { + resultObj = Jim_NewStringObj(interp, "", 0); + } + + if (pmatch[j].rm_so == -1) { + if (opt_indices) { + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); + } + } + else { + if (opt_indices) { + + int so = utf8_strlen(source_str, pmatch[j].rm_so); + int eo = utf8_strlen(source_str, pmatch[j].rm_eo); + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, offset + so)); + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, offset + eo - 1)); + } + else { + Jim_AppendString(interp, resultObj, source_str + pmatch[j].rm_so, pmatch[j].rm_eo - pmatch[j].rm_so); + } + } + + if (opt_inline) { + Jim_ListAppendElement(interp, resultListObj, resultObj); + } + else { + + result = Jim_SetVariable(interp, argv[i], resultObj); + + if (result != JIM_OK) { + Jim_FreeObj(interp, resultObj); + break; + } + } + } + + try_next_match: + if (opt_all && (pattern[0] != '^' || (regcomp_flags & REG_NEWLINE)) && *source_str) { + if (pmatch[0].rm_eo) { + offset += utf8_strlen(source_str, pmatch[0].rm_eo); + source_str += pmatch[0].rm_eo; + } + else { + source_str++; + offset++; + } + if (*source_str) { + eflags = REG_NOTBOL; + goto next_match; + } + } + + done: + if (result == JIM_OK) { + if (opt_inline) { + Jim_SetResult(interp, resultListObj); + } + else { + Jim_SetResultInt(interp, num_matches); + } + } + + Jim_Free(pmatch); + return result; +} + +#define MAX_SUB_MATCHES 50 + +int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int regcomp_flags = 0; + int regexec_flags = 0; + int opt_all = 0; + int opt_command = 0; + int offset = 0; + regex_t *regex; + const char *p; + int result = JIM_OK; + regmatch_t pmatch[MAX_SUB_MATCHES + 1]; + int num_matches = 0; + + int i, j, n; + Jim_Obj *varname; + Jim_Obj *resultObj; + Jim_Obj *cmd_prefix = NULL; + Jim_Obj *regcomp_obj = NULL; + const char *source_str; + int source_len; + const char *replace_str = NULL; + int replace_len; + const char *pattern; + int option; + enum { + OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_START, OPT_COMMAND, OPT_END + }; + static const char * const options[] = { + "-nocase", "-line", "-all", "-start", "-command", "--", NULL + }; + + if (argc < 4) { + wrongNumArgs: + Jim_WrongNumArgs(interp, 1, argv, + "?-switch ...? exp string subSpec ?varName?"); + return JIM_ERR; + } + + for (i = 1; i < argc; i++) { + const char *opt = Jim_String(argv[i]); + + if (*opt != '-') { + break; + } + if (Jim_GetEnum(interp, argv[i], options, &option, "switch", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + if (option == OPT_END) { + i++; + break; + } + switch (option) { + case OPT_NOCASE: + regcomp_flags |= REG_ICASE; + break; + + case OPT_LINE: + regcomp_flags |= REG_NEWLINE; + break; + + case OPT_ALL: + opt_all = 1; + break; + + case OPT_START: + if (++i == argc) { + goto wrongNumArgs; + } + if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { + return JIM_ERR; + } + break; + + case OPT_COMMAND: + opt_command = 1; + break; + } + } + if (argc - i != 3 && argc - i != 4) { + goto wrongNumArgs; + } + + + regcomp_obj = Jim_DuplicateObj(interp, argv[i]); + Jim_IncrRefCount(regcomp_obj); + regex = SetRegexpFromAny(interp, regcomp_obj, regcomp_flags); + if (!regex) { + Jim_DecrRefCount(interp, regcomp_obj); + return JIM_ERR; + } + pattern = Jim_String(argv[i]); + + source_str = Jim_GetString(argv[i + 1], &source_len); + if (opt_command) { + cmd_prefix = argv[i + 2]; + if (Jim_ListLength(interp, cmd_prefix) == 0) { + Jim_SetResultString(interp, "command prefix must be a list of at least one element", -1); + Jim_DecrRefCount(interp, regcomp_obj); + return JIM_ERR; + } + Jim_IncrRefCount(cmd_prefix); + } + else { + replace_str = Jim_GetString(argv[i + 2], &replace_len); + } + varname = argv[i + 3]; + + + resultObj = Jim_NewStringObj(interp, "", 0); + + if (offset) { + if (offset < 0) { + offset += source_len + 1; + } + if (offset > source_len) { + offset = source_len; + } + else if (offset < 0) { + offset = 0; + } + } + + offset = utf8_index(source_str, offset); + + + Jim_AppendString(interp, resultObj, source_str, offset); + + + n = source_len - offset; + p = source_str + offset; + do { + int match = jim_regexec(regex, p, MAX_SUB_MATCHES, pmatch, regexec_flags); + + if (match >= REG_BADPAT) { + char buf[100]; + + jim_regerror(match, regex, buf, sizeof(buf)); + Jim_SetResultFormatted(interp, "error while matching pattern: %s", buf); + return JIM_ERR; + } + if (match == REG_NOMATCH) { + break; + } + + num_matches++; + + Jim_AppendString(interp, resultObj, p, pmatch[0].rm_so); + + if (opt_command) { + + Jim_Obj *cmdListObj = Jim_DuplicateObj(interp, cmd_prefix); + for (j = 0; j < MAX_SUB_MATCHES; j++) { + if (pmatch[j].rm_so == -1) { + break; + } + else { + Jim_Obj *srcObj = Jim_NewStringObj(interp, p + pmatch[j].rm_so, pmatch[j].rm_eo - pmatch[j].rm_so); + Jim_ListAppendElement(interp, cmdListObj, srcObj); + } + } + Jim_IncrRefCount(cmdListObj); + + result = Jim_EvalObj(interp, cmdListObj); + Jim_DecrRefCount(interp, cmdListObj); + if (result != JIM_OK) { + goto cmd_error; + } + Jim_AppendString(interp, resultObj, Jim_String(Jim_GetResult(interp)), -1); + } + else { + + for (j = 0; j < replace_len; j++) { + int idx; + int c = replace_str[j]; + + if (c == '&') { + idx = 0; + } + else if (c == '\\' && j < replace_len) { + c = replace_str[++j]; + if ((c >= '0') && (c <= '9')) { + idx = c - '0'; + } + else if ((c == '\\') || (c == '&')) { + Jim_AppendString(interp, resultObj, replace_str + j, 1); + continue; + } + else { + Jim_AppendString(interp, resultObj, replace_str + j - 1, (j == replace_len) ? 1 : 2); + continue; + } + } + else { + Jim_AppendString(interp, resultObj, replace_str + j, 1); + continue; + } + if ((idx < MAX_SUB_MATCHES) && pmatch[idx].rm_so != -1 && pmatch[idx].rm_eo != -1) { + Jim_AppendString(interp, resultObj, p + pmatch[idx].rm_so, + pmatch[idx].rm_eo - pmatch[idx].rm_so); + } + } + } + + p += pmatch[0].rm_eo; + n -= pmatch[0].rm_eo; + + + if (!opt_all || n == 0) { + break; + } + + + if ((regcomp_flags & REG_NEWLINE) == 0 && pattern[0] == '^') { + break; + } + + + if (pattern[0] == '\0' && n) { + + Jim_AppendString(interp, resultObj, p, 1); + p++; + n--; + } + + if (pmatch[0].rm_eo == pmatch[0].rm_so) { + + regexec_flags = REG_NOTBOL; + } + else { + regexec_flags = 0; + } + + } while (n); + + Jim_AppendString(interp, resultObj, p, -1); + +cmd_error: + if (result == JIM_OK) { + + if (argc - i == 4) { + result = Jim_SetVariable(interp, varname, resultObj); + + if (result == JIM_OK) { + Jim_SetResultInt(interp, num_matches); + } + else { + Jim_FreeObj(interp, resultObj); + } + } + else { + Jim_SetResult(interp, resultObj); + result = JIM_OK; + } + } + else { + Jim_FreeObj(interp, resultObj); + } + + if (opt_command) { + Jim_DecrRefCount(interp, cmd_prefix); + } + + Jim_DecrRefCount(interp, regcomp_obj); + + return result; +} + +int Jim_regexpInit(Jim_Interp *interp) +{ + Jim_PackageProvideCheck(interp, "regexp"); + Jim_CreateCommand(interp, "regexp", Jim_RegexpCmd, NULL, NULL); + Jim_CreateCommand(interp, "regsub", Jim_RegsubCmd, NULL, NULL); + return JIM_OK; +} + +#include +#include +#include +#include +#include + + +#ifdef HAVE_UTIMES +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#elif defined(_MSC_VER) +#include +#define F_OK 0 +#define W_OK 2 +#define R_OK 4 +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +# ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else +# define MAXPATHLEN JIM_PATH_LEN +# endif +# endif + +#if defined(__MINGW32__) || defined(__MSYS__) || defined(_MSC_VER) +#define ISWINDOWS 1 + +#undef HAVE_SYMLINK +#else +#define ISWINDOWS 0 +#endif + + +#if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) + #define STAT_MTIME_US(STAT) ((STAT).st_mtimespec.tv_sec * 1000000ll + (STAT).st_mtimespec.tv_nsec / 1000) +#elif defined(HAVE_STRUCT_STAT_ST_MTIM) + #define STAT_MTIME_US(STAT) ((STAT).st_mtim.tv_sec * 1000000ll + (STAT).st_mtim.tv_nsec / 1000) +#endif + + +static void JimFixPath(char *path) +{ + if (ISWINDOWS) { + + char *p = path; + while ((p = strchr(p, '\\')) != NULL) { + *p++ = '/'; + } + } +} + + +static const char *JimGetFileType(int mode) +{ + if (S_ISREG(mode)) { + return "file"; + } + else if (S_ISDIR(mode)) { + return "directory"; + } +#ifdef S_ISCHR + else if (S_ISCHR(mode)) { + return "characterSpecial"; + } +#endif +#ifdef S_ISBLK + else if (S_ISBLK(mode)) { + return "blockSpecial"; + } +#endif +#ifdef S_ISFIFO + else if (S_ISFIFO(mode)) { + return "fifo"; + } +#endif +#ifdef S_ISLNK + else if (S_ISLNK(mode)) { + return "link"; + } +#endif +#ifdef S_ISSOCK + else if (S_ISSOCK(mode)) { + return "socket"; + } +#endif + return "unknown"; +} + +static void AppendStatElement(Jim_Interp *interp, Jim_Obj *listObj, const char *key, jim_wide value) +{ + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, key, -1)); + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value)); +} + +int Jim_FileStoreStatData(Jim_Interp *interp, Jim_Obj *varName, const jim_stat_t *sb) +{ + + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + AppendStatElement(interp, listObj, "dev", sb->st_dev); + AppendStatElement(interp, listObj, "ino", sb->st_ino); + AppendStatElement(interp, listObj, "mode", sb->st_mode); + AppendStatElement(interp, listObj, "nlink", sb->st_nlink); + AppendStatElement(interp, listObj, "uid", sb->st_uid); + AppendStatElement(interp, listObj, "gid", sb->st_gid); + AppendStatElement(interp, listObj, "size", sb->st_size); + AppendStatElement(interp, listObj, "atime", sb->st_atime); + AppendStatElement(interp, listObj, "mtime", sb->st_mtime); + AppendStatElement(interp, listObj, "ctime", sb->st_ctime); +#ifdef STAT_MTIME_US + AppendStatElement(interp, listObj, "mtimeus", STAT_MTIME_US(*sb)); +#endif + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1)); + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, JimGetFileType((int)sb->st_mode), -1)); + + + if (varName) { + Jim_Obj *objPtr; + objPtr = Jim_GetVariable(interp, varName, JIM_NONE); + + if (objPtr) { + Jim_Obj *objv[2]; + + objv[0] = objPtr; + objv[1] = listObj; + + objPtr = Jim_DictMerge(interp, 2, objv); + if (objPtr == NULL) { + + Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName); + Jim_FreeNewObj(interp, listObj); + return JIM_ERR; + } + + Jim_InvalidateStringRep(objPtr); + + Jim_FreeNewObj(interp, listObj); + listObj = objPtr; + } + Jim_SetVariable(interp, varName, listObj); + } + + + Jim_SetResult(interp, listObj); + + return JIM_OK; +} + +static int JimPathLenNoTrailingSlashes(const char *path, int len) +{ + int i; + for (i = len; i > 1 && path[i - 1] == '/'; i--) { + + if (ISWINDOWS && path[i - 2] == ':') { + + break; + } + } + return i; +} + +static Jim_Obj *JimStripTrailingSlashes(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int len = Jim_Length(objPtr); + const char *path = Jim_String(objPtr); + int i = JimPathLenNoTrailingSlashes(path, len); + if (i != len) { + objPtr = Jim_NewStringObj(interp, path, i); + } + Jim_IncrRefCount(objPtr); + return objPtr; +} + +static int file_cmd_dirname(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]); + const char *path = Jim_String(objPtr); + const char *p = strrchr(path, '/'); + + if (!p) { + Jim_SetResultString(interp, ".", -1); + } + else if (p[1] == 0) { + + Jim_SetResult(interp, objPtr); + } + else if (p == path) { + Jim_SetResultString(interp, "/", -1); + } + else if (ISWINDOWS && p[-1] == ':') { + + Jim_SetResultString(interp, path, p - path + 1); + } + else { + + int len = JimPathLenNoTrailingSlashes(path, p - path); + Jim_SetResultString(interp, path, len); + } + Jim_DecrRefCount(interp, objPtr); + return JIM_OK; +} + +static int file_cmd_split(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + const char *path = Jim_String(argv[0]); + + if (*path == '/') { + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "/", 1)); + } + + while (1) { + + while (*path == '/') { + path++; + } + if (*path) { + const char *pt = strchr(path, '/'); + if (pt) { + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, path, pt - path)); + path = pt; + continue; + } + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, path, -1)); + } + break; + } + Jim_SetResult(interp, listObj); + return JIM_OK; +} + +static int file_cmd_rootname(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + const char *lastSlash = strrchr(path, '/'); + const char *p = strrchr(path, '.'); + + if (p == NULL || (lastSlash != NULL && lastSlash > p)) { + Jim_SetResult(interp, argv[0]); + } + else { + Jim_SetResultString(interp, path, p - path); + } + return JIM_OK; +} + +static int file_cmd_extension(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]); + const char *path = Jim_String(objPtr); + const char *lastSlash = strrchr(path, '/'); + const char *p = strrchr(path, '.'); + + if (p == NULL || (lastSlash != NULL && lastSlash >= p)) { + p = ""; + } + Jim_SetResultString(interp, p, -1); + Jim_DecrRefCount(interp, objPtr); + return JIM_OK; +} + +static int file_cmd_tail(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = JimStripTrailingSlashes(interp, argv[0]); + const char *path = Jim_String(objPtr); + const char *lastSlash = strrchr(path, '/'); + + if (lastSlash) { + Jim_SetResultString(interp, lastSlash + 1, -1); + } + else { + Jim_SetResult(interp, objPtr); + } + Jim_DecrRefCount(interp, objPtr); + return JIM_OK; +} + +#ifndef HAVE_RESTRICT +#define restrict +#endif + +static char *JimRealPath(const char *restrict path, char *restrict resolved_path, size_t len) +{ +#if defined(HAVE__FULLPATH) + return _fullpath(resolved_path, path, len); +#elif defined(HAVE_REALPATH) + return realpath(path, resolved_path); +#else + return NULL; +#endif +} + +static int file_cmd_normalize(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + char *newname = Jim_Alloc(MAXPATHLEN); + + if (JimRealPath(path, newname, MAXPATHLEN)) { + JimFixPath(newname); + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, -1)); + return JIM_OK; + } + Jim_Free(newname); + Jim_SetResultFormatted(interp, "can't normalize \"%#s\": %s", argv[0], strerror(errno)); + return JIM_ERR; +} + +static int file_cmd_join(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + char *newname = Jim_Alloc(MAXPATHLEN + 1); + char *last = newname; + + *newname = 0; + + + for (i = 0; i < argc; i++) { + int len; + const char *part = Jim_GetString(argv[i], &len); + + if (*part == '/') { + + last = newname; + } + else if (ISWINDOWS && strchr(part, ':')) { + + last = newname; + } + else if (part[0] == '.') { + if (part[1] == '/') { + part += 2; + len -= 2; + } + else if (part[1] == 0 && last != newname) { + + continue; + } + } + + + if (last != newname && last[-1] != '/') { + *last++ = '/'; + } + + if (len) { + if (last + len - newname >= MAXPATHLEN) { + Jim_Free(newname); + Jim_SetResultString(interp, "Path too long", -1); + return JIM_ERR; + } + memcpy(last, part, len); + last += len; + } + + + if (last > newname + 1 && last[-1] == '/') { + + if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) { + *--last = 0; + } + } + } + + *last = 0; + + + + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, newname, last - newname)); + + return JIM_OK; +} + +static int file_access(Jim_Interp *interp, Jim_Obj *filename, int mode) +{ + Jim_SetResultBool(interp, access(Jim_String(filename), mode) != -1); + + return JIM_OK; +} + +static int file_cmd_readable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], R_OK); +} + +static int file_cmd_writable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], W_OK); +} + +static int file_cmd_executable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ +#ifdef X_OK + return file_access(interp, argv[0], X_OK); +#else + + Jim_SetResultBool(interp, 1); + return JIM_OK; +#endif +} + +static int file_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return file_access(interp, argv[0], F_OK); +} + +static int file_cmd_delete(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int force = Jim_CompareStringImmediate(interp, argv[0], "-force"); + + if (force || Jim_CompareStringImmediate(interp, argv[0], "--")) { + argc--; + argv++; + } + + while (argc--) { + const char *path = Jim_String(argv[0]); + + if (unlink(path) == -1 && errno != ENOENT) { + if (rmdir(path) == -1) { + + if (!force || Jim_EvalPrefix(interp, "file delete force", 1, argv) != JIM_OK) { + Jim_SetResultFormatted(interp, "couldn't delete file \"%s\": %s", path, + strerror(errno)); + return JIM_ERR; + } + } + } + argv++; + } + return JIM_OK; +} + +#ifdef HAVE_MKDIR_ONE_ARG +#define MKDIR_DEFAULT(PATHNAME) mkdir(PATHNAME) +#else +#define MKDIR_DEFAULT(PATHNAME) mkdir(PATHNAME, 0755) +#endif + +static int mkdir_all(char *path) +{ + int ok = 1; + + + goto first; + + while (ok--) { + + { + char *slash = strrchr(path, '/'); + + if (slash && slash != path) { + *slash = 0; + if (mkdir_all(path) != 0) { + return -1; + } + *slash = '/'; + } + } + first: + if (MKDIR_DEFAULT(path) == 0) { + return 0; + } + if (errno == ENOENT) { + + continue; + } + + if (errno == EEXIST) { + jim_stat_t sb; + + if (Jim_Stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { + return 0; + } + + errno = EEXIST; + } + + break; + } + return -1; +} + +static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + while (argc--) { + char *path = Jim_StrDup(Jim_String(argv[0])); + int rc = mkdir_all(path); + + Jim_Free(path); + if (rc != 0) { + Jim_SetResultFormatted(interp, "can't create directory \"%#s\": %s", argv[0], + strerror(errno)); + return JIM_ERR; + } + argv++; + } + return JIM_OK; +} + +static int file_cmd_tempfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int fd = Jim_MakeTempFile(interp, (argc >= 1) ? Jim_String(argv[0]) : NULL, 0); + + if (fd < 0) { + return JIM_ERR; + } + close(fd); + + return JIM_OK; +} + +static int file_cmd_rename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *source; + const char *dest; + int force = 0; + + if (argc == 3) { + if (!Jim_CompareStringImmediate(interp, argv[0], "-force")) { + return -1; + } + force++; + argv++; + argc--; + } + + source = Jim_String(argv[0]); + dest = Jim_String(argv[1]); + + if (!force && access(dest, F_OK) == 0) { + Jim_SetResultFormatted(interp, "error renaming \"%#s\" to \"%#s\": target exists", argv[0], + argv[1]); + return JIM_ERR; + } +#if ISWINDOWS + if (access(dest, F_OK) == 0) { + + remove(dest); + } +#endif + if (rename(source, dest) != 0) { + Jim_SetResultFormatted(interp, "error renaming \"%#s\" to \"%#s\": %s", argv[0], argv[1], + strerror(errno)); + return JIM_ERR; + } + + return JIM_OK; +} + +#if defined(HAVE_LINK) && defined(HAVE_SYMLINK) +static int file_cmd_link(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int ret; + const char *source; + const char *dest; + static const char * const options[] = { "-hard", "-symbolic", NULL }; + enum { OPT_HARD, OPT_SYMBOLIC, }; + int option = OPT_HARD; + + if (argc == 3) { + if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ENUM_ABBREV | JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + argv++; + argc--; + } + + dest = Jim_String(argv[0]); + source = Jim_String(argv[1]); + + if (option == OPT_HARD) { + ret = link(source, dest); + } + else { + ret = symlink(source, dest); + } + + if (ret != 0) { + Jim_SetResultFormatted(interp, "error linking \"%#s\" to \"%#s\": %s", argv[0], argv[1], + strerror(errno)); + return JIM_ERR; + } + + return JIM_OK; +} +#endif + +static int file_stat(Jim_Interp *interp, Jim_Obj *filename, jim_stat_t *sb) +{ + const char *path = Jim_String(filename); + + if (Jim_Stat(path, sb) == -1) { + Jim_SetResultFormatted(interp, "could not read \"%#s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} + +#ifdef Jim_LinkStat +static int file_lstat(Jim_Interp *interp, Jim_Obj *filename, jim_stat_t *sb) +{ + const char *path = Jim_String(filename); + + if (Jim_LinkStat(path, sb) == -1) { + Jim_SetResultFormatted(interp, "could not read \"%#s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} +#else +#define file_lstat file_stat +#endif + +static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_atime); + return JIM_OK; +} + +static int JimSetFileTimes(Jim_Interp *interp, const char *filename, jim_wide us) +{ +#ifdef HAVE_UTIMES + struct timeval times[2]; + + times[1].tv_sec = times[0].tv_sec = us / 1000000; + times[1].tv_usec = times[0].tv_usec = us % 1000000; + + if (utimes(filename, times) != 0) { + Jim_SetResultFormatted(interp, "can't set time on \"%s\": %s", filename, strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +#else + Jim_SetResultString(interp, "Not implemented", -1); + return JIM_ERR; +#endif +} + +static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + + if (argc == 2) { + jim_wide secs; + if (Jim_GetWide(interp, argv[1], &secs) != JIM_OK) { + return JIM_ERR; + } + return JimSetFileTimes(interp, Jim_String(argv[0]), secs * 1000000); + } + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_mtime); + return JIM_OK; +} + +#ifdef STAT_MTIME_US +static int file_cmd_mtimeus(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + + if (argc == 2) { + jim_wide us; + if (Jim_GetWide(interp, argv[1], &us) != JIM_OK) { + return JIM_ERR; + } + return JimSetFileTimes(interp, Jim_String(argv[0]), us); + } + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, STAT_MTIME_US(sb)); + return JIM_OK; +} +#endif + +static int file_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_EvalPrefix(interp, "file copy", argc, argv); +} + +static int file_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultInt(interp, sb.st_size); + return JIM_OK; +} + +static int file_cmd_isdirectory(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = S_ISDIR(sb.st_mode); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} + +static int file_cmd_isfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = S_ISREG(sb.st_mode); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} + +#ifdef HAVE_GETEUID +static int file_cmd_owned(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + int ret = 0; + + if (file_stat(interp, argv[0], &sb) == JIM_OK) { + ret = (geteuid() == sb.st_uid); + } + Jim_SetResultInt(interp, ret); + return JIM_OK; +} +#endif + +#if defined(HAVE_READLINK) +static int file_cmd_readlink(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path = Jim_String(argv[0]); + char *linkValue = Jim_Alloc(MAXPATHLEN + 1); + + int linkLength = readlink(path, linkValue, MAXPATHLEN); + + if (linkLength == -1) { + Jim_Free(linkValue); + Jim_SetResultFormatted(interp, "could not read link \"%#s\": %s", argv[0], strerror(errno)); + return JIM_ERR; + } + linkValue[linkLength] = 0; + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, linkValue, linkLength)); + return JIM_OK; +} +#endif + +static int file_cmd_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + + if (file_lstat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResultString(interp, JimGetFileType((int)sb.st_mode), -1); + return JIM_OK; +} + +#ifdef Jim_LinkStat +static int file_cmd_lstat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + + if (file_lstat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + return Jim_FileStoreStatData(interp, argc == 2 ? argv[1] : NULL, &sb); +} +#else +#define file_cmd_lstat file_cmd_stat +#endif + +static int file_cmd_stat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + + if (file_stat(interp, argv[0], &sb) != JIM_OK) { + return JIM_ERR; + } + return Jim_FileStoreStatData(interp, argc == 2 ? argv[1] : NULL, &sb); +} + +static const jim_subcmd_type file_command_table[] = { + { "atime", + "name", + file_cmd_atime, + 1, + 1, + + }, + { "mtime", + "name ?time?", + file_cmd_mtime, + 1, + 2, + + }, +#ifdef STAT_MTIME_US + { "mtimeus", + "name ?time?", + file_cmd_mtimeus, + 1, + 2, + + }, +#endif + { "copy", + "?-force? source dest", + file_cmd_copy, + 2, + 3, + + }, + { "dirname", + "name", + file_cmd_dirname, + 1, + 1, + + }, + { "rootname", + "name", + file_cmd_rootname, + 1, + 1, + + }, + { "extension", + "name", + file_cmd_extension, + 1, + 1, + + }, + { "tail", + "name", + file_cmd_tail, + 1, + 1, + + }, + { "split", + "name", + file_cmd_split, + 1, + 1, + + }, + { "normalize", + "name", + file_cmd_normalize, + 1, + 1, + + }, + { "join", + "name ?name ...?", + file_cmd_join, + 1, + -1, + + }, + { "readable", + "name", + file_cmd_readable, + 1, + 1, + + }, + { "writable", + "name", + file_cmd_writable, + 1, + 1, + + }, + { "executable", + "name", + file_cmd_executable, + 1, + 1, + + }, + { "exists", + "name", + file_cmd_exists, + 1, + 1, + + }, + { "delete", + "?-force|--? name ...", + file_cmd_delete, + 1, + -1, + + }, + { "mkdir", + "dir ...", + file_cmd_mkdir, + 1, + -1, + + }, + { "tempfile", + "?template?", + file_cmd_tempfile, + 0, + 1, + + }, + { "rename", + "?-force? source dest", + file_cmd_rename, + 2, + 3, + + }, +#if defined(HAVE_LINK) && defined(HAVE_SYMLINK) + { "link", + "?-symbolic|-hard? newname target", + file_cmd_link, + 2, + 3, + + }, +#endif +#if defined(HAVE_READLINK) + { "readlink", + "name", + file_cmd_readlink, + 1, + 1, + + }, +#endif + { "size", + "name", + file_cmd_size, + 1, + 1, + + }, + { "stat", + "name ?var?", + file_cmd_stat, + 1, + 2, + + }, + { "lstat", + "name ?var?", + file_cmd_lstat, + 1, + 2, + + }, + { "type", + "name", + file_cmd_type, + 1, + 1, + + }, +#ifdef HAVE_GETEUID + { "owned", + "name", + file_cmd_owned, + 1, + 1, + + }, +#endif + { "isdirectory", + "name", + file_cmd_isdirectory, + 1, + 1, + + }, + { "isfile", + "name", + file_cmd_isfile, + 1, + 1, + + }, + { + NULL + } +}; + +static int Jim_CdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *path; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "dirname"); + return JIM_ERR; + } + + path = Jim_String(argv[1]); + + if (chdir(path) != 0) { + Jim_SetResultFormatted(interp, "couldn't change working directory to \"%s\": %s", path, + strerror(errno)); + return JIM_ERR; + } + return JIM_OK; +} + +static int Jim_PwdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + char *cwd = Jim_Alloc(MAXPATHLEN); + + if (getcwd(cwd, MAXPATHLEN) == NULL) { + Jim_SetResultString(interp, "Failed to get pwd", -1); + Jim_Free(cwd); + return JIM_ERR; + } + JimFixPath(cwd); + Jim_SetResultString(interp, cwd, -1); + + Jim_Free(cwd); + return JIM_OK; +} + +int Jim_fileInit(Jim_Interp *interp) +{ + Jim_PackageProvideCheck(interp, "file"); + Jim_CreateCommand(interp, "file", Jim_SubCmdProc, (void *)file_command_table, NULL); + Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL); + Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL); + return JIM_OK; +} + +#include +#include + + +#if (!(defined(HAVE_VFORK) || defined(HAVE_FORK)) || !defined(HAVE_WAITPID)) && !defined(__MINGW32__) +static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *cmdlineObj = Jim_NewEmptyStringObj(interp); + int i, j; + int rc; + + + for (i = 1; i < argc; i++) { + int len; + const char *arg = Jim_GetString(argv[i], &len); + + if (i > 1) { + Jim_AppendString(interp, cmdlineObj, " ", 1); + } + if (strpbrk(arg, "\\\" ") == NULL) { + + Jim_AppendString(interp, cmdlineObj, arg, len); + continue; + } + + Jim_AppendString(interp, cmdlineObj, "\"", 1); + for (j = 0; j < len; j++) { + if (arg[j] == '\\' || arg[j] == '"') { + Jim_AppendString(interp, cmdlineObj, "\\", 1); + } + Jim_AppendString(interp, cmdlineObj, &arg[j], 1); + } + Jim_AppendString(interp, cmdlineObj, "\"", 1); + } + rc = system(Jim_String(cmdlineObj)); + + Jim_FreeNewObj(interp, cmdlineObj); + + if (rc) { + Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, 0)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, rc)); + Jim_SetGlobalVariableStr(interp, "errorCode", errorCode); + return JIM_ERR; + } + + return JIM_OK; +} + +int Jim_execInit(Jim_Interp *interp) +{ + Jim_PackageProvideCheck(interp, "exec"); + Jim_CreateCommand(interp, "exec", Jim_ExecCmd, NULL, NULL); + return JIM_OK; +} +#else + + +#include +#include +#include + +struct WaitInfoTable; + +static char **JimOriginalEnviron(void); +static char **JimSaveEnv(char **env); +static void JimRestoreEnv(char **env); +static int JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, + phandle_t **pidArrayPtr, int *inPipePtr, int *outPipePtr, int *errFilePtr); +static void JimDetachPids(struct WaitInfoTable *table, int numPids, const phandle_t *pidPtr); +static int JimCleanupChildren(Jim_Interp *interp, int numPids, phandle_t *pidPtr, Jim_Obj *errStrObj); +static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv); + +#if defined(__MINGW32__) +static phandle_t JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, int inputId, int outputId, int errorId); +#endif + +static void Jim_RemoveTrailingNewline(Jim_Obj *objPtr) +{ + int len; + const char *s = Jim_GetString(objPtr, &len); + + if (len > 0 && s[len - 1] == '\n') { + objPtr->length--; + objPtr->bytes[objPtr->length] = '\0'; + } +} + +static int JimAppendStreamToString(Jim_Interp *interp, int fd, Jim_Obj *strObj) +{ + char buf[256]; + int ret = 0; + + while (1) { + int retval = read(fd, buf, sizeof(buf)); + if (retval > 0) { + ret = 1; + Jim_AppendString(interp, strObj, buf, retval); + } + if (retval <= 0) { + break; + } + } + close(fd); + return ret; +} + +static char **JimBuildEnv(Jim_Interp *interp) +{ + int i; + int size; + int num; + int n; + char **envptr; + char *envdata; + + Jim_Obj *objPtr = Jim_GetGlobalVariableStr(interp, "env", JIM_NONE); + + if (!objPtr) { + return JimOriginalEnviron(); + } + + + + num = Jim_ListLength(interp, objPtr); + if (num % 2) { + + num--; + } + size = Jim_Length(objPtr) + 2; + + envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size); + envdata = (char *)&envptr[num / 2 + 1]; + + n = 0; + for (i = 0; i < num; i += 2) { + const char *s1, *s2; + Jim_Obj *elemObj; + + Jim_ListIndex(interp, objPtr, i, &elemObj, JIM_NONE); + s1 = Jim_String(elemObj); + Jim_ListIndex(interp, objPtr, i + 1, &elemObj, JIM_NONE); + s2 = Jim_String(elemObj); + + envptr[n] = envdata; + envdata += sprintf(envdata, "%s=%s", s1, s2); + envdata++; + n++; + } + envptr[n] = NULL; + *envdata = 0; + + return envptr; +} + +static void JimFreeEnv(char **env, char **original_environ) +{ + if (env != original_environ) { + Jim_Free(env); + } +} + +static Jim_Obj *JimMakeErrorCode(Jim_Interp *interp, long pid, int waitStatus, Jim_Obj *errStrObj) +{ + Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0); + + if (pid <= 0) { + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, -1)); + } + else if (WIFEXITED(waitStatus)) { + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus))); + } + else { + const char *type; + const char *action; + const char *signame; + + if (WIFSIGNALED(waitStatus)) { + type = "CHILDKILLED"; + action = "killed"; + signame = Jim_SignalId(WTERMSIG(waitStatus)); + } + else { + type = "CHILDSUSP"; + action = "suspended"; + signame = "none"; + } + + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1)); + + if (errStrObj) { + Jim_AppendStrings(interp, errStrObj, "child ", action, " by signal ", Jim_SignalId(WTERMSIG(waitStatus)), "\n", NULL); + } + + Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid)); + Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, signame, -1)); + } + return errorCode; +} + +static int JimCheckWaitStatus(Jim_Interp *interp, long pid, int waitStatus, Jim_Obj *errStrObj) +{ + if (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus) == 0) { + return JIM_OK; + } + Jim_SetGlobalVariableStr(interp, "errorCode", JimMakeErrorCode(interp, pid, waitStatus, errStrObj)); + + return JIM_ERR; +} + + +struct WaitInfo +{ + phandle_t phandle; + int status; + int flags; +}; + + +struct WaitInfoTable { + struct WaitInfo *info; + int size; + int used; + int refcount; +}; + + +#define WI_DETACHED 2 + +#define WAIT_TABLE_GROW_BY 4 + +static void JimFreeWaitInfoTable(struct Jim_Interp *interp, void *privData) +{ + struct WaitInfoTable *table = privData; + + if (--table->refcount == 0) { + Jim_Free(table->info); + Jim_Free(table); + } +} + +static struct WaitInfoTable *JimAllocWaitInfoTable(void) +{ + struct WaitInfoTable *table = Jim_Alloc(sizeof(*table)); + table->info = NULL; + table->size = table->used = 0; + table->refcount = 1; + + return table; +} + +static int JimWaitRemove(struct WaitInfoTable *table, phandle_t phandle) +{ + int i; + + + for (i = 0; i < table->used; i++) { + if (phandle == table->info[i].phandle) { + if (i != table->used - 1) { + table->info[i] = table->info[table->used - 1]; + } + table->used--; + return 0; + } + } + return -1; +} + +static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int outputId; + int errorId; + phandle_t *pidPtr; + int numPids, result; + int child_siginfo = 1; + Jim_Obj *childErrObj; + Jim_Obj *errStrObj; + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + + if (argc > 1 && Jim_CompareStringImmediate(interp, argv[argc - 1], "&")) { + Jim_Obj *listObj; + int i; + + argc--; + numPids = JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, NULL, NULL); + if (numPids < 0) { + return JIM_ERR; + } + + listObj = Jim_NewListObj(interp, NULL, 0); + for (i = 0; i < numPids; i++) { + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, JimProcessPid(pidPtr[i]))); + } + Jim_SetResult(interp, listObj); + JimDetachPids(table, numPids, pidPtr); + Jim_Free(pidPtr); + return JIM_OK; + } + + numPids = + JimCreatePipeline(interp, argc - 1, argv + 1, &pidPtr, NULL, &outputId, &errorId); + + if (numPids < 0) { + return JIM_ERR; + } + + result = JIM_OK; + + errStrObj = Jim_NewStringObj(interp, "", 0); + + + if (outputId != -1) { + if (JimAppendStreamToString(interp, outputId, errStrObj) < 0) { + result = JIM_ERR; + Jim_SetResultErrno(interp, "error reading from output pipe"); + } + } + + + childErrObj = Jim_NewStringObj(interp, "", 0); + Jim_IncrRefCount(childErrObj); + + if (JimCleanupChildren(interp, numPids, pidPtr, childErrObj) != JIM_OK) { + result = JIM_ERR; + } + + if (errorId != -1) { + int ret; + Jim_Lseek(errorId, 0, SEEK_SET); + ret = JimAppendStreamToString(interp, errorId, errStrObj); + if (ret < 0) { + Jim_SetResultErrno(interp, "error reading from error pipe"); + result = JIM_ERR; + } + else if (ret > 0) { + + child_siginfo = 0; + } + } + + if (child_siginfo) { + + Jim_AppendObj(interp, errStrObj, childErrObj); + } + Jim_DecrRefCount(interp, childErrObj); + + + Jim_RemoveTrailingNewline(errStrObj); + + + Jim_SetResult(interp, errStrObj); + + return result; +} + +static long JimWaitForProcess(struct WaitInfoTable *table, phandle_t phandle, int *statusPtr) +{ + if (JimWaitRemove(table, phandle) == 0) { + + return waitpid(phandle, statusPtr, 0); + } + + + return -1; +} + +static void JimDetachPids(struct WaitInfoTable *table, int numPids, const phandle_t *pidPtr) +{ + int j; + + for (j = 0; j < numPids; j++) { + + int i; + for (i = 0; i < table->used; i++) { + if (pidPtr[j] == table->info[i].phandle) { + table->info[i].flags |= WI_DETACHED; + break; + } + } + } +} + +static int JimGetChannelFd(Jim_Interp *interp, const char *name) +{ + Jim_Obj *objv[2]; + + objv[0] = Jim_NewStringObj(interp, name, -1); + objv[1] = Jim_NewStringObj(interp, "getfd", -1); + + if (Jim_EvalObjVector(interp, 2, objv) == JIM_OK) { + jim_wide fd; + if (Jim_GetWide(interp, Jim_GetResult(interp), &fd) == JIM_OK) { + return fd; + } + } + return -1; +} + +static void JimReapDetachedPids(struct WaitInfoTable *table) +{ + struct WaitInfo *waitPtr; + int count; + int dest; + + if (!table) { + return; + } + + waitPtr = table->info; + dest = 0; + for (count = table->used; count > 0; waitPtr++, count--) { + if (waitPtr->flags & WI_DETACHED) { + int status; + long pid = waitpid(waitPtr->phandle, &status, WNOHANG); + if (pid > 0) { + + table->used--; + continue; + } + } + if (waitPtr != &table->info[dest]) { + table->info[dest] = *waitPtr; + } + dest++; + } +} + +static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + int nohang = 0; + long pid; + phandle_t phandle; + int status; + Jim_Obj *errCodeObj; + + + if (argc == 1) { + JimReapDetachedPids(table); + return JIM_OK; + } + + if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-nohang")) { + nohang = 1; + } + if (argc != nohang + 2) { + Jim_WrongNumArgs(interp, 1, argv, "?-nohang? ?pid?"); + return JIM_ERR; + } + if (Jim_GetLong(interp, argv[nohang + 1], &pid) != JIM_OK) { + return JIM_ERR; + } + + + phandle = JimWaitPid(pid, &status, nohang ? WNOHANG : 0); + if (phandle == JIM_BAD_PHANDLE) { + pid = -1; + } +#ifndef __MINGW32__ + else if (pid < 0) { + pid = phandle; + } +#endif + + errCodeObj = JimMakeErrorCode(interp, pid, status, NULL); + + if (phandle != JIM_BAD_PHANDLE && (WIFEXITED(status) || WIFSIGNALED(status))) { + + JimWaitRemove(table, phandle); + } + Jim_SetResult(interp, errCodeObj); + return JIM_OK; +} + +static int Jim_PidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + + Jim_SetResultInt(interp, (jim_wide)getpid()); + return JIM_OK; +} + +static int +JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, phandle_t **pidArrayPtr, + int *inPipePtr, int *outPipePtr, int *errFilePtr) +{ + phandle_t *pidPtr = NULL; /* Points to alloc-ed array holding all + * the pids of child processes. */ + int numPids = 0; /* Actual number of processes that exist + * at *pidPtr right now. */ + int cmdCount; /* Count of number of distinct commands + * found in argc/argv. */ + const char *input = NULL; /* Describes input for pipeline, depending + * on "inputFile". NULL means take input + * from stdin/pipe. */ + int input_len = 0; + +#define FILE_NAME 0 +#define FILE_APPEND 1 +#define FILE_HANDLE 2 +#define FILE_TEXT 3 + + int inputFile = FILE_NAME; /* 1 means input is name of input file. + * 2 means input is filehandle name. + * 0 means input holds actual + * text to be input to command. */ + + int outputFile = FILE_NAME; /* 0 means output is the name of output file. + * 1 means output is the name of output file, and append. + * 2 means output is filehandle name. + * All this is ignored if output is NULL + */ + int errorFile = FILE_NAME; /* 0 means error is the name of error file. + * 1 means error is the name of error file, and append. + * 2 means error is filehandle name. + * All this is ignored if error is NULL + */ + const char *output = NULL; /* Holds name of output file to pipe to, + * or NULL if output goes to stdout/pipe. */ + const char *error = NULL; /* Holds name of stderr file to pipe to, + * or NULL if stderr goes to stderr/pipe. */ + int inputId = -1; + int outputId = -1; + int errorId = -1; + int lastOutputId = -1; + int pipeIds[2]; + int firstArg, lastArg; /* Indexes of first and last arguments in + * current command. */ + int lastBar; + int i; + phandle_t phandle; + char **save_environ; +#if defined(HAVE_EXECVPE) && !defined(__MINGW32__) + char **child_environ; +#endif + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + + + char **arg_array = Jim_Alloc(sizeof(*arg_array) * (argc + 1)); + int arg_count = 0; + + if (inPipePtr != NULL) { + *inPipePtr = -1; + } + if (outPipePtr != NULL) { + *outPipePtr = -1; + } + if (errFilePtr != NULL) { + *errFilePtr = -1; + } + pipeIds[0] = pipeIds[1] = -1; + + cmdCount = 1; + lastBar = -1; + for (i = 0; i < argc; i++) { + const char *arg = Jim_String(argv[i]); + + if (arg[0] == '<') { + inputFile = FILE_NAME; + input = arg + 1; + if (*input == '<') { + inputFile = FILE_TEXT; + input_len = Jim_Length(argv[i]) - 2; + input++; + } + else if (*input == '@') { + inputFile = FILE_HANDLE; + input++; + } + + if (!*input && ++i < argc) { + input = Jim_GetString(argv[i], &input_len); + } + } + else if (arg[0] == '>') { + int dup_error = 0; + + outputFile = FILE_NAME; + + output = arg + 1; + if (*output == '>') { + outputFile = FILE_APPEND; + output++; + } + if (*output == '&') { + + output++; + dup_error = 1; + } + if (*output == '@') { + outputFile = FILE_HANDLE; + output++; + } + if (!*output && ++i < argc) { + output = Jim_String(argv[i]); + } + if (dup_error) { + errorFile = outputFile; + error = output; + } + } + else if (arg[0] == '2' && arg[1] == '>') { + error = arg + 2; + errorFile = FILE_NAME; + + if (*error == '@') { + errorFile = FILE_HANDLE; + error++; + } + else if (*error == '>') { + errorFile = FILE_APPEND; + error++; + } + if (!*error && ++i < argc) { + error = Jim_String(argv[i]); + } + } + else { + if (strcmp(arg, "|") == 0 || strcmp(arg, "|&") == 0) { + if (i == lastBar + 1 || i == argc - 1) { + Jim_SetResultString(interp, "illegal use of | or |& in command", -1); + goto badargs; + } + lastBar = i; + cmdCount++; + } + + arg_array[arg_count++] = (char *)arg; + continue; + } + + if (i >= argc) { + Jim_SetResultFormatted(interp, "can't specify \"%s\" as last word in command", arg); + goto badargs; + } + } + + if (arg_count == 0) { + Jim_SetResultString(interp, "didn't specify command to execute", -1); +badargs: + Jim_Free(arg_array); + return -1; + } + + + save_environ = JimSaveEnv(JimBuildEnv(interp)); + + if (input != NULL) { + if (inputFile == FILE_TEXT) { + inputId = Jim_MakeTempFile(interp, NULL, 1); + if (inputId == -1) { + goto error; + } + if (write(inputId, input, input_len) != input_len) { + Jim_SetResultErrno(interp, "couldn't write temp file"); + close(inputId); + goto error; + } + Jim_Lseek(inputId, 0L, SEEK_SET); + } + else if (inputFile == FILE_HANDLE) { + int fd = JimGetChannelFd(interp, input); + + if (fd < 0) { + goto error; + } + inputId = dup(fd); + } + else { + inputId = Jim_OpenForRead(input); + if (inputId == -1) { + Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", input, strerror(Jim_Errno())); + goto error; + } + } + } + else if (inPipePtr != NULL) { + if (pipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create input pipe for command"); + goto error; + } + inputId = pipeIds[0]; + *inPipePtr = pipeIds[1]; + pipeIds[0] = pipeIds[1] = -1; + } + + if (output != NULL) { + if (outputFile == FILE_HANDLE) { + int fd = JimGetChannelFd(interp, output); + if (fd < 0) { + goto error; + } + lastOutputId = dup(fd); + } + else { + lastOutputId = Jim_OpenForWrite(output, outputFile == FILE_APPEND); + if (lastOutputId == -1) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", output, strerror(Jim_Errno())); + goto error; + } + } + } + else if (outPipePtr != NULL) { + if (pipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create output pipe"); + goto error; + } + lastOutputId = pipeIds[1]; + *outPipePtr = pipeIds[0]; + pipeIds[0] = pipeIds[1] = -1; + } + + if (error != NULL) { + if (errorFile == FILE_HANDLE) { + if (strcmp(error, "1") == 0) { + + if (lastOutputId != -1) { + errorId = dup(lastOutputId); + } + else { + + error = "stdout"; + } + } + if (errorId == -1) { + int fd = JimGetChannelFd(interp, error); + if (fd < 0) { + goto error; + } + errorId = dup(fd); + } + } + else { + errorId = Jim_OpenForWrite(error, errorFile == FILE_APPEND); + if (errorId == -1) { + Jim_SetResultFormatted(interp, "couldn't write file \"%s\": %s", error, strerror(Jim_Errno())); + goto error; + } + } + } + else if (errFilePtr != NULL) { + errorId = Jim_MakeTempFile(interp, NULL, 1); + if (errorId == -1) { + goto error; + } + *errFilePtr = dup(errorId); + } + + + pidPtr = Jim_Alloc(cmdCount * sizeof(*pidPtr)); + for (firstArg = 0; firstArg < arg_count; numPids++, firstArg = lastArg + 1) { + int pipe_dup_err = 0; + int origErrorId = errorId; + + for (lastArg = firstArg; lastArg < arg_count; lastArg++) { + if (strcmp(arg_array[lastArg], "|") == 0) { + break; + } + if (strcmp(arg_array[lastArg], "|&") == 0) { + pipe_dup_err = 1; + break; + } + } + + if (lastArg == firstArg) { + Jim_SetResultString(interp, "missing command to exec", -1); + goto error; + } + + + arg_array[lastArg] = NULL; + if (lastArg == arg_count) { + outputId = lastOutputId; + lastOutputId = -1; + } + else { + if (pipe(pipeIds) != 0) { + Jim_SetResultErrno(interp, "couldn't create pipe"); + goto error; + } + outputId = pipeIds[1]; + } + + + if (pipe_dup_err) { + errorId = outputId; + } + + + +#ifdef __MINGW32__ + phandle = JimStartWinProcess(interp, &arg_array[firstArg], save_environ, inputId, outputId, errorId); + if (phandle == JIM_BAD_PHANDLE) { + Jim_SetResultFormatted(interp, "couldn't exec \"%s\"", arg_array[firstArg]); + goto error; + } +#else + i = strlen(arg_array[firstArg]); + +#ifdef HAVE_EXECVPE + child_environ = Jim_GetEnviron(); +#endif +#ifdef HAVE_VFORK + phandle = vfork(); +#else + phandle = fork(); +#endif + if (phandle < 0) { + Jim_SetResultErrno(interp, "couldn't fork child process"); + goto error; + } + if (phandle == 0) { + + + if (inputId != -1 && inputId != fileno(stdin)) { + dup2(inputId, fileno(stdin)); + close(inputId); + } + if (outputId != -1 && outputId != fileno(stdout)) { + dup2(outputId, fileno(stdout)); + if (outputId != errorId) { + close(outputId); + } + } + if (errorId != -1 && errorId != fileno(stderr)) { + dup2(errorId, fileno(stderr)); + close(errorId); + } + + if (outPipePtr && *outPipePtr != -1) { + close(*outPipePtr); + } + if (errFilePtr && *errFilePtr != -1) { + close(*errFilePtr); + } + if (pipeIds[0] != -1) { + close(pipeIds[0]); + } + if (lastOutputId != -1) { + close(lastOutputId); + } + + execvpe(arg_array[firstArg], &arg_array[firstArg], child_environ); + + if (write(fileno(stderr), "couldn't exec \"", 15) && + write(fileno(stderr), arg_array[firstArg], i) && + write(fileno(stderr), "\"\n", 2)) { + + } +#ifdef JIM_MAINTAINER + { + + static char *const false_argv[2] = {"false", NULL}; + execvp(false_argv[0],false_argv); + } +#endif + _exit(127); + } +#endif + + + + if (table->used == table->size) { + table->size += WAIT_TABLE_GROW_BY; + table->info = Jim_Realloc(table->info, table->size * sizeof(*table->info)); + } + + table->info[table->used].phandle = phandle; + table->info[table->used].flags = 0; + table->used++; + + pidPtr[numPids] = phandle; + + + errorId = origErrorId; + + + if (inputId != -1) { + close(inputId); + } + if (outputId != -1) { + close(outputId); + } + inputId = pipeIds[0]; + pipeIds[0] = pipeIds[1] = -1; + } + *pidArrayPtr = pidPtr; + + + cleanup: + if (inputId != -1) { + close(inputId); + } + if (lastOutputId != -1) { + close(lastOutputId); + } + if (errorId != -1) { + close(errorId); + } + Jim_Free(arg_array); + + JimRestoreEnv(save_environ); + + return numPids; + + + error: + if ((inPipePtr != NULL) && (*inPipePtr != -1)) { + close(*inPipePtr); + *inPipePtr = -1; + } + if ((outPipePtr != NULL) && (*outPipePtr != -1)) { + close(*outPipePtr); + *outPipePtr = -1; + } + if ((errFilePtr != NULL) && (*errFilePtr != -1)) { + close(*errFilePtr); + *errFilePtr = -1; + } + if (pipeIds[0] != -1) { + close(pipeIds[0]); + } + if (pipeIds[1] != -1) { + close(pipeIds[1]); + } + if (pidPtr != NULL) { + for (i = 0; i < numPids; i++) { + if (pidPtr[i] != JIM_BAD_PHANDLE) { + JimDetachPids(table, 1, &pidPtr[i]); + } + } + Jim_Free(pidPtr); + } + numPids = -1; + goto cleanup; +} + + +static int JimCleanupChildren(Jim_Interp *interp, int numPids, phandle_t *pidPtr, Jim_Obj *errStrObj) +{ + struct WaitInfoTable *table = Jim_CmdPrivData(interp); + int result = JIM_OK; + int i; + + + for (i = 0; i < numPids; i++) { + int waitStatus = 0; + long pid = JimWaitForProcess(table, pidPtr[i], &waitStatus); + if (pid > 0) { + if (JimCheckWaitStatus(interp, pid, waitStatus, errStrObj) != JIM_OK) { + result = JIM_ERR; + } + } + } + Jim_Free(pidPtr); + + return result; +} + +int Jim_execInit(Jim_Interp *interp) +{ + struct WaitInfoTable *waitinfo; + + Jim_PackageProvideCheck(interp, "exec"); + + waitinfo = JimAllocWaitInfoTable(); + Jim_CreateCommand(interp, "exec", Jim_ExecCmd, waitinfo, JimFreeWaitInfoTable); + waitinfo->refcount++; + Jim_CreateCommand(interp, "wait", Jim_WaitCommand, waitinfo, JimFreeWaitInfoTable); + Jim_CreateCommand(interp, "pid", Jim_PidCommand, 0, 0); + + return JIM_OK; +} + +#if defined(__MINGW32__) + + +static int +JimWinFindExecutable(const char *originalName, char fullPath[MAX_PATH]) +{ + int i; + static char extensions[][5] = {".exe", "", ".bat"}; + + for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) { + snprintf(fullPath, MAX_PATH, "%s%s", originalName, extensions[i]); + + if (SearchPath(NULL, fullPath, NULL, MAX_PATH, fullPath, NULL) == 0) { + continue; + } + if (GetFileAttributes(fullPath) & FILE_ATTRIBUTE_DIRECTORY) { + continue; + } + return 0; + } + + return -1; +} + +static char **JimSaveEnv(char **env) +{ + return env; +} + +static void JimRestoreEnv(char **env) +{ + JimFreeEnv(env, Jim_GetEnviron()); +} + +static char **JimOriginalEnviron(void) +{ + return NULL; +} + +static Jim_Obj * +JimWinBuildCommandLine(Jim_Interp *interp, char **argv) +{ + char *start, *special; + int quote, i; + + Jim_Obj *strObj = Jim_NewStringObj(interp, "", 0); + + for (i = 0; argv[i]; i++) { + if (i > 0) { + Jim_AppendString(interp, strObj, " ", 1); + } + + if (argv[i][0] == '\0') { + quote = 1; + } + else { + quote = 0; + for (start = argv[i]; *start != '\0'; start++) { + if (isspace(UCHAR(*start))) { + quote = 1; + break; + } + } + } + if (quote) { + Jim_AppendString(interp, strObj, "\"" , 1); + } + + start = argv[i]; + for (special = argv[i]; ; ) { + if ((*special == '\\') && (special[1] == '\\' || + special[1] == '"' || (quote && special[1] == '\0'))) { + Jim_AppendString(interp, strObj, start, special - start); + start = special; + while (1) { + special++; + if (*special == '"' || (quote && *special == '\0')) { + + Jim_AppendString(interp, strObj, start, special - start); + break; + } + if (*special != '\\') { + break; + } + } + Jim_AppendString(interp, strObj, start, special - start); + start = special; + } + if (*special == '"') { + if (special == start) { + Jim_AppendString(interp, strObj, "\"", 1); + } + else { + Jim_AppendString(interp, strObj, start, special - start); + } + Jim_AppendString(interp, strObj, "\\\"", 2); + start = special + 1; + } + if (*special == '\0') { + break; + } + special++; + } + Jim_AppendString(interp, strObj, start, special - start); + if (quote) { + Jim_AppendString(interp, strObj, "\"", 1); + } + } + return strObj; +} + +static phandle_t +JimStartWinProcess(Jim_Interp *interp, char **argv, char **env, int inputId, int outputId, int errorId) +{ + STARTUPINFO startInfo; + PROCESS_INFORMATION procInfo; + HANDLE hProcess; + char execPath[MAX_PATH]; + phandle_t phandle = INVALID_HANDLE_VALUE; + Jim_Obj *cmdLineObj; + char *winenv; + + if (JimWinFindExecutable(argv[0], execPath) < 0) { + return phandle; + } + argv[0] = execPath; + + hProcess = GetCurrentProcess(); + cmdLineObj = JimWinBuildCommandLine(interp, argv); + + + ZeroMemory(&startInfo, sizeof(startInfo)); + startInfo.cb = sizeof(startInfo); + startInfo.dwFlags = STARTF_USESTDHANDLES; + startInfo.hStdInput = INVALID_HANDLE_VALUE; + startInfo.hStdOutput= INVALID_HANDLE_VALUE; + startInfo.hStdError = INVALID_HANDLE_VALUE; + + if (inputId == -1) { + inputId = _fileno(stdin); + } + DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(inputId), hProcess, &startInfo.hStdInput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { + goto end; + } + + if (outputId == -1) { + outputId = _fileno(stdout); + } + DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(outputId), hProcess, &startInfo.hStdOutput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { + goto end; + } + + + if (errorId == -1) { + errorId = _fileno(stderr); + } + DuplicateHandle(hProcess, (HANDLE)_get_osfhandle(errorId), hProcess, &startInfo.hStdError, + 0, TRUE, DUPLICATE_SAME_ACCESS); + if (startInfo.hStdError == INVALID_HANDLE_VALUE) { + goto end; + } + + if (env == NULL) { + + winenv = NULL; + } + else if (env[0] == NULL) { + winenv = (char *)"\0"; + } + else { + winenv = env[0]; + } + + if (!CreateProcess(NULL, (char *)Jim_String(cmdLineObj), NULL, NULL, TRUE, + 0, winenv, NULL, &startInfo, &procInfo)) { + goto end; + } + + + WaitForInputIdle(procInfo.hProcess, 5000); + CloseHandle(procInfo.hThread); + + phandle = procInfo.hProcess; + + end: + Jim_FreeNewObj(interp, cmdLineObj); + if (startInfo.hStdInput != INVALID_HANDLE_VALUE) { + CloseHandle(startInfo.hStdInput); + } + if (startInfo.hStdOutput != INVALID_HANDLE_VALUE) { + CloseHandle(startInfo.hStdOutput); + } + if (startInfo.hStdError != INVALID_HANDLE_VALUE) { + CloseHandle(startInfo.hStdError); + } + return phandle; +} + +#else + +static char **JimOriginalEnviron(void) +{ + return Jim_GetEnviron(); +} + +static char **JimSaveEnv(char **env) +{ + char **saveenv = Jim_GetEnviron(); + Jim_SetEnviron(env); + return saveenv; +} + +static void JimRestoreEnv(char **env) +{ + JimFreeEnv(Jim_GetEnviron(), env); + Jim_SetEnviron(env); +} +#endif +#endif + + +#include +#include +#include +#include + + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +struct clock_options { + int gmt; + const char *format; +}; + +static int parse_clock_options(Jim_Interp *interp, int argc, Jim_Obj *const *argv, struct clock_options *opts) +{ + static const char * const options[] = { "-gmt", "-format", NULL }; + enum { OPT_GMT, OPT_FORMAT, }; + int i; + + for (i = 0; i < argc; i += 2) { + int option; + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_GMT: + if (Jim_GetBoolean(interp, argv[i + 1], &opts->gmt) != JIM_OK) { + return JIM_ERR; + } + break; + case OPT_FORMAT: + opts->format = Jim_String(argv[i + 1]); + break; + } + } + return JIM_OK; +} + +static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + + char buf[100]; + time_t t; + jim_wide seconds; + struct clock_options options = { 0, "%a %b %d %H:%M:%S %Z %Y" }; + struct tm *tm; + + if (Jim_GetWide(interp, argv[0], &seconds) != JIM_OK) { + return JIM_ERR; + } + if (argc % 2 == 0) { + return -1; + } + if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) { + return JIM_ERR; + } + + t = seconds; + tm = options.gmt ? gmtime(&t) : localtime(&t); + + if (tm == NULL || strftime(buf, sizeof(buf), options.format, tm) == 0) { + Jim_SetResultString(interp, "format string too long or invalid time", -1); + return JIM_ERR; + } + + Jim_SetResultString(interp, buf, -1); + + return JIM_OK; +} + +#ifdef HAVE_STRPTIME +static time_t jim_timegm(const struct tm *tm) +{ + int m = tm->tm_mon + 1; + int y = 1900 + tm->tm_year - (m <= 2); + int era = (y >= 0 ? y : y - 399) / 400; + unsigned yoe = (unsigned)(y - era * 400); + unsigned doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + tm->tm_mday - 1; + unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; + long days = (era * 146097 + (int)doe - 719468); + int secs = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; + + return days * 24 * 60 * 60 + secs; +} + +static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + char *pt; + struct tm tm; + time_t now = time(NULL); + + struct clock_options options = { 0, NULL }; + + if (argc % 2 == 0) { + return -1; + } + + if (parse_clock_options(interp, argc - 1, argv + 1, &options) == JIM_ERR) { + return JIM_ERR; + } + if (options.format == NULL) { + return -1; + } + + localtime_r(&now, &tm); + + pt = strptime(Jim_String(argv[0]), options.format, &tm); + if (pt == 0 || *pt != 0) { + Jim_SetResultString(interp, "Failed to parse time according to format", -1); + return JIM_ERR; + } + + + tm.tm_isdst = options.gmt ? 0 : -1; + Jim_SetResultInt(interp, options.gmt ? jim_timegm(&tm) : mktime(&tm)); + + return JIM_OK; +} +#endif + +static int clock_cmd_seconds(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResultInt(interp, Jim_GetTimeUsec(CLOCK_REALTIME) / 1000000); + return JIM_OK; +} + +static int clock_cmd_clicks(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResultInt(interp, Jim_GetTimeUsec(CLOCK_MONOTONIC_RAW)); + return JIM_OK; +} + +static int clock_cmd_micros(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResultInt(interp, Jim_GetTimeUsec(CLOCK_REALTIME)); + return JIM_OK; +} + +static int clock_cmd_millis(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResultInt(interp, Jim_GetTimeUsec(CLOCK_REALTIME) / 1000); + return JIM_OK; +} + +static const jim_subcmd_type clock_command_table[] = { + { "clicks", + NULL, + clock_cmd_clicks, + 0, + 0, + + }, + { "format", + "seconds ?-format string? ?-gmt boolean?", + clock_cmd_format, + 1, + 5, + + }, + { "microseconds", + NULL, + clock_cmd_micros, + 0, + 0, + + }, + { "milliseconds", + NULL, + clock_cmd_millis, + 0, + 0, + + }, +#ifdef HAVE_STRPTIME + { "scan", + "str -format format ?-gmt boolean?", + clock_cmd_scan, + 3, + 5, + + }, +#endif + { "seconds", + NULL, + clock_cmd_seconds, + 0, + 0, + + }, + { NULL } +}; + +int Jim_clockInit(Jim_Interp *interp) +{ + Jim_PackageProvideCheck(interp, "clock"); + Jim_CreateCommand(interp, "clock", Jim_SubCmdProc, (void *)clock_command_table, NULL); + return JIM_OK; +} + +#include +#include +#include +#include +#include + + +static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + + Jim_Obj *dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); + Jim_SetResultInt(interp, dictObj && Jim_DictSize(interp, dictObj) != -1); + return JIM_OK; +} + +static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + Jim_Obj *patternObj; + + if (!objPtr) { + return JIM_OK; + } + + patternObj = (argc == 1) ? NULL : argv[1]; + + + if (patternObj == NULL || Jim_CompareStringImmediate(interp, patternObj, "*")) { + if (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0) { + + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + } + + return Jim_DictMatchTypes(interp, objPtr, patternObj, JIM_DICTMATCH_KEYS, JIM_DICTMATCH_KEYS | JIM_DICTMATCH_VALUES); +} + +static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + + if (!objPtr) { + return JIM_OK; + } + + return Jim_DictMatchTypes(interp, objPtr, argc == 1 ? NULL : argv[1], JIM_DICTMATCH_KEYS, JIM_DICTMATCH_KEYS); +} + +static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + int len; + Jim_Obj *resultObj; + Jim_Obj *objPtr; + Jim_Obj **dictValuesObj; + + if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) { + + Jim_UnsetVariable(interp, argv[0], JIM_NONE); + return JIM_OK; + } + + objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + + if (objPtr == NULL) { + + return JIM_OK; + } + + dictValuesObj = Jim_DictPairs(interp, objPtr, &len); + if (dictValuesObj == NULL) { + + Jim_SetResultString(interp, "", -1); + return JIM_OK; + } + + + resultObj = Jim_NewDictObj(interp, NULL, 0); + + for (i = 0; i < len; i += 2) { + if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) { + Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]); + } + } + + Jim_SetVariable(interp, argv[0], resultObj); + return JIM_OK; +} + +static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int len = 0; + + + objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + if (objPtr) { + len = Jim_DictSize(interp, objPtr); + if (len < 0) { + + Jim_SetResultInt(interp, 0); + return JIM_OK; + } + } + + Jim_SetResultInt(interp, len); + + return JIM_OK; +} + +static int array_cmd_stat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE); + if (objPtr) { + return Jim_DictInfo(interp, objPtr); + } + Jim_SetResultFormatted(interp, "\"%#s\" isn't an array", argv[0], NULL); + return JIM_ERR; +} + +static int array_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + int len; + Jim_Obj *listObj = argv[1]; + Jim_Obj *dictObj; + + len = Jim_ListLength(interp, listObj); + if (len % 2) { + Jim_SetResultString(interp, "list must have an even number of elements", -1); + return JIM_ERR; + } + + dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED); + if (!dictObj) { + + return Jim_SetVariable(interp, argv[0], listObj); + } + else if (Jim_DictSize(interp, dictObj) < 0) { + return JIM_ERR; + } + + if (Jim_IsShared(dictObj)) { + dictObj = Jim_DuplicateObj(interp, dictObj); + } + + for (i = 0; i < len; i += 2) { + Jim_Obj *nameObj; + Jim_Obj *valueObj; + + Jim_ListIndex(interp, listObj, i, &nameObj, JIM_NONE); + Jim_ListIndex(interp, listObj, i + 1, &valueObj, JIM_NONE); + + Jim_DictAddElement(interp, dictObj, nameObj, valueObj); + } + return Jim_SetVariable(interp, argv[0], dictObj); +} + +static const jim_subcmd_type array_command_table[] = { + { "exists", + "arrayName", + array_cmd_exists, + 1, + 1, + + }, + { "get", + "arrayName ?pattern?", + array_cmd_get, + 1, + 2, + + }, + { "names", + "arrayName ?pattern?", + array_cmd_names, + 1, + 2, + + }, + { "set", + "arrayName list", + array_cmd_set, + 2, + 2, + + }, + { "size", + "arrayName", + array_cmd_size, + 1, + 1, + + }, + { "stat", + "arrayName", + array_cmd_stat, + 1, + 1, + + }, + { "unset", + "arrayName ?pattern?", + array_cmd_unset, + 1, + 2, + + }, + { NULL + } +}; + +int Jim_arrayInit(Jim_Interp *interp) +{ + Jim_PackageProvideCheck(interp, "array"); + Jim_CreateCommand(interp, "array", Jim_SubCmdProc, (void *)array_command_table, NULL); + return JIM_OK; +} + +#include +#include +#include +#include +#include +#include + + +#ifdef HAVE_SYS_SYSINFO_H +#include +#endif + +static void Jim_PosixSetError(Jim_Interp *interp) +{ + Jim_SetResultString(interp, strerror(errno), -1); +} + +#if defined(HAVE_FORK) +static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + pid_t pid; + + JIM_NOTUSED(argv); + + if (argc != 1) { + Jim_WrongNumArgs(interp, 1, argv, ""); + return JIM_ERR; + } + if ((pid = fork()) == -1) { + Jim_PosixSetError(interp); + return JIM_ERR; + } + Jim_SetResultInt(interp, (jim_wide) pid); + return JIM_OK; +} +#endif + + +int Jim_posixInit(Jim_Interp *interp) +{ + Jim_PackageProvideCheck(interp, "posix"); +#ifdef HAVE_FORK + Jim_CreateCommand(interp, "os.fork", Jim_PosixForkCommand, NULL, NULL); +#endif + return JIM_OK; +} +int Jim_InitStaticExtensions(Jim_Interp *interp) +{ +extern int Jim_bootstrapInit(Jim_Interp *); +extern int Jim_aioInit(Jim_Interp *); +extern int Jim_readdirInit(Jim_Interp *); +extern int Jim_regexpInit(Jim_Interp *); +extern int Jim_fileInit(Jim_Interp *); +extern int Jim_globInit(Jim_Interp *); +extern int Jim_execInit(Jim_Interp *); +extern int Jim_posixInit(Jim_Interp *); +extern int Jim_clockInit(Jim_Interp *); +extern int Jim_arrayInit(Jim_Interp *); +extern int Jim_stdlibInit(Jim_Interp *); +extern int Jim_tclcompatInit(Jim_Interp *); +Jim_bootstrapInit(interp); +Jim_aioInit(interp); +Jim_readdirInit(interp); +Jim_regexpInit(interp); +Jim_fileInit(interp); +Jim_globInit(interp); +Jim_execInit(interp); +Jim_posixInit(interp); +Jim_clockInit(interp); +Jim_arrayInit(interp); +Jim_stdlibInit(interp); +Jim_tclcompatInit(interp); +return JIM_OK; +} +#ifndef JIM_TINY +#define JIM_OPTIMIZATION +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_EXECINFO_H +#include +#endif +#ifdef HAVE_CRT_EXTERNS_H +#include +#endif + + +#include + + + + + +#ifndef TCL_LIBRARY +#define TCL_LIBRARY "." +#endif +#ifndef TCL_PLATFORM_OS +#define TCL_PLATFORM_OS "unknown" +#endif +#ifndef TCL_PLATFORM_PLATFORM +#define TCL_PLATFORM_PLATFORM "unknown" +#endif +#ifndef TCL_PLATFORM_PATH_SEPARATOR +#define TCL_PLATFORM_PATH_SEPARATOR ":" +#endif + + + + + + + +#ifdef JIM_MAINTAINER +#define JIM_DEBUG_COMMAND +#define JIM_DEBUG_PANIC +#endif + + + +#define JIM_INTEGER_SPACE 24 + +#if defined(DEBUG_SHOW_SCRIPT) || defined(DEBUG_SHOW_SCRIPT_TOKENS) || defined(JIM_DEBUG_COMMAND) || defined(DEBUG_SHOW_SUBST) +static const char *jim_tt_name(int type); +#endif + +#ifdef JIM_DEBUG_PANIC +static void JimPanicDump(int fail_condition, const char *fmt, ...); +#define JimPanic(X) JimPanicDump X +#else +#define JimPanic(X) +#endif + +#ifdef JIM_OPTIMIZATION +static int JimIsWide(Jim_Obj *objPtr); +#define JIM_IF_OPTIM(X) X +#else +#define JIM_IF_OPTIM(X) +#endif + + +static char JimEmptyStringRep[] = ""; + +static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action); +static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr, + int flags); +static int Jim_ListIndices(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *const *indexv, int indexc, + Jim_Obj **resultObj, int flags); +static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands); +static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr); +static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr); +static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, + const char *prefix, const char *const *tablePtr, const char *name); +static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv); +static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr); +static int JimSign(jim_wide w); +static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen); +static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len); +static int JimSetNewVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr, Jim_VarVal *vv); +static Jim_VarVal *JimFindVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr); +static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +#define JIM_DICT_SUGAR 100 + + + + +#define JimWideValue(objPtr) (objPtr)->internalRep.wideValue + +#define JimObjTypeName(O) ((O)->typePtr ? (O)->typePtr->name : "none") + +static int utf8_tounicode_case(const char *s, int *uc, int upper) +{ + int l = utf8_tounicode(s, uc); + if (upper) { + *uc = utf8_upper(*uc); + } + return l; +} + +static Jim_Obj *JimPushInterpObjImpl(Jim_Obj **iop, Jim_Obj *no) +{ + Jim_Obj *io = *iop; + Jim_IncrRefCount(no); + *iop = no; + return io; +} + +#define JimPushInterpObj(IO, NO) JimPushInterpObjImpl(&(IO), NO) +#define JimPopInterpObj(I, IO, SO) do { Jim_DecrRefCount(I, IO); IO = SO; } while (0) + + +#define JIM_CHARSET_SCAN 2 +#define JIM_CHARSET_GLOB 0 + +static const char *JimCharsetMatch(const char *pattern, int plen, int c, int flags) +{ + int not = 0; + int pchar; + int match = 0; + int nocase = 0; + int n; + + if (flags & JIM_NOCASE) { + nocase++; + c = utf8_upper(c); + } + + if (flags & JIM_CHARSET_SCAN) { + if (*pattern == '^') { + not++; + pattern++; + plen--; + } + + + if (*pattern == ']') { + goto first; + } + } + + while (plen && *pattern != ']') { + + if (pattern[0] == '\\') { +first: + n = utf8_tounicode_case(pattern, &pchar, nocase); + pattern += n; + plen -= n; + } + else { + + int start; + int end; + + n = utf8_tounicode_case(pattern, &start, nocase); + pattern += n; + plen -= n; + if (pattern[0] == '-' && plen > 1) { + + n = 1 + utf8_tounicode_case(pattern + 1, &end, nocase); + pattern += n; + plen -= n; + + + if ((c >= start && c <= end) || (c >= end && c <= start)) { + match = 1; + } + continue; + } + pchar = start; + } + + if (pchar == c) { + match = 1; + } + } + if (not) { + match = !match; + } + + return match ? pattern : NULL; +} + + + +static int JimGlobMatch(const char *pattern, int plen, const char *string, int slen, int nocase) +{ + int c; + int pchar; + int n; + const char *p; + while (plen) { + switch (pattern[0]) { + case '*': + while (pattern[1] == '*' && plen) { + pattern++; + plen--; + } + pattern++; + plen--; + if (!plen) { + return 1; + } + while (slen) { + + if (JimGlobMatch(pattern, plen, string, slen, nocase)) + return 1; + n = utf8_tounicode(string, &c); + string += n; + slen -= n; + } + return 0; + + case '?': + n = utf8_tounicode(string, &c); + string += n; + slen -= n; + break; + + case '[': { + n = utf8_tounicode(string, &c); + string += n; + slen -= n; + p = JimCharsetMatch(pattern + 1, plen - 1, c, nocase ? JIM_NOCASE : 0); + if (!p) { + return 0; + } + plen -= p - pattern; + pattern = p; + + if (!plen) { + + continue; + } + break; + } + case '\\': + if (pattern[1]) { + pattern++; + plen--; + } + + default: + n = utf8_tounicode_case(string, &c, nocase); + string += n; + slen -= n; + utf8_tounicode_case(pattern, &pchar, nocase); + if (pchar != c) { + return 0; + } + break; + } + n = utf8_tounicode_case(pattern, &pchar, nocase); + pattern += n; + plen -= n; + if (!slen) { + while (*pattern == '*' && plen) { + pattern++; + plen--; + } + break; + } + } + if (!plen && !slen) { + return 1; + } + return 0; +} + +static int JimStringCompareUtf8(const char *s1, int l1, const char *s2, int l2, int nocase) +{ + int minlen = l1; + if (l2 < l1) { + minlen = l2; + } + while (minlen) { + int c1, c2; + s1 += utf8_tounicode_case(s1, &c1, nocase); + s2 += utf8_tounicode_case(s2, &c2, nocase); + if (c1 != c2) { + return JimSign(c1 - c2); + } + minlen--; + } + + if (l1 < l2) { + return -1; + } + if (l1 > l2) { + return 1; + } + return 0; +} + +static int JimStringFirst(const char *s1, int l1, const char *s2, int l2, int idx) +{ + int i; + int l1bytelen; + + if (!l1 || !l2 || l1 > l2) { + return -1; + } + if (idx < 0) + idx = 0; + s2 += utf8_index(s2, idx); + + l1bytelen = utf8_index(s1, l1); + + for (i = idx; i <= l2 - l1; i++) { + int c; + if (memcmp(s2, s1, l1bytelen) == 0) { + return i; + } + s2 += utf8_tounicode(s2, &c); + } + return -1; +} + +static int JimStringLast(const char *s1, int l1, const char *s2, int l2) +{ + const char *p; + + if (!l1 || !l2 || l1 > l2) + return -1; + + + for (p = s2 + l2 - 1; p != s2 - 1; p--) { + if (*p == *s1 && memcmp(s1, p, l1) == 0) { + return p - s2; + } + } + return -1; +} + +#ifdef JIM_UTF8 +static int JimStringLastUtf8(const char *s1, int l1, const char *s2, int l2) +{ + int n = JimStringLast(s1, utf8_index(s1, l1), s2, utf8_index(s2, l2)); + if (n > 0) { + n = utf8_strlen(s2, n); + } + return n; +} +#endif + +static int JimCheckConversion(const char *str, const char *endptr) +{ + if (str[0] == '\0' || str == endptr) { + return JIM_ERR; + } + + if (endptr[0] != '\0') { + while (*endptr) { + if (!isspace(UCHAR(*endptr))) { + return JIM_ERR; + } + endptr++; + } + } + return JIM_OK; +} + +static int JimNumberBase(const char *str, int *base, int *sign) +{ + int i = 0; + + *base = 0; + + while (isspace(UCHAR(str[i]))) { + i++; + } + + if (str[i] == '-') { + *sign = -1; + i++; + } + else { + if (str[i] == '+') { + i++; + } + *sign = 1; + } + + if (str[i] != '0') { + + return 0; + } + + + switch (str[i + 1]) { + case 'x': case 'X': *base = 16; break; + case 'o': case 'O': *base = 8; break; + case 'b': case 'B': *base = 2; break; + case 'd': case 'D': *base = 10; break; + default: return 0; + } + i += 2; + + if (str[i] != '-' && str[i] != '+' && !isspace(UCHAR(str[i]))) { + + return i; + } + + *base = 0; + return 0; +} + +static long jim_strtol(const char *str, char **endptr) +{ + int sign; + int base; + int i = JimNumberBase(str, &base, &sign); + + if (base != 0) { + long value = strtol(str + i, endptr, base); + if (endptr == NULL || *endptr != str + i) { + return value * sign; + } + } + + + return strtol(str, endptr, 10); +} + + +static jim_wide jim_strtoull(const char *str, char **endptr) +{ +#ifdef HAVE_LONG_LONG + int sign; + int base; + int i = JimNumberBase(str, &base, &sign); + + if (base != 0) { + jim_wide value = strtoull(str + i, endptr, base); + if (endptr == NULL || *endptr != str + i) { + return value * sign; + } + } + + + return strtoull(str, endptr, 10); +#else + return (unsigned long)jim_strtol(str, endptr); +#endif +} + +int Jim_StringToWide(const char *str, jim_wide * widePtr, int base) +{ + char *endptr; + + if (base) { + *widePtr = strtoull(str, &endptr, base); + } + else { + *widePtr = jim_strtoull(str, &endptr); + } + + return JimCheckConversion(str, endptr); +} + +int Jim_StringToDouble(const char *str, double *doublePtr) +{ + char *endptr; + + + errno = 0; + + *doublePtr = strtod(str, &endptr); + + return JimCheckConversion(str, endptr); +} + +static jim_wide JimPowWide(jim_wide b, jim_wide e) +{ + jim_wide res = 1; + + + if (b == 1) { + + return 1; + } + if (e < 0) { + if (b != -1) { + return 0; + } + e = -e; + } + while (e) + { + if (e & 1) { + res *= b; + } + e >>= 1; + b *= b; + } + return res; +} + +#ifdef JIM_DEBUG_PANIC +static void JimPanicDump(int condition, const char *fmt, ...) +{ + va_list ap; + + if (!condition) { + return; + } + + va_start(ap, fmt); + + fprintf(stderr, "\nJIM INTERPRETER PANIC: "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n\n"); + va_end(ap); + +#if defined(HAVE_BACKTRACE) + { + void *array[40]; + int size, i; + char **strings; + + size = backtrace(array, 40); + strings = backtrace_symbols(array, size); + for (i = 0; i < size; i++) + fprintf(stderr, "[backtrace] %s\n", strings[i]); + fprintf(stderr, "[backtrace] Include the above lines and the output\n"); + fprintf(stderr, "[backtrace] of 'nm ' in the bug report.\n"); + } +#endif + + exit(1); +} +#endif + + +void *JimDefaultAllocator(void *ptr, size_t size) +{ + if (size == 0) { + free(ptr); + return NULL; + } + else if (ptr) { + return realloc(ptr, size); + } + else { + return malloc(size); + } +} + +void *(*Jim_Allocator)(void *ptr, size_t size) = JimDefaultAllocator; + +char *Jim_StrDup(const char *s) +{ + return Jim_StrDupLen(s, strlen(s)); +} + +char *Jim_StrDupLen(const char *s, int l) +{ + char *copy = Jim_Alloc(l + 1); + + memcpy(copy, s, l); + copy[l] = 0; + return copy; +} + + +jim_wide Jim_GetTimeUsec(unsigned type) +{ + long long now; + struct timeval tv; + +#if defined(HAVE_CLOCK_GETTIME) + struct timespec ts; + + if (clock_gettime(type, &ts) == 0) { + now = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000; + } + else +#endif + { + gettimeofday(&tv, NULL); + + now = tv.tv_sec * 1000000LL + tv.tv_usec; + } + + return now; +} + + + + + +static void JimExpandHashTableIfNeeded(Jim_HashTable *ht); +static unsigned int JimHashTableNextPower(unsigned int size); +static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace); + + + + +unsigned int Jim_IntHashFunction(unsigned int key) +{ + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; +} + + +unsigned int Jim_GenHashFunction(const unsigned char *string, int length) +{ + unsigned result = 0; + string += length; + while (length--) { + result += (result << 3) + (unsigned char)(*--string); + } + return result; +} + + + +static void JimResetHashTable(Jim_HashTable *ht) +{ + ht->table = NULL; + ht->size = 0; + ht->sizemask = 0; + ht->used = 0; + ht->collisions = 0; +#ifdef JIM_RANDOMISE_HASH + ht->uniq = (rand() ^ time(NULL) ^ clock()); +#else + ht->uniq = 0; +#endif +} + +static void JimInitHashTableIterator(Jim_HashTable *ht, Jim_HashTableIterator *iter) +{ + iter->ht = ht; + iter->index = -1; + iter->entry = NULL; + iter->nextEntry = NULL; +} + + +int Jim_InitHashTable(Jim_HashTable *ht, const Jim_HashTableType *type, void *privDataPtr) +{ + JimResetHashTable(ht); + ht->type = type; + ht->privdata = privDataPtr; + return JIM_OK; +} + + +void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size) +{ + Jim_HashTable n; + unsigned int realsize = JimHashTableNextPower(size), i; + + if (size <= ht->used) + return; + + Jim_InitHashTable(&n, ht->type, ht->privdata); + n.size = realsize; + n.sizemask = realsize - 1; + n.table = Jim_Alloc(realsize * sizeof(Jim_HashEntry *)); + + n.uniq = ht->uniq; + + + memset(n.table, 0, realsize * sizeof(Jim_HashEntry *)); + + n.used = ht->used; + for (i = 0; ht->used > 0; i++) { + Jim_HashEntry *he, *nextHe; + + if (ht->table[i] == NULL) + continue; + + + he = ht->table[i]; + while (he) { + unsigned int h; + + nextHe = he->next; + + h = Jim_HashKey(ht, he->key) & n.sizemask; + he->next = n.table[h]; + n.table[h] = he; + ht->used--; + + he = nextHe; + } + } + assert(ht->used == 0); + Jim_Free(ht->table); + + + *ht = n; +} + +int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val) +{ + Jim_HashEntry *entry = JimInsertHashEntry(ht, key, 0);; + if (entry == NULL) + return JIM_ERR; + + + Jim_SetHashKey(ht, entry, key); + Jim_SetHashVal(ht, entry, val); + return JIM_OK; +} + + +int Jim_ReplaceHashEntry(Jim_HashTable *ht, const void *key, void *val) +{ + int existed; + Jim_HashEntry *entry; + + entry = JimInsertHashEntry(ht, key, 1); + if (entry->key) { + if (ht->type->valDestructor && ht->type->valDup) { + void *newval = ht->type->valDup(ht->privdata, val); + ht->type->valDestructor(ht->privdata, entry->u.val); + entry->u.val = newval; + } + else { + Jim_FreeEntryVal(ht, entry); + Jim_SetHashVal(ht, entry, val); + } + existed = 1; + } + else { + + Jim_SetHashKey(ht, entry, key); + Jim_SetHashVal(ht, entry, val); + existed = 0; + } + + return existed; +} + +int Jim_DeleteHashEntry(Jim_HashTable *ht, const void *key) +{ + if (ht->used) { + unsigned int h = Jim_HashKey(ht, key) & ht->sizemask; + Jim_HashEntry *prevHe = NULL; + Jim_HashEntry *he = ht->table[h]; + + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) { + + if (prevHe) + prevHe->next = he->next; + else + ht->table[h] = he->next; + ht->used--; + Jim_FreeEntryKey(ht, he); + Jim_FreeEntryVal(ht, he); + Jim_Free(he); + return JIM_OK; + } + prevHe = he; + he = he->next; + } + } + + return JIM_ERR; +} + +void Jim_ClearHashTable(Jim_HashTable *ht) +{ + unsigned int i; + + + for (i = 0; ht->used > 0; i++) { + Jim_HashEntry *he, *nextHe; + + he = ht->table[i]; + while (he) { + nextHe = he->next; + Jim_FreeEntryKey(ht, he); + Jim_FreeEntryVal(ht, he); + Jim_Free(he); + ht->used--; + he = nextHe; + } + ht->table[i] = NULL; + } +} + +int Jim_FreeHashTable(Jim_HashTable *ht) +{ + Jim_ClearHashTable(ht); + + Jim_Free(ht->table); + + JimResetHashTable(ht); + return JIM_OK; +} + +Jim_HashEntry *Jim_FindHashEntry(Jim_HashTable *ht, const void *key) +{ + Jim_HashEntry *he; + unsigned int h; + + if (ht->used == 0) + return NULL; + h = Jim_HashKey(ht, key) & ht->sizemask; + he = ht->table[h]; + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) + return he; + he = he->next; + } + return NULL; +} + +Jim_HashTableIterator *Jim_GetHashTableIterator(Jim_HashTable *ht) +{ + Jim_HashTableIterator *iter = Jim_Alloc(sizeof(*iter)); + JimInitHashTableIterator(ht, iter); + return iter; +} + +Jim_HashEntry *Jim_NextHashEntry(Jim_HashTableIterator *iter) +{ + while (1) { + if (iter->entry == NULL) { + iter->index++; + if (iter->index >= (signed)iter->ht->size) + break; + iter->entry = iter->ht->table[iter->index]; + } + else { + iter->entry = iter->nextEntry; + } + if (iter->entry) { + iter->nextEntry = iter->entry->next; + return iter->entry; + } + } + return NULL; +} + + + + +static void JimExpandHashTableIfNeeded(Jim_HashTable *ht) +{ + if (ht->size == 0) + Jim_ExpandHashTable(ht, JIM_HT_INITIAL_SIZE); + if (ht->size == ht->used) + Jim_ExpandHashTable(ht, ht->size * 2); +} + + +static unsigned int JimHashTableNextPower(unsigned int size) +{ + unsigned int i = JIM_HT_INITIAL_SIZE; + + if (size >= 2147483648U) + return 2147483648U; + while (1) { + if (i >= size) + return i; + i *= 2; + } +} + +static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace) +{ + unsigned int h; + Jim_HashEntry *he; + + + JimExpandHashTableIfNeeded(ht); + + + h = Jim_HashKey(ht, key) & ht->sizemask; + + he = ht->table[h]; + while (he) { + if (Jim_CompareHashKeys(ht, key, he->key)) + return replace ? he : NULL; + he = he->next; + } + + + he = Jim_Alloc(sizeof(*he)); + he->next = ht->table[h]; + ht->table[h] = he; + ht->used++; + he->key = NULL; + + return he; +} + + + +static unsigned int JimStringCopyHTHashFunction(const void *key) +{ + return Jim_GenHashFunction(key, strlen(key)); +} + +static void *JimStringCopyHTDup(void *privdata, const void *key) +{ + return Jim_StrDup(key); +} + +static int JimStringCopyHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + return strcmp(key1, key2) == 0; +} + +static void JimStringCopyHTKeyDestructor(void *privdata, void *key) +{ + Jim_Free(key); +} + +static const Jim_HashTableType JimPackageHashTableType = { + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + NULL +}; + +typedef struct AssocDataValue +{ + Jim_InterpDeleteProc *delProc; + void *data; +} AssocDataValue; + +static void JimAssocDataHashTableValueDestructor(void *privdata, void *data) +{ + AssocDataValue *assocPtr = (AssocDataValue *) data; + + if (assocPtr->delProc != NULL) + assocPtr->delProc((Jim_Interp *)privdata, assocPtr->data); + Jim_Free(data); +} + +static const Jim_HashTableType JimAssocDataHashTableType = { + JimStringCopyHTHashFunction, + JimStringCopyHTDup, + NULL, + JimStringCopyHTKeyCompare, + JimStringCopyHTKeyDestructor, + JimAssocDataHashTableValueDestructor +}; + +void Jim_InitStack(Jim_Stack *stack) +{ + stack->len = 0; + stack->maxlen = 0; + stack->vector = NULL; +} + +void Jim_FreeStack(Jim_Stack *stack) +{ + Jim_Free(stack->vector); +} + +int Jim_StackLen(Jim_Stack *stack) +{ + return stack->len; +} + +void Jim_StackPush(Jim_Stack *stack, void *element) +{ + int neededLen = stack->len + 1; + + if (neededLen > stack->maxlen) { + stack->maxlen = neededLen < 20 ? 20 : neededLen * 2; + stack->vector = Jim_Realloc(stack->vector, sizeof(void *) * stack->maxlen); + } + stack->vector[stack->len] = element; + stack->len++; +} + +void *Jim_StackPop(Jim_Stack *stack) +{ + if (stack->len == 0) + return NULL; + stack->len--; + return stack->vector[stack->len]; +} + +void *Jim_StackPeek(Jim_Stack *stack) +{ + if (stack->len == 0) + return NULL; + return stack->vector[stack->len - 1]; +} + +void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc) (void *ptr)) +{ + int i; + + for (i = 0; i < stack->len; i++) + freeFunc(stack->vector[i]); +} + + + +#define JIM_TT_NONE 0 +#define JIM_TT_STR 1 +#define JIM_TT_ESC 2 +#define JIM_TT_VAR 3 +#define JIM_TT_DICTSUGAR 4 +#define JIM_TT_CMD 5 + +#define JIM_TT_SEP 6 +#define JIM_TT_EOL 7 +#define JIM_TT_EOF 8 + +#define JIM_TT_LINE 9 +#define JIM_TT_WORD 10 + + +#define JIM_TT_SUBEXPR_START 11 +#define JIM_TT_SUBEXPR_END 12 +#define JIM_TT_SUBEXPR_COMMA 13 +#define JIM_TT_EXPR_INT 14 +#define JIM_TT_EXPR_DOUBLE 15 +#define JIM_TT_EXPR_BOOLEAN 16 + +#define JIM_TT_EXPRSUGAR 17 + + +#define JIM_TT_EXPR_OP 20 + +#define TOKEN_IS_SEP(type) (type >= JIM_TT_SEP && type <= JIM_TT_EOF) + +#define TOKEN_IS_EXPR_START(type) (type == JIM_TT_NONE || type == JIM_TT_SUBEXPR_START || type == JIM_TT_SUBEXPR_COMMA) + +#define TOKEN_IS_EXPR_OP(type) (type >= JIM_TT_EXPR_OP) + +struct JimParseMissing { + int ch; + int line; +}; + +struct JimParserCtx +{ + const char *p; + int len; + int linenr; + const char *tstart; + const char *tend; + int tline; + int tt; + int eof; + int inquote; + int comment; + struct JimParseMissing missing; + const char *errmsg; +}; + +static int JimParseScript(struct JimParserCtx *pc); +static int JimParseSep(struct JimParserCtx *pc); +static int JimParseEol(struct JimParserCtx *pc); +static int JimParseCmd(struct JimParserCtx *pc); +static int JimParseQuote(struct JimParserCtx *pc); +static int JimParseVar(struct JimParserCtx *pc); +static int JimParseBrace(struct JimParserCtx *pc); +static int JimParseStr(struct JimParserCtx *pc); +static int JimParseComment(struct JimParserCtx *pc); +static void JimParseSubCmd(struct JimParserCtx *pc); +static int JimParseSubQuote(struct JimParserCtx *pc); +static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc); + +static void JimParserInit(struct JimParserCtx *pc, const char *prg, int len, int linenr) +{ + pc->p = prg; + pc->len = len; + pc->tstart = NULL; + pc->tend = NULL; + pc->tline = 0; + pc->tt = JIM_TT_NONE; + pc->eof = 0; + pc->inquote = 0; + pc->linenr = linenr; + pc->comment = 1; + pc->missing.ch = ' '; + pc->missing.line = linenr; +} + +static int JimParseScript(struct JimParserCtx *pc) +{ + while (1) { + if (!pc->len) { + pc->tstart = pc->p; + pc->tend = pc->p - 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EOL; + if (pc->inquote) { + pc->missing.ch = '"'; + } + pc->eof = 1; + return JIM_OK; + } + switch (*(pc->p)) { + case '\\': + if (*(pc->p + 1) == '\n' && !pc->inquote) { + return JimParseSep(pc); + } + pc->comment = 0; + return JimParseStr(pc); + case ' ': + case '\t': + case '\r': + case '\f': + if (!pc->inquote) + return JimParseSep(pc); + pc->comment = 0; + return JimParseStr(pc); + case '\n': + case ';': + pc->comment = 1; + if (!pc->inquote) + return JimParseEol(pc); + return JimParseStr(pc); + case '[': + pc->comment = 0; + return JimParseCmd(pc); + case '$': + pc->comment = 0; + if (JimParseVar(pc) == JIM_ERR) { + + pc->tstart = pc->tend = pc->p++; + pc->len--; + pc->tt = JIM_TT_ESC; + } + return JIM_OK; + case '#': + if (pc->comment) { + JimParseComment(pc); + continue; + } + return JimParseStr(pc); + default: + pc->comment = 0; + return JimParseStr(pc); + } + return JIM_OK; + } +} + +static int JimParseSep(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p)) || (*pc->p == '\\' && *(pc->p + 1) == '\n')) { + if (*pc->p == '\n') { + break; + } + if (*pc->p == '\\') { + pc->p++; + pc->len--; + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_SEP; + return JIM_OK; +} + +static int JimParseEol(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p)) || *pc->p == ';') { + if (*pc->p == '\n') + pc->linenr++; + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_EOL; + return JIM_OK; +} + + +static void JimParseSubBrace(struct JimParserCtx *pc) +{ + int level = 1; + + + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + } + break; + + case '{': + level++; + break; + + case '}': + if (--level == 0) { + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return; + } + break; + + case '\n': + pc->linenr++; + break; + } + pc->p++; + pc->len--; + } + pc->missing.ch = '{'; + pc->missing.line = pc->tline; + pc->tend = pc->p - 1; +} + +static int JimParseSubQuote(struct JimParserCtx *pc) +{ + int tt = JIM_TT_STR; + int line = pc->tline; + + + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + tt = JIM_TT_ESC; + } + break; + + case '"': + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return tt; + + case '[': + JimParseSubCmd(pc); + tt = JIM_TT_ESC; + continue; + + case '\n': + pc->linenr++; + break; + + case '$': + tt = JIM_TT_ESC; + break; + } + pc->p++; + pc->len--; + } + pc->missing.ch = '"'; + pc->missing.line = line; + pc->tend = pc->p - 1; + return tt; +} + +static void JimParseSubCmd(struct JimParserCtx *pc) +{ + int level = 1; + int startofword = 1; + int line = pc->tline; + + + pc->p++; + pc->len--; + while (pc->len) { + switch (*pc->p) { + case '\\': + if (pc->len > 1) { + if (*++pc->p == '\n') { + pc->linenr++; + } + pc->len--; + } + break; + + case '[': + level++; + break; + + case ']': + if (--level == 0) { + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return; + } + break; + + case '"': + if (startofword) { + JimParseSubQuote(pc); + if (pc->missing.ch == '"') { + return; + } + continue; + } + break; + + case '{': + JimParseSubBrace(pc); + startofword = 0; + continue; + + case '\n': + pc->linenr++; + break; + } + startofword = isspace(UCHAR(*pc->p)); + pc->p++; + pc->len--; + } + pc->missing.ch = '['; + pc->missing.line = line; + pc->tend = pc->p - 1; +} + +static int JimParseBrace(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + JimParseSubBrace(pc); + return JIM_OK; +} + +static int JimParseCmd(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JIM_TT_CMD; + JimParseSubCmd(pc); + return JIM_OK; +} + +static int JimParseQuote(struct JimParserCtx *pc) +{ + pc->tstart = pc->p + 1; + pc->tline = pc->linenr; + pc->tt = JimParseSubQuote(pc); + return JIM_OK; +} + +static int JimParseVar(struct JimParserCtx *pc) +{ + + pc->p++; + pc->len--; + +#ifdef EXPRSUGAR_BRACKET + if (*pc->p == '[') { + + JimParseCmd(pc); + pc->tt = JIM_TT_EXPRSUGAR; + return JIM_OK; + } +#endif + + pc->tstart = pc->p; + pc->tt = JIM_TT_VAR; + pc->tline = pc->linenr; + + if (*pc->p == '{') { + pc->tstart = ++pc->p; + pc->len--; + + while (pc->len && *pc->p != '}') { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + if (pc->len) { + pc->p++; + pc->len--; + } + } + else { + while (1) { + + if (pc->p[0] == ':' && pc->p[1] == ':') { + while (*pc->p == ':') { + pc->p++; + pc->len--; + } + continue; + } + if (isalnum(UCHAR(*pc->p)) || *pc->p == '_' || UCHAR(*pc->p) >= 0x80) { + pc->p++; + pc->len--; + continue; + } + break; + } + + if (*pc->p == '(') { + int count = 1; + const char *paren = NULL; + + pc->tt = JIM_TT_DICTSUGAR; + + while (count && pc->len) { + pc->p++; + pc->len--; + if (*pc->p == '\\' && pc->len >= 1) { + pc->p++; + pc->len--; + } + else if (*pc->p == '(') { + count++; + } + else if (*pc->p == ')') { + paren = pc->p; + count--; + } + } + if (count == 0) { + pc->p++; + pc->len--; + } + else if (paren) { + + paren++; + pc->len += (pc->p - paren); + pc->p = paren; + } +#ifndef EXPRSUGAR_BRACKET + if (*pc->tstart == '(') { + pc->tt = JIM_TT_EXPRSUGAR; + } +#endif + } + pc->tend = pc->p - 1; + } + if (pc->tstart == pc->p) { + pc->p--; + pc->len++; + return JIM_ERR; + } + return JIM_OK; +} + +static int JimParseStr(struct JimParserCtx *pc) +{ + if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL || + pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) { + + if (*pc->p == '{') { + return JimParseBrace(pc); + } + if (*pc->p == '"') { + pc->inquote = 1; + pc->p++; + pc->len--; + + pc->missing.line = pc->tline; + } + } + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (1) { + if (pc->len == 0) { + if (pc->inquote) { + pc->missing.ch = '"'; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + switch (*pc->p) { + case '\\': + if (!pc->inquote && *(pc->p + 1) == '\n') { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + if (pc->len >= 2) { + if (*(pc->p + 1) == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + else if (pc->len == 1) { + + pc->missing.ch = '\\'; + } + break; + case '(': + + if (pc->len > 1 && pc->p[1] != '$') { + break; + } + + case ')': + + if (*pc->p == '(' || pc->tt == JIM_TT_VAR) { + if (pc->p == pc->tstart) { + + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + break; + + case '$': + case '[': + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + case ';': + if (!pc->inquote) { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + return JIM_OK; + } + else if (*pc->p == '\n') { + pc->linenr++; + } + break; + case '"': + if (pc->inquote) { + pc->tend = pc->p - 1; + pc->tt = JIM_TT_ESC; + pc->p++; + pc->len--; + pc->inquote = 0; + return JIM_OK; + } + break; + } + pc->p++; + pc->len--; + } + return JIM_OK; +} + +static int JimParseComment(struct JimParserCtx *pc) +{ + while (*pc->p) { + if (*pc->p == '\\') { + pc->p++; + pc->len--; + if (pc->len == 0) { + pc->missing.ch = '\\'; + return JIM_OK; + } + if (*pc->p == '\n') { + pc->linenr++; + } + } + else if (*pc->p == '\n') { + pc->p++; + pc->len--; + pc->linenr++; + break; + } + pc->p++; + pc->len--; + } + return JIM_OK; +} + + +static int xdigitval(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int odigitval(int c) +{ + if (c >= '0' && c <= '7') + return c - '0'; + return -1; +} + +static int JimEscape(char *dest, const char *s, int slen) +{ + char *p = dest; + int i, len; + + for (i = 0; i < slen; i++) { + switch (s[i]) { + case '\\': + switch (s[i + 1]) { + case 'a': + *p++ = 0x7; + i++; + break; + case 'b': + *p++ = 0x8; + i++; + break; + case 'f': + *p++ = 0xc; + i++; + break; + case 'n': + *p++ = 0xa; + i++; + break; + case 'r': + *p++ = 0xd; + i++; + break; + case 't': + *p++ = 0x9; + i++; + break; + case 'u': + case 'U': + case 'x': + { + unsigned val = 0; + int k; + int maxchars = 2; + + i++; + + if (s[i] == 'U') { + maxchars = 8; + } + else if (s[i] == 'u') { + if (s[i + 1] == '{') { + maxchars = 6; + i++; + } + else { + maxchars = 4; + } + } + + for (k = 0; k < maxchars; k++) { + int c = xdigitval(s[i + k + 1]); + if (c == -1) { + break; + } + val = (val << 4) | c; + } + + if (s[i] == '{') { + if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') { + + i--; + k = 0; + } + else { + + k++; + } + } + if (k) { + + if (s[i] == 'x') { + *p++ = val; + } + else { + p += utf8_fromunicode(p, val); + } + i += k; + break; + } + + *p++ = s[i]; + } + break; + case 'v': + *p++ = 0xb; + i++; + break; + case '\0': + *p++ = '\\'; + i++; + break; + case '\n': + + *p++ = ' '; + do { + i++; + } while (s[i + 1] == ' ' || s[i + 1] == '\t'); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + + { + int val = 0; + int c = odigitval(s[i + 1]); + + val = c; + c = odigitval(s[i + 2]); + if (c == -1) { + *p++ = val; + i++; + break; + } + val = (val * 8) + c; + c = odigitval(s[i + 3]); + if (c == -1) { + *p++ = val; + i += 2; + break; + } + val = (val * 8) + c; + *p++ = val; + i += 3; + } + break; + default: + *p++ = s[i + 1]; + i++; + break; + } + break; + default: + *p++ = s[i]; + break; + } + } + len = p - dest; + *p = '\0'; + return len; +} + +static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc) +{ + const char *start, *end; + char *token; + int len; + + start = pc->tstart; + end = pc->tend; + len = (end - start) + 1; + if (len < 0) { + len = 0; + } + token = Jim_Alloc(len + 1); + if (pc->tt != JIM_TT_ESC) { + + memcpy(token, start, len); + token[len] = '\0'; + } + else { + + len = JimEscape(token, start, len); + } + + return Jim_NewStringObjNoAlloc(interp, token, len); +} + +static int JimParseListSep(struct JimParserCtx *pc); +static int JimParseListStr(struct JimParserCtx *pc); +static int JimParseListQuote(struct JimParserCtx *pc); + +static int JimParseList(struct JimParserCtx *pc) +{ + if (isspace(UCHAR(*pc->p))) { + return JimParseListSep(pc); + } + switch (*pc->p) { + case '"': + return JimParseListQuote(pc); + + case '{': + return JimParseBrace(pc); + + default: + if (pc->len) { + return JimParseListStr(pc); + } + break; + } + + pc->tstart = pc->tend = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return JIM_OK; +} + +static int JimParseListSep(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + while (isspace(UCHAR(*pc->p))) { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = JIM_TT_SEP; + return JIM_OK; +} + +static int JimParseListQuote(struct JimParserCtx *pc) +{ + pc->p++; + pc->len--; + + pc->tstart = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + + while (pc->len) { + switch (*pc->p) { + case '\\': + pc->tt = JIM_TT_ESC; + if (--pc->len == 0) { + + pc->tend = pc->p; + return JIM_OK; + } + pc->p++; + break; + case '\n': + pc->linenr++; + break; + case '"': + pc->tend = pc->p - 1; + pc->p++; + pc->len--; + return JIM_OK; + } + pc->p++; + pc->len--; + } + + pc->tend = pc->p - 1; + return JIM_OK; +} + +static int JimParseListStr(struct JimParserCtx *pc) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + pc->tt = JIM_TT_STR; + + while (pc->len) { + if (isspace(UCHAR(*pc->p))) { + pc->tend = pc->p - 1; + return JIM_OK; + } + if (*pc->p == '\\') { + if (--pc->len == 0) { + + pc->tend = pc->p; + return JIM_OK; + } + pc->tt = JIM_TT_ESC; + pc->p++; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + return JIM_OK; +} + + + +Jim_Obj *Jim_NewObj(Jim_Interp *interp) +{ + Jim_Obj *objPtr; + + + if (interp->freeList != NULL) { + + objPtr = interp->freeList; + interp->freeList = objPtr->nextObjPtr; + } + else { + + objPtr = Jim_Alloc(sizeof(*objPtr)); + } + + objPtr->refCount = 0; + + + objPtr->prevObjPtr = NULL; + objPtr->nextObjPtr = interp->liveList; + if (interp->liveList) + interp->liveList->prevObjPtr = objPtr; + interp->liveList = objPtr; + + return objPtr; +} + +void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr) +{ + + JimPanic((objPtr->refCount != 0, "!!!Object %p freed with bad refcount %d, type=%s", objPtr, + objPtr->refCount, objPtr->typePtr ? objPtr->typePtr->name : "")); + + + Jim_FreeIntRep(interp, objPtr); + + if (objPtr->bytes != NULL) { + if (objPtr->bytes != JimEmptyStringRep) + Jim_Free(objPtr->bytes); + } + + if (objPtr->prevObjPtr) + objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr; + if (objPtr->nextObjPtr) + objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr; + if (interp->liveList == objPtr) + interp->liveList = objPtr->nextObjPtr; +#ifdef JIM_DISABLE_OBJECT_POOL + Jim_Free(objPtr); +#else + + objPtr->prevObjPtr = NULL; + objPtr->nextObjPtr = interp->freeList; + if (interp->freeList) + interp->freeList->prevObjPtr = objPtr; + interp->freeList = objPtr; + objPtr->refCount = -1; +#endif +} + + +void Jim_InvalidateStringRep(Jim_Obj *objPtr) +{ + if (objPtr->bytes != NULL) { + if (objPtr->bytes != JimEmptyStringRep) + Jim_Free(objPtr->bytes); + } + objPtr->bytes = NULL; +} + + +Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *dupPtr; + + dupPtr = Jim_NewObj(interp); + if (objPtr->bytes == NULL) { + + dupPtr->bytes = NULL; + } + else if (objPtr->length == 0) { + dupPtr->bytes = JimEmptyStringRep; + dupPtr->length = 0; + dupPtr->typePtr = NULL; + return dupPtr; + } + else { + dupPtr->bytes = Jim_Alloc(objPtr->length + 1); + dupPtr->length = objPtr->length; + + memcpy(dupPtr->bytes, objPtr->bytes, objPtr->length + 1); + } + + + dupPtr->typePtr = objPtr->typePtr; + if (objPtr->typePtr != NULL) { + if (objPtr->typePtr->dupIntRepProc == NULL) { + dupPtr->internalRep = objPtr->internalRep; + } + else { + + objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr); + } + } + return dupPtr; +} + +const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr) +{ + if (objPtr->bytes == NULL) { + + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + if (lenPtr) + *lenPtr = objPtr->length; + return objPtr->bytes; +} + + +int Jim_Length(Jim_Obj *objPtr) +{ + if (objPtr->bytes == NULL) { + + Jim_GetString(objPtr, NULL); + } + return objPtr->length; +} + + +const char *Jim_String(Jim_Obj *objPtr) +{ + if (objPtr->bytes == NULL) { + + Jim_GetString(objPtr, NULL); + } + return objPtr->bytes; +} + +static void JimSetStringBytes(Jim_Obj *objPtr, const char *str) +{ + objPtr->bytes = Jim_StrDup(str); + objPtr->length = strlen(str); +} + +static void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); + +static const Jim_ObjType dictSubstObjType = { + "dict-substitution", + FreeDictSubstInternalRep, + DupDictSubstInternalRep, + NULL, + JIM_TYPE_NONE, +}; + +static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); + +static const Jim_ObjType interpolatedObjType = { + "interpolated", + FreeInterpolatedInternalRep, + DupInterpolatedInternalRep, + NULL, + JIM_TYPE_NONE, +}; + +static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); +} + +static void DupInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + + dupPtr->internalRep = srcPtr->internalRep; + + Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.indexObjPtr); +} + +static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static int SetStringFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType stringObjType = { + "string", + NULL, + DupStringInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + + dupPtr->internalRep.strValue.maxLength = srcPtr->length; + dupPtr->internalRep.strValue.charLength = srcPtr->internalRep.strValue.charLength; +} + +static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &stringObjType) { + + if (objPtr->bytes == NULL) { + + JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); + objPtr->typePtr->updateStringProc(objPtr); + } + + Jim_FreeIntRep(interp, objPtr); + + objPtr->typePtr = &stringObjType; + objPtr->internalRep.strValue.maxLength = objPtr->length; + + objPtr->internalRep.strValue.charLength = -1; + } + return JIM_OK; +} + +int Jim_Utf8Length(Jim_Interp *interp, Jim_Obj *objPtr) +{ +#ifdef JIM_UTF8 + SetStringFromAny(interp, objPtr); + + if (objPtr->internalRep.strValue.charLength < 0) { + objPtr->internalRep.strValue.charLength = utf8_strlen(objPtr->bytes, objPtr->length); + } + return objPtr->internalRep.strValue.charLength; +#else + return Jim_Length(objPtr); +#endif +} + + +Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len) +{ + Jim_Obj *objPtr = Jim_NewObj(interp); + + + if (len == -1) + len = strlen(s); + + if (len == 0) { + objPtr->bytes = JimEmptyStringRep; + } + else { + objPtr->bytes = Jim_StrDupLen(s, len); + } + objPtr->length = len; + + + objPtr->typePtr = NULL; + return objPtr; +} + + +Jim_Obj *Jim_NewStringObjUtf8(Jim_Interp *interp, const char *s, int charlen) +{ +#ifdef JIM_UTF8 + + int bytelen = utf8_index(s, charlen); + + Jim_Obj *objPtr = Jim_NewStringObj(interp, s, bytelen); + + + objPtr->typePtr = &stringObjType; + objPtr->internalRep.strValue.maxLength = bytelen; + objPtr->internalRep.strValue.charLength = charlen; + + return objPtr; +#else + return Jim_NewStringObj(interp, s, charlen); +#endif +} + +Jim_Obj *Jim_NewStringObjNoAlloc(Jim_Interp *interp, char *s, int len) +{ + Jim_Obj *objPtr = Jim_NewObj(interp); + + objPtr->bytes = s; + objPtr->length = (len == -1) ? strlen(s) : len; + objPtr->typePtr = NULL; + return objPtr; +} + +static void StringAppendString(Jim_Obj *objPtr, const char *str, int len) +{ + int needlen; + + if (len == -1) + len = strlen(str); + needlen = objPtr->length + len; + if (objPtr->internalRep.strValue.maxLength < needlen || + objPtr->internalRep.strValue.maxLength == 0) { + needlen *= 2; + + if (needlen < 7) { + needlen = 7; + } + if (objPtr->bytes == JimEmptyStringRep) { + objPtr->bytes = Jim_Alloc(needlen + 1); + } + else { + objPtr->bytes = Jim_Realloc(objPtr->bytes, needlen + 1); + } + objPtr->internalRep.strValue.maxLength = needlen; + } + memcpy(objPtr->bytes + objPtr->length, str, len); + objPtr->bytes[objPtr->length + len] = '\0'; + + if (objPtr->internalRep.strValue.charLength >= 0) { + + objPtr->internalRep.strValue.charLength += utf8_strlen(objPtr->bytes + objPtr->length, len); + } + objPtr->length += len; +} + +void Jim_AppendString(Jim_Interp *interp, Jim_Obj *objPtr, const char *str, int len) +{ + JimPanic((Jim_IsShared(objPtr), "Jim_AppendString called with shared object")); + SetStringFromAny(interp, objPtr); + StringAppendString(objPtr, str, len); +} + +void Jim_AppendObj(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *appendObjPtr) +{ + int len; + const char *str = Jim_GetString(appendObjPtr, &len); + Jim_AppendString(interp, objPtr, str, len); +} + +void Jim_AppendStrings(Jim_Interp *interp, Jim_Obj *objPtr, ...) +{ + va_list ap; + + SetStringFromAny(interp, objPtr); + va_start(ap, objPtr); + while (1) { + const char *s = va_arg(ap, const char *); + + if (s == NULL) + break; + Jim_AppendString(interp, objPtr, s, -1); + } + va_end(ap); +} + +int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr) +{ + if (aObjPtr == bObjPtr) { + return 1; + } + else { + int Alen, Blen; + const char *sA = Jim_GetString(aObjPtr, &Alen); + const char *sB = Jim_GetString(bObjPtr, &Blen); + + return Alen == Blen && memcmp(sA, sB, Alen) == 0; + } +} + +int Jim_StringMatchObj(Jim_Interp *interp, Jim_Obj *patternObjPtr, Jim_Obj *objPtr, int nocase) +{ + int plen, slen; + const char *pattern = Jim_GetString(patternObjPtr, &plen); + const char *string = Jim_GetString(objPtr, &slen); + return JimGlobMatch(pattern, plen, string, slen, nocase); +} + +int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *secondObjPtr, int nocase) +{ + const char *s1 = Jim_String(firstObjPtr); + int l1 = Jim_Utf8Length(interp, firstObjPtr); + const char *s2 = Jim_String(secondObjPtr); + int l2 = Jim_Utf8Length(interp, secondObjPtr); + return JimStringCompareUtf8(s1, l1, s2, l2, nocase); +} + +static int JimRelToAbsIndex(int len, int idx) +{ + if (idx < 0 && idx > -INT_MAX) + return len + idx; + return idx; +} + +static void JimRelToAbsRange(int len, int *firstPtr, int *lastPtr, int *rangeLenPtr) +{ + int rangeLen; + + if (*firstPtr > *lastPtr) { + rangeLen = 0; + } + else { + rangeLen = *lastPtr - *firstPtr + 1; + if (rangeLen) { + if (*firstPtr < 0) { + rangeLen += *firstPtr; + *firstPtr = 0; + } + if (*lastPtr >= len) { + rangeLen -= (*lastPtr - (len - 1)); + *lastPtr = len - 1; + } + } + } + if (rangeLen < 0) + rangeLen = 0; + + *rangeLenPtr = rangeLen; +} + +static int JimStringGetRange(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr, + int len, int *first, int *last, int *range) +{ + if (Jim_GetIndex(interp, firstObjPtr, first) != JIM_OK) { + return JIM_ERR; + } + if (Jim_GetIndex(interp, lastObjPtr, last) != JIM_OK) { + return JIM_ERR; + } + *first = JimRelToAbsIndex(len, *first); + *last = JimRelToAbsIndex(len, *last); + JimRelToAbsRange(len, first, last, range); + return JIM_OK; +} + +Jim_Obj *Jim_StringByteRangeObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr) +{ + int first, last; + const char *str; + int rangeLen; + int bytelen; + + str = Jim_GetString(strObjPtr, &bytelen); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, bytelen, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (first == 0 && rangeLen == bytelen) { + return strObjPtr; + } + return Jim_NewStringObj(interp, str + first, rangeLen); +} + +Jim_Obj *Jim_StringRangeObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr) +{ +#ifdef JIM_UTF8 + int first, last; + const char *str; + int len, rangeLen; + int bytelen; + + str = Jim_GetString(strObjPtr, &bytelen); + len = Jim_Utf8Length(interp, strObjPtr); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (first == 0 && rangeLen == len) { + return strObjPtr; + } + if (len == bytelen) { + + return Jim_NewStringObj(interp, str + first, rangeLen); + } + return Jim_NewStringObjUtf8(interp, str + utf8_index(str, first), rangeLen); +#else + return Jim_StringByteRangeObj(interp, strObjPtr, firstObjPtr, lastObjPtr); +#endif +} + +Jim_Obj *JimStringReplaceObj(Jim_Interp *interp, + Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr, Jim_Obj *newStrObj) +{ + int first, last; + const char *str; + int len, rangeLen; + Jim_Obj *objPtr; + + len = Jim_Utf8Length(interp, strObjPtr); + + if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) { + return NULL; + } + + if (last < first) { + return strObjPtr; + } + + str = Jim_String(strObjPtr); + + + objPtr = Jim_NewStringObjUtf8(interp, str, first); + + + if (newStrObj) { + Jim_AppendObj(interp, objPtr, newStrObj); + } + + + Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1); + + return objPtr; +} + +static void JimStrCopyUpperLower(char *dest, const char *str, int uc) +{ + while (*str) { + int c; + str += utf8_tounicode(str, &c); + dest += utf8_getchars(dest, uc ? utf8_upper(c) : utf8_lower(c)); + } + *dest = 0; +} + +static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf; + int len; + const char *str; + + str = Jim_GetString(strObjPtr, &len); + +#ifdef JIM_UTF8 + len *= 2; +#endif + buf = Jim_Alloc(len + 1); + JimStrCopyUpperLower(buf, str, 0); + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf; + const char *str; + int len; + + str = Jim_GetString(strObjPtr, &len); + +#ifdef JIM_UTF8 + len *= 2; +#endif + buf = Jim_Alloc(len + 1); + JimStrCopyUpperLower(buf, str, 1); + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +static Jim_Obj *JimStringToTitle(Jim_Interp *interp, Jim_Obj *strObjPtr) +{ + char *buf, *p; + int len; + int c; + const char *str; + + str = Jim_GetString(strObjPtr, &len); + +#ifdef JIM_UTF8 + len *= 2; +#endif + buf = p = Jim_Alloc(len + 1); + + str += utf8_tounicode(str, &c); + p += utf8_getchars(p, utf8_title(c)); + + JimStrCopyUpperLower(p, str, 0); + + return Jim_NewStringObjNoAlloc(interp, buf, -1); +} + +static const char *utf8_memchr(const char *str, int len, int c) +{ +#ifdef JIM_UTF8 + while (len) { + int sc; + int n = utf8_tounicode(str, &sc); + if (sc == c) { + return str; + } + str += n; + len -= n; + } + return NULL; +#else + return memchr(str, c, len); +#endif +} + +static const char *JimFindTrimLeft(const char *str, int len, const char *trimchars, int trimlen) +{ + while (len) { + int c; + int n = utf8_tounicode(str, &c); + + if (utf8_memchr(trimchars, trimlen, c) == NULL) { + + break; + } + str += n; + len -= n; + } + return str; +} + +static const char *JimFindTrimRight(const char *str, int len, const char *trimchars, int trimlen) +{ + str += len; + + while (len) { + int c; + int n = utf8_prev_len(str, len); + + len -= n; + str -= n; + + n = utf8_tounicode(str, &c); + + if (utf8_memchr(trimchars, trimlen, c) == NULL) { + return str + n; + } + } + + return NULL; +} + +static const char default_trim_chars[] = " \t\n\r"; + +static int default_trim_chars_len = sizeof(default_trim_chars); + +static Jim_Obj *JimStringTrimLeft(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + int len; + const char *str = Jim_GetString(strObjPtr, &len); + const char *trimchars = default_trim_chars; + int trimcharslen = default_trim_chars_len; + const char *newstr; + + if (trimcharsObjPtr) { + trimchars = Jim_GetString(trimcharsObjPtr, &trimcharslen); + } + + newstr = JimFindTrimLeft(str, len, trimchars, trimcharslen); + if (newstr == str) { + return strObjPtr; + } + + return Jim_NewStringObj(interp, newstr, len - (newstr - str)); +} + +static Jim_Obj *JimStringTrimRight(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + int len; + const char *trimchars = default_trim_chars; + int trimcharslen = default_trim_chars_len; + const char *nontrim; + + if (trimcharsObjPtr) { + trimchars = Jim_GetString(trimcharsObjPtr, &trimcharslen); + } + + SetStringFromAny(interp, strObjPtr); + + len = Jim_Length(strObjPtr); + nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen); + + if (nontrim == NULL) { + + return Jim_NewEmptyStringObj(interp); + } + if (nontrim == strObjPtr->bytes + len) { + + return strObjPtr; + } + + if (Jim_IsShared(strObjPtr)) { + strObjPtr = Jim_NewStringObj(interp, strObjPtr->bytes, (nontrim - strObjPtr->bytes)); + } + else { + + strObjPtr->bytes[nontrim - strObjPtr->bytes] = 0; + strObjPtr->length = (nontrim - strObjPtr->bytes); + } + + return strObjPtr; +} + +static Jim_Obj *JimStringTrim(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *trimcharsObjPtr) +{ + + Jim_Obj *objPtr = JimStringTrimLeft(interp, strObjPtr, trimcharsObjPtr); + + + strObjPtr = JimStringTrimRight(interp, objPtr, trimcharsObjPtr); + + + if (objPtr != strObjPtr && objPtr->refCount == 0) { + + Jim_FreeNewObj(interp, objPtr); + } + + return strObjPtr; +} + + +#ifdef HAVE_ISASCII +#define jim_isascii isascii +#else +static int jim_isascii(int c) +{ + return !(c & ~0x7f); +} +#endif + +static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict) +{ + static const char * const strclassnames[] = { + "integer", "alpha", "alnum", "ascii", "digit", + "double", "lower", "upper", "space", "xdigit", + "control", "print", "graph", "punct", "boolean", + NULL + }; + enum { + STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT, + STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT, + STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT, STR_IS_BOOLEAN, + }; + int strclass; + int len; + int i; + const char *str; + int (*isclassfunc)(int c) = NULL; + + if (Jim_GetEnum(interp, strClass, strclassnames, &strclass, "class", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + + str = Jim_GetString(strObjPtr, &len); + if (len == 0) { + Jim_SetResultBool(interp, !strict); + return JIM_OK; + } + + switch (strclass) { + case STR_IS_INTEGER: + { + jim_wide w; + Jim_SetResultBool(interp, JimGetWideNoErr(interp, strObjPtr, &w) == JIM_OK); + return JIM_OK; + } + + case STR_IS_DOUBLE: + { + double d; + Jim_SetResultBool(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE); + return JIM_OK; + } + + case STR_IS_BOOLEAN: + { + int b; + Jim_SetResultBool(interp, Jim_GetBoolean(interp, strObjPtr, &b) == JIM_OK); + return JIM_OK; + } + + case STR_IS_ALPHA: isclassfunc = isalpha; break; + case STR_IS_ALNUM: isclassfunc = isalnum; break; + case STR_IS_ASCII: isclassfunc = jim_isascii; break; + case STR_IS_DIGIT: isclassfunc = isdigit; break; + case STR_IS_LOWER: isclassfunc = islower; break; + case STR_IS_UPPER: isclassfunc = isupper; break; + case STR_IS_SPACE: isclassfunc = isspace; break; + case STR_IS_XDIGIT: isclassfunc = isxdigit; break; + case STR_IS_CONTROL: isclassfunc = iscntrl; break; + case STR_IS_PRINT: isclassfunc = isprint; break; + case STR_IS_GRAPH: isclassfunc = isgraph; break; + case STR_IS_PUNCT: isclassfunc = ispunct; break; + default: + return JIM_ERR; + } + + for (i = 0; i < len; i++) { + if (!isclassfunc(UCHAR(str[i]))) { + Jim_SetResultBool(interp, 0); + return JIM_OK; + } + } + Jim_SetResultBool(interp, 1); + return JIM_OK; +} + + + +static const Jim_ObjType comparedStringObjType = { + "compared-string", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES, +}; + +int Jim_CompareStringImmediate(Jim_Interp *interp, Jim_Obj *objPtr, const char *str) +{ + if (objPtr->typePtr == &comparedStringObjType && objPtr->internalRep.ptr == str) { + return 1; + } + else { + if (strcmp(str, Jim_String(objPtr)) != 0) + return 0; + + if (objPtr->typePtr != &comparedStringObjType) { + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &comparedStringObjType; + } + objPtr->internalRep.ptr = (char *)str; + return 1; + } +} + +static int qsortCompareStringPointers(const void *a, const void *b) +{ + char *const *sa = (char *const *)a; + char *const *sb = (char *const *)b; + + return strcmp(*sa, *sb); +} + + + +static void FreeSourceInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); + +static const Jim_ObjType sourceObjType = { + "source", + FreeSourceInternalRep, + DupSourceInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +void FreeSourceInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.sourceValue.fileNameObj); +} + +void DupSourceInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + dupPtr->internalRep.sourceValue = srcPtr->internalRep.sourceValue; + Jim_IncrRefCount(dupPtr->internalRep.sourceValue.fileNameObj); +} + +static const Jim_ObjType scriptLineObjType = { + "scriptline", + NULL, + NULL, + NULL, + JIM_NONE, +}; + +static Jim_Obj *JimNewScriptLineObj(Jim_Interp *interp, int argc, int line) +{ + Jim_Obj *objPtr; + +#ifdef DEBUG_SHOW_SCRIPT + char buf[100]; + snprintf(buf, sizeof(buf), "line=%d, argc=%d", line, argc); + objPtr = Jim_NewStringObj(interp, buf, -1); +#else + objPtr = Jim_NewEmptyStringObj(interp); +#endif + objPtr->typePtr = &scriptLineObjType; + objPtr->internalRep.scriptLineValue.argc = argc; + objPtr->internalRep.scriptLineValue.line = line; + + return objPtr; +} + +static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); + +static const Jim_ObjType scriptObjType = { + "script", + FreeScriptInternalRep, + DupScriptInternalRep, + NULL, + JIM_TYPE_NONE, +}; + +typedef struct ScriptToken +{ + Jim_Obj *objPtr; + int type; +} ScriptToken; + +typedef struct ScriptObj +{ + ScriptToken *token; + Jim_Obj *fileNameObj; + int len; + int substFlags; + int inUse; /* Used to share a ScriptObj. Currently + only used by Jim_EvalObj() as protection against + shimmering of the currently evaluated object. */ + int firstline; + int linenr; + int missing; +} ScriptObj; + +static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); +static int JimParseCheckMissing(Jim_Interp *interp, int ch); +static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr); +static void JimSetErrorStack(Jim_Interp *interp, ScriptObj *script); + +void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int i; + struct ScriptObj *script = (void *)objPtr->internalRep.ptr; + + if (--script->inUse != 0) + return; + for (i = 0; i < script->len; i++) { + Jim_DecrRefCount(interp, script->token[i].objPtr); + } + Jim_Free(script->token); + Jim_DecrRefCount(interp, script->fileNameObj); + Jim_Free(script); +} + +void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + JIM_NOTUSED(srcPtr); + + dupPtr->typePtr = NULL; +} + +typedef struct +{ + const char *token; + int len; + int type; + int line; +} ParseToken; + +typedef struct +{ + + ParseToken *list; + int size; + int count; + ParseToken static_list[20]; +} ParseTokenList; + +static void ScriptTokenListInit(ParseTokenList *tokenlist) +{ + tokenlist->list = tokenlist->static_list; + tokenlist->size = sizeof(tokenlist->static_list) / sizeof(ParseToken); + tokenlist->count = 0; +} + +static void ScriptTokenListFree(ParseTokenList *tokenlist) +{ + if (tokenlist->list != tokenlist->static_list) { + Jim_Free(tokenlist->list); + } +} + +static void ScriptAddToken(ParseTokenList *tokenlist, const char *token, int len, int type, + int line) +{ + ParseToken *t; + + if (tokenlist->count == tokenlist->size) { + + tokenlist->size *= 2; + if (tokenlist->list != tokenlist->static_list) { + tokenlist->list = + Jim_Realloc(tokenlist->list, tokenlist->size * sizeof(*tokenlist->list)); + } + else { + + tokenlist->list = Jim_Alloc(tokenlist->size * sizeof(*tokenlist->list)); + memcpy(tokenlist->list, tokenlist->static_list, + tokenlist->count * sizeof(*tokenlist->list)); + } + } + t = &tokenlist->list[tokenlist->count++]; + t->token = token; + t->len = len; + t->type = type; + t->line = line; +} + +static int JimCountWordTokens(struct ScriptObj *script, ParseToken *t) +{ + int expand = 1; + int count = 0; + + + if (t->type == JIM_TT_STR && !TOKEN_IS_SEP(t[1].type)) { + if ((t->len == 1 && *t->token == '*') || (t->len == 6 && strncmp(t->token, "expand", 6) == 0)) { + + expand = -1; + t++; + } + else { + if (script->missing == ' ') { + + script->missing = '}'; + script->linenr = t[1].line; + } + } + } + + + while (!TOKEN_IS_SEP(t->type)) { + t++; + count++; + } + + return count * expand; +} + +static Jim_Obj *JimMakeScriptObj(Jim_Interp *interp, const ParseToken *t) +{ + Jim_Obj *objPtr; + + if (t->type == JIM_TT_ESC && memchr(t->token, '\\', t->len) != NULL) { + + int len = t->len; + char *str = Jim_Alloc(len + 1); + len = JimEscape(str, t->token, len); + objPtr = Jim_NewStringObjNoAlloc(interp, str, len); + } + else { + objPtr = Jim_NewStringObj(interp, t->token, t->len); + } + return objPtr; +} + +static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, + ParseTokenList *tokenlist) +{ + int i; + struct ScriptToken *token; + + int lineargs = 0; + + ScriptToken *linefirst; + int count; + int linenr; + +#ifdef DEBUG_SHOW_SCRIPT_TOKENS + printf("==== Tokens ====\n"); + for (i = 0; i < tokenlist->count; i++) { + printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, jim_tt_name(tokenlist->list[i].type), + tokenlist->list[i].len, tokenlist->list[i].token); + } +#endif + + + count = tokenlist->count; + for (i = 0; i < tokenlist->count; i++) { + if (tokenlist->list[i].type == JIM_TT_EOL) { + count++; + } + } + linenr = script->firstline = tokenlist->list[0].line; + + token = script->token = Jim_Alloc(sizeof(ScriptToken) * count); + + + linefirst = token++; + + for (i = 0; i < tokenlist->count; ) { + + int wordtokens; + + + while (tokenlist->list[i].type == JIM_TT_SEP) { + i++; + } + + wordtokens = JimCountWordTokens(script, tokenlist->list + i); + + if (wordtokens == 0) { + + if (lineargs) { + linefirst->type = JIM_TT_LINE; + linefirst->objPtr = JimNewScriptLineObj(interp, lineargs, linenr); + Jim_IncrRefCount(linefirst->objPtr); + + + lineargs = 0; + linefirst = token++; + } + i++; + continue; + } + else if (wordtokens != 1) { + + token->type = JIM_TT_WORD; + token->objPtr = Jim_NewIntObj(interp, wordtokens); + Jim_IncrRefCount(token->objPtr); + token++; + if (wordtokens < 0) { + + i++; + wordtokens = -wordtokens - 1; + lineargs--; + } + } + + if (lineargs == 0) { + + linenr = tokenlist->list[i].line; + } + lineargs++; + + + while (wordtokens--) { + const ParseToken *t = &tokenlist->list[i++]; + + token->type = t->type; + token->objPtr = JimMakeScriptObj(interp, t); + Jim_IncrRefCount(token->objPtr); + + Jim_SetSourceInfo(interp, token->objPtr, script->fileNameObj, t->line); + token++; + } + } + + if (lineargs == 0) { + token--; + } + + script->len = token - script->token; + + JimPanic((script->len >= count, "allocated script array is too short")); + +#ifdef DEBUG_SHOW_SCRIPT + printf("==== Script (%s) ====\n", Jim_String(script->fileNameObj)); + for (i = 0; i < script->len; i++) { + const ScriptToken *t = &script->token[i]; + printf("[%2d] %s %s\n", i, jim_tt_name(t->type), Jim_String(t->objPtr)); + } +#endif + +} + +int Jim_ScriptIsComplete(Jim_Interp *interp, Jim_Obj *scriptObj, char *stateCharPtr) +{ + ScriptObj *script = JimGetScript(interp, scriptObj); + if (stateCharPtr) { + *stateCharPtr = script->missing; + } + return script->missing == ' ' || script->missing == '}'; +} + +static int JimParseCheckMissing(Jim_Interp *interp, int ch) +{ + const char *msg; + + switch (ch) { + case '\\': + case ' ': + return JIM_OK; + + case '[': + msg = "unmatched \"[\""; + break; + case '{': + msg = "missing close-brace"; + break; + case '}': + msg = "extra characters after close-brace"; + break; + case '"': + default: + msg = "missing quote"; + break; + } + + Jim_SetResultString(interp, msg, -1); + return JIM_ERR; +} + +Jim_Obj *Jim_GetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, int *lineptr) +{ + int line; + Jim_Obj *fileNameObj; + + if (objPtr->typePtr == &sourceObjType) { + fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; + line = objPtr->internalRep.sourceValue.lineNumber; + } + else if (objPtr->typePtr == &scriptObjType) { + ScriptObj *script = JimGetScript(interp, objPtr); + fileNameObj = script->fileNameObj; + line = script->firstline; + } + else { + fileNameObj = interp->emptyObj; + line = 1; + } + *lineptr = line; + return fileNameObj; +} + +void Jim_SetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *fileNameObj, int lineNumber) +{ + JimPanic((Jim_IsShared(objPtr), "Jim_SetSourceInfo called with shared object")); + Jim_FreeIntRep(interp, objPtr); + Jim_IncrRefCount(fileNameObj); + objPtr->internalRep.sourceValue.fileNameObj = fileNameObj; + objPtr->internalRep.sourceValue.lineNumber = lineNumber; + objPtr->typePtr = &sourceObjType; +} + +static void SubstObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, + ParseTokenList *tokenlist) +{ + int i; + struct ScriptToken *token; + + token = script->token = Jim_Alloc(sizeof(ScriptToken) * tokenlist->count); + + for (i = 0; i < tokenlist->count; i++) { + const ParseToken *t = &tokenlist->list[i]; + + + token->type = t->type; + token->objPtr = JimMakeScriptObj(interp, t); + Jim_IncrRefCount(token->objPtr); + token++; + } + + script->len = i; +} + +static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + int scriptTextLen; + const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); + struct JimParserCtx parser; + struct ScriptObj *script; + ParseTokenList tokenlist; + Jim_Obj *fileNameObj; + int line; + + + fileNameObj = Jim_GetSourceInfo(interp, objPtr, &line); + + + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, scriptText, scriptTextLen, line); + while (!parser.eof) { + JimParseScript(&parser); + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + + + ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0); + + + script = Jim_Alloc(sizeof(*script)); + memset(script, 0, sizeof(*script)); + script->inUse = 1; + script->fileNameObj = fileNameObj; + Jim_IncrRefCount(script->fileNameObj); + script->missing = parser.missing.ch; + script->linenr = parser.missing.line; + + ScriptObjAddTokens(interp, script, &tokenlist); + + + ScriptTokenListFree(&tokenlist); + + + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, script); + objPtr->typePtr = &scriptObjType; +} + +static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr == interp->emptyObj) { + + objPtr = interp->nullScriptObj; + } + + if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) { + JimSetScriptFromAny(interp, objPtr); + } + + return (ScriptObj *)Jim_GetIntRepPtr(objPtr); +} + +void Jim_InterpIncrProcEpoch(Jim_Interp *interp) +{ + interp->procEpoch++; + + + while (interp->oldCmdCache) { + Jim_Cmd *next = interp->oldCmdCache->prevCmd; + Jim_Free(interp->oldCmdCache); + interp->oldCmdCache = next; + } + interp->oldCmdCacheSize = 0; +} + +static void JimIncrCmdRefCount(Jim_Cmd *cmdPtr) +{ + cmdPtr->inUse++; +} + +static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr) +{ + if (--cmdPtr->inUse == 0) { + if (cmdPtr->isproc) { + Jim_DecrRefCount(interp, cmdPtr->u.proc.argListObjPtr); + Jim_DecrRefCount(interp, cmdPtr->u.proc.bodyObjPtr); + Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); + if (cmdPtr->u.proc.staticVars) { + Jim_FreeHashTable(cmdPtr->u.proc.staticVars); + Jim_Free(cmdPtr->u.proc.staticVars); + } + } + else { + + if (cmdPtr->u.native.delProc) { + cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData); + } + } + if (cmdPtr->prevCmd) { + + JimDecrCmdRefCount(interp, cmdPtr->prevCmd); + } + + cmdPtr->prevCmd = interp->oldCmdCache; + interp->oldCmdCache = cmdPtr; + if (!interp->quitting && ++interp->oldCmdCacheSize >= 1000) { + Jim_InterpIncrProcEpoch(interp); + } + } +} + +static void JimIncrVarRef(Jim_VarVal *vv) +{ + vv->refCount++; +} + +static void JimDecrVarRef(Jim_Interp *interp, Jim_VarVal *vv) +{ + assert(vv->refCount > 0); + if (--vv->refCount == 0) { + if (vv->objPtr) { + Jim_DecrRefCount(interp, vv->objPtr); + } + Jim_Free(vv); + } +} + +static void JimVariablesHTValDestructor(void *interp, void *val) +{ + JimDecrVarRef(interp, val); +} + +static unsigned int JimObjectHTHashFunction(const void *key) +{ + Jim_Obj *keyObj = (Jim_Obj *)key; + int length; + const char *string; + +#ifdef JIM_OPTIMIZATION + if (JimIsWide(keyObj) && keyObj->bytes == NULL) { + + jim_wide objValue = JimWideValue(keyObj); + if (objValue > INT_MIN && objValue < INT_MAX) { + unsigned result = 0; + unsigned value = (unsigned)objValue; + + if (objValue < 0) { + value = (unsigned)-objValue; + } + + + do { + result += (result << 3) + (value % 10 + '0'); + value /= 10; + } while (value); + + if (objValue < 0) { + result += (result << 3) + '-'; + } + return result; + } + } +#endif + string = Jim_GetString(keyObj, &length); + return Jim_GenHashFunction((const unsigned char *)string, length); +} + +static int JimObjectHTKeyCompare(void *privdata, const void *key1, const void *key2) +{ + return Jim_StringEqObj((Jim_Obj *)key1, (Jim_Obj *)key2); +} + +static void *JimObjectHTKeyValDup(void *privdata, const void *val) +{ + Jim_IncrRefCount((Jim_Obj *)val); + return (void *)val; +} + +static void JimObjectHTKeyValDestructor(void *interp, void *val) +{ + Jim_DecrRefCount(interp, (Jim_Obj *)val); +} + + +static void *JimVariablesHTValDup(void *privdata, const void *val) +{ + JimIncrVarRef((Jim_VarVal *)val); + return (void *)val; +} + +static const Jim_HashTableType JimVariablesHashTableType = { + JimObjectHTHashFunction, + JimObjectHTKeyValDup, + JimVariablesHTValDup, + JimObjectHTKeyCompare, + JimObjectHTKeyValDestructor, + JimVariablesHTValDestructor +}; + + +static const char *Jim_GetStringNoQualifier(Jim_Obj *objPtr, int *length) +{ + int len; + const char *str = Jim_GetString(objPtr, &len); + if (len >= 2 && str[0] == ':' && str[1] == ':') { + while (len && *str == ':') { + len--; + str++; + } + } + *length = len; + return str; +} + +static unsigned int JimCommandsHT_HashFunction(const void *key) +{ + int len; + const char *str = Jim_GetStringNoQualifier((Jim_Obj *)key, &len); + return Jim_GenHashFunction((const unsigned char *)str, len); +} + +static int JimCommandsHT_KeyCompare(void *privdata, const void *key1, const void *key2) +{ + int len1, len2; + const char *str1 = Jim_GetStringNoQualifier((Jim_Obj *)key1, &len1); + const char *str2 = Jim_GetStringNoQualifier((Jim_Obj *)key2, &len2); + return len1 == len2 && memcmp(str1, str2, len1) == 0; +} + +static void JimCommandsHT_ValDestructor(void *interp, void *val) +{ + JimDecrCmdRefCount(interp, val); +} + +static const Jim_HashTableType JimCommandsHashTableType = { + JimCommandsHT_HashFunction, + JimObjectHTKeyValDup, + NULL, + JimCommandsHT_KeyCompare, + JimObjectHTKeyValDestructor, + JimCommandsHT_ValDestructor +}; + + + +Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr) +{ +#ifdef jim_ext_namespace + Jim_Obj *resultObj; + + const char *name = Jim_String(nameObjPtr); + if (name[0] == ':' && name[1] == ':') { + return nameObjPtr; + } + Jim_IncrRefCount(nameObjPtr); + resultObj = Jim_NewStringObj(interp, "::", -1); + Jim_AppendObj(interp, resultObj, nameObjPtr); + Jim_DecrRefCount(interp, nameObjPtr); + + return resultObj; +#else + return nameObjPtr; +#endif +} + +static Jim_Obj *JimQualifyName(Jim_Interp *interp, Jim_Obj *objPtr) +{ +#ifdef jim_ext_namespace + if (Jim_Length(interp->framePtr->nsObj)) { + int len; + const char *name = Jim_GetString(objPtr, &len); + if (len < 2 || name[0] != ':' || name[1] != ':') { + + objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj); + Jim_AppendStrings(interp, objPtr, "::", name, NULL); + } + } +#endif + Jim_IncrRefCount(objPtr); + return objPtr; +} + +static void JimCreateCommand(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Cmd *cmd) +{ + JimPanic((nameObjPtr->refCount == 0, "JimCreateCommand called with zero ref count name")); + + if (interp->local) { + Jim_HashEntry *he = Jim_FindHashEntry(&interp->commands, nameObjPtr); + if (he) { + + cmd->prevCmd = Jim_GetHashEntryVal(he); + Jim_SetHashVal(&interp->commands, he, cmd); + + Jim_InterpIncrProcEpoch(interp); + return; + } + } + + + + Jim_ReplaceHashEntry(&interp->commands, nameObjPtr, cmd); +} + +int Jim_CreateCommandObj(Jim_Interp *interp, Jim_Obj *cmdNameObj, + Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc) +{ + Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr)); + + + memset(cmdPtr, 0, sizeof(*cmdPtr)); + cmdPtr->inUse = 1; + cmdPtr->u.native.delProc = delProc; + cmdPtr->u.native.cmdProc = cmdProc; + cmdPtr->u.native.privData = privData; + + Jim_IncrRefCount(cmdNameObj); + JimCreateCommand(interp, cmdNameObj, cmdPtr); + Jim_DecrRefCount(interp, cmdNameObj); + + return JIM_OK; +} + + +int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr, + Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc) +{ + return Jim_CreateCommandObj(interp, Jim_NewStringObj(interp, cmdNameStr, -1), cmdProc, privData, delProc); +} + +static int JimCreateProcedureStatics(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Obj *staticsListObjPtr) +{ + int len, i; + + len = Jim_ListLength(interp, staticsListObjPtr); + if (len == 0) { + return JIM_OK; + } + + cmdPtr->u.proc.staticVars = Jim_Alloc(sizeof(Jim_HashTable)); + Jim_InitHashTable(cmdPtr->u.proc.staticVars, &JimVariablesHashTableType, interp); + for (i = 0; i < len; i++) { + Jim_Obj *initObjPtr = NULL; + Jim_Obj *nameObjPtr; + Jim_VarVal *vv = NULL; + Jim_Obj *objPtr = Jim_ListGetIndex(interp, staticsListObjPtr, i); + int subLen = Jim_ListLength(interp, objPtr); + int byref = 0; + + + if (subLen != 1 && subLen != 2) { + Jim_SetResultFormatted(interp, "too many fields in static specifier \"%#s\"", + objPtr); + return JIM_ERR; + } + + nameObjPtr = Jim_ListGetIndex(interp, objPtr, 0); + + + if (subLen == 1) { + int len; + const char *pt = Jim_GetString(nameObjPtr, &len); + if (*pt == '&') { + + nameObjPtr = Jim_NewStringObj(interp, pt + 1, len - 1); + byref = 1; + } + } + Jim_IncrRefCount(nameObjPtr); + + if (subLen == 1) { + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_DICT_SUGAR: + + if (byref) { + Jim_SetResultFormatted(interp, "Can't link to array element \"%#s\"", nameObjPtr); + } + else { + Jim_SetResultFormatted(interp, "Can't initialise array element \"%#s\"", nameObjPtr); + } + Jim_DecrRefCount(interp, nameObjPtr); + return JIM_ERR; + + case JIM_OK: + if (byref) { + vv = nameObjPtr->internalRep.varValue.vv; + } + else { + initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE); + } + break; + + case JIM_ERR: + + Jim_SetResultFormatted(interp, + "variable for initialization of static \"%#s\" not found in the local context", + nameObjPtr); + Jim_DecrRefCount(interp, nameObjPtr); + return JIM_ERR; + } + } + else { + initObjPtr = Jim_ListGetIndex(interp, objPtr, 1); + } + + if (vv == NULL) { + vv = Jim_Alloc(sizeof(*vv)); + vv->objPtr = initObjPtr; + Jim_IncrRefCount(vv->objPtr); + vv->linkFramePtr = NULL; + vv->refCount = 0; + } + + if (JimSetNewVariable(cmdPtr->u.proc.staticVars, nameObjPtr, vv) != JIM_OK) { + Jim_SetResultFormatted(interp, + "static variable name \"%#s\" duplicated in statics list", nameObjPtr); + JimIncrVarRef(vv); + JimDecrVarRef(interp, vv); + Jim_DecrRefCount(interp, nameObjPtr); + return JIM_ERR; + } + + Jim_DecrRefCount(interp, nameObjPtr); + } + return JIM_OK; +} + + +#ifdef jim_ext_namespace +static const char *Jim_memrchr(const char *p, int c, int len) +{ + int i; + for (i = len; i > 0; i--) { + if (p[i] == c) { + return p + i; + } + } + return NULL; +} +#endif + +static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Obj *nameObjPtr) +{ +#ifdef jim_ext_namespace + if (cmdPtr->isproc) { + int len; + const char *cmdname = Jim_GetStringNoQualifier(nameObjPtr, &len); + + const char *pt = Jim_memrchr(cmdname, ':', len); + if (pt && pt != cmdname && pt[-1] == ':') { + pt++; + Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); + cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 2); + Jim_IncrRefCount(cmdPtr->u.proc.nsObj); + + Jim_Obj *tempObj = Jim_NewStringObj(interp, pt, len - (pt - cmdname)); + if (Jim_FindHashEntry(&interp->commands, tempObj)) { + + Jim_InterpIncrProcEpoch(interp); + } + Jim_FreeNewObj(interp, tempObj); + } + } +#endif +} + +static Jim_Cmd *JimCreateProcedureCmd(Jim_Interp *interp, Jim_Obj *argListObjPtr, + Jim_Obj *staticsListObjPtr, Jim_Obj *bodyObjPtr, Jim_Obj *nsObj) +{ + Jim_Cmd *cmdPtr; + int argListLen; + int i; + + argListLen = Jim_ListLength(interp, argListObjPtr); + + + cmdPtr = Jim_Alloc(sizeof(*cmdPtr) + sizeof(struct Jim_ProcArg) * argListLen); + assert(cmdPtr); + memset(cmdPtr, 0, sizeof(*cmdPtr)); + cmdPtr->inUse = 1; + cmdPtr->isproc = 1; + cmdPtr->u.proc.argListObjPtr = argListObjPtr; + cmdPtr->u.proc.argListLen = argListLen; + cmdPtr->u.proc.bodyObjPtr = bodyObjPtr; + cmdPtr->u.proc.argsPos = -1; + cmdPtr->u.proc.arglist = (struct Jim_ProcArg *)(cmdPtr + 1); + cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj; + Jim_IncrRefCount(argListObjPtr); + Jim_IncrRefCount(bodyObjPtr); + Jim_IncrRefCount(cmdPtr->u.proc.nsObj); + + + if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) { + goto err; + } + + + + for (i = 0; i < argListLen; i++) { + Jim_Obj *argPtr; + Jim_Obj *nameObjPtr; + Jim_Obj *defaultObjPtr; + int len; + + + argPtr = Jim_ListGetIndex(interp, argListObjPtr, i); + len = Jim_ListLength(interp, argPtr); + if (len == 0) { + Jim_SetResultString(interp, "argument with no name", -1); +err: + JimDecrCmdRefCount(interp, cmdPtr); + return NULL; + } + if (len > 2) { + Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr); + goto err; + } + + if (len == 2) { + + nameObjPtr = Jim_ListGetIndex(interp, argPtr, 0); + defaultObjPtr = Jim_ListGetIndex(interp, argPtr, 1); + } + else { + + nameObjPtr = argPtr; + defaultObjPtr = NULL; + } + + + if (Jim_CompareStringImmediate(interp, nameObjPtr, "args")) { + if (cmdPtr->u.proc.argsPos >= 0) { + Jim_SetResultString(interp, "'args' specified more than once", -1); + goto err; + } + cmdPtr->u.proc.argsPos = i; + } + else { + if (len == 2) { + cmdPtr->u.proc.optArity++; + } + else { + cmdPtr->u.proc.reqArity++; + } + } + + cmdPtr->u.proc.arglist[i].nameObjPtr = nameObjPtr; + cmdPtr->u.proc.arglist[i].defaultObjPtr = defaultObjPtr; + } + + return cmdPtr; +} + +int Jim_DeleteCommand(Jim_Interp *interp, Jim_Obj *nameObj) +{ + int ret = JIM_OK; + + nameObj = JimQualifyName(interp, nameObj); + + if (Jim_DeleteHashEntry(&interp->commands, nameObj) == JIM_ERR) { + Jim_SetResultFormatted(interp, "can't delete \"%#s\": command doesn't exist", nameObj); + ret = JIM_ERR; + } + Jim_DecrRefCount(interp, nameObj); + + return ret; +} + +int Jim_RenameCommand(Jim_Interp *interp, Jim_Obj *oldNameObj, Jim_Obj *newNameObj) +{ + int ret = JIM_ERR; + Jim_HashEntry *he; + Jim_Cmd *cmdPtr; + + if (Jim_Length(newNameObj) == 0) { + return Jim_DeleteCommand(interp, oldNameObj); + } + + + + oldNameObj = JimQualifyName(interp, oldNameObj); + newNameObj = JimQualifyName(interp, newNameObj); + + + he = Jim_FindHashEntry(&interp->commands, oldNameObj); + if (he == NULL) { + Jim_SetResultFormatted(interp, "can't rename \"%#s\": command doesn't exist", oldNameObj); + } + else if (Jim_FindHashEntry(&interp->commands, newNameObj)) { + Jim_SetResultFormatted(interp, "can't rename to \"%#s\": command already exists", newNameObj); + } + else { + cmdPtr = Jim_GetHashEntryVal(he); + if (cmdPtr->prevCmd) { + Jim_SetResultFormatted(interp, "can't rename local command \"%#s\"", oldNameObj); + } + else { + + JimIncrCmdRefCount(cmdPtr); + JimUpdateProcNamespace(interp, cmdPtr, newNameObj); + Jim_AddHashEntry(&interp->commands, newNameObj, cmdPtr); + + + Jim_DeleteHashEntry(&interp->commands, oldNameObj); + + + Jim_InterpIncrProcEpoch(interp); + + ret = JIM_OK; + } + } + + Jim_DecrRefCount(interp, oldNameObj); + Jim_DecrRefCount(interp, newNameObj); + + return ret; +} + + +static void FreeCommandInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.cmdValue.nsObj); +} + +static void DupCommandInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + dupPtr->internalRep.cmdValue = srcPtr->internalRep.cmdValue; + dupPtr->typePtr = srcPtr->typePtr; + Jim_IncrRefCount(dupPtr->internalRep.cmdValue.nsObj); +} + +static const Jim_ObjType commandObjType = { + "command", + FreeCommandInternalRep, + DupCommandInternalRep, + NULL, + JIM_TYPE_REFERENCES, +}; + +Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + Jim_Cmd *cmd; + + if (objPtr->typePtr == &commandObjType + && objPtr->internalRep.cmdValue.procEpoch == interp->procEpoch +#ifdef jim_ext_namespace + && Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj) +#endif + && objPtr->internalRep.cmdValue.cmdPtr->inUse) { + + cmd = objPtr->internalRep.cmdValue.cmdPtr; + } + else { + Jim_Obj *qualifiedNameObj = JimQualifyName(interp, objPtr); + Jim_HashEntry *he = Jim_FindHashEntry(&interp->commands, qualifiedNameObj); +#ifdef jim_ext_namespace + if (he == NULL && Jim_Length(interp->framePtr->nsObj)) { + he = Jim_FindHashEntry(&interp->commands, objPtr); + } +#endif + if (he == NULL) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr); + } + Jim_DecrRefCount(interp, qualifiedNameObj); + return NULL; + } + cmd = Jim_GetHashEntryVal(he); + + cmd->cmdNameObj = Jim_GetHashEntryKey(he); + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &commandObjType; + objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch; + objPtr->internalRep.cmdValue.cmdPtr = cmd; + objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj; + Jim_IncrRefCount(interp->framePtr->nsObj); + Jim_DecrRefCount(interp, qualifiedNameObj); + } + while (cmd->u.proc.upcall) { + cmd = cmd->prevCmd; + } + return cmd; +} + + + +static const Jim_ObjType variableObjType = { + "variable", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES, +}; + +static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + const char *varName; + Jim_CallFrame *framePtr; + int global; + int len; + Jim_VarVal *vv; + + + if (objPtr->typePtr == &variableObjType) { + framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr; + if (objPtr->internalRep.varValue.callFrameId == framePtr->id) { + + return JIM_OK; + } + + } + else if (objPtr->typePtr == &dictSubstObjType) { + return JIM_DICT_SUGAR; + } + + varName = Jim_GetString(objPtr, &len); + + + if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) { + return JIM_DICT_SUGAR; + } + + if (varName[0] == ':' && varName[1] == ':') { + while (*varName == ':') { + varName++; + len--; + } + global = 1; + framePtr = interp->topFramePtr; + + Jim_Obj *tempObj = Jim_NewStringObj(interp, varName, len); + vv = JimFindVariable(&framePtr->vars, tempObj); + Jim_FreeNewObj(interp, tempObj); + } + else { + global = 0; + framePtr = interp->framePtr; + + vv = JimFindVariable(&framePtr->vars, objPtr); + if (vv == NULL && framePtr->staticVars) { + + vv = JimFindVariable(framePtr->staticVars, objPtr); + } + } + + if (vv == NULL) { + return JIM_ERR; + } + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &variableObjType; + objPtr->internalRep.varValue.callFrameId = framePtr->id; + objPtr->internalRep.varValue.vv = vv; + objPtr->internalRep.varValue.global = global; + return JIM_OK; +} + + +static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *ObjPtr, Jim_Obj *valObjPtr); +static Jim_Obj *JimDictSugarGet(Jim_Interp *interp, Jim_Obj *ObjPtr, int flags); + +static int JimSetNewVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr, Jim_VarVal *vv) +{ + return Jim_AddHashEntry(ht, nameObjPtr, vv); +} + +static Jim_VarVal *JimFindVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr) +{ + Jim_HashEntry *he = Jim_FindHashEntry(ht, nameObjPtr); + if (he) { + return (Jim_VarVal *)Jim_GetHashEntryVal(he); + } + return NULL; +} + +static int JimUnsetVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr) +{ + return Jim_DeleteHashEntry(ht, nameObjPtr); +} + +static Jim_VarVal *JimCreateVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr) +{ + const char *name; + Jim_CallFrame *framePtr; + int global; + int len; + + + Jim_VarVal *vv = Jim_Alloc(sizeof(*vv)); + + vv->objPtr = valObjPtr; + Jim_IncrRefCount(valObjPtr); + vv->linkFramePtr = NULL; + vv->refCount = 0; + + name = Jim_GetString(nameObjPtr, &len); + if (name[0] == ':' && name[1] == ':') { + while (*name == ':') { + name++; + len--; + } + framePtr = interp->topFramePtr; + global = 1; + JimSetNewVariable(&framePtr->vars, Jim_NewStringObj(interp, name, len), vv); + } + else { + framePtr = interp->framePtr; + global = 0; + JimSetNewVariable(&framePtr->vars, nameObjPtr, vv); + } + + + Jim_FreeIntRep(interp, nameObjPtr); + nameObjPtr->typePtr = &variableObjType; + nameObjPtr->internalRep.varValue.callFrameId = framePtr->id; + nameObjPtr->internalRep.varValue.vv = vv; + nameObjPtr->internalRep.varValue.global = global; + + return vv; +} + +int Jim_SetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr) +{ + int err; + Jim_VarVal *vv; + + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_DICT_SUGAR: + return JimDictSugarSet(interp, nameObjPtr, valObjPtr); + + case JIM_ERR: + JimCreateVariable(interp, nameObjPtr, valObjPtr); + break; + + case JIM_OK: + vv = nameObjPtr->internalRep.varValue.vv; + if (vv->linkFramePtr == NULL) { + Jim_IncrRefCount(valObjPtr); + Jim_DecrRefCount(interp, vv->objPtr); + vv->objPtr = valObjPtr; + } + else { + Jim_CallFrame *savedCallFrame; + + savedCallFrame = interp->framePtr; + interp->framePtr = vv->linkFramePtr; + err = Jim_SetVariable(interp, vv->objPtr, valObjPtr); + interp->framePtr = savedCallFrame; + if (err != JIM_OK) + return err; + } + } + return JIM_OK; +} + +int Jim_SetVariableStr(Jim_Interp *interp, const char *name, Jim_Obj *objPtr) +{ + Jim_Obj *nameObjPtr; + int result; + + nameObjPtr = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(nameObjPtr); + result = Jim_SetVariable(interp, nameObjPtr, objPtr); + Jim_DecrRefCount(interp, nameObjPtr); + return result; +} + +int Jim_SetGlobalVariableStr(Jim_Interp *interp, const char *name, Jim_Obj *objPtr) +{ + Jim_CallFrame *savedFramePtr; + int result; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + result = Jim_SetVariableStr(interp, name, objPtr); + interp->framePtr = savedFramePtr; + return result; +} + +int Jim_SetVariableStrWithStr(Jim_Interp *interp, const char *name, const char *val) +{ + Jim_Obj *valObjPtr; + int result; + + valObjPtr = Jim_NewStringObj(interp, val, -1); + Jim_IncrRefCount(valObjPtr); + result = Jim_SetVariableStr(interp, name, valObjPtr); + Jim_DecrRefCount(interp, valObjPtr); + return result; +} + +int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr, + Jim_Obj *targetNameObjPtr, Jim_CallFrame *targetCallFrame) +{ + const char *varName; + const char *targetName; + Jim_CallFrame *framePtr; + Jim_VarVal *vv; + int len; + int varnamelen; + + + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_DICT_SUGAR: + + Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr); + return JIM_ERR; + + case JIM_OK: + vv = nameObjPtr->internalRep.varValue.vv; + + if (vv->linkFramePtr == NULL) { + Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr); + return JIM_ERR; + } + + + vv->linkFramePtr = NULL; + break; + } + + + + varName = Jim_GetString(nameObjPtr, &varnamelen); + + if (varName[0] == ':' && varName[1] == ':') { + while (*varName == ':') { + varName++; + varnamelen--; + } + + framePtr = interp->topFramePtr; + } + else { + framePtr = interp->framePtr; + } + + targetName = Jim_GetString(targetNameObjPtr, &len); + if (targetName[0] == ':' && targetName[1] == ':') { + while (*targetName == ':') { + targetName++; + len--; + } + targetNameObjPtr = Jim_NewStringObj(interp, targetName, len); + targetCallFrame = interp->topFramePtr; + } + Jim_IncrRefCount(targetNameObjPtr); + + if (framePtr->level < targetCallFrame->level) { + Jim_SetResultFormatted(interp, + "bad variable name \"%#s\": upvar won't create namespace variable that refers to procedure variable", + nameObjPtr); + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_ERR; + } + + + if (framePtr == targetCallFrame) { + Jim_Obj *objPtr = targetNameObjPtr; + + + while (1) { + if (Jim_Length(objPtr) == varnamelen && memcmp(Jim_String(objPtr), varName, varnamelen) == 0) { + Jim_SetResultString(interp, "can't upvar from variable to itself", -1); + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_ERR; + } + if (SetVariableFromAny(interp, objPtr) != JIM_OK) + break; + vv = objPtr->internalRep.varValue.vv; + if (vv->linkFramePtr != targetCallFrame) + break; + objPtr = vv->objPtr; + } + } + + + Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr); + + nameObjPtr->internalRep.varValue.vv->linkFramePtr = targetCallFrame; + Jim_DecrRefCount(interp, targetNameObjPtr); + return JIM_OK; +} + +Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + if (interp->safeexpr) { + return nameObjPtr; + } + switch (SetVariableFromAny(interp, nameObjPtr)) { + case JIM_OK:{ + Jim_VarVal *vv = nameObjPtr->internalRep.varValue.vv; + + if (vv->linkFramePtr == NULL) { + return vv->objPtr; + } + else { + Jim_Obj *objPtr; + + + Jim_CallFrame *savedCallFrame = interp->framePtr; + + interp->framePtr = vv->linkFramePtr; + objPtr = Jim_GetVariable(interp, vv->objPtr, flags); + interp->framePtr = savedCallFrame; + if (objPtr) { + return objPtr; + } + + } + } + break; + + case JIM_DICT_SUGAR: + + return JimDictSugarGet(interp, nameObjPtr, flags); + } + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "can't read \"%#s\": no such variable", nameObjPtr); + } + return NULL; +} + +Jim_Obj *Jim_GetGlobalVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + Jim_CallFrame *savedFramePtr; + Jim_Obj *objPtr; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + objPtr = Jim_GetVariable(interp, nameObjPtr, flags); + interp->framePtr = savedFramePtr; + + return objPtr; +} + +Jim_Obj *Jim_GetVariableStr(Jim_Interp *interp, const char *name, int flags) +{ + Jim_Obj *nameObjPtr, *varObjPtr; + + nameObjPtr = Jim_NewStringObj(interp, name, -1); + Jim_IncrRefCount(nameObjPtr); + varObjPtr = Jim_GetVariable(interp, nameObjPtr, flags); + Jim_DecrRefCount(interp, nameObjPtr); + return varObjPtr; +} + +Jim_Obj *Jim_GetGlobalVariableStr(Jim_Interp *interp, const char *name, int flags) +{ + Jim_CallFrame *savedFramePtr; + Jim_Obj *objPtr; + + savedFramePtr = interp->framePtr; + interp->framePtr = interp->topFramePtr; + objPtr = Jim_GetVariableStr(interp, name, flags); + interp->framePtr = savedFramePtr; + + return objPtr; +} + +int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags) +{ + Jim_VarVal *vv; + int retval; + Jim_CallFrame *framePtr; + + retval = SetVariableFromAny(interp, nameObjPtr); + if (retval == JIM_DICT_SUGAR) { + + return JimDictSugarSet(interp, nameObjPtr, NULL); + } + else if (retval == JIM_OK) { + vv = nameObjPtr->internalRep.varValue.vv; + + + if (vv->linkFramePtr) { + framePtr = interp->framePtr; + interp->framePtr = vv->linkFramePtr; + retval = Jim_UnsetVariable(interp, vv->objPtr, JIM_NONE); + interp->framePtr = framePtr; + } + else { + if (nameObjPtr->internalRep.varValue.global) { + int len; + const char *name = Jim_GetString(nameObjPtr, &len); + while (*name == ':') { + name++; + len--; + } + framePtr = interp->topFramePtr; + Jim_Obj *tempObj = Jim_NewStringObj(interp, name, len); + retval = JimUnsetVariable(&framePtr->vars, tempObj); + Jim_FreeNewObj(interp, tempObj); + } + else { + framePtr = interp->framePtr; + retval = JimUnsetVariable(&framePtr->vars, nameObjPtr); + } + + if (retval == JIM_OK) { + + framePtr->id = interp->callFrameEpoch++; + } + } + } + if (retval != JIM_OK && (flags & JIM_ERRMSG)) { + Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such variable", nameObjPtr); + } + return retval; +} + + + +static void JimDictSugarParseVarKey(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj **varPtrPtr, Jim_Obj **keyPtrPtr) +{ + const char *str, *p; + int len, keyLen; + Jim_Obj *varObjPtr, *keyObjPtr; + + str = Jim_GetString(objPtr, &len); + + p = strchr(str, '('); + JimPanic((p == NULL, "JimDictSugarParseVarKey() called for non-dict-sugar (%s)", str)); + + varObjPtr = Jim_NewStringObj(interp, str, p - str); + + p++; + keyLen = (str + len) - p; + if (str[len - 1] == ')') { + keyLen--; + } + + + keyObjPtr = Jim_NewStringObj(interp, p, keyLen); + + Jim_IncrRefCount(varObjPtr); + Jim_IncrRefCount(keyObjPtr); + *varPtrPtr = varObjPtr; + *keyPtrPtr = keyObjPtr; +} + +static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *valObjPtr) +{ + int err; + + SetDictSubstFromAny(interp, objPtr); + + err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, + &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST); + + if (err == JIM_OK) { + + Jim_SetEmptyResult(interp); + } + else { + if (!valObjPtr) { + + if (Jim_GetVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, JIM_NONE)) { + Jim_SetResultFormatted(interp, "can't unset \"%#s\": no such element in array", + objPtr); + return err; + } + } + + Jim_SetResultFormatted(interp, "can't %s \"%#s\": variable isn't array", + (valObjPtr ? "set" : "unset"), objPtr); + } + return err; +} + +static Jim_Obj *JimDictExpandArrayVariable(Jim_Interp *interp, Jim_Obj *varObjPtr, + Jim_Obj *keyObjPtr, int flags) +{ + Jim_Obj *dictObjPtr; + Jim_Obj *resObjPtr = NULL; + int ret; + + dictObjPtr = Jim_GetVariable(interp, varObjPtr, JIM_ERRMSG); + if (!dictObjPtr) { + return NULL; + } + + ret = Jim_DictKey(interp, dictObjPtr, keyObjPtr, &resObjPtr, JIM_NONE); + if (ret != JIM_OK) { + Jim_SetResultFormatted(interp, + "can't read \"%#s(%#s)\": %s array", varObjPtr, keyObjPtr, + ret < 0 ? "variable isn't" : "no such element in"); + } + else if ((flags & JIM_UNSHARED) && Jim_IsShared(dictObjPtr)) { + + Jim_SetVariable(interp, varObjPtr, Jim_DuplicateObj(interp, dictObjPtr)); + } + + return resObjPtr; +} + + +static Jim_Obj *JimDictSugarGet(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + SetDictSubstFromAny(interp, objPtr); + + return JimDictExpandArrayVariable(interp, + objPtr->internalRep.dictSubstValue.varNameObjPtr, + objPtr->internalRep.dictSubstValue.indexObjPtr, flags); +} + + + +void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr); + Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr); +} + +static void DupDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + + dupPtr->internalRep = srcPtr->internalRep; + + Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.varNameObjPtr); + Jim_IncrRefCount(dupPtr->internalRep.dictSubstValue.indexObjPtr); +} + + +static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &dictSubstObjType) { + Jim_Obj *varObjPtr, *keyObjPtr; + + if (objPtr->typePtr == &interpolatedObjType) { + + + varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr; + keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr; + + Jim_IncrRefCount(varObjPtr); + Jim_IncrRefCount(keyObjPtr); + } + else { + JimDictSugarParseVarKey(interp, objPtr, &varObjPtr, &keyObjPtr); + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &dictSubstObjType; + objPtr->internalRep.dictSubstValue.varNameObjPtr = varObjPtr; + objPtr->internalRep.dictSubstValue.indexObjPtr = keyObjPtr; + } +} + +static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr) +{ + Jim_Obj *resObjPtr = NULL; + Jim_Obj *substKeyObjPtr = NULL; + + if (interp->safeexpr) { + return objPtr; + } + + SetDictSubstFromAny(interp, objPtr); + + if (Jim_SubstObj(interp, objPtr->internalRep.dictSubstValue.indexObjPtr, + &substKeyObjPtr, JIM_NONE) + != JIM_OK) { + return NULL; + } + Jim_IncrRefCount(substKeyObjPtr); + resObjPtr = + JimDictExpandArrayVariable(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr, + substKeyObjPtr, 0); + Jim_DecrRefCount(interp, substKeyObjPtr); + + return resObjPtr; +} + + +static Jim_CallFrame *JimCreateCallFrame(Jim_Interp *interp, Jim_CallFrame *parent, Jim_Obj *nsObj) +{ + Jim_CallFrame *cf; + + if (interp->freeFramesList) { + cf = interp->freeFramesList; + interp->freeFramesList = cf->next; + + cf->argv = NULL; + cf->argc = 0; + cf->procArgsObjPtr = NULL; + cf->procBodyObjPtr = NULL; + cf->next = NULL; + cf->staticVars = NULL; + cf->localCommands = NULL; + cf->tailcallObj = NULL; + cf->tailcallCmd = NULL; + } + else { + cf = Jim_Alloc(sizeof(*cf)); + memset(cf, 0, sizeof(*cf)); + + Jim_InitHashTable(&cf->vars, &JimVariablesHashTableType, interp); + } + + cf->id = interp->callFrameEpoch++; + cf->parent = parent; + cf->level = parent ? parent->level + 1 : 0; + cf->nsObj = nsObj; + Jim_IncrRefCount(nsObj); + + return cf; +} + +static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands) +{ + + if (localCommands) { + Jim_Obj *cmdNameObj; + + while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) { + Jim_HashTable *ht = &interp->commands; + Jim_HashEntry *he = Jim_FindHashEntry(ht, cmdNameObj); + if (he) { + Jim_Cmd *cmd = Jim_GetHashEntryVal(he); + if (cmd->prevCmd) { + Jim_Cmd *prevCmd = cmd->prevCmd; + cmd->prevCmd = NULL; + + + JimDecrCmdRefCount(interp, cmd); + + + Jim_SetHashVal(ht, he, prevCmd); + } + else { + Jim_DeleteHashEntry(ht, cmdNameObj); + } + } + Jim_DecrRefCount(interp, cmdNameObj); + } + Jim_FreeStack(localCommands); + Jim_Free(localCommands); + } + return JIM_OK; +} + +static int JimInvokeDefer(Jim_Interp *interp, int retcode) +{ + Jim_Obj *objPtr; + + + if (JimFindVariable(&interp->framePtr->vars, interp->defer) == NULL) { + return retcode; + } + objPtr = Jim_GetVariable(interp, interp->defer, JIM_NONE); + + if (objPtr) { + int ret = JIM_OK; + int i; + int listLen = Jim_ListLength(interp, objPtr); + Jim_Obj *resultObjPtr; + + Jim_IncrRefCount(objPtr); + + resultObjPtr = Jim_GetResult(interp); + Jim_IncrRefCount(resultObjPtr); + Jim_SetEmptyResult(interp); + + + for (i = listLen; i > 0; i--) { + + Jim_Obj *scriptObjPtr = Jim_ListGetIndex(interp, objPtr, i - 1); + ret = Jim_EvalObj(interp, scriptObjPtr); + if (ret != JIM_OK) { + break; + } + } + + if (ret == JIM_OK || retcode == JIM_ERR) { + + Jim_SetResult(interp, resultObjPtr); + } + else { + retcode = ret; + } + + Jim_DecrRefCount(interp, resultObjPtr); + Jim_DecrRefCount(interp, objPtr); + } + return retcode; +} + +#define JIM_FCF_FULL 0 +#define JIM_FCF_REUSE 1 +static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int action) + { + JimDeleteLocalProcs(interp, cf->localCommands); + + if (cf->procArgsObjPtr) + Jim_DecrRefCount(interp, cf->procArgsObjPtr); + if (cf->procBodyObjPtr) + Jim_DecrRefCount(interp, cf->procBodyObjPtr); + Jim_DecrRefCount(interp, cf->nsObj); + if (action == JIM_FCF_FULL || cf->vars.size != JIM_HT_INITIAL_SIZE) + Jim_FreeHashTable(&cf->vars); + else { + Jim_ClearHashTable(&cf->vars); + } + cf->next = interp->freeFramesList; + interp->freeFramesList = cf; +} + + + +int Jim_IsBigEndian(void) +{ + union { + unsigned short s; + unsigned char c[2]; + } uval = {0x0102}; + + return uval.c[0] == 1; +} + + +Jim_Interp *Jim_CreateInterp(void) +{ + Jim_Interp *i = Jim_Alloc(sizeof(*i)); + + memset(i, 0, sizeof(*i)); + + i->maxCallFrameDepth = JIM_MAX_CALLFRAME_DEPTH; + i->maxEvalDepth = JIM_MAX_EVAL_DEPTH; + i->lastCollectTime = Jim_GetTimeUsec(CLOCK_MONOTONIC_RAW); + + Jim_InitHashTable(&i->commands, &JimCommandsHashTableType, i); +#ifdef JIM_REFERENCES + Jim_InitHashTable(&i->references, &JimReferencesHashTableType, i); +#endif + Jim_InitHashTable(&i->assocData, &JimAssocDataHashTableType, i); + Jim_InitHashTable(&i->packages, &JimPackageHashTableType, NULL); + i->emptyObj = Jim_NewEmptyStringObj(i); + i->trueObj = Jim_NewIntObj(i, 1); + i->falseObj = Jim_NewIntObj(i, 0); + i->framePtr = i->topFramePtr = JimCreateCallFrame(i, NULL, i->emptyObj); + i->result = i->emptyObj; + i->stackTrace = Jim_NewListObj(i, NULL, 0); + i->unknown = Jim_NewStringObj(i, "unknown", -1); + i->defer = Jim_NewStringObj(i, "jim::defer", -1); + i->errorProc = i->emptyObj; + i->nullScriptObj = Jim_NewEmptyStringObj(i); + i->evalFrame = &i->topEvalFrame; + i->currentFilenameObj = Jim_NewEmptyStringObj(i); + Jim_IncrRefCount(i->emptyObj); + Jim_IncrRefCount(i->result); + Jim_IncrRefCount(i->stackTrace); + Jim_IncrRefCount(i->unknown); + Jim_IncrRefCount(i->defer); + Jim_IncrRefCount(i->nullScriptObj); + Jim_IncrRefCount(i->errorProc); + Jim_IncrRefCount(i->trueObj); + Jim_IncrRefCount(i->falseObj); + Jim_IncrRefCount(i->currentFilenameObj); + + + Jim_SetVariableStrWithStr(i, JIM_LIBPATH, TCL_LIBRARY); + Jim_SetVariableStrWithStr(i, JIM_INTERACTIVE, "0"); + + Jim_SetVariableStrWithStr(i, "tcl_platform(engine)", "Jim"); + Jim_SetVariableStrWithStr(i, "tcl_platform(os)", TCL_PLATFORM_OS); + Jim_SetVariableStrWithStr(i, "tcl_platform(platform)", TCL_PLATFORM_PLATFORM); + Jim_SetVariableStrWithStr(i, "tcl_platform(pathSeparator)", TCL_PLATFORM_PATH_SEPARATOR); + Jim_SetVariableStrWithStr(i, "tcl_platform(byteOrder)", Jim_IsBigEndian() ? "bigEndian" : "littleEndian"); + Jim_SetVariableStrWithStr(i, "tcl_platform(threaded)", "0"); + Jim_SetVariableStrWithStr(i, "tcl_platform(bootstrap)", "0"); + Jim_SetVariableStr(i, "tcl_platform(pointerSize)", Jim_NewIntObj(i, sizeof(void *))); + Jim_SetVariableStr(i, "tcl_platform(wordSize)", Jim_NewIntObj(i, sizeof(jim_wide))); + Jim_SetVariableStr(i, "tcl_platform(stackFormat)", Jim_NewIntObj(i, 4)); + + return i; +} + +void Jim_FreeInterp(Jim_Interp *i) +{ + Jim_CallFrame *cf, *cfx; + + Jim_Obj *objPtr, *nextObjPtr; + + i->quitting = 1; + + + for (cf = i->framePtr; cf; cf = cfx) { + + JimInvokeDefer(i, JIM_OK); + cfx = cf->parent; + JimFreeCallFrame(i, cf, JIM_FCF_FULL); + } + + Jim_DecrRefCount(i, i->emptyObj); + Jim_DecrRefCount(i, i->trueObj); + Jim_DecrRefCount(i, i->falseObj); + Jim_DecrRefCount(i, i->result); + Jim_DecrRefCount(i, i->stackTrace); + Jim_DecrRefCount(i, i->errorProc); + Jim_DecrRefCount(i, i->unknown); + Jim_DecrRefCount(i, i->defer); + Jim_DecrRefCount(i, i->nullScriptObj); + Jim_DecrRefCount(i, i->currentFilenameObj); + + Jim_FreeHashTable(&i->commands); + + + Jim_InterpIncrProcEpoch(i); + +#ifdef JIM_REFERENCES + Jim_FreeHashTable(&i->references); +#endif + Jim_FreeHashTable(&i->packages); + Jim_Free(i->prngState); + Jim_FreeHashTable(&i->assocData); + if (i->traceCmdObj) { + Jim_DecrRefCount(i, i->traceCmdObj); + } + +#ifdef JIM_MAINTAINER + if (i->liveList != NULL) { + objPtr = i->liveList; + + printf("\n-------------------------------------\n"); + printf("Objects still in the free list:\n"); + while (objPtr) { + const char *type = objPtr->typePtr ? objPtr->typePtr->name : "string"; + Jim_String(objPtr); + + if (objPtr->bytes && strlen(objPtr->bytes) > 20) { + printf("%p (%d) %-10s: '%.20s...'\n", + (void *)objPtr, objPtr->refCount, type, objPtr->bytes); + } + else { + printf("%p (%d) %-10s: '%s'\n", + (void *)objPtr, objPtr->refCount, type, objPtr->bytes ? objPtr->bytes : "(null)"); + } + if (objPtr->typePtr == &sourceObjType) { + printf("FILE %s LINE %d\n", + Jim_String(objPtr->internalRep.sourceValue.fileNameObj), + objPtr->internalRep.sourceValue.lineNumber); + } + objPtr = objPtr->nextObjPtr; + } + printf("-------------------------------------\n\n"); + JimPanic((1, "Live list non empty freeing the interpreter! Leak?")); + } +#endif + + + objPtr = i->freeList; + while (objPtr) { + nextObjPtr = objPtr->nextObjPtr; + Jim_Free(objPtr); + objPtr = nextObjPtr; + } + + + for (cf = i->freeFramesList; cf; cf = cfx) { + cfx = cf->next; + if (cf->vars.table) + Jim_FreeHashTable(&cf->vars); + Jim_Free(cf); + } + + + Jim_Free(i); +} + +Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr) +{ + long level; + const char *str; + Jim_CallFrame *framePtr; + + if (levelObjPtr) { + str = Jim_String(levelObjPtr); + if (str[0] == '#') { + char *endptr; + + level = jim_strtol(str + 1, &endptr); + if (str[1] == '\0' || endptr[0] != '\0') { + level = -1; + } + } + else { + if (Jim_GetLong(interp, levelObjPtr, &level) != JIM_OK || level < 0) { + level = -1; + } + else { + + level = interp->framePtr->level - level; + } + } + } + else { + str = "1"; + level = interp->framePtr->level - 1; + } + + if (level == 0) { + return interp->topFramePtr; + } + if (level > 0) { + + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { + if (framePtr->level == level) { + return framePtr; + } + } + } + + Jim_SetResultFormatted(interp, "bad level \"%s\"", str); + return NULL; +} + +static Jim_CallFrame *JimGetCallFrameByInteger(Jim_Interp *interp, long level) +{ + Jim_CallFrame *framePtr; + + if (level == 0) { + return interp->framePtr; + } + + if (level < 0) { + + level = interp->framePtr->level + level; + } + + if (level > 0) { + + for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) { + if (framePtr->level == level) { + return framePtr; + } + } + } + return NULL; +} + +static Jim_EvalFrame *JimGetEvalFrameByProcLevel(Jim_Interp *interp, int proclevel) +{ + Jim_EvalFrame *evalFrame; + + if (proclevel == 0) { + return interp->evalFrame; + } + + if (proclevel < 0) { + + proclevel = interp->procLevel + proclevel; + } + + if (proclevel >= 0) { + + for (evalFrame = interp->evalFrame; evalFrame; evalFrame = evalFrame->parent) { + if (evalFrame->procLevel == proclevel) { + return evalFrame; + } + } + } + return NULL; +} + +static Jim_Obj *JimProcForEvalFrame(Jim_Interp *interp, Jim_EvalFrame *frame) +{ + if (frame == interp->evalFrame || (frame->cmd && frame->cmd->cmdNameObj)) { + Jim_EvalFrame *e; + for (e = frame->parent; e; e = e->parent) { + if (e->cmd && e->cmd->isproc && e->cmd->cmdNameObj) { + break; + } + } + if (e && e->cmd && e->cmd->cmdNameObj) { + return e->cmd->cmdNameObj; + } + } + return NULL; +} + +static void JimAddStackFrame(Jim_Interp *interp, Jim_EvalFrame *frame, Jim_Obj *listObj) +{ + Jim_Obj *procNameObj = JimProcForEvalFrame(interp, frame); + Jim_Obj *fileNameObj = interp->emptyObj; + int linenr = 1; + + if (frame->scriptObj) { + ScriptObj *script = JimGetScript(interp, frame->scriptObj); + fileNameObj = script->fileNameObj; + linenr = script->linenr; + } + + Jim_ListAppendElement(interp, listObj, procNameObj ? procNameObj : interp->emptyObj); + Jim_ListAppendElement(interp, listObj, fileNameObj); + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, linenr)); + Jim_ListAppendElement(interp, listObj, Jim_NewListObj(interp, frame->argv, frame->argc)); +} + +static void JimSetStackTrace(Jim_Interp *interp, Jim_Obj *stackTraceObj) +{ + + Jim_IncrRefCount(stackTraceObj); + Jim_DecrRefCount(interp, interp->stackTrace); + interp->stackTrace = stackTraceObj; + interp->errorFlag = 1; +} + +static void JimSetErrorStack(Jim_Interp *interp, ScriptObj *script) +{ + if (!interp->errorFlag) { + int i; + Jim_Obj *stackTrace = Jim_NewListObj(interp, NULL, 0); + + if (interp->procLevel == 0 && script) { + Jim_ListAppendElement(interp, stackTrace, interp->emptyObj); + Jim_ListAppendElement(interp, stackTrace, script->fileNameObj); + Jim_ListAppendElement(interp, stackTrace, Jim_NewIntObj(interp, script->linenr)); + Jim_ListAppendElement(interp, stackTrace, interp->emptyObj); + } + else { + for (i = 0; i <= interp->procLevel; i++) { + Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, -i); + if (frame) { + JimAddStackFrame(interp, frame, stackTrace); + } + } + } + JimSetStackTrace(interp, stackTrace); + } +} + +int Jim_SetAssocData(Jim_Interp *interp, const char *key, Jim_InterpDeleteProc * delProc, + void *data) +{ + AssocDataValue *assocEntryPtr = (AssocDataValue *) Jim_Alloc(sizeof(AssocDataValue)); + + assocEntryPtr->delProc = delProc; + assocEntryPtr->data = data; + return Jim_AddHashEntry(&interp->assocData, key, assocEntryPtr); +} + +void *Jim_GetAssocData(Jim_Interp *interp, const char *key) +{ + Jim_HashEntry *entryPtr = Jim_FindHashEntry(&interp->assocData, key); + + if (entryPtr != NULL) { + AssocDataValue *assocEntryPtr = Jim_GetHashEntryVal(entryPtr); + return assocEntryPtr->data; + } + return NULL; +} + +int Jim_DeleteAssocData(Jim_Interp *interp, const char *key) +{ + return Jim_DeleteHashEntry(&interp->assocData, key); +} + +int Jim_GetExitCode(Jim_Interp *interp) +{ + return interp->exitCode; +} + +static void UpdateStringOfInt(struct Jim_Obj *objPtr); +static int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags); + +static const Jim_ObjType intObjType = { + "int", + NULL, + NULL, + UpdateStringOfInt, + JIM_TYPE_NONE, +}; + +static const Jim_ObjType coercedDoubleObjType = { + "coerced-double", + NULL, + NULL, + UpdateStringOfInt, + JIM_TYPE_NONE, +}; + + +static void UpdateStringOfInt(struct Jim_Obj *objPtr) +{ + char buf[JIM_INTEGER_SPACE + 1]; + jim_wide wideValue = JimWideValue(objPtr); + int pos = 0; + + if (wideValue == 0) { + buf[pos++] = '0'; + } + else { + char tmp[JIM_INTEGER_SPACE]; + int num = 0; + int i; + + if (wideValue < 0) { + buf[pos++] = '-'; + i = wideValue % 10; + tmp[num++] = (i > 0) ? (10 - i) : -i; + wideValue /= -10; + } + + while (wideValue) { + tmp[num++] = wideValue % 10; + wideValue /= 10; + } + + for (i = 0; i < num; i++) { + buf[pos++] = '0' + tmp[num - i - 1]; + } + } + buf[pos] = 0; + + JimSetStringBytes(objPtr, buf); +} + +static int SetIntFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + jim_wide wideValue; + const char *str; + + if (objPtr->typePtr == &coercedDoubleObjType) { + + objPtr->typePtr = &intObjType; + return JIM_OK; + } + + + str = Jim_String(objPtr); + + if (Jim_StringToWide(str, &wideValue, 0) != JIM_OK) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "expected integer but got \"%#s\"", objPtr); + } + return JIM_ERR; + } + if ((wideValue == JIM_WIDE_MIN || wideValue == JIM_WIDE_MAX) && errno == ERANGE) { + Jim_SetResultString(interp, "Integer value too big to be represented", -1); + return JIM_ERR; + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &intObjType; + objPtr->internalRep.wideValue = wideValue; + return JIM_OK; +} + +#ifdef JIM_OPTIMIZATION +static int JimIsWide(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &intObjType; +} +#endif + +int Jim_GetWide(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr) +{ + if (objPtr->typePtr != &intObjType && SetIntFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR) + return JIM_ERR; + *widePtr = JimWideValue(objPtr); + return JIM_OK; +} + +int Jim_GetWideExpr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr) +{ + int ret = JIM_OK; + + if (objPtr->typePtr == &sourceObjType || objPtr->typePtr == NULL) { + SetIntFromAny(interp, objPtr, 0); + } + if (objPtr->typePtr == &intObjType) { + *widePtr = JimWideValue(objPtr); + } + else { + JimPanic((interp->safeexpr, "interp->safeexpr is set")); + interp->safeexpr++; + ret = Jim_EvalExpression(interp, objPtr); + interp->safeexpr--; + + if (ret == JIM_OK) { + ret = Jim_GetWide(interp, Jim_GetResult(interp), widePtr); + } + if (ret != JIM_OK) { + Jim_SetResultFormatted(interp, "expected integer expression but got \"%#s\"", objPtr); + } + } + return ret; +} + + +static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr) +{ + if (objPtr->typePtr != &intObjType && SetIntFromAny(interp, objPtr, JIM_NONE) == JIM_ERR) + return JIM_ERR; + *widePtr = JimWideValue(objPtr); + return JIM_OK; +} + +int Jim_GetLong(Jim_Interp *interp, Jim_Obj *objPtr, long *longPtr) +{ + jim_wide wideValue; + int retval; + + retval = Jim_GetWide(interp, objPtr, &wideValue); + if (retval == JIM_OK) { + *longPtr = (long)wideValue; + return JIM_OK; + } + return JIM_ERR; +} + +Jim_Obj *Jim_NewIntObj(Jim_Interp *interp, jim_wide wideValue) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &intObjType; + objPtr->bytes = NULL; + objPtr->internalRep.wideValue = wideValue; + return objPtr; +} + +#define JIM_DOUBLE_SPACE 30 + +static void UpdateStringOfDouble(struct Jim_Obj *objPtr); +static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr); + +static const Jim_ObjType doubleObjType = { + "double", + NULL, + NULL, + UpdateStringOfDouble, + JIM_TYPE_NONE, +}; + +#if !HAVE_DECL_ISNAN +#undef isnan +#define isnan(X) ((X) != (X)) +#endif +#if !HAVE_DECL_ISINF +#undef isinf +#define isinf(X) (1.0 / (X) == 0.0) +#endif + +static void UpdateStringOfDouble(struct Jim_Obj *objPtr) +{ + double value = objPtr->internalRep.doubleValue; + + if (isnan(value)) { + JimSetStringBytes(objPtr, "NaN"); + return; + } + if (isinf(value)) { + if (value < 0) { + JimSetStringBytes(objPtr, "-Inf"); + } + else { + JimSetStringBytes(objPtr, "Inf"); + } + return; + } + { + char buf[JIM_DOUBLE_SPACE + 1]; + int i; + int len = sprintf(buf, "%.12g", value); + + + for (i = 0; i < len; i++) { + if (buf[i] == '.' || buf[i] == 'e') { +#if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX) + char *e = strchr(buf, 'e'); + if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') { + + e += 2; + memmove(e, e + 1, len - (e - buf)); + } +#endif + break; + } + } + if (buf[i] == '\0') { + buf[i++] = '.'; + buf[i++] = '0'; + buf[i] = '\0'; + } + JimSetStringBytes(objPtr, buf); + } +} + +static int SetDoubleFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + double doubleValue; + jim_wide wideValue; + const char *str; + +#ifdef HAVE_LONG_LONG + +#define MIN_INT_IN_DOUBLE -(1LL << 53) +#define MAX_INT_IN_DOUBLE -(MIN_INT_IN_DOUBLE + 1) + + if (objPtr->typePtr == &intObjType + && JimWideValue(objPtr) >= MIN_INT_IN_DOUBLE + && JimWideValue(objPtr) <= MAX_INT_IN_DOUBLE) { + + + objPtr->typePtr = &coercedDoubleObjType; + return JIM_OK; + } +#endif + str = Jim_String(objPtr); + + if (Jim_StringToWide(str, &wideValue, 10) == JIM_OK) { + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &coercedDoubleObjType; + objPtr->internalRep.wideValue = wideValue; + return JIM_OK; + } + else { + + if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) { + Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr); + return JIM_ERR; + } + + Jim_FreeIntRep(interp, objPtr); + } + objPtr->typePtr = &doubleObjType; + objPtr->internalRep.doubleValue = doubleValue; + return JIM_OK; +} + +int Jim_GetDouble(Jim_Interp *interp, Jim_Obj *objPtr, double *doublePtr) +{ + if (objPtr->typePtr == &coercedDoubleObjType) { + *doublePtr = JimWideValue(objPtr); + return JIM_OK; + } + if (objPtr->typePtr != &doubleObjType && SetDoubleFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + + if (objPtr->typePtr == &coercedDoubleObjType) { + *doublePtr = JimWideValue(objPtr); + } + else { + *doublePtr = objPtr->internalRep.doubleValue; + } + return JIM_OK; +} + +Jim_Obj *Jim_NewDoubleObj(Jim_Interp *interp, double doubleValue) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &doubleObjType; + objPtr->bytes = NULL; + objPtr->internalRep.doubleValue = doubleValue; + return objPtr; +} + +static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags); + +int Jim_GetBoolean(Jim_Interp *interp, Jim_Obj *objPtr, int * booleanPtr) +{ + if (objPtr->typePtr != &intObjType && SetBooleanFromAny(interp, objPtr, JIM_ERRMSG) == JIM_ERR) + return JIM_ERR; + *booleanPtr = (int) JimWideValue(objPtr); + return JIM_OK; +} + +static const char * const jim_true_false_strings[8] = { + "1", "true", "yes", "on", + "0", "false", "no", "off" +}; + +static const int jim_true_false_lens[8] = { + 1, 4, 3, 2, + 1, 5, 2, 3, +}; + +static int SetBooleanFromAny(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + int index = Jim_FindByName(Jim_String(objPtr), jim_true_false_strings, + sizeof(jim_true_false_strings) / sizeof(*jim_true_false_strings)); + if (index < 0) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "expected boolean but got \"%#s\"", objPtr); + } + return JIM_ERR; + } + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &intObjType; + + objPtr->internalRep.wideValue = index < 4 ? 1 : 0; + return JIM_OK; +} + +static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec); +static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr); +static void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfList(struct Jim_Obj *objPtr); +static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType listObjType = { + "list", + FreeListInternalRep, + DupListInternalRep, + UpdateStringOfList, + JIM_TYPE_NONE, +}; + +void FreeListInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int i; + + for (i = 0; i < objPtr->internalRep.listValue.len; i++) { + Jim_DecrRefCount(interp, objPtr->internalRep.listValue.ele[i]); + } + Jim_Free(objPtr->internalRep.listValue.ele); +} + +void DupListInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + int i; + + JIM_NOTUSED(interp); + + dupPtr->internalRep.listValue.len = srcPtr->internalRep.listValue.len; + dupPtr->internalRep.listValue.maxLen = srcPtr->internalRep.listValue.maxLen; + dupPtr->internalRep.listValue.ele = + Jim_Alloc(sizeof(Jim_Obj *) * srcPtr->internalRep.listValue.maxLen); + memcpy(dupPtr->internalRep.listValue.ele, srcPtr->internalRep.listValue.ele, + sizeof(Jim_Obj *) * srcPtr->internalRep.listValue.len); + for (i = 0; i < dupPtr->internalRep.listValue.len; i++) { + Jim_IncrRefCount(dupPtr->internalRep.listValue.ele[i]); + } + dupPtr->typePtr = &listObjType; +} + +#define JIM_ELESTR_SIMPLE 0 +#define JIM_ELESTR_BRACE 1 +#define JIM_ELESTR_QUOTE 2 +static unsigned char ListElementQuotingType(const char *s, int len) +{ + int i, level, blevel, trySimple = 1; + + + if (len == 0) + return JIM_ELESTR_BRACE; + if (s[0] == '"' || s[0] == '{') { + trySimple = 0; + goto testbrace; + } + for (i = 0; i < len; i++) { + switch (s[i]) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case ';': + case '\\': + case '\r': + case '\n': + case '\t': + case '\f': + case '\v': + trySimple = 0; + + case '{': + case '}': + goto testbrace; + } + } + return JIM_ELESTR_SIMPLE; + + testbrace: + + if (s[len - 1] == '\\') + return JIM_ELESTR_QUOTE; + level = 0; + blevel = 0; + for (i = 0; i < len; i++) { + switch (s[i]) { + case '{': + level++; + break; + case '}': + level--; + if (level < 0) + return JIM_ELESTR_QUOTE; + break; + case '[': + blevel++; + break; + case ']': + blevel--; + break; + case '\\': + if (s[i + 1] == '\n') + return JIM_ELESTR_QUOTE; + else if (s[i + 1] != '\0') + i++; + break; + } + } + if (blevel < 0) { + return JIM_ELESTR_QUOTE; + } + + if (level == 0) { + if (!trySimple) + return JIM_ELESTR_BRACE; + for (i = 0; i < len; i++) { + switch (s[i]) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case ';': + case '\\': + case '\r': + case '\n': + case '\t': + case '\f': + case '\v': + return JIM_ELESTR_BRACE; + break; + } + } + return JIM_ELESTR_SIMPLE; + } + return JIM_ELESTR_QUOTE; +} + +static int BackslashQuoteString(const char *s, int len, char *q) +{ + char *p = q; + + while (len--) { + switch (*s) { + case ' ': + case '$': + case '"': + case '[': + case ']': + case '{': + case '}': + case ';': + case '\\': + *p++ = '\\'; + *p++ = *s++; + break; + case '\n': + *p++ = '\\'; + *p++ = 'n'; + s++; + break; + case '\r': + *p++ = '\\'; + *p++ = 'r'; + s++; + break; + case '\t': + *p++ = '\\'; + *p++ = 't'; + s++; + break; + case '\f': + *p++ = '\\'; + *p++ = 'f'; + s++; + break; + case '\v': + *p++ = '\\'; + *p++ = 'v'; + s++; + break; + default: + *p++ = *s++; + break; + } + } + *p = '\0'; + + return p - q; +} + +static void JimMakeListStringRep(Jim_Obj *objPtr, Jim_Obj **objv, int objc) +{ + #define STATIC_QUOTING_LEN 32 + int i, bufLen, realLength; + const char *strRep; + char *p; + unsigned char *quotingType, staticQuoting[STATIC_QUOTING_LEN]; + + + if (objc > STATIC_QUOTING_LEN) { + quotingType = Jim_Alloc(objc); + } + else { + quotingType = staticQuoting; + } + bufLen = 0; + for (i = 0; i < objc; i++) { + int len; + + strRep = Jim_GetString(objv[i], &len); + quotingType[i] = ListElementQuotingType(strRep, len); + switch (quotingType[i]) { + case JIM_ELESTR_SIMPLE: + if (i != 0 || strRep[0] != '#') { + bufLen += len; + break; + } + + quotingType[i] = JIM_ELESTR_BRACE; + + case JIM_ELESTR_BRACE: + bufLen += len + 2; + break; + case JIM_ELESTR_QUOTE: + bufLen += len * 2; + break; + } + bufLen++; + } + bufLen++; + + + p = objPtr->bytes = Jim_Alloc(bufLen + 1); + realLength = 0; + for (i = 0; i < objc; i++) { + int len, qlen; + + strRep = Jim_GetString(objv[i], &len); + + switch (quotingType[i]) { + case JIM_ELESTR_SIMPLE: + memcpy(p, strRep, len); + p += len; + realLength += len; + break; + case JIM_ELESTR_BRACE: + *p++ = '{'; + memcpy(p, strRep, len); + p += len; + *p++ = '}'; + realLength += len + 2; + break; + case JIM_ELESTR_QUOTE: + if (i == 0 && strRep[0] == '#') { + *p++ = '\\'; + realLength++; + } + qlen = BackslashQuoteString(strRep, len, p); + p += qlen; + realLength += qlen; + break; + } + + if (i + 1 != objc) { + *p++ = ' '; + realLength++; + } + } + *p = '\0'; + objPtr->length = realLength; + + if (quotingType != staticQuoting) { + Jim_Free(quotingType); + } +} + +static void UpdateStringOfList(struct Jim_Obj *objPtr) +{ + JimMakeListStringRep(objPtr, objPtr->internalRep.listValue.ele, objPtr->internalRep.listValue.len); +} + +static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + struct JimParserCtx parser; + const char *str; + int strLen; + Jim_Obj *fileNameObj; + int linenr; + + if (objPtr->typePtr == &listObjType) { + return JIM_OK; + } + + + if (Jim_IsDict(objPtr) && objPtr->bytes == NULL) { + Jim_Dict *dict = objPtr->internalRep.dictValue; + + + objPtr->typePtr = &listObjType; + objPtr->internalRep.listValue.len = dict->len; + objPtr->internalRep.listValue.maxLen = dict->maxLen; + objPtr->internalRep.listValue.ele = dict->table; + + + Jim_Free(dict->ht); + + + Jim_Free(dict); + return JIM_OK; + } + + + fileNameObj = Jim_GetSourceInfo(interp, objPtr, &linenr); + Jim_IncrRefCount(fileNameObj); + + + str = Jim_GetString(objPtr, &strLen); + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &listObjType; + objPtr->internalRep.listValue.len = 0; + objPtr->internalRep.listValue.maxLen = 0; + objPtr->internalRep.listValue.ele = NULL; + + + if (strLen) { + JimParserInit(&parser, str, strLen, linenr); + while (!parser.eof) { + Jim_Obj *elementPtr; + + JimParseList(&parser); + if (parser.tt != JIM_TT_STR && parser.tt != JIM_TT_ESC) + continue; + elementPtr = JimParserGetTokenObj(interp, &parser); + Jim_SetSourceInfo(interp, elementPtr, fileNameObj, parser.tline); + ListAppendElement(objPtr, elementPtr); + } + } + Jim_DecrRefCount(interp, fileNameObj); + return JIM_OK; +} + +Jim_Obj *Jim_NewListObj(Jim_Interp *interp, Jim_Obj *const *elements, int len) +{ + Jim_Obj *objPtr; + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &listObjType; + objPtr->bytes = NULL; + objPtr->internalRep.listValue.ele = NULL; + objPtr->internalRep.listValue.len = 0; + objPtr->internalRep.listValue.maxLen = 0; + + if (len) { + ListInsertElements(objPtr, 0, len, elements); + } + + return objPtr; +} + +static void JimListGetElements(Jim_Interp *interp, Jim_Obj *listObj, int *listLen, + Jim_Obj ***listVec) +{ + *listLen = Jim_ListLength(interp, listObj); + *listVec = listObj->internalRep.listValue.ele; +} + + +static int JimSign(jim_wide w) +{ + if (w == 0) { + return 0; + } + else if (w < 0) { + return -1; + } + return 1; +} + + +struct lsort_info { + jmp_buf jmpbuf; + Jim_Obj *command; + Jim_Interp *interp; + enum { + JIM_LSORT_ASCII, + JIM_LSORT_NOCASE, + JIM_LSORT_INTEGER, + JIM_LSORT_REAL, + JIM_LSORT_COMMAND, + JIM_LSORT_DICT + } type; + int order; + Jim_Obj **indexv; + int indexc; + int unique; + int (*subfn)(Jim_Obj **, Jim_Obj **); +}; + +static struct lsort_info *sort_info; + +static int ListSortIndexHelper(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + Jim_Obj *lObj, *rObj; + + if (Jim_ListIndices(sort_info->interp, *lhsObj, sort_info->indexv, sort_info->indexc, &lObj, JIM_ERRMSG) != JIM_OK || + Jim_ListIndices(sort_info->interp, *rhsObj, sort_info->indexv, sort_info->indexc, &rObj, JIM_ERRMSG) != JIM_OK) { + longjmp(sort_info->jmpbuf, JIM_ERR); + } + return sort_info->subfn(&lObj, &rObj); +} + + +static int ListSortString(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 0) * sort_info->order; +} + +static int ListSortStringNoCase(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 1) * sort_info->order; +} + +static int ListSortDict(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + + const char *left = Jim_String(*lhsObj); + const char *right = Jim_String(*rhsObj); + + while (1) { + if (isdigit(UCHAR(*left)) && isdigit(UCHAR(*right))) { + + jim_wide lint, rint; + char *lend, *rend; + lint = jim_strtoull(left, &lend); + rint = jim_strtoull(right, &rend); + if (lint != rint) { + return JimSign(lint - rint) * sort_info->order; + } + if (lend -left != rend - right) { + return JimSign((lend - left) - (rend - right)) * sort_info->order; + } + left = lend; + right = rend; + } + else { + int cl, cr; + left += utf8_tounicode_case(left, &cl, 1); + right += utf8_tounicode_case(right, &cr, 1); + if (cl != cr) { + return JimSign(cl - cr) * sort_info->order; + } + if (cl == 0) { + + return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 0) * sort_info->order; + } + } + } +} + +static int ListSortInteger(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + jim_wide lhs = 0, rhs = 0; + + if (Jim_GetWide(sort_info->interp, *lhsObj, &lhs) != JIM_OK || + Jim_GetWide(sort_info->interp, *rhsObj, &rhs) != JIM_OK) { + longjmp(sort_info->jmpbuf, JIM_ERR); + } + + return JimSign(lhs - rhs) * sort_info->order; +} + +static int ListSortReal(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + double lhs = 0, rhs = 0; + + if (Jim_GetDouble(sort_info->interp, *lhsObj, &lhs) != JIM_OK || + Jim_GetDouble(sort_info->interp, *rhsObj, &rhs) != JIM_OK) { + longjmp(sort_info->jmpbuf, JIM_ERR); + } + if (lhs == rhs) { + return 0; + } + if (lhs > rhs) { + return sort_info->order; + } + return -sort_info->order; +} + +static int ListSortCommand(Jim_Obj **lhsObj, Jim_Obj **rhsObj) +{ + Jim_Obj *compare_script; + int rc; + + jim_wide ret = 0; + + + compare_script = Jim_DuplicateObj(sort_info->interp, sort_info->command); + Jim_ListAppendElement(sort_info->interp, compare_script, *lhsObj); + Jim_ListAppendElement(sort_info->interp, compare_script, *rhsObj); + + rc = Jim_EvalObj(sort_info->interp, compare_script); + + if (rc != JIM_OK || Jim_GetWide(sort_info->interp, Jim_GetResult(sort_info->interp), &ret) != JIM_OK) { + longjmp(sort_info->jmpbuf, rc); + } + + return JimSign(ret) * sort_info->order; +} + +static void ListRemoveDuplicates(Jim_Obj *listObjPtr, int (*comp)(Jim_Obj **lhs, Jim_Obj **rhs)) +{ + int src; + int dst = 0; + Jim_Obj **ele = listObjPtr->internalRep.listValue.ele; + + for (src = 1; src < listObjPtr->internalRep.listValue.len; src++) { + if (comp(&ele[dst], &ele[src]) == 0) { + + Jim_DecrRefCount(sort_info->interp, ele[dst]); + } + else { + + dst++; + } + ele[dst] = ele[src]; + } + + + dst++; + if (dst < listObjPtr->internalRep.listValue.len) { + ele[dst] = ele[src]; + } + + + listObjPtr->internalRep.listValue.len = dst; +} + + +static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsort_info *info) +{ + struct lsort_info *prev_info; + + typedef int (qsort_comparator) (const void *, const void *); + int (*fn) (Jim_Obj **, Jim_Obj **); + Jim_Obj **vector; + int len; + int rc; + + JimPanic((Jim_IsShared(listObjPtr), "ListSortElements called with shared object")); + SetListFromAny(interp, listObjPtr); + + + prev_info = sort_info; + sort_info = info; + + vector = listObjPtr->internalRep.listValue.ele; + len = listObjPtr->internalRep.listValue.len; + switch (info->type) { + case JIM_LSORT_ASCII: + fn = ListSortString; + break; + case JIM_LSORT_NOCASE: + fn = ListSortStringNoCase; + break; + case JIM_LSORT_INTEGER: + fn = ListSortInteger; + break; + case JIM_LSORT_REAL: + fn = ListSortReal; + break; + case JIM_LSORT_COMMAND: + fn = ListSortCommand; + break; + case JIM_LSORT_DICT: + fn = ListSortDict; + break; + default: + fn = NULL; + JimPanic((1, "ListSort called with invalid sort type")); + return -1; + } + + if (info->indexc) { + + info->subfn = fn; + fn = ListSortIndexHelper; + } + + if ((rc = setjmp(info->jmpbuf)) == 0) { + qsort(vector, len, sizeof(Jim_Obj *), (qsort_comparator *) fn); + + if (info->unique && len > 1) { + ListRemoveDuplicates(listObjPtr, fn); + } + + Jim_InvalidateStringRep(listObjPtr); + } + sort_info = prev_info; + + return rc; +} + + +static void ListEnsureLength(Jim_Obj *listPtr, int idx) +{ + assert(idx >= 0); + if (idx >= listPtr->internalRep.listValue.maxLen) { + if (idx < 4) { + + idx = 4; + } + listPtr->internalRep.listValue.ele = Jim_Realloc(listPtr->internalRep.listValue.ele, + sizeof(Jim_Obj *) * idx); + + listPtr->internalRep.listValue.maxLen = idx; + } +} + +static void ListInsertElements(Jim_Obj *listPtr, int idx, int elemc, Jim_Obj *const *elemVec) +{ + int currentLen = listPtr->internalRep.listValue.len; + int requiredLen = currentLen + elemc; + int i; + Jim_Obj **point; + + if (elemc == 0) { + + return; + } + + if (requiredLen > listPtr->internalRep.listValue.maxLen) { + if (currentLen) { + + requiredLen *= 2; + } + ListEnsureLength(listPtr, requiredLen); + } + if (idx < 0) { + idx = currentLen; + } + point = listPtr->internalRep.listValue.ele + idx; + memmove(point + elemc, point, (currentLen - idx) * sizeof(Jim_Obj *)); + for (i = 0; i < elemc; ++i) { + point[i] = elemVec[i]; + Jim_IncrRefCount(point[i]); + } + listPtr->internalRep.listValue.len += elemc; +} + +static void ListAppendElement(Jim_Obj *listPtr, Jim_Obj *objPtr) +{ + ListInsertElements(listPtr, -1, 1, &objPtr); +} + +static void ListAppendList(Jim_Obj *listPtr, Jim_Obj *appendListPtr) +{ + ListInsertElements(listPtr, -1, + appendListPtr->internalRep.listValue.len, appendListPtr->internalRep.listValue.ele); +} + +void Jim_ListAppendElement(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *objPtr) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListAppendElement called with shared object")); + SetListFromAny(interp, listPtr); + Jim_InvalidateStringRep(listPtr); + ListAppendElement(listPtr, objPtr); +} + +void Jim_ListAppendList(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *appendListPtr) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListAppendList called with shared object")); + SetListFromAny(interp, listPtr); + SetListFromAny(interp, appendListPtr); + Jim_InvalidateStringRep(listPtr); + ListAppendList(listPtr, appendListPtr); +} + +int Jim_ListLength(Jim_Interp *interp, Jim_Obj *objPtr) +{ + SetListFromAny(interp, objPtr); + return objPtr->internalRep.listValue.len; +} + +void Jim_ListInsertElements(Jim_Interp *interp, Jim_Obj *listPtr, int idx, + int objc, Jim_Obj *const *objVec) +{ + JimPanic((Jim_IsShared(listPtr), "Jim_ListInsertElement called with shared object")); + SetListFromAny(interp, listPtr); + if (idx >= 0 && idx > listPtr->internalRep.listValue.len) + idx = listPtr->internalRep.listValue.len; + else if (idx < 0) + idx = 0; + Jim_InvalidateStringRep(listPtr); + ListInsertElements(listPtr, idx, objc, objVec); +} + +Jim_Obj *Jim_ListGetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx) +{ + SetListFromAny(interp, listPtr); + if ((idx >= 0 && idx >= listPtr->internalRep.listValue.len) || + (idx < 0 && (-idx - 1) >= listPtr->internalRep.listValue.len)) { + return NULL; + } + if (idx < 0) + idx = listPtr->internalRep.listValue.len + idx; + return listPtr->internalRep.listValue.ele[idx]; +} + +int Jim_ListIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx, Jim_Obj **objPtrPtr, int flags) +{ + *objPtrPtr = Jim_ListGetIndex(interp, listPtr, idx); + if (*objPtrPtr == NULL) { + if (flags & JIM_ERRMSG) { + Jim_SetResultString(interp, "list index out of range", -1); + } + return JIM_ERR; + } + return JIM_OK; +} + +static int Jim_ListIndices(Jim_Interp *interp, Jim_Obj *listPtr, + Jim_Obj *const *indexv, int indexc, Jim_Obj **resultObj, int flags) +{ + int i; + int static_idxes[5]; + int *idxes = static_idxes; + int ret = JIM_OK; + + if (indexc > sizeof(static_idxes) / sizeof(*static_idxes)) { + idxes = Jim_Alloc(indexc * sizeof(*idxes)); + } + + for (i = 0; i < indexc; i++) { + ret = Jim_GetIndex(interp, indexv[i], &idxes[i]); + if (ret != JIM_OK) { + goto err; + } + } + + for (i = 0; i < indexc; i++) { + Jim_Obj *objPtr = Jim_ListGetIndex(interp, listPtr, idxes[i]); + if (!objPtr) { + if (flags & JIM_ERRMSG) { + if (idxes[i] < 0 || idxes[i] > Jim_ListLength(interp, listPtr)) { + Jim_SetResultFormatted(interp, "index \"%#s\" out of range", indexv[i]); + } + else { + Jim_SetResultFormatted(interp, "element %#s missing from sublist \"%#s\"", indexv[i], listPtr); + } + } + return -1; + } + listPtr = objPtr; + } + *resultObj = listPtr; +err: + if (idxes != static_idxes) + Jim_Free(idxes); + return ret; +} + +static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx, + Jim_Obj *newObjPtr, int flags) +{ + SetListFromAny(interp, listPtr); + if ((idx >= 0 && idx >= listPtr->internalRep.listValue.len) || + (idx < 0 && (-idx - 1) >= listPtr->internalRep.listValue.len)) { + if (flags & JIM_ERRMSG) { + Jim_SetResultString(interp, "list index out of range", -1); + } + return JIM_ERR; + } + if (idx < 0) + idx = listPtr->internalRep.listValue.len + idx; + Jim_DecrRefCount(interp, listPtr->internalRep.listValue.ele[idx]); + listPtr->internalRep.listValue.ele[idx] = newObjPtr; + Jim_IncrRefCount(newObjPtr); + return JIM_OK; +} + +int Jim_ListSetIndex(Jim_Interp *interp, Jim_Obj *varNamePtr, + Jim_Obj *const *indexv, int indexc, Jim_Obj *newObjPtr) +{ + Jim_Obj *varObjPtr, *objPtr, *listObjPtr; + int shared, i, idx; + + varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG | JIM_UNSHARED); + if (objPtr == NULL) + return JIM_ERR; + if ((shared = Jim_IsShared(objPtr))) + varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr); + for (i = 0; i < indexc - 1; i++) { + listObjPtr = objPtr; + if (Jim_GetIndex(interp, indexv[i], &idx) != JIM_OK) + goto err; + + objPtr = Jim_ListGetIndex(interp, listObjPtr, idx); + if (objPtr == NULL) { + Jim_SetResultFormatted(interp, "index \"%#s\" out of range", indexv[i]); + goto err; + } + if (Jim_IsShared(objPtr)) { + objPtr = Jim_DuplicateObj(interp, objPtr); + ListSetIndex(interp, listObjPtr, idx, objPtr, JIM_NONE); + } + Jim_InvalidateStringRep(listObjPtr); + } + if (Jim_GetIndex(interp, indexv[indexc - 1], &idx) != JIM_OK) + goto err; + if (ListSetIndex(interp, objPtr, idx, newObjPtr, JIM_ERRMSG) == JIM_ERR) + goto err; + Jim_InvalidateStringRep(objPtr); + Jim_InvalidateStringRep(varObjPtr); + if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) + goto err; + Jim_SetResult(interp, varObjPtr); + return JIM_OK; + err: + if (shared) { + Jim_FreeNewObj(interp, varObjPtr); + } + return JIM_ERR; +} + +Jim_Obj *Jim_ListJoin(Jim_Interp *interp, Jim_Obj *listObjPtr, const char *joinStr, int joinStrLen) +{ + int i; + int listLen = Jim_ListLength(interp, listObjPtr); + Jim_Obj *resObjPtr = Jim_NewEmptyStringObj(interp); + + for (i = 0; i < listLen; ) { + Jim_AppendObj(interp, resObjPtr, Jim_ListGetIndex(interp, listObjPtr, i)); + if (++i != listLen) { + Jim_AppendString(interp, resObjPtr, joinStr, joinStrLen); + } + } + return resObjPtr; +} + +Jim_Obj *Jim_ConcatObj(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int i; + + for (i = 0; i < objc; i++) { + if (!Jim_IsList(objv[i])) + break; + } + if (i == objc) { + Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; i < objc; i++) + ListAppendList(objPtr, objv[i]); + return objPtr; + } + else { + + int len = 0, objLen; + char *bytes, *p; + + + for (i = 0; i < objc; i++) { + len += Jim_Length(objv[i]); + } + if (objc) + len += objc - 1; + + p = bytes = Jim_Alloc(len + 1); + for (i = 0; i < objc; i++) { + const char *s = Jim_GetString(objv[i], &objLen); + + + while (objLen && isspace(UCHAR(*s))) { + s++; + objLen--; + len--; + } + + while (objLen && isspace(UCHAR(s[objLen - 1]))) { + + if (objLen > 1 && s[objLen - 2] == '\\') { + break; + } + objLen--; + len--; + } + memcpy(p, s, objLen); + p += objLen; + if (i + 1 != objc) { + if (objLen) + *p++ = ' '; + else { + len--; + } + } + } + *p = '\0'; + return Jim_NewStringObjNoAlloc(interp, bytes, len); + } +} + +Jim_Obj *Jim_ListRange(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *firstObjPtr, + Jim_Obj *lastObjPtr) +{ + int first, last; + int len, rangeLen; + + if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK || + Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK) + return NULL; + len = Jim_ListLength(interp, listObjPtr); + first = JimRelToAbsIndex(len, first); + last = JimRelToAbsIndex(len, last); + JimRelToAbsRange(len, &first, &last, &rangeLen); + if (first == 0 && last == len) { + return listObjPtr; + } + return Jim_NewListObj(interp, listObjPtr->internalRep.listValue.ele + first, rangeLen); +} + +static void FreeDictInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupDictInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfDict(struct Jim_Obj *objPtr); +static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + + +static const Jim_ObjType dictObjType = { + "dict", + FreeDictInternalRep, + DupDictInternalRep, + UpdateStringOfDict, + JIM_TYPE_NONE, +}; + +static void JimFreeDict(Jim_Interp *interp, Jim_Dict *dict) +{ + int i; + for (i = 0; i < dict->len; i++) { + Jim_DecrRefCount(interp, dict->table[i]); + } + Jim_Free(dict->table); + Jim_Free(dict->ht); + Jim_Free(dict); +} + +enum { + DICT_HASH_FIND = -1, + DICT_HASH_REMOVE = -2, + DICT_HASH_ADD = -3, +}; + +static int JimDictHashFind(Jim_Dict *dict, Jim_Obj *keyObjPtr, int op_tvoffset) +{ + unsigned h = (JimObjectHTHashFunction(keyObjPtr) + dict->uniq); + unsigned idx = h & dict->sizemask; + int tvoffset = 0; + unsigned peturb = h; + unsigned first_removed = ~0; + + if (dict->len) { + while ((tvoffset = dict->ht[idx].offset)) { + if (tvoffset == -1) { + if (first_removed == ~0) { + first_removed = idx; + } + } + else if (dict->ht[idx].hash == h) { + if (Jim_StringEqObj(keyObjPtr, dict->table[tvoffset - 1])) { + break; + } + } + + peturb >>= 5; + idx = (5 * idx + 1 + peturb) & dict->sizemask; + } + } + + switch (op_tvoffset) { + case DICT_HASH_FIND: + + break; + case DICT_HASH_REMOVE: + if (tvoffset) { + + dict->ht[idx].offset = -1; + dict->dummy++; + } + + break; + case DICT_HASH_ADD: + if (tvoffset == 0) { + + if (first_removed != ~0) { + idx = first_removed; + dict->dummy--; + } + dict->ht[idx].offset = dict->len + 1; + dict->ht[idx].hash = h; + } + + break; + default: + assert(tvoffset); + + dict->ht[idx].offset = op_tvoffset; + break; + } + + return tvoffset; +} + +static void JimDictExpandHashTable(Jim_Dict *dict, unsigned int size) +{ + int i; + struct JimDictHashEntry *prevht = dict->ht; + int prevsize = dict->size; + + dict->size = JimHashTableNextPower(size); + dict->sizemask = dict->size - 1; + + + dict->ht = Jim_Alloc(dict->size * sizeof(*dict->ht)); + memset(dict->ht, 0, dict->size * sizeof(*dict->ht)); + + + for (i = 0; i < prevsize; i++) { + if (prevht[i].offset > 0) { + + unsigned h = prevht[i].hash; + unsigned idx = h & dict->sizemask; + unsigned peturb = h; + + while (dict->ht[idx].offset) { + peturb >>= 5; + idx = (5 * idx + 1 + peturb) & dict->sizemask; + } + dict->ht[idx].offset = prevht[i].offset; + dict->ht[idx].hash = h; + } + } + Jim_Free(prevht); +} + +static int JimDictAdd(Jim_Dict *dict, Jim_Obj *keyObjPtr) +{ + if (dict->size <= dict->len + dict->dummy) { + JimDictExpandHashTable(dict, dict->size ? dict->size * 2 : 8); + } + return JimDictHashFind(dict, keyObjPtr, DICT_HASH_ADD); +} + +static Jim_Dict *JimDictNew(Jim_Interp *interp, int table_size, int ht_size) +{ + Jim_Dict *dict = Jim_Alloc(sizeof(*dict)); + memset(dict, 0, sizeof(*dict)); + + if (ht_size) { + JimDictExpandHashTable(dict, ht_size); + } + if (table_size) { + dict->table = Jim_Alloc(table_size * sizeof(*dict->table)); + dict->maxLen = table_size; + } +#ifdef JIM_RANDOMISE_HASH + dict->uniq = (rand() ^ time(NULL) ^ clock()); +#endif + return dict; +} + +static void FreeDictInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + JimFreeDict(interp, objPtr->internalRep.dictValue); +} + +static void DupDictInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + Jim_Dict *oldDict = srcPtr->internalRep.dictValue; + int i; + + + Jim_Dict *newDict = JimDictNew(interp, oldDict->maxLen, oldDict->size); + + + for (i = 0; i < oldDict->len; i++) { + newDict->table[i] = oldDict->table[i]; + Jim_IncrRefCount(newDict->table[i]); + } + newDict->len = oldDict->len; + + + newDict->uniq = oldDict->uniq; + + + memcpy(newDict->ht, oldDict->ht, sizeof(*oldDict->ht) * oldDict->size); + + dupPtr->internalRep.dictValue = newDict; + dupPtr->typePtr = &dictObjType; +} + +static void UpdateStringOfDict(struct Jim_Obj *objPtr) +{ + JimMakeListStringRep(objPtr, objPtr->internalRep.dictValue->table, objPtr->internalRep.dictValue->len); +} + +static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + int listlen; + + if (objPtr->typePtr == &dictObjType) { + return JIM_OK; + } + + if (Jim_IsList(objPtr) && Jim_IsShared(objPtr)) { + Jim_String(objPtr); + } + + listlen = Jim_ListLength(interp, objPtr); + if (listlen % 2) { + Jim_SetResultString(interp, "missing value to go with key", -1); + return JIM_ERR; + } + else { + + Jim_Dict *dict = JimDictNew(interp, 0, listlen); + int i; + + + dict->table = objPtr->internalRep.listValue.ele; + dict->maxLen = objPtr->internalRep.listValue.maxLen; + + + for (i = 0; i < listlen; i += 2) { + int tvoffset = JimDictAdd(dict, dict->table[i]); + if (tvoffset) { + + + Jim_DecrRefCount(interp, dict->table[tvoffset]); + + dict->table[tvoffset] = dict->table[i + 1]; + + Jim_DecrRefCount(interp, dict->table[i]); + } + else { + if (dict->len != i) { + dict->table[dict->len++] = dict->table[i]; + dict->table[dict->len++] = dict->table[i + 1]; + } + else { + dict->len += 2; + } + } + } + + objPtr->typePtr = &dictObjType; + objPtr->internalRep.dictValue = dict; + + return JIM_OK; + } +} + + + +static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr) +{ + Jim_Dict *dict = objPtr->internalRep.dictValue; + if (valueObjPtr == NULL) { + + int tvoffset = JimDictHashFind(dict, keyObjPtr, DICT_HASH_REMOVE); + if (tvoffset) { + + Jim_DecrRefCount(interp, dict->table[tvoffset - 1]); + Jim_DecrRefCount(interp, dict->table[tvoffset]); + dict->len -= 2; + if (tvoffset != dict->len + 1) { + + dict->table[tvoffset - 1] = dict->table[dict->len]; + dict->table[tvoffset] = dict->table[dict->len + 1]; + + + JimDictHashFind(dict, dict->table[tvoffset - 1], tvoffset); + } + return JIM_OK; + } + return JIM_ERR; + } + else { + + int tvoffset = JimDictAdd(dict, keyObjPtr); + if (tvoffset) { + + Jim_IncrRefCount(valueObjPtr); + Jim_DecrRefCount(interp, dict->table[tvoffset]); + dict->table[tvoffset] = valueObjPtr; + } + else { + if (dict->maxLen == dict->len) { + + if (dict->maxLen < 4) { + dict->maxLen = 4; + } + else { + dict->maxLen *= 2; + } + dict->table = Jim_Realloc(dict->table, dict->maxLen * sizeof(*dict->table)); + } + Jim_IncrRefCount(keyObjPtr); + Jim_IncrRefCount(valueObjPtr); + + dict->table[dict->len++] = keyObjPtr; + dict->table[dict->len++] = valueObjPtr; + + } + return JIM_OK; + } +} + +int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr, + Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr) +{ + JimPanic((Jim_IsShared(objPtr), "Jim_DictAddElement called with shared object")); + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + Jim_InvalidateStringRep(objPtr); + return DictAddElement(interp, objPtr, keyObjPtr, valueObjPtr); +} + +Jim_Obj *Jim_NewDictObj(Jim_Interp *interp, Jim_Obj *const *elements, int len) +{ + Jim_Obj *objPtr; + int i; + + JimPanic((len % 2, "Jim_NewDictObj() 'len' argument must be even")); + + objPtr = Jim_NewObj(interp); + objPtr->typePtr = &dictObjType; + objPtr->bytes = NULL; + + objPtr->internalRep.dictValue = JimDictNew(interp, len, len); + for (i = 0; i < len; i += 2) + DictAddElement(interp, objPtr, elements[i], elements[i + 1]); + return objPtr; +} + +int Jim_DictKey(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj *keyPtr, + Jim_Obj **objPtrPtr, int flags) +{ + int tvoffset; + Jim_Dict *dict; + + if (SetDictFromAny(interp, dictPtr) != JIM_OK) { + return -1; + } + dict = dictPtr->internalRep.dictValue; + tvoffset = JimDictHashFind(dict, keyPtr, DICT_HASH_FIND); + if (tvoffset == 0) { + if (flags & JIM_ERRMSG) { + Jim_SetResultFormatted(interp, "key \"%#s\" not known in dictionary", keyPtr); + } + return JIM_ERR; + } + *objPtrPtr = dict->table[tvoffset]; + return JIM_OK; +} + +Jim_Obj **Jim_DictPairs(Jim_Interp *interp, Jim_Obj *dictPtr, int *len) +{ + + if (Jim_IsList(dictPtr)) { + Jim_Obj **table; + JimListGetElements(interp, dictPtr, len, &table); + if (*len % 2 == 0) { + return table; + } + + } + if (SetDictFromAny(interp, dictPtr) != JIM_OK) { + + *len = 1; + return NULL; + } + *len = dictPtr->internalRep.dictValue->len; + return dictPtr->internalRep.dictValue->table; +} + + +int Jim_DictKeysVector(Jim_Interp *interp, Jim_Obj *dictPtr, + Jim_Obj *const *keyv, int keyc, Jim_Obj **objPtrPtr, int flags) +{ + int i; + + if (keyc == 0) { + *objPtrPtr = dictPtr; + return JIM_OK; + } + + for (i = 0; i < keyc; i++) { + Jim_Obj *objPtr; + + int rc = Jim_DictKey(interp, dictPtr, keyv[i], &objPtr, flags); + if (rc != JIM_OK) { + return rc; + } + dictPtr = objPtr; + } + *objPtrPtr = dictPtr; + return JIM_OK; +} + +int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr, + Jim_Obj *const *keyv, int keyc, Jim_Obj *newObjPtr, int flags) +{ + Jim_Obj *varObjPtr, *objPtr, *dictObjPtr; + int shared, i; + + varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags); + if (objPtr == NULL) { + if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) { + + return JIM_ERR; + } + varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0); + if (Jim_SetVariable(interp, varNamePtr, objPtr) != JIM_OK) { + Jim_FreeNewObj(interp, varObjPtr); + return JIM_ERR; + } + } + if ((shared = Jim_IsShared(objPtr))) + varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr); + for (i = 0; i < keyc; i++) { + dictObjPtr = objPtr; + + + if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) { + goto err; + } + + if (i == keyc - 1) { + + if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) { + if (newObjPtr || (flags & JIM_MUSTEXIST)) { + goto err; + } + } + break; + } + + + Jim_InvalidateStringRep(dictObjPtr); + if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr, + newObjPtr ? JIM_NONE : JIM_ERRMSG) == JIM_OK) { + if (Jim_IsShared(objPtr)) { + objPtr = Jim_DuplicateObj(interp, objPtr); + DictAddElement(interp, dictObjPtr, keyv[i], objPtr); + } + } + else { + if (newObjPtr == NULL) { + goto err; + } + objPtr = Jim_NewDictObj(interp, NULL, 0); + DictAddElement(interp, dictObjPtr, keyv[i], objPtr); + } + } + + Jim_InvalidateStringRep(objPtr); + Jim_InvalidateStringRep(varObjPtr); + if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) { + goto err; + } + + if (!(flags & JIM_NORESULT)) { + Jim_SetResult(interp, varObjPtr); + } + return JIM_OK; + err: + if (shared) { + Jim_FreeNewObj(interp, varObjPtr); + } + return JIM_ERR; +} + +static void UpdateStringOfIndex(struct Jim_Obj *objPtr); +static int SetIndexFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType indexObjType = { + "index", + NULL, + NULL, + UpdateStringOfIndex, + JIM_TYPE_NONE, +}; + +static void UpdateStringOfIndex(struct Jim_Obj *objPtr) +{ + if (objPtr->internalRep.intValue == -1) { + JimSetStringBytes(objPtr, "end"); + } + else { + char buf[JIM_INTEGER_SPACE + 1]; + if (objPtr->internalRep.intValue >= 0 || objPtr->internalRep.intValue == -INT_MAX) { + sprintf(buf, "%d", objPtr->internalRep.intValue); + } + else { + + sprintf(buf, "end%d", objPtr->internalRep.intValue + 1); + } + JimSetStringBytes(objPtr, buf); + } +} + +static int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + jim_wide idx; + int end = 0; + const char *str; + Jim_Obj *exprObj = objPtr; + + JimPanic((objPtr->refCount == 0, "SetIndexFromAny() called with zero refcount object")); + + + str = Jim_String(objPtr); + + + if (strncmp(str, "end", 3) == 0) { + end = 1; + str += 3; + idx = 0; + switch (*str) { + case '\0': + exprObj = NULL; + break; + + case '-': + case '+': + exprObj = Jim_NewStringObj(interp, str, -1); + break; + + default: + goto badindex; + } + } + if (exprObj) { + int ret; + Jim_IncrRefCount(exprObj); + ret = Jim_GetWideExpr(interp, exprObj, &idx); + Jim_DecrRefCount(interp, exprObj); + if (ret != JIM_OK) { + goto badindex; + } + } + + if (end) { + if (idx > 0) { + idx = INT_MAX; + } + else { + + idx--; + } + } + else if (idx < 0) { + idx = -INT_MAX; + } + + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &indexObjType; + objPtr->internalRep.intValue = idx; + return JIM_OK; + + badindex: + Jim_SetResultFormatted(interp, + "bad index \"%#s\": must be intexpr or end?[+-]intexpr?", objPtr); + return JIM_ERR; +} + +int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr) +{ + + if (objPtr->typePtr == &intObjType) { + jim_wide val = JimWideValue(objPtr); + + if (val < 0) + *indexPtr = -INT_MAX; + else if (val > INT_MAX) + *indexPtr = INT_MAX; + else + *indexPtr = (int)val; + return JIM_OK; + } + if (objPtr->typePtr != &indexObjType && SetIndexFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + *indexPtr = objPtr->internalRep.intValue; + return JIM_OK; +} + + + +static const char * const jimReturnCodes[] = { + "ok", + "error", + "return", + "break", + "continue", + "signal", + "exit", + "eval", + NULL +}; + +#define jimReturnCodesSize (sizeof(jimReturnCodes)/sizeof(*jimReturnCodes) - 1) + +static const Jim_ObjType returnCodeObjType = { + "return-code", + NULL, + NULL, + NULL, + JIM_TYPE_NONE, +}; + +const char *Jim_ReturnCode(int code) +{ + if (code < 0 || code >= (int)jimReturnCodesSize) { + return "?"; + } + else { + return jimReturnCodes[code]; + } +} + +static int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + int returnCode; + jim_wide wideValue; + + + if (JimGetWideNoErr(interp, objPtr, &wideValue) != JIM_ERR) + returnCode = (int)wideValue; + else if (Jim_GetEnum(interp, objPtr, jimReturnCodes, &returnCode, NULL, JIM_NONE) != JIM_OK) { + Jim_SetResultFormatted(interp, "expected return code but got \"%#s\"", objPtr); + return JIM_ERR; + } + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &returnCodeObjType; + objPtr->internalRep.intValue = returnCode; + return JIM_OK; +} + +int Jim_GetReturnCode(Jim_Interp *interp, Jim_Obj *objPtr, int *intPtr) +{ + if (objPtr->typePtr != &returnCodeObjType && SetReturnCodeFromAny(interp, objPtr) == JIM_ERR) + return JIM_ERR; + *intPtr = objPtr->internalRep.intValue; + return JIM_OK; +} + +static int JimParseExprOperator(struct JimParserCtx *pc); +static int JimParseExprNumber(struct JimParserCtx *pc); +static int JimParseExprIrrational(struct JimParserCtx *pc); +static int JimParseExprBoolean(struct JimParserCtx *pc); + + +enum +{ + + + + JIM_EXPROP_MUL = JIM_TT_EXPR_OP, + JIM_EXPROP_DIV, + JIM_EXPROP_MOD, + JIM_EXPROP_SUB, + JIM_EXPROP_ADD, + JIM_EXPROP_LSHIFT, + JIM_EXPROP_RSHIFT, + JIM_EXPROP_ROTL, + JIM_EXPROP_ROTR, + JIM_EXPROP_LT, + JIM_EXPROP_GT, + JIM_EXPROP_LTE, + JIM_EXPROP_GTE, + JIM_EXPROP_NUMEQ, + JIM_EXPROP_NUMNE, + JIM_EXPROP_BITAND, + JIM_EXPROP_BITXOR, + JIM_EXPROP_BITOR, + JIM_EXPROP_LOGICAND, + JIM_EXPROP_LOGICOR, + JIM_EXPROP_TERNARY, + JIM_EXPROP_COLON, + JIM_EXPROP_POW, + + + JIM_EXPROP_STREQ, + JIM_EXPROP_STRNE, + JIM_EXPROP_STRIN, + JIM_EXPROP_STRNI, + JIM_EXPROP_STRLT, + JIM_EXPROP_STRGT, + JIM_EXPROP_STRLE, + JIM_EXPROP_STRGE, + + + JIM_EXPROP_NOT, + JIM_EXPROP_BITNOT, + JIM_EXPROP_UNARYMINUS, + JIM_EXPROP_UNARYPLUS, + + + JIM_EXPROP_FUNC_INT, + JIM_EXPROP_FUNC_WIDE, + JIM_EXPROP_FUNC_ABS, + JIM_EXPROP_FUNC_DOUBLE, + JIM_EXPROP_FUNC_ROUND, + JIM_EXPROP_FUNC_RAND, + JIM_EXPROP_FUNC_SRAND, + + + JIM_EXPROP_FUNC_SIN, + JIM_EXPROP_FUNC_COS, + JIM_EXPROP_FUNC_TAN, + JIM_EXPROP_FUNC_ASIN, + JIM_EXPROP_FUNC_ACOS, + JIM_EXPROP_FUNC_ATAN, + JIM_EXPROP_FUNC_ATAN2, + JIM_EXPROP_FUNC_SINH, + JIM_EXPROP_FUNC_COSH, + JIM_EXPROP_FUNC_TANH, + JIM_EXPROP_FUNC_CEIL, + JIM_EXPROP_FUNC_FLOOR, + JIM_EXPROP_FUNC_EXP, + JIM_EXPROP_FUNC_LOG, + JIM_EXPROP_FUNC_LOG10, + JIM_EXPROP_FUNC_SQRT, + JIM_EXPROP_FUNC_POW, + JIM_EXPROP_FUNC_HYPOT, + JIM_EXPROP_FUNC_FMOD, +}; + +struct JimExprNode { + int type; + struct Jim_Obj *objPtr; + + struct JimExprNode *left; + struct JimExprNode *right; + struct JimExprNode *ternary; +}; + + +typedef struct Jim_ExprOperator +{ + const char *name; + int (*funcop) (Jim_Interp *interp, struct JimExprNode *opnode); + unsigned char precedence; + unsigned char arity; + unsigned char attr; + unsigned char namelen; +} Jim_ExprOperator; + +static int JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node, Jim_Obj **objPtrPtr); +static int JimExprGetTermBoolean(Jim_Interp *interp, struct JimExprNode *node); +static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node); + +static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprNode *node) +{ + int intresult = 1; + int rc, bA = 0; + double dA, dC = 0; + jim_wide wA, wC = 0; + Jim_Obj *A; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + + if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) { + switch (node->type) { + case JIM_EXPROP_FUNC_INT: + case JIM_EXPROP_FUNC_WIDE: + case JIM_EXPROP_FUNC_ROUND: + case JIM_EXPROP_UNARYPLUS: + wC = wA; + break; + case JIM_EXPROP_FUNC_DOUBLE: + dC = wA; + intresult = 0; + break; + case JIM_EXPROP_FUNC_ABS: + wC = wA >= 0 ? wA : -wA; + break; + case JIM_EXPROP_UNARYMINUS: + wC = -wA; + break; + case JIM_EXPROP_NOT: + wC = !wA; + break; + default: + abort(); + } + } + else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) { + switch (node->type) { + case JIM_EXPROP_FUNC_INT: + case JIM_EXPROP_FUNC_WIDE: + wC = dA; + break; + case JIM_EXPROP_FUNC_ROUND: + wC = dA < 0 ? (dA - 0.5) : (dA + 0.5); + break; + case JIM_EXPROP_FUNC_DOUBLE: + case JIM_EXPROP_UNARYPLUS: + dC = dA; + intresult = 0; + break; + case JIM_EXPROP_FUNC_ABS: +#ifdef JIM_MATH_FUNCTIONS + dC = fabs(dA); +#else + dC = dA >= 0 ? dA : -dA; +#endif + intresult = 0; + break; + case JIM_EXPROP_UNARYMINUS: + dC = -dA; + intresult = 0; + break; + case JIM_EXPROP_NOT: + wC = !dA; + break; + default: + abort(); + } + } + else if ((rc = Jim_GetBoolean(interp, A, &bA)) == JIM_OK) { + switch (node->type) { + case JIM_EXPROP_NOT: + wC = !bA; + break; + default: + abort(); + } + } + + if (rc == JIM_OK) { + if (intresult) { + Jim_SetResultInt(interp, wC); + } + else { + Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); + } + } + + Jim_DecrRefCount(interp, A); + + return rc; +} + +static double JimRandDouble(Jim_Interp *interp) +{ + unsigned long x; + JimRandomBytes(interp, &x, sizeof(x)); + + return (double)x / (double)~0UL; +} + +static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprNode *node) +{ + jim_wide wA; + Jim_Obj *A; + int rc; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + + rc = Jim_GetWide(interp, A, &wA); + if (rc == JIM_OK) { + switch (node->type) { + case JIM_EXPROP_BITNOT: + Jim_SetResultInt(interp, ~wA); + break; + case JIM_EXPROP_FUNC_SRAND: + JimPrngSeed(interp, (unsigned char *)&wA, sizeof(wA)); + Jim_SetResult(interp, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + break; + default: + abort(); + } + } + + Jim_DecrRefCount(interp, A); + + return rc; +} + +static int JimExprOpNone(Jim_Interp *interp, struct JimExprNode *node) +{ + JimPanic((node->type != JIM_EXPROP_FUNC_RAND, "JimExprOpNone only support rand()")); + + Jim_SetResult(interp, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + + return JIM_OK; +} + +#ifdef JIM_MATH_FUNCTIONS +static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprNode *node) +{ + int rc; + double dA, dC; + Jim_Obj *A; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + + rc = Jim_GetDouble(interp, A, &dA); + if (rc == JIM_OK) { + switch (node->type) { + case JIM_EXPROP_FUNC_SIN: + dC = sin(dA); + break; + case JIM_EXPROP_FUNC_COS: + dC = cos(dA); + break; + case JIM_EXPROP_FUNC_TAN: + dC = tan(dA); + break; + case JIM_EXPROP_FUNC_ASIN: + dC = asin(dA); + break; + case JIM_EXPROP_FUNC_ACOS: + dC = acos(dA); + break; + case JIM_EXPROP_FUNC_ATAN: + dC = atan(dA); + break; + case JIM_EXPROP_FUNC_SINH: + dC = sinh(dA); + break; + case JIM_EXPROP_FUNC_COSH: + dC = cosh(dA); + break; + case JIM_EXPROP_FUNC_TANH: + dC = tanh(dA); + break; + case JIM_EXPROP_FUNC_CEIL: + dC = ceil(dA); + break; + case JIM_EXPROP_FUNC_FLOOR: + dC = floor(dA); + break; + case JIM_EXPROP_FUNC_EXP: + dC = exp(dA); + break; + case JIM_EXPROP_FUNC_LOG: + dC = log(dA); + break; + case JIM_EXPROP_FUNC_LOG10: + dC = log10(dA); + break; + case JIM_EXPROP_FUNC_SQRT: + dC = sqrt(dA); + break; + default: + abort(); + } + Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); + } + + Jim_DecrRefCount(interp, A); + + return rc; +} +#endif + + +static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprNode *node) +{ + jim_wide wA, wB; + int rc; + Jim_Obj *A, *B; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) { + Jim_DecrRefCount(interp, A); + return rc; + } + + rc = JIM_ERR; + + if (Jim_GetWide(interp, A, &wA) == JIM_OK && Jim_GetWide(interp, B, &wB) == JIM_OK) { + jim_wide wC; + + rc = JIM_OK; + + switch (node->type) { + case JIM_EXPROP_LSHIFT: + wC = wA << wB; + break; + case JIM_EXPROP_RSHIFT: + wC = wA >> wB; + break; + case JIM_EXPROP_BITAND: + wC = wA & wB; + break; + case JIM_EXPROP_BITXOR: + wC = wA ^ wB; + break; + case JIM_EXPROP_BITOR: + wC = wA | wB; + break; + case JIM_EXPROP_MOD: + if (wB == 0) { + wC = 0; + Jim_SetResultString(interp, "Division by zero", -1); + rc = JIM_ERR; + } + else { + int negative = 0; + + if (wB < 0) { + wB = -wB; + wA = -wA; + negative = 1; + } + wC = wA % wB; + if (wC < 0) { + wC += wB; + } + if (negative) { + wC = -wC; + } + } + break; + case JIM_EXPROP_ROTL: + case JIM_EXPROP_ROTR:{ + + unsigned long uA = (unsigned long)wA; + unsigned long uB = (unsigned long)wB; + const unsigned int S = sizeof(unsigned long) * 8; + + + uB %= S; + + if (node->type == JIM_EXPROP_ROTR) { + uB = S - uB; + } + wC = (unsigned long)(uA << uB) | (uA >> (S - uB)); + break; + } + default: + abort(); + } + Jim_SetResultInt(interp, wC); + } + + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + + return rc; +} + + + +static int JimExprOpBin(Jim_Interp *interp, struct JimExprNode *node) +{ + int rc = JIM_OK; + double dA, dB, dC = 0; + jim_wide wA, wB, wC = 0; + Jim_Obj *A, *B; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) { + Jim_DecrRefCount(interp, A); + return rc; + } + + if ((A->typePtr != &doubleObjType || A->bytes) && + (B->typePtr != &doubleObjType || B->bytes) && + JimGetWideNoErr(interp, A, &wA) == JIM_OK && JimGetWideNoErr(interp, B, &wB) == JIM_OK) { + + + + switch (node->type) { + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: + if (wA == 0 && wB < 0) { + Jim_SetResultString(interp, "exponentiation of zero by negative power", -1); + rc = JIM_ERR; + goto done; + } + wC = JimPowWide(wA, wB); + goto intresult; + case JIM_EXPROP_ADD: + wC = wA + wB; + goto intresult; + case JIM_EXPROP_SUB: + wC = wA - wB; + goto intresult; + case JIM_EXPROP_MUL: + wC = wA * wB; + goto intresult; + case JIM_EXPROP_DIV: + if (wB == 0) { + Jim_SetResultString(interp, "Division by zero", -1); + rc = JIM_ERR; + goto done; + } + else { + if (wB < 0) { + wB = -wB; + wA = -wA; + } + wC = wA / wB; + if (wA % wB < 0) { + wC--; + } + goto intresult; + } + case JIM_EXPROP_LT: + wC = wA < wB; + goto intresult; + case JIM_EXPROP_GT: + wC = wA > wB; + goto intresult; + case JIM_EXPROP_LTE: + wC = wA <= wB; + goto intresult; + case JIM_EXPROP_GTE: + wC = wA >= wB; + goto intresult; + case JIM_EXPROP_NUMEQ: + wC = wA == wB; + goto intresult; + case JIM_EXPROP_NUMNE: + wC = wA != wB; + goto intresult; + } + } + if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { + switch (node->type) { +#ifndef JIM_MATH_FUNCTIONS + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: + case JIM_EXPROP_FUNC_ATAN2: + case JIM_EXPROP_FUNC_HYPOT: + case JIM_EXPROP_FUNC_FMOD: + Jim_SetResultString(interp, "unsupported", -1); + rc = JIM_ERR; + goto done; +#else + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: + dC = pow(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_ATAN2: + dC = atan2(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_HYPOT: + dC = hypot(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_FMOD: + dC = fmod(dA, dB); + goto doubleresult; +#endif + case JIM_EXPROP_ADD: + dC = dA + dB; + goto doubleresult; + case JIM_EXPROP_SUB: + dC = dA - dB; + goto doubleresult; + case JIM_EXPROP_MUL: + dC = dA * dB; + goto doubleresult; + case JIM_EXPROP_DIV: + if (dB == 0) { +#ifdef INFINITY + dC = dA < 0 ? -INFINITY : INFINITY; +#else + dC = (dA < 0 ? -1.0 : 1.0) * strtod("Inf", NULL); +#endif + } + else { + dC = dA / dB; + } + goto doubleresult; + case JIM_EXPROP_LT: + wC = dA < dB; + goto intresult; + case JIM_EXPROP_GT: + wC = dA > dB; + goto intresult; + case JIM_EXPROP_LTE: + wC = dA <= dB; + goto intresult; + case JIM_EXPROP_GTE: + wC = dA >= dB; + goto intresult; + case JIM_EXPROP_NUMEQ: + wC = dA == dB; + goto intresult; + case JIM_EXPROP_NUMNE: + wC = dA != dB; + goto intresult; + } + } + else { + + + + int i = Jim_StringCompareObj(interp, A, B, 0); + + switch (node->type) { + case JIM_EXPROP_LT: + wC = i < 0; + goto intresult; + case JIM_EXPROP_GT: + wC = i > 0; + goto intresult; + case JIM_EXPROP_LTE: + wC = i <= 0; + goto intresult; + case JIM_EXPROP_GTE: + wC = i >= 0; + goto intresult; + case JIM_EXPROP_NUMEQ: + wC = i == 0; + goto intresult; + case JIM_EXPROP_NUMNE: + wC = i != 0; + goto intresult; + } + } + + rc = JIM_ERR; +done: + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + return rc; +intresult: + Jim_SetResultInt(interp, wC); + goto done; +doubleresult: + Jim_SetResult(interp, Jim_NewDoubleObj(interp, dC)); + goto done; +} + +static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj) +{ + int listlen; + int i; + + listlen = Jim_ListLength(interp, listObjPtr); + for (i = 0; i < listlen; i++) { + if (Jim_StringEqObj(Jim_ListGetIndex(interp, listObjPtr, i), valObj)) { + return 1; + } + } + return 0; +} + + + +static int JimExprOpStrBin(Jim_Interp *interp, struct JimExprNode *node) +{ + Jim_Obj *A, *B; + jim_wide wC; + int comp, rc; + + if ((rc = JimExprGetTerm(interp, node->left, &A)) != JIM_OK) { + return rc; + } + if ((rc = JimExprGetTerm(interp, node->right, &B)) != JIM_OK) { + Jim_DecrRefCount(interp, A); + return rc; + } + + switch (node->type) { + case JIM_EXPROP_STREQ: + case JIM_EXPROP_STRNE: + wC = Jim_StringEqObj(A, B); + if (node->type == JIM_EXPROP_STRNE) { + wC = !wC; + } + break; + case JIM_EXPROP_STRLT: + case JIM_EXPROP_STRGT: + case JIM_EXPROP_STRLE: + case JIM_EXPROP_STRGE: + comp = Jim_StringCompareObj(interp, A, B, 0); + if (node->type == JIM_EXPROP_STRLT) { + wC = comp == -1; + } else if (node->type == JIM_EXPROP_STRGT) { + wC = comp == 1; + } else if (node->type == JIM_EXPROP_STRLE) { + wC = comp == -1 || comp == 0; + } else { + wC = comp == 0 || comp == 1; + } + break; + case JIM_EXPROP_STRIN: + wC = JimSearchList(interp, B, A); + break; + case JIM_EXPROP_STRNI: + wC = !JimSearchList(interp, B, A); + break; + default: + abort(); + } + Jim_SetResultInt(interp, wC); + + Jim_DecrRefCount(interp, A); + Jim_DecrRefCount(interp, B); + + return rc; +} + +static int ExprBool(Jim_Interp *interp, Jim_Obj *obj) +{ + long l; + double d; + int b; + int ret = -1; + + + Jim_IncrRefCount(obj); + + if (Jim_GetLong(interp, obj, &l) == JIM_OK) { + ret = (l != 0); + } + else if (Jim_GetDouble(interp, obj, &d) == JIM_OK) { + ret = (d != 0); + } + else if (Jim_GetBoolean(interp, obj, &b) == JIM_OK) { + ret = (b != 0); + } + + Jim_DecrRefCount(interp, obj); + return ret; +} + +static int JimExprOpAnd(Jim_Interp *interp, struct JimExprNode *node) +{ + + int result = JimExprGetTermBoolean(interp, node->left); + + if (result == 1) { + + result = JimExprGetTermBoolean(interp, node->right); + } + if (result == -1) { + return JIM_ERR; + } + Jim_SetResultInt(interp, result); + return JIM_OK; +} + +static int JimExprOpOr(Jim_Interp *interp, struct JimExprNode *node) +{ + + int result = JimExprGetTermBoolean(interp, node->left); + + if (result == 0) { + + result = JimExprGetTermBoolean(interp, node->right); + } + if (result == -1) { + return JIM_ERR; + } + Jim_SetResultInt(interp, result); + return JIM_OK; +} + +static int JimExprOpTernary(Jim_Interp *interp, struct JimExprNode *node) +{ + + int result = JimExprGetTermBoolean(interp, node->left); + + if (result == 1) { + + return JimExprEvalTermNode(interp, node->right); + } + else if (result == 0) { + + return JimExprEvalTermNode(interp, node->ternary); + } + + return JIM_ERR; +} + +enum +{ + OP_FUNC = 0x0001, + OP_RIGHT_ASSOC = 0x0002, +}; + +#define OPRINIT_ATTR(N, P, ARITY, F, ATTR) {N, F, P, ARITY, ATTR, sizeof(N) - 1} +#define OPRINIT(N, P, ARITY, F) OPRINIT_ATTR(N, P, ARITY, F, 0) + +static const struct Jim_ExprOperator Jim_ExprOperators[] = { + OPRINIT("*", 110, 2, JimExprOpBin), + OPRINIT("/", 110, 2, JimExprOpBin), + OPRINIT("%", 110, 2, JimExprOpIntBin), + + OPRINIT("-", 100, 2, JimExprOpBin), + OPRINIT("+", 100, 2, JimExprOpBin), + + OPRINIT("<<", 90, 2, JimExprOpIntBin), + OPRINIT(">>", 90, 2, JimExprOpIntBin), + + OPRINIT("<<<", 90, 2, JimExprOpIntBin), + OPRINIT(">>>", 90, 2, JimExprOpIntBin), + + OPRINIT("<", 80, 2, JimExprOpBin), + OPRINIT(">", 80, 2, JimExprOpBin), + OPRINIT("<=", 80, 2, JimExprOpBin), + OPRINIT(">=", 80, 2, JimExprOpBin), + + OPRINIT("==", 70, 2, JimExprOpBin), + OPRINIT("!=", 70, 2, JimExprOpBin), + + OPRINIT("&", 50, 2, JimExprOpIntBin), + OPRINIT("^", 49, 2, JimExprOpIntBin), + OPRINIT("|", 48, 2, JimExprOpIntBin), + + OPRINIT("&&", 10, 2, JimExprOpAnd), + OPRINIT("||", 9, 2, JimExprOpOr), + OPRINIT_ATTR("?", 5, 3, JimExprOpTernary, OP_RIGHT_ASSOC), + OPRINIT_ATTR(":", 5, 3, NULL, OP_RIGHT_ASSOC), + + + OPRINIT_ATTR("**", 120, 2, JimExprOpBin, OP_RIGHT_ASSOC), + + OPRINIT("eq", 60, 2, JimExprOpStrBin), + OPRINIT("ne", 60, 2, JimExprOpStrBin), + + OPRINIT("in", 55, 2, JimExprOpStrBin), + OPRINIT("ni", 55, 2, JimExprOpStrBin), + + OPRINIT("lt", 75, 2, JimExprOpStrBin), + OPRINIT("gt", 75, 2, JimExprOpStrBin), + OPRINIT("le", 75, 2, JimExprOpStrBin), + OPRINIT("ge", 75, 2, JimExprOpStrBin), + + OPRINIT_ATTR("!", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC), + OPRINIT_ATTR("~", 150, 1, JimExprOpIntUnary, OP_RIGHT_ASSOC), + OPRINIT_ATTR(" -", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC), + OPRINIT_ATTR(" +", 150, 1, JimExprOpNumUnary, OP_RIGHT_ASSOC), + + + + OPRINIT_ATTR("int", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("wide", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("abs", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("double", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("round", 200, 1, JimExprOpNumUnary, OP_FUNC), + OPRINIT_ATTR("rand", 200, 0, JimExprOpNone, OP_FUNC), + OPRINIT_ATTR("srand", 200, 1, JimExprOpIntUnary, OP_FUNC), + +#ifdef JIM_MATH_FUNCTIONS + OPRINIT_ATTR("sin", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("cos", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("tan", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("asin", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("acos", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("atan", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("atan2", 200, 2, JimExprOpBin, OP_FUNC), + OPRINIT_ATTR("sinh", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("cosh", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("tanh", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("ceil", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("floor", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("exp", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("log", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("log10", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("sqrt", 200, 1, JimExprOpDoubleUnary, OP_FUNC), + OPRINIT_ATTR("pow", 200, 2, JimExprOpBin, OP_FUNC), + OPRINIT_ATTR("hypot", 200, 2, JimExprOpBin, OP_FUNC), + OPRINIT_ATTR("fmod", 200, 2, JimExprOpBin, OP_FUNC), +#endif +}; +#undef OPRINIT +#undef OPRINIT_ATTR + +#define JIM_EXPR_OPERATORS_NUM \ + (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator)) + +static int JimParseExpression(struct JimParserCtx *pc) +{ + pc->errmsg = NULL; + + while (1) { + + while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) { + if (*pc->p == '\n') { + pc->linenr++; + } + pc->p++; + pc->len--; + } + + if (*pc->p == '#') { + JimParseComment(pc); + + continue; + } + break; + } + + + pc->tline = pc->linenr; + pc->tstart = pc->p; + + if (pc->len == 0) { + pc->tend = pc->p; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return JIM_OK; + } + switch (*(pc->p)) { + case '(': + pc->tt = JIM_TT_SUBEXPR_START; + goto singlechar; + case ')': + pc->tt = JIM_TT_SUBEXPR_END; + goto singlechar; + case ',': + pc->tt = JIM_TT_SUBEXPR_COMMA; +singlechar: + pc->tend = pc->p; + pc->p++; + pc->len--; + break; + case '[': + return JimParseCmd(pc); + case '$': + if (JimParseVar(pc) == JIM_ERR) + return JimParseExprOperator(pc); + else { + + if (pc->tt == JIM_TT_EXPRSUGAR) { + pc->errmsg = "nesting expr in expr is not allowed"; + return JIM_ERR; + } + return JIM_OK; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + return JimParseExprNumber(pc); + case '"': + return JimParseQuote(pc); + case '{': + return JimParseBrace(pc); + + case 'N': + case 'I': + case 'n': + case 'i': + if (JimParseExprIrrational(pc) == JIM_ERR) + if (JimParseExprBoolean(pc) == JIM_ERR) + return JimParseExprOperator(pc); + break; + case 't': + case 'f': + case 'o': + case 'y': + if (JimParseExprBoolean(pc) == JIM_ERR) + return JimParseExprOperator(pc); + break; + default: + return JimParseExprOperator(pc); + break; + } + return JIM_OK; +} + +static int JimParseExprNumber(struct JimParserCtx *pc) +{ + char *end; + + + pc->tt = JIM_TT_EXPR_INT; + + jim_strtoull(pc->p, (char **)&pc->p); + + if (strchr("eENnIi.", *pc->p) || pc->p == pc->tstart) { + if (strtod(pc->tstart, &end)) { } + if (end == pc->tstart) + return JIM_ERR; + if (end > pc->p) { + + pc->tt = JIM_TT_EXPR_DOUBLE; + pc->p = end; + } + } + pc->tend = pc->p - 1; + pc->len -= (pc->p - pc->tstart); + return JIM_OK; +} + +static int JimParseExprIrrational(struct JimParserCtx *pc) +{ + const char *irrationals[] = { "NaN", "nan", "NAN", "Inf", "inf", "INF", NULL }; + int i; + + for (i = 0; irrationals[i]; i++) { + const char *irr = irrationals[i]; + + if (strncmp(irr, pc->p, 3) == 0) { + pc->p += 3; + pc->len -= 3; + pc->tend = pc->p - 1; + pc->tt = JIM_TT_EXPR_DOUBLE; + return JIM_OK; + } + } + return JIM_ERR; +} + +static int JimParseExprBoolean(struct JimParserCtx *pc) +{ + int i; + for (i = 0; i < sizeof(jim_true_false_strings) / sizeof(*jim_true_false_strings); i++) { + if (strncmp(pc->p, jim_true_false_strings[i], jim_true_false_lens[i]) == 0) { + pc->p += jim_true_false_lens[i]; + pc->len -= jim_true_false_lens[i]; + pc->tend = pc->p - 1; + pc->tt = JIM_TT_EXPR_BOOLEAN; + return JIM_OK; + } + } + return JIM_ERR; +} + +static const struct Jim_ExprOperator *JimExprOperatorInfoByOpcode(int opcode) +{ + static Jim_ExprOperator dummy_op; + if (opcode < JIM_TT_EXPR_OP) { + return &dummy_op; + } + return &Jim_ExprOperators[opcode - JIM_TT_EXPR_OP]; +} + +static int JimParseExprOperator(struct JimParserCtx *pc) +{ + int i; + const struct Jim_ExprOperator *bestOp = NULL; + int bestLen = 0; + + + for (i = 0; i < (signed)JIM_EXPR_OPERATORS_NUM; i++) { + const struct Jim_ExprOperator *op = &Jim_ExprOperators[i]; + + if (op->name[0] != pc->p[0]) { + continue; + } + + if (op->namelen > bestLen && strncmp(op->name, pc->p, op->namelen) == 0) { + bestOp = op; + bestLen = op->namelen; + } + } + if (bestOp == NULL) { + return JIM_ERR; + } + + + if (bestOp->attr & OP_FUNC) { + const char *p = pc->p + bestLen; + int len = pc->len - bestLen; + + while (len && isspace(UCHAR(*p))) { + len--; + p++; + } + if (*p != '(') { + pc->errmsg = "function requires parentheses"; + return JIM_ERR; + } + } + pc->tend = pc->p + bestLen - 1; + pc->p += bestLen; + pc->len -= bestLen; + + pc->tt = (bestOp - Jim_ExprOperators) + JIM_TT_EXPR_OP; + return JIM_OK; +} + + +static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); + +static const Jim_ObjType exprObjType = { + "expression", + FreeExprInternalRep, + DupExprInternalRep, + NULL, + JIM_TYPE_NONE, +}; + + +struct ExprTree +{ + struct JimExprNode *expr; + struct JimExprNode *nodes; + int len; + int inUse; +}; + +static void ExprTreeFreeNodes(Jim_Interp *interp, struct JimExprNode *nodes, int num) +{ + int i; + for (i = 0; i < num; i++) { + if (nodes[i].objPtr) { + Jim_DecrRefCount(interp, nodes[i].objPtr); + } + } + Jim_Free(nodes); +} + +static void ExprTreeFree(Jim_Interp *interp, struct ExprTree *expr) +{ + ExprTreeFreeNodes(interp, expr->nodes, expr->len); + Jim_Free(expr); +} + +static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + struct ExprTree *expr = (void *)objPtr->internalRep.ptr; + + if (expr) { + if (--expr->inUse != 0) { + return; + } + + ExprTreeFree(interp, expr); + } +} + +static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + JIM_NOTUSED(interp); + JIM_NOTUSED(srcPtr); + + + dupPtr->typePtr = NULL; +} + +struct ExprBuilder { + int parencount; + int level; + ParseToken *token; + ParseToken *first_token; + Jim_Stack stack; + Jim_Obj *exprObjPtr; + Jim_Obj *fileNameObj; + struct JimExprNode *nodes; + struct JimExprNode *next; +}; + +#ifdef DEBUG_SHOW_EXPR +static void JimShowExprNode(struct JimExprNode *node, int level) +{ + int i; + for (i = 0; i < level; i++) { + printf(" "); + } + if (TOKEN_IS_EXPR_OP(node->type)) { + printf("%s\n", jim_tt_name(node->type)); + if (node->left) { + JimShowExprNode(node->left, level + 1); + } + if (node->right) { + JimShowExprNode(node->right, level + 1); + } + if (node->ternary) { + JimShowExprNode(node->ternary, level + 1); + } + } + else { + printf("[%s] %s\n", jim_tt_name(node->type), Jim_String(node->objPtr)); + } +} +#endif + +#define EXPR_UNTIL_CLOSE 0x0001 +#define EXPR_FUNC_ARGS 0x0002 +#define EXPR_TERNARY 0x0004 + +static int ExprTreeBuildTree(Jim_Interp *interp, struct ExprBuilder *builder, int precedence, int flags, int exp_numterms) { + int rc; + struct JimExprNode *node; + + int exp_stacklen = builder->stack.len + exp_numterms; + + if (builder->level++ > 200) { + Jim_SetResultString(interp, "Expression too complex", -1); + return JIM_ERR; + } + + while (builder->token->type != JIM_TT_EOL) { + ParseToken *t = builder->token++; + int prevtt; + + if (t == builder->first_token) { + prevtt = JIM_TT_NONE; + } + else { + prevtt = t[-1].type; + } + + if (t->type == JIM_TT_SUBEXPR_START) { + if (builder->stack.len == exp_stacklen) { + Jim_SetResultFormatted(interp, "unexpected open parenthesis in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; + } + builder->parencount++; + rc = ExprTreeBuildTree(interp, builder, 0, EXPR_UNTIL_CLOSE, 1); + if (rc != JIM_OK) { + return rc; + } + + } + else if (t->type == JIM_TT_SUBEXPR_END) { + if (!(flags & EXPR_UNTIL_CLOSE)) { + if (builder->stack.len == exp_stacklen && builder->level > 1) { + builder->token--; + builder->level--; + return JIM_OK; + } + Jim_SetResultFormatted(interp, "unexpected closing parenthesis in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; + } + builder->parencount--; + if (builder->stack.len == exp_stacklen) { + + break; + } + } + else if (t->type == JIM_TT_SUBEXPR_COMMA) { + if (!(flags & EXPR_FUNC_ARGS)) { + if (builder->stack.len == exp_stacklen) { + + builder->token--; + builder->level--; + return JIM_OK; + } + Jim_SetResultFormatted(interp, "unexpected comma in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; + } + else { + + if (builder->stack.len > exp_stacklen) { + Jim_SetResultFormatted(interp, "too many arguments to math function"); + return JIM_ERR; + } + } + + } + else if (t->type == JIM_EXPROP_COLON) { + if (!(flags & EXPR_TERNARY)) { + if (builder->level != 1) { + + builder->token--; + builder->level--; + return JIM_OK; + } + Jim_SetResultFormatted(interp, ": without ? in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; + } + if (builder->stack.len == exp_stacklen) { + + builder->token--; + builder->level--; + return JIM_OK; + } + + } + else if (TOKEN_IS_EXPR_OP(t->type)) { + const struct Jim_ExprOperator *op; + + + if (TOKEN_IS_EXPR_OP(prevtt) || TOKEN_IS_EXPR_START(prevtt)) { + if (t->type == JIM_EXPROP_SUB) { + t->type = JIM_EXPROP_UNARYMINUS; + } + else if (t->type == JIM_EXPROP_ADD) { + t->type = JIM_EXPROP_UNARYPLUS; + } + } + + op = JimExprOperatorInfoByOpcode(t->type); + + if (op->precedence < precedence || (!(op->attr & OP_RIGHT_ASSOC) && op->precedence == precedence)) { + + builder->token--; + break; + } + + if (op->attr & OP_FUNC) { + if (builder->token->type != JIM_TT_SUBEXPR_START) { + Jim_SetResultString(interp, "missing arguments for math function", -1); + return JIM_ERR; + } + builder->token++; + if (op->arity == 0) { + if (builder->token->type != JIM_TT_SUBEXPR_END) { + Jim_SetResultString(interp, "too many arguments for math function", -1); + return JIM_ERR; + } + builder->token++; + goto noargs; + } + builder->parencount++; + + + rc = ExprTreeBuildTree(interp, builder, 0, EXPR_FUNC_ARGS | EXPR_UNTIL_CLOSE, op->arity); + } + else if (t->type == JIM_EXPROP_TERNARY) { + + rc = ExprTreeBuildTree(interp, builder, op->precedence, EXPR_TERNARY, 2); + } + else { + rc = ExprTreeBuildTree(interp, builder, op->precedence, 0, 1); + } + + if (rc != JIM_OK) { + return rc; + } + +noargs: + node = builder->next++; + node->type = t->type; + + if (op->arity >= 3) { + node->ternary = Jim_StackPop(&builder->stack); + if (node->ternary == NULL) { + goto missingoperand; + } + } + if (op->arity >= 2) { + node->right = Jim_StackPop(&builder->stack); + if (node->right == NULL) { + goto missingoperand; + } + } + if (op->arity >= 1) { + node->left = Jim_StackPop(&builder->stack); + if (node->left == NULL) { +missingoperand: + Jim_SetResultFormatted(interp, "missing operand to %s in expression: \"%#s\"", op->name, builder->exprObjPtr); + builder->next--; + return JIM_ERR; + + } + } + + + Jim_StackPush(&builder->stack, node); + } + else { + Jim_Obj *objPtr = NULL; + + + + + if (!TOKEN_IS_EXPR_START(prevtt) && !TOKEN_IS_EXPR_OP(prevtt)) { + Jim_SetResultFormatted(interp, "missing operator in expression: \"%#s\"", builder->exprObjPtr); + return JIM_ERR; + } + + + if (t->type == JIM_TT_EXPR_INT || t->type == JIM_TT_EXPR_DOUBLE) { + char *endptr; + if (t->type == JIM_TT_EXPR_INT) { + objPtr = Jim_NewIntObj(interp, jim_strtoull(t->token, &endptr)); + } + else { + objPtr = Jim_NewDoubleObj(interp, strtod(t->token, &endptr)); + } + if (endptr != t->token + t->len) { + + Jim_FreeNewObj(interp, objPtr); + objPtr = NULL; + } + } + + if (!objPtr) { + + objPtr = Jim_NewStringObj(interp, t->token, t->len); + if (t->type == JIM_TT_CMD) { + + Jim_SetSourceInfo(interp, objPtr, builder->fileNameObj, t->line); + } + } + + + node = builder->next++; + node->objPtr = objPtr; + Jim_IncrRefCount(node->objPtr); + node->type = t->type; + Jim_StackPush(&builder->stack, node); + } + } + + if (builder->stack.len == exp_stacklen) { + builder->level--; + return JIM_OK; + } + + if ((flags & EXPR_FUNC_ARGS)) { + Jim_SetResultFormatted(interp, "too %s arguments for math function", (builder->stack.len < exp_stacklen) ? "few" : "many"); + } + else { + if (builder->stack.len < exp_stacklen) { + if (builder->level == 0) { + Jim_SetResultFormatted(interp, "empty expression"); + } + else { + Jim_SetResultFormatted(interp, "syntax error in expression \"%#s\": premature end of expression", builder->exprObjPtr); + } + } + else { + Jim_SetResultFormatted(interp, "extra terms after expression"); + } + } + + return JIM_ERR; +} + +static struct ExprTree *ExprTreeCreateTree(Jim_Interp *interp, const ParseTokenList *tokenlist, Jim_Obj *exprObjPtr, Jim_Obj *fileNameObj) +{ + struct ExprTree *expr; + struct ExprBuilder builder; + int rc; + struct JimExprNode *top = NULL; + + builder.parencount = 0; + builder.level = 0; + builder.token = builder.first_token = tokenlist->list; + builder.exprObjPtr = exprObjPtr; + builder.fileNameObj = fileNameObj; + + builder.nodes = Jim_Alloc(sizeof(struct JimExprNode) * (tokenlist->count - 1)); + memset(builder.nodes, 0, sizeof(struct JimExprNode) * (tokenlist->count - 1)); + builder.next = builder.nodes; + Jim_InitStack(&builder.stack); + + rc = ExprTreeBuildTree(interp, &builder, 0, 0, 1); + + if (rc == JIM_OK) { + top = Jim_StackPop(&builder.stack); + + if (builder.parencount) { + Jim_SetResultString(interp, "missing close parenthesis", -1); + rc = JIM_ERR; + } + } + + + Jim_FreeStack(&builder.stack); + + if (rc != JIM_OK) { + ExprTreeFreeNodes(interp, builder.nodes, builder.next - builder.nodes); + return NULL; + } + + expr = Jim_Alloc(sizeof(*expr)); + expr->inUse = 1; + expr->expr = top; + expr->nodes = builder.nodes; + expr->len = builder.next - builder.nodes; + + assert(expr->len <= tokenlist->count - 1); + + return expr; +} + +static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) +{ + int exprTextLen; + const char *exprText; + struct JimParserCtx parser; + struct ExprTree *expr; + ParseTokenList tokenlist; + int line; + Jim_Obj *fileNameObj; + int rc = JIM_ERR; + + + fileNameObj = Jim_GetSourceInfo(interp, objPtr, &line); + Jim_IncrRefCount(fileNameObj); + + exprText = Jim_GetString(objPtr, &exprTextLen); + + + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, exprText, exprTextLen, line); + while (!parser.eof) { + if (JimParseExpression(&parser) != JIM_OK) { + ScriptTokenListFree(&tokenlist); + Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr); + if (parser.errmsg) { + Jim_AppendStrings(interp, Jim_GetResult(interp), ": ", parser.errmsg, NULL); + } + expr = NULL; + goto err; + } + + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + +#ifdef DEBUG_SHOW_EXPR_TOKENS + { + int i; + printf("==== Expr Tokens (%s) ====\n", Jim_String(fileNameObj)); + for (i = 0; i < tokenlist.count; i++) { + printf("[%2d]@%d %s '%.*s'\n", i, tokenlist.list[i].line, jim_tt_name(tokenlist.list[i].type), + tokenlist.list[i].len, tokenlist.list[i].token); + } + } +#endif + + if (tokenlist.count <= 1) { + Jim_SetResultString(interp, "empty expression", -1); + rc = JIM_ERR; + } + else { + rc = JimParseCheckMissing(interp, parser.missing.ch); + } + if (rc != JIM_OK) { + ScriptTokenListFree(&tokenlist); + Jim_DecrRefCount(interp, fileNameObj); + return rc; + } + + + expr = ExprTreeCreateTree(interp, &tokenlist, objPtr, fileNameObj); + + + ScriptTokenListFree(&tokenlist); + + if (!expr) { + goto err; + } + +#ifdef DEBUG_SHOW_EXPR + printf("==== Expr ====\n"); + JimShowExprNode(expr->expr, 0); +#endif + + rc = JIM_OK; + + err: + + Jim_DecrRefCount(interp, fileNameObj); + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, expr); + objPtr->typePtr = &exprObjType; + return rc; +} + +static struct ExprTree *JimGetExpression(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (objPtr->typePtr != &exprObjType) { + if (SetExprFromAny(interp, objPtr) != JIM_OK) { + return NULL; + } + } + return (struct ExprTree *) Jim_GetIntRepPtr(objPtr); +} + +#ifdef JIM_OPTIMIZATION +static Jim_Obj *JimExprIntValOrVar(Jim_Interp *interp, struct JimExprNode *node) +{ + if (node->type == JIM_TT_EXPR_INT) + return node->objPtr; + else if (node->type == JIM_TT_VAR) + return Jim_GetVariable(interp, node->objPtr, JIM_NONE); + else if (node->type == JIM_TT_DICTSUGAR) + return JimExpandDictSugar(interp, node->objPtr); + else + return NULL; +} +#endif + + +static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node) +{ + if (TOKEN_IS_EXPR_OP(node->type)) { + const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(node->type); + return op->funcop(interp, node); + } + else { + Jim_Obj *objPtr; + + + switch (node->type) { + case JIM_TT_EXPR_INT: + case JIM_TT_EXPR_DOUBLE: + case JIM_TT_EXPR_BOOLEAN: + case JIM_TT_STR: + Jim_SetResult(interp, node->objPtr); + return JIM_OK; + + case JIM_TT_VAR: + objPtr = Jim_GetVariable(interp, node->objPtr, JIM_ERRMSG); + if (objPtr) { + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + return JIM_ERR; + + case JIM_TT_DICTSUGAR: + objPtr = JimExpandDictSugar(interp, node->objPtr); + if (objPtr) { + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + return JIM_ERR; + + case JIM_TT_ESC: + if (interp->safeexpr) { + return JIM_ERR; + } + if (Jim_SubstObj(interp, node->objPtr, &objPtr, JIM_NONE) == JIM_OK) { + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + return JIM_ERR; + + case JIM_TT_CMD: + if (interp->safeexpr) { + return JIM_ERR; + } + return Jim_EvalObj(interp, node->objPtr); + + default: + + return JIM_ERR; + } + } +} + +static int JimExprGetTerm(Jim_Interp *interp, struct JimExprNode *node, Jim_Obj **objPtrPtr) +{ + int rc = JimExprEvalTermNode(interp, node); + if (rc == JIM_OK) { + *objPtrPtr = Jim_GetResult(interp); + Jim_IncrRefCount(*objPtrPtr); + } + return rc; +} + +static int JimExprGetTermBoolean(Jim_Interp *interp, struct JimExprNode *node) +{ + if (JimExprEvalTermNode(interp, node) == JIM_OK) { + return ExprBool(interp, Jim_GetResult(interp)); + } + return -1; +} + +int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr) +{ + struct ExprTree *expr; + int retcode = JIM_OK; + + Jim_IncrRefCount(exprObjPtr); + expr = JimGetExpression(interp, exprObjPtr); + if (!expr) { + retcode = JIM_ERR; + goto done; + } + +#ifdef JIM_OPTIMIZATION + if (!interp->safeexpr) { + Jim_Obj *objPtr; + + + switch (expr->len) { + case 1: + objPtr = JimExprIntValOrVar(interp, expr->expr); + if (objPtr) { + Jim_SetResult(interp, objPtr); + goto done; + } + break; + + case 2: + if (expr->expr->type == JIM_EXPROP_NOT) { + objPtr = JimExprIntValOrVar(interp, expr->expr->left); + + if (objPtr && JimIsWide(objPtr)) { + Jim_SetResult(interp, JimWideValue(objPtr) ? interp->falseObj : interp->trueObj); + goto done; + } + } + break; + + case 3: + objPtr = JimExprIntValOrVar(interp, expr->expr->left); + if (objPtr && JimIsWide(objPtr)) { + Jim_Obj *objPtr2 = JimExprIntValOrVar(interp, expr->expr->right); + if (objPtr2 && JimIsWide(objPtr2)) { + jim_wide wideValueA = JimWideValue(objPtr); + jim_wide wideValueB = JimWideValue(objPtr2); + int cmpRes; + switch (expr->expr->type) { + case JIM_EXPROP_LT: + cmpRes = wideValueA < wideValueB; + break; + case JIM_EXPROP_LTE: + cmpRes = wideValueA <= wideValueB; + break; + case JIM_EXPROP_GT: + cmpRes = wideValueA > wideValueB; + break; + case JIM_EXPROP_GTE: + cmpRes = wideValueA >= wideValueB; + break; + case JIM_EXPROP_NUMEQ: + cmpRes = wideValueA == wideValueB; + break; + case JIM_EXPROP_NUMNE: + cmpRes = wideValueA != wideValueB; + break; + default: + goto noopt; + } + Jim_SetResult(interp, cmpRes ? interp->trueObj : interp->falseObj); + goto done; + } + } + break; + } + } +noopt: +#endif + + expr->inUse++; + + + retcode = JimExprEvalTermNode(interp, expr->expr); + + + Jim_FreeIntRep(interp, exprObjPtr); + exprObjPtr->typePtr = &exprObjType; + Jim_SetIntRepPtr(exprObjPtr, expr); + +done: + Jim_DecrRefCount(interp, exprObjPtr); + + return retcode; +} + +int Jim_GetBoolFromExpr(Jim_Interp *interp, Jim_Obj *exprObjPtr, int *boolPtr) +{ + int retcode = Jim_EvalExpression(interp, exprObjPtr); + + if (retcode == JIM_OK) { + switch (ExprBool(interp, Jim_GetResult(interp))) { + case 0: + *boolPtr = 0; + break; + + case 1: + *boolPtr = 1; + break; + + case -1: + retcode = JIM_ERR; + break; + } + } + return retcode; +} + + + + +typedef struct ScanFmtPartDescr +{ + const char *arg; + const char *prefix; + size_t width; + int pos; + char type; + char modifier; +} ScanFmtPartDescr; + + +typedef struct ScanFmtStringObj +{ + jim_wide size; + char *stringRep; + size_t count; + size_t convCount; + size_t maxPos; + const char *error; + char *scratch; + ScanFmtPartDescr descr[1]; +} ScanFmtStringObj; + + +static void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); +static void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); +static void UpdateStringOfScanFmt(Jim_Obj *objPtr); + +static const Jim_ObjType scanFmtStringObjType = { + "scanformatstring", + FreeScanFmtInternalRep, + DupScanFmtInternalRep, + UpdateStringOfScanFmt, + JIM_TYPE_NONE, +}; + +void FreeScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + JIM_NOTUSED(interp); + Jim_Free((char *)objPtr->internalRep.ptr); + objPtr->internalRep.ptr = 0; +} + +void DupScanFmtInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr) +{ + size_t size = (size_t) ((ScanFmtStringObj *) srcPtr->internalRep.ptr)->size; + ScanFmtStringObj *newVec = (ScanFmtStringObj *) Jim_Alloc(size); + + JIM_NOTUSED(interp); + memcpy(newVec, srcPtr->internalRep.ptr, size); + dupPtr->internalRep.ptr = newVec; + dupPtr->typePtr = &scanFmtStringObjType; +} + +static void UpdateStringOfScanFmt(Jim_Obj *objPtr) +{ + JimSetStringBytes(objPtr, ((ScanFmtStringObj *) objPtr->internalRep.ptr)->stringRep); +} + + +static int SetScanFmtFromAny(Jim_Interp *interp, Jim_Obj *objPtr) +{ + ScanFmtStringObj *fmtObj; + char *buffer; + int maxCount, i, approxSize, lastPos = -1; + const char *fmt = Jim_String(objPtr); + int maxFmtLen = Jim_Length(objPtr); + const char *fmtEnd = fmt + maxFmtLen; + int curr; + + Jim_FreeIntRep(interp, objPtr); + + for (i = 0, maxCount = 0; i < maxFmtLen; ++i) + if (fmt[i] == '%') + ++maxCount; + + approxSize = sizeof(ScanFmtStringObj) + +(maxCount + 1) * sizeof(ScanFmtPartDescr) + +maxFmtLen * sizeof(char) + 3 + 1 + + maxFmtLen * sizeof(char) + 1 + + maxFmtLen * sizeof(char) + +(maxCount + 1) * sizeof(char) + +1; + fmtObj = (ScanFmtStringObj *) Jim_Alloc(approxSize); + memset(fmtObj, 0, approxSize); + fmtObj->size = approxSize; + fmtObj->maxPos = 0; + fmtObj->scratch = (char *)&fmtObj->descr[maxCount + 1]; + fmtObj->stringRep = fmtObj->scratch + maxFmtLen + 3 + 1; + memcpy(fmtObj->stringRep, fmt, maxFmtLen); + buffer = fmtObj->stringRep + maxFmtLen + 1; + objPtr->internalRep.ptr = fmtObj; + objPtr->typePtr = &scanFmtStringObjType; + for (i = 0, curr = 0; fmt < fmtEnd; ++fmt) { + int width = 0, skip; + ScanFmtPartDescr *descr = &fmtObj->descr[curr]; + + fmtObj->count++; + descr->width = 0; + + if (*fmt != '%' || fmt[1] == '%') { + descr->type = 0; + descr->prefix = &buffer[i]; + for (; fmt < fmtEnd; ++fmt) { + if (*fmt == '%') { + if (fmt[1] != '%') + break; + ++fmt; + } + buffer[i++] = *fmt; + } + buffer[i++] = 0; + } + + ++fmt; + + if (fmt >= fmtEnd) + goto done; + descr->pos = 0; + if (*fmt == '*') { + descr->pos = -1; + ++fmt; + } + else + fmtObj->convCount++; + + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { + fmt += skip; + + if (descr->pos != -1 && *fmt == '$') { + int prev; + + ++fmt; + descr->pos = width; + width = 0; + + if ((lastPos == 0 && descr->pos > 0) + || (lastPos > 0 && descr->pos == 0)) { + fmtObj->error = "cannot mix \"%\" and \"%n$\" conversion specifiers"; + return JIM_ERR; + } + + for (prev = 0; prev < curr; ++prev) { + if (fmtObj->descr[prev].pos == -1) + continue; + if (fmtObj->descr[prev].pos == descr->pos) { + fmtObj->error = + "variable is assigned by multiple \"%n$\" conversion specifiers"; + return JIM_ERR; + } + } + if (descr->pos < 0) { + fmtObj->error = + "\"%n$\" conversion specifier is negative"; + return JIM_ERR; + } + + if (sscanf(fmt, "%d%n", &width, &skip) == 1) { + descr->width = width; + fmt += skip; + } + if (descr->pos > 0 && (size_t) descr->pos > fmtObj->maxPos) + fmtObj->maxPos = descr->pos; + } + else { + + descr->width = width; + } + } + + if (lastPos == -1) + lastPos = descr->pos; + + if (*fmt == '[') { + int swapped = 1, beg = i, end, j; + + descr->type = '['; + descr->arg = &buffer[i]; + ++fmt; + if (*fmt == '^') + buffer[i++] = *fmt++; + if (*fmt == ']') + buffer[i++] = *fmt++; + while (*fmt && *fmt != ']') + buffer[i++] = *fmt++; + if (*fmt != ']') { + fmtObj->error = "unmatched [ in format string"; + return JIM_ERR; + } + end = i; + buffer[i++] = 0; + + while (swapped) { + swapped = 0; + for (j = beg + 1; j < end - 1; ++j) { + if (buffer[j] == '-' && buffer[j - 1] > buffer[j + 1]) { + char tmp = buffer[j - 1]; + + buffer[j - 1] = buffer[j + 1]; + buffer[j + 1] = tmp; + swapped = 1; + } + } + } + } + else { + + if (fmt < fmtEnd && strchr("hlL", *fmt)) + descr->modifier = tolower((int)*fmt++); + + if (fmt >= fmtEnd) { + fmtObj->error = "missing scan conversion character"; + return JIM_ERR; + } + + descr->type = *fmt; + if (strchr("efgcsndoxui", *fmt) == 0) { + fmtObj->error = "bad scan conversion character"; + return JIM_ERR; + } + else if (*fmt == 'c' && descr->width != 0) { + fmtObj->error = "field width may not be specified in %c " "conversion"; + return JIM_ERR; + } + else if (*fmt == 'u' && descr->modifier == 'l') { + fmtObj->error = "unsigned wide not supported"; + return JIM_ERR; + } + } + curr++; + } + done: + return JIM_OK; +} + + + +#define FormatGetCnvCount(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->convCount +#define FormatGetMaxPos(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->maxPos +#define FormatGetError(_fo_) \ + ((ScanFmtStringObj*)((_fo_)->internalRep.ptr))->error + +static Jim_Obj *JimScanAString(Jim_Interp *interp, const char *sdescr, const char *str) +{ + char *buffer = Jim_StrDup(str); + char *p = buffer; + + while (*str) { + int c; + int n; + + if (!sdescr && isspace(UCHAR(*str))) + break; + + n = utf8_tounicode(str, &c); + if (sdescr && !JimCharsetMatch(sdescr, strlen(sdescr), c, JIM_CHARSET_SCAN)) + break; + while (n--) + *p++ = *str++; + } + *p = 0; + return Jim_NewStringObjNoAlloc(interp, buffer, p - buffer); +} + + +static int ScanOneEntry(Jim_Interp *interp, const char *str, int pos, int str_bytelen, + ScanFmtStringObj * fmtObj, long idx, Jim_Obj **valObjPtr) +{ + const char *tok; + const ScanFmtPartDescr *descr = &fmtObj->descr[idx]; + size_t scanned = 0; + size_t anchor = pos; + int i; + Jim_Obj *tmpObj = NULL; + + + *valObjPtr = 0; + if (descr->prefix) { + for (i = 0; pos < str_bytelen && descr->prefix[i]; ++i) { + + if (isspace(UCHAR(descr->prefix[i]))) + while (pos < str_bytelen && isspace(UCHAR(str[pos]))) + ++pos; + else if (descr->prefix[i] != str[pos]) + break; + else + ++pos; + } + if (pos >= str_bytelen) { + return -1; + } + else if (descr->prefix[i] != 0) + return 0; + } + + if (descr->type != 'c' && descr->type != '[' && descr->type != 'n') + while (isspace(UCHAR(str[pos]))) + ++pos; + + + scanned = pos - anchor; + + + if (descr->type == 'n') { + + *valObjPtr = Jim_NewIntObj(interp, anchor + scanned); + } + else if (pos >= str_bytelen) { + + return -1; + } + else if (descr->type == 'c') { + int c; + scanned += utf8_tounicode(&str[pos], &c); + *valObjPtr = Jim_NewIntObj(interp, c); + return scanned; + } + else { + + if (descr->width > 0) { + size_t sLen = utf8_strlen(&str[pos], str_bytelen - pos); + size_t tLen = descr->width > sLen ? sLen : descr->width; + + tmpObj = Jim_NewStringObjUtf8(interp, str + pos, tLen); + tok = tmpObj->bytes; + } + else { + + tok = &str[pos]; + } + switch (descr->type) { + case 'd': + case 'o': + case 'x': + case 'u': + case 'i':{ + char *endp; + jim_wide w; + + int base = descr->type == 'o' ? 8 + : descr->type == 'x' ? 16 : descr->type == 'i' ? 0 : 10; + + + if (base == 0) { + w = jim_strtoull(tok, &endp); + } + else { + w = strtoull(tok, &endp, base); + } + + if (endp != tok) { + + *valObjPtr = Jim_NewIntObj(interp, w); + + + scanned += endp - tok; + } + else { + scanned = *tok ? 0 : -1; + } + break; + } + case 's': + case '[':{ + *valObjPtr = JimScanAString(interp, descr->arg, tok); + scanned += Jim_Length(*valObjPtr); + break; + } + case 'e': + case 'f': + case 'g':{ + char *endp; + double value = strtod(tok, &endp); + + if (endp != tok) { + + *valObjPtr = Jim_NewDoubleObj(interp, value); + + scanned += endp - tok; + } + else { + scanned = *tok ? 0 : -1; + } + break; + } + } + if (tmpObj) { + Jim_FreeNewObj(interp, tmpObj); + } + } + return scanned; +} + + +Jim_Obj *Jim_ScanString(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *fmtObjPtr, int flags) +{ + size_t i, pos; + int scanned = 1; + const char *str = Jim_String(strObjPtr); + int str_bytelen = Jim_Length(strObjPtr); + Jim_Obj *resultList = 0; + Jim_Obj **resultVec = 0; + int resultc; + Jim_Obj *emptyStr = 0; + ScanFmtStringObj *fmtObj; + + + JimPanic((fmtObjPtr->typePtr != &scanFmtStringObjType, "Jim_ScanString() for non-scan format")); + + fmtObj = (ScanFmtStringObj *) fmtObjPtr->internalRep.ptr; + + if (fmtObj->error != 0) { + if (flags & JIM_ERRMSG) + Jim_SetResultString(interp, fmtObj->error, -1); + return 0; + } + + emptyStr = Jim_NewEmptyStringObj(interp); + Jim_IncrRefCount(emptyStr); + + resultList = Jim_NewListObj(interp, NULL, 0); + if (fmtObj->maxPos > 0) { + for (i = 0; i < fmtObj->maxPos; ++i) + Jim_ListAppendElement(interp, resultList, emptyStr); + JimListGetElements(interp, resultList, &resultc, &resultVec); + } + + for (i = 0, pos = 0; i < fmtObj->count; ++i) { + ScanFmtPartDescr *descr = &(fmtObj->descr[i]); + Jim_Obj *value = 0; + + + if (descr->type == 0) + continue; + + if (scanned > 0) + scanned = ScanOneEntry(interp, str, pos, str_bytelen, fmtObj, i, &value); + + if (scanned == -1 && i == 0) + goto eof; + + pos += scanned; + + + if (value == 0) + value = Jim_NewEmptyStringObj(interp); + + if (descr->pos == -1) { + Jim_FreeNewObj(interp, value); + } + else if (descr->pos == 0) + + Jim_ListAppendElement(interp, resultList, value); + else if (resultVec[descr->pos - 1] == emptyStr) { + + Jim_DecrRefCount(interp, resultVec[descr->pos - 1]); + Jim_IncrRefCount(value); + resultVec[descr->pos - 1] = value; + } + else { + + Jim_FreeNewObj(interp, value); + goto err; + } + } + Jim_DecrRefCount(interp, emptyStr); + return resultList; + eof: + Jim_DecrRefCount(interp, emptyStr); + Jim_FreeNewObj(interp, resultList); + return (Jim_Obj *)EOF; + err: + Jim_DecrRefCount(interp, emptyStr); + Jim_FreeNewObj(interp, resultList); + return 0; +} + + +static void JimPrngInit(Jim_Interp *interp) +{ +#define PRNG_SEED_SIZE 256 + int i; + unsigned int *seed; + time_t t = time(NULL); + + interp->prngState = Jim_Alloc(sizeof(Jim_PrngState)); + + seed = Jim_Alloc(PRNG_SEED_SIZE * sizeof(*seed)); + for (i = 0; i < PRNG_SEED_SIZE; i++) { + seed[i] = (rand() ^ t ^ clock()); + } + JimPrngSeed(interp, (unsigned char *)seed, PRNG_SEED_SIZE * sizeof(*seed)); + Jim_Free(seed); +} + + +static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len) +{ + Jim_PrngState *prng; + unsigned char *destByte = (unsigned char *)dest; + unsigned int si, sj, x; + + + if (interp->prngState == NULL) + JimPrngInit(interp); + prng = interp->prngState; + + for (x = 0; x < len; x++) { + prng->i = (prng->i + 1) & 0xff; + si = prng->sbox[prng->i]; + prng->j = (prng->j + si) & 0xff; + sj = prng->sbox[prng->j]; + prng->sbox[prng->i] = sj; + prng->sbox[prng->j] = si; + *destByte++ = prng->sbox[(si + sj) & 0xff]; + } +} + + +static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen) +{ + int i; + Jim_PrngState *prng; + + + if (interp->prngState == NULL) + JimPrngInit(interp); + prng = interp->prngState; + + + for (i = 0; i < 256; i++) + prng->sbox[i] = i; + + for (i = 0; i < seedLen; i++) { + unsigned char t; + + t = prng->sbox[i & 0xFF]; + prng->sbox[i & 0xFF] = prng->sbox[seed[i]]; + prng->sbox[seed[i]] = t; + } + prng->i = prng->j = 0; + + for (i = 0; i < 256; i += seedLen) { + JimRandomBytes(interp, seed, seedLen); + } +} + + +static int Jim_IncrCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide wideValue, increment = 1; + Jim_Obj *intObjPtr; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?increment?"); + return JIM_ERR; + } + if (argc == 3) { + if (Jim_GetWideExpr(interp, argv[2], &increment) != JIM_OK) + return JIM_ERR; + } + intObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!intObjPtr) { + + wideValue = 0; + } + else if (Jim_GetWide(interp, intObjPtr, &wideValue) != JIM_OK) { + return JIM_ERR; + } + if (!intObjPtr || Jim_IsShared(intObjPtr)) { + intObjPtr = Jim_NewIntObj(interp, wideValue + increment); + if (Jim_SetVariable(interp, argv[1], intObjPtr) != JIM_OK) { + Jim_FreeNewObj(interp, intObjPtr); + return JIM_ERR; + } + } + else { + + Jim_InvalidateStringRep(intObjPtr); + JimWideValue(intObjPtr) = wideValue + increment; + + if (argv[1]->typePtr != &variableObjType) { + + Jim_SetVariable(interp, argv[1], intObjPtr); + } + } + Jim_SetResult(interp, intObjPtr); + return JIM_OK; +} + + +#define JIM_EVAL_SARGV_LEN 8 +#define JIM_EVAL_SINTV_LEN 8 + +static int JimTraceCallback(Jim_Interp *interp, const char *type, int argc, Jim_Obj *const *argv) +{ + JimPanic((interp->traceCmdObj == NULL, "xtrace invoked with no object")); + + int ret; + Jim_Obj *nargv[7]; + Jim_Obj *traceCmdObj = interp->traceCmdObj; + Jim_Obj *resultObj = Jim_GetResult(interp); + ScriptObj *script = NULL; + + + + if (interp->evalFrame->scriptObj) { + script = JimGetScript(interp, interp->evalFrame->scriptObj); + } + + nargv[0] = traceCmdObj; + nargv[1] = Jim_NewStringObj(interp, type, -1); + nargv[2] = script ? script->fileNameObj : interp->emptyObj; + nargv[3] = Jim_NewIntObj(interp, script ? script->linenr : 1); + nargv[4] = resultObj; + nargv[5] = argv[0]; + nargv[6] = Jim_NewListObj(interp, argv + 1, argc - 1); + + + interp->traceCmdObj = NULL; + + Jim_IncrRefCount(resultObj); + ret = Jim_EvalObjVector(interp, 7, nargv); + Jim_DecrRefCount(interp, resultObj); + + if (ret == JIM_OK || ret == JIM_RETURN) { + + interp->traceCmdObj = traceCmdObj; + Jim_SetEmptyResult(interp); + ret = JIM_OK; + } + else { + + Jim_DecrRefCount(interp, traceCmdObj); + } + return ret; +} + + +static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retcode; + + if (interp->unknown_called > 50) { + return JIM_ERR; + } + + + + if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL) + return JIM_ERR; + + interp->unknown_called++; + + retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv); + interp->unknown_called--; + + return retcode; +} + +static void JimPushEvalFrame(Jim_Interp *interp, Jim_EvalFrame *frame, Jim_Obj *scriptObj) +{ + memset(frame, 0, sizeof(*frame)); + frame->parent = interp->evalFrame; + frame->level = frame->parent->level + 1; + frame->procLevel = interp->procLevel; + frame->framePtr = interp->framePtr; + if (scriptObj) { + frame->scriptObj = scriptObj; + } + else { + frame->scriptObj = frame->parent->scriptObj; + } + interp->evalFrame = frame; +#if 0 + if (frame->scriptObj) { + printf("script: %.*s\n", 20, Jim_String(frame->scriptObj)); + } +#endif +} + +static void JimPopEvalFrame(Jim_Interp *interp) +{ + interp->evalFrame = interp->evalFrame->parent; +} + + +static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int retcode; + Jim_Cmd *cmdPtr; + void *prevPrivData; + Jim_Obj *tailcallObj = NULL; + +#if 0 + printf("invoke"); + int j; + for (j = 0; j < objc; j++) { + printf(" '%s'", Jim_String(objv[j])); + } + printf("\n"); +#endif + + cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG); + if (cmdPtr == NULL) { + return JimUnknown(interp, objc, objv); + } + JimIncrCmdRefCount(cmdPtr); + + if (interp->evalDepth == interp->maxEvalDepth) { + Jim_SetResultString(interp, "Infinite eval recursion", -1); + retcode = JIM_ERR; + goto out; + } + interp->evalDepth++; + prevPrivData = interp->cmdPrivData; + +tailcall: + + interp->evalFrame->argc = objc; + interp->evalFrame->argv = objv; + interp->evalFrame->cmd = cmdPtr; + + if (!interp->traceCmdObj || + (retcode = JimTraceCallback(interp, "cmd", objc, objv)) == JIM_OK) { + + Jim_SetEmptyResult(interp); + if (cmdPtr->isproc) { + retcode = JimCallProcedure(interp, cmdPtr, objc, objv); + } + else { + interp->cmdPrivData = cmdPtr->u.native.privData; + retcode = cmdPtr->u.native.cmdProc(interp, objc, objv); + } + if (retcode == JIM_ERR) { + JimSetErrorStack(interp, NULL); + } + } + + if (tailcallObj) { + + Jim_DecrRefCount(interp, tailcallObj); + tailcallObj = NULL; + } + + + interp->evalFrame->argc = 0; + interp->evalFrame->argv = NULL; + + + if (retcode == JIM_EVAL && interp->framePtr->tailcallObj) { + JimDecrCmdRefCount(interp, cmdPtr); + + + cmdPtr = interp->framePtr->tailcallCmd; + interp->framePtr->tailcallCmd = NULL; + tailcallObj = interp->framePtr->tailcallObj; + interp->framePtr->tailcallObj = NULL; + objc = tailcallObj->internalRep.listValue.len; + objv = tailcallObj->internalRep.listValue.ele; + goto tailcall; + } + + interp->cmdPrivData = prevPrivData; + interp->evalDepth--; + +out: + JimDecrCmdRefCount(interp, cmdPtr); + + if (retcode == JIM_ERR) { + JimSetErrorStack(interp, NULL); + } + + if (interp->framePtr->tailcallObj) { + JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd); + Jim_DecrRefCount(interp, interp->framePtr->tailcallObj); + interp->framePtr->tailcallCmd = NULL; + interp->framePtr->tailcallObj = NULL; + } + + return retcode; +} + +int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + int i, retcode; + Jim_EvalFrame frame; + + + for (i = 0; i < objc; i++) + Jim_IncrRefCount(objv[i]); + + + JimPushEvalFrame(interp, &frame, NULL); + + retcode = JimInvokeCommand(interp, objc, objv); + + JimPopEvalFrame(interp); + + + for (i = 0; i < objc; i++) + Jim_DecrRefCount(interp, objv[i]); + + return retcode; +} + +int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix, int objc, Jim_Obj *const *objv) +{ + int ret; + Jim_Obj **nargv = Jim_Alloc((objc + 1) * sizeof(*nargv)); + + nargv[0] = prefix; + memcpy(&nargv[1], &objv[0], sizeof(nargv[0]) * objc); + ret = Jim_EvalObjVector(interp, objc + 1, nargv); + Jim_Free(nargv); + return ret; +} + +static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Obj **objPtrPtr) +{ + Jim_Obj *objPtr; + int ret = JIM_ERR; + + switch (token->type) { + case JIM_TT_STR: + case JIM_TT_ESC: + objPtr = token->objPtr; + break; + case JIM_TT_VAR: + objPtr = Jim_GetVariable(interp, token->objPtr, JIM_ERRMSG); + break; + case JIM_TT_DICTSUGAR: + objPtr = JimExpandDictSugar(interp, token->objPtr); + break; + case JIM_TT_EXPRSUGAR: + ret = Jim_EvalExpression(interp, token->objPtr); + if (ret == JIM_OK) { + objPtr = Jim_GetResult(interp); + } + else { + objPtr = NULL; + } + break; + case JIM_TT_CMD: + ret = Jim_EvalObj(interp, token->objPtr); + if (ret == JIM_OK || ret == JIM_RETURN) { + objPtr = interp->result; + } else { + + objPtr = NULL; + } + break; + default: + JimPanic((1, + "default token type (%d) reached " "in Jim_SubstObj().", token->type)); + objPtr = NULL; + break; + } + if (objPtr) { + *objPtrPtr = objPtr; + return JIM_OK; + } + return ret; +} + +static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * token, int tokens, int flags) +{ + int totlen = 0, i; + Jim_Obj **intv; + Jim_Obj *sintv[JIM_EVAL_SINTV_LEN]; + Jim_Obj *objPtr; + char *s; + + if (tokens <= JIM_EVAL_SINTV_LEN) + intv = sintv; + else + intv = Jim_Alloc(sizeof(Jim_Obj *) * tokens); + + for (i = 0; i < tokens; i++) { + switch (JimSubstOneToken(interp, &token[i], &intv[i])) { + case JIM_OK: + case JIM_RETURN: + break; + case JIM_BREAK: + if (flags & JIM_SUBST_FLAG) { + + tokens = i; + continue; + } + + + case JIM_CONTINUE: + if (flags & JIM_SUBST_FLAG) { + intv[i] = NULL; + continue; + } + + + default: + while (i--) { + Jim_DecrRefCount(interp, intv[i]); + } + if (intv != sintv) { + Jim_Free(intv); + } + return NULL; + } + Jim_IncrRefCount(intv[i]); + Jim_String(intv[i]); + totlen += intv[i]->length; + } + + + if (tokens == 1 && intv[0] && intv == sintv) { + + intv[0]->refCount--; + return intv[0]; + } + + objPtr = Jim_NewStringObjNoAlloc(interp, NULL, 0); + + if (tokens == 4 && token[0].type == JIM_TT_ESC && token[1].type == JIM_TT_ESC + && token[2].type == JIM_TT_VAR) { + + objPtr->typePtr = &interpolatedObjType; + objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr; + objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2]; + Jim_IncrRefCount(intv[2]); + } + else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) { + + int line; + Jim_Obj *fileNameObj = Jim_GetSourceInfo(interp, intv[0], &line); + Jim_SetSourceInfo(interp, objPtr, fileNameObj, line); + } + + + s = objPtr->bytes = Jim_Alloc(totlen + 1); + objPtr->length = totlen; + for (i = 0; i < tokens; i++) { + if (intv[i]) { + memcpy(s, intv[i]->bytes, intv[i]->length); + s += intv[i]->length; + Jim_DecrRefCount(interp, intv[i]); + } + } + objPtr->bytes[totlen] = '\0'; + + if (intv != sintv) { + Jim_Free(intv); + } + + return objPtr; +} + + +static int JimEvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) +{ + int retcode = JIM_OK; + Jim_EvalFrame frame; + + JimPanic((Jim_IsList(listPtr) == 0, "JimEvalObjList() invoked on non-list.")); + + JimPushEvalFrame(interp, &frame, NULL); + + if (listPtr->internalRep.listValue.len) { + Jim_IncrRefCount(listPtr); + retcode = JimInvokeCommand(interp, + listPtr->internalRep.listValue.len, + listPtr->internalRep.listValue.ele); + Jim_DecrRefCount(interp, listPtr); + } + + JimPopEvalFrame(interp); + + return retcode; +} + +int Jim_EvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) +{ + SetListFromAny(interp, listPtr); + return JimEvalObjList(interp, listPtr); +} + +int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) +{ + int i; + ScriptObj *script; + ScriptToken *token; + int retcode = JIM_OK; + Jim_Obj *sargv[JIM_EVAL_SARGV_LEN], **argv = NULL; + Jim_EvalFrame frame; + + if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) { + return JimEvalObjList(interp, scriptObjPtr); + } + + Jim_IncrRefCount(scriptObjPtr); + script = JimGetScript(interp, scriptObjPtr); + if (JimParseCheckMissing(interp, script->missing) == JIM_ERR) { + JimSetErrorStack(interp, script); + Jim_DecrRefCount(interp, scriptObjPtr); + return JIM_ERR; + } + + Jim_SetEmptyResult(interp); + + token = script->token; + +#ifdef JIM_OPTIMIZATION + if (script->len == 0) { + Jim_DecrRefCount(interp, scriptObjPtr); + return JIM_OK; + } + if (script->len == 3 + && token[1].objPtr->typePtr == &commandObjType + && token[1].objPtr->internalRep.cmdValue.cmdPtr->isproc == 0 + && token[1].objPtr->internalRep.cmdValue.cmdPtr->u.native.cmdProc == Jim_IncrCoreCommand + && token[2].objPtr->typePtr == &variableObjType) { + + Jim_Obj *objPtr = Jim_GetVariable(interp, token[2].objPtr, JIM_NONE); + + if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + JimWideValue(objPtr)++; + Jim_InvalidateStringRep(objPtr); + Jim_DecrRefCount(interp, scriptObjPtr); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + } +#endif + + script->inUse++; + + JimPushEvalFrame(interp, &frame, scriptObjPtr); + + + interp->errorFlag = 0; + argv = sargv; + + for (i = 0; i < script->len && retcode == JIM_OK; ) { + int argc; + int j; + + + argc = token[i].objPtr->internalRep.scriptLineValue.argc; + script->linenr = token[i].objPtr->internalRep.scriptLineValue.line; + + + if (argc > JIM_EVAL_SARGV_LEN) + argv = Jim_Alloc(sizeof(Jim_Obj *) * argc); + + + i++; + + for (j = 0; j < argc; j++) { + long wordtokens = 1; + int expand = 0; + Jim_Obj *wordObjPtr = NULL; + + if (token[i].type == JIM_TT_WORD) { + wordtokens = JimWideValue(token[i++].objPtr); + if (wordtokens < 0) { + expand = 1; + wordtokens = -wordtokens; + } + } + + if (wordtokens == 1) { + + switch (token[i].type) { + case JIM_TT_ESC: + case JIM_TT_STR: + wordObjPtr = token[i].objPtr; + break; + case JIM_TT_VAR: + wordObjPtr = Jim_GetVariable(interp, token[i].objPtr, JIM_ERRMSG); + break; + case JIM_TT_EXPRSUGAR: + retcode = Jim_EvalExpression(interp, token[i].objPtr); + if (retcode == JIM_OK) { + wordObjPtr = Jim_GetResult(interp); + } + else { + wordObjPtr = NULL; + } + break; + case JIM_TT_DICTSUGAR: + wordObjPtr = JimExpandDictSugar(interp, token[i].objPtr); + break; + case JIM_TT_CMD: + retcode = Jim_EvalObj(interp, token[i].objPtr); + if (retcode == JIM_OK) { + wordObjPtr = Jim_GetResult(interp); + } + break; + default: + JimPanic((1, "default token type reached " "in Jim_EvalObj().")); + } + } + else { + wordObjPtr = JimInterpolateTokens(interp, token + i, wordtokens, JIM_NONE); + } + + if (!wordObjPtr) { + if (retcode == JIM_OK) { + retcode = JIM_ERR; + } + break; + } + + Jim_IncrRefCount(wordObjPtr); + i += wordtokens; + + if (!expand) { + argv[j] = wordObjPtr; + } + else { + + int len = Jim_ListLength(interp, wordObjPtr); + int newargc = argc + len - 1; + int k; + + if (len > 1) { + if (argv == sargv) { + if (newargc > JIM_EVAL_SARGV_LEN) { + argv = Jim_Alloc(sizeof(*argv) * newargc); + memcpy(argv, sargv, sizeof(*argv) * j); + } + } + else { + + argv = Jim_Realloc(argv, sizeof(*argv) * newargc); + } + } + + + for (k = 0; k < len; k++) { + argv[j++] = wordObjPtr->internalRep.listValue.ele[k]; + Jim_IncrRefCount(wordObjPtr->internalRep.listValue.ele[k]); + } + + Jim_DecrRefCount(interp, wordObjPtr); + + + j--; + argc += len - 1; + } + } + + if (retcode == JIM_OK && argc) { + + retcode = JimInvokeCommand(interp, argc, argv); + + if (Jim_CheckSignal(interp)) { + retcode = JIM_SIGNAL; + } + } + + + while (j-- > 0) { + Jim_DecrRefCount(interp, argv[j]); + } + + if (argv != sargv) { + Jim_Free(argv); + argv = sargv; + } + } + + + if (retcode == JIM_ERR) { + JimSetErrorStack(interp, NULL); + } + + JimPopEvalFrame(interp); + + Jim_FreeIntRep(interp, scriptObjPtr); + scriptObjPtr->typePtr = &scriptObjType; + Jim_SetIntRepPtr(scriptObjPtr, script); + Jim_DecrRefCount(interp, scriptObjPtr); + + return retcode; +} + +static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argValObj) +{ + int retcode; + + const char *varname = Jim_String(argNameObj); + if (*varname == '&') { + + Jim_Obj *objPtr; + Jim_CallFrame *savedCallFrame = interp->framePtr; + + interp->framePtr = interp->framePtr->parent; + objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG); + interp->framePtr = savedCallFrame; + if (!objPtr) { + return JIM_ERR; + } + + + objPtr = Jim_NewStringObj(interp, varname + 1, -1); + Jim_IncrRefCount(objPtr); + retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent); + Jim_DecrRefCount(interp, objPtr); + } + else { + retcode = Jim_SetVariable(interp, argNameObj, argValObj); + } + return retcode; +} + +static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd) +{ + + Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0); + int i; + + for (i = 0; i < cmd->u.proc.argListLen; i++) { + Jim_AppendString(interp, argmsg, " ", 1); + + if (i == cmd->u.proc.argsPos) { + if (cmd->u.proc.arglist[i].defaultObjPtr) { + + Jim_AppendString(interp, argmsg, "?", 1); + Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr); + Jim_AppendString(interp, argmsg, " ...?", -1); + } + else { + + Jim_AppendString(interp, argmsg, "?arg ...?", -1); + } + } + else { + if (cmd->u.proc.arglist[i].defaultObjPtr) { + Jim_AppendString(interp, argmsg, "?", 1); + Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].nameObjPtr); + Jim_AppendString(interp, argmsg, "?", 1); + } + else { + const char *arg = Jim_String(cmd->u.proc.arglist[i].nameObjPtr); + if (*arg == '&') { + arg++; + } + Jim_AppendString(interp, argmsg, arg, -1); + } + } + } + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s%#s\"", procNameObj, argmsg); +} + +#ifdef jim_ext_namespace +int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj) +{ + Jim_CallFrame *callFramePtr; + int retcode; + + + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj); + callFramePtr->argv = interp->evalFrame->argv; + callFramePtr->argc = interp->evalFrame->argc; + callFramePtr->procArgsObjPtr = NULL; + callFramePtr->procBodyObjPtr = scriptObj; + callFramePtr->staticVars = NULL; + Jim_IncrRefCount(scriptObj); + interp->framePtr = callFramePtr; + + + if (interp->framePtr->level == interp->maxCallFrameDepth) { + Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); + retcode = JIM_ERR; + } + else { + + retcode = Jim_EvalObj(interp, scriptObj); + } + + + interp->framePtr = interp->framePtr->parent; + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE); + + return retcode; +} +#endif + +static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv) +{ + Jim_CallFrame *callFramePtr; + int i, d, retcode, optargs; + + + if (argc - 1 < cmd->u.proc.reqArity || + (cmd->u.proc.argsPos < 0 && argc - 1 > cmd->u.proc.reqArity + cmd->u.proc.optArity)) { + JimSetProcWrongArgs(interp, argv[0], cmd); + return JIM_ERR; + } + + if (Jim_Length(cmd->u.proc.bodyObjPtr) == 0) { + + return JIM_OK; + } + + + if (interp->framePtr->level == interp->maxCallFrameDepth) { + Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1); + return JIM_ERR; + } + + + callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj); + callFramePtr->argv = argv; + callFramePtr->argc = argc; + callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr; + callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr; + callFramePtr->staticVars = cmd->u.proc.staticVars; + + interp->procLevel++; + + Jim_IncrRefCount(cmd->u.proc.argListObjPtr); + Jim_IncrRefCount(cmd->u.proc.bodyObjPtr); + interp->framePtr = callFramePtr; + + + optargs = (argc - 1 - cmd->u.proc.reqArity); + + + i = 1; + for (d = 0; d < cmd->u.proc.argListLen; d++) { + Jim_Obj *nameObjPtr = cmd->u.proc.arglist[d].nameObjPtr; + if (d == cmd->u.proc.argsPos) { + + Jim_Obj *listObjPtr; + int argsLen = 0; + if (cmd->u.proc.reqArity + cmd->u.proc.optArity < argc - 1) { + argsLen = argc - 1 - (cmd->u.proc.reqArity + cmd->u.proc.optArity); + } + listObjPtr = Jim_NewListObj(interp, &argv[i], argsLen); + + + if (cmd->u.proc.arglist[d].defaultObjPtr) { + nameObjPtr =cmd->u.proc.arglist[d].defaultObjPtr; + } + retcode = Jim_SetVariable(interp, nameObjPtr, listObjPtr); + if (retcode != JIM_OK) { + goto badargset; + } + + i += argsLen; + continue; + } + + + if (cmd->u.proc.arglist[d].defaultObjPtr == NULL || optargs-- > 0) { + retcode = JimSetProcArg(interp, nameObjPtr, argv[i++]); + } + else { + + retcode = Jim_SetVariable(interp, nameObjPtr, cmd->u.proc.arglist[d].defaultObjPtr); + } + if (retcode != JIM_OK) { + goto badargset; + } + } + + if (interp->traceCmdObj == NULL || + (retcode = JimTraceCallback(interp, "proc", argc, argv)) == JIM_OK) { + + retcode = Jim_EvalObj(interp, cmd->u.proc.bodyObjPtr); + } + +badargset: + + + retcode = JimInvokeDefer(interp, retcode); + interp->framePtr = interp->framePtr->parent; + JimFreeCallFrame(interp, callFramePtr, JIM_FCF_REUSE); + + + if (retcode == JIM_RETURN) { + if (--interp->returnLevel <= 0) { + retcode = interp->returnCode; + interp->returnCode = JIM_OK; + interp->returnLevel = 0; + } + } + interp->procLevel--; + + return retcode; +} + +int Jim_EvalSource(Jim_Interp *interp, const char *filename, int lineno, const char *script) +{ + int retval; + Jim_Obj *scriptObjPtr; + + scriptObjPtr = Jim_NewStringObj(interp, script, -1); + Jim_IncrRefCount(scriptObjPtr); + if (filename) { + Jim_SetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), lineno); + } + retval = Jim_EvalObj(interp, scriptObjPtr); + Jim_DecrRefCount(interp, scriptObjPtr); + return retval; +} + +int Jim_Eval(Jim_Interp *interp, const char *script) +{ + return Jim_EvalObj(interp, Jim_NewStringObj(interp, script, -1)); +} + + +int Jim_EvalGlobal(Jim_Interp *interp, const char *script) +{ + int retval; + Jim_CallFrame *savedFramePtr = interp->framePtr; + + interp->framePtr = interp->topFramePtr; + retval = Jim_Eval(interp, script); + interp->framePtr = savedFramePtr; + + return retval; +} + +int Jim_EvalFileGlobal(Jim_Interp *interp, const char *filename) +{ + int retval; + Jim_CallFrame *savedFramePtr = interp->framePtr; + + interp->framePtr = interp->topFramePtr; + retval = Jim_EvalFile(interp, filename); + interp->framePtr = savedFramePtr; + + return retval; +} + +#include + +static Jim_Obj *JimReadTextFile(Jim_Interp *interp, const char *filename) +{ + jim_stat_t sb; + int fd; + char *buf; + int readlen; + + if (Jim_Stat(filename, &sb) == -1 || (fd = open(filename, O_RDONLY | O_TEXT, 0666)) < 0) { + Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", filename, strerror(errno)); + return NULL; + } + buf = Jim_Alloc(sb.st_size + 1); + readlen = read(fd, buf, sb.st_size); + close(fd); + if (readlen < 0) { + Jim_Free(buf); + Jim_SetResultFormatted(interp, "failed to load file \"%s\": %s", filename, strerror(errno)); + return NULL; + } + else { + Jim_Obj *objPtr; + buf[readlen] = 0; + + objPtr = Jim_NewStringObjNoAlloc(interp, buf, readlen); + + return objPtr; + } +} + + +int Jim_EvalFile(Jim_Interp *interp, const char *filename) +{ + Jim_Obj *filenameObj; + Jim_Obj *oldFilenameObj; + Jim_Obj *scriptObjPtr; + int retcode; + + scriptObjPtr = JimReadTextFile(interp, filename); + if (!scriptObjPtr) { + return JIM_ERR; + } + + filenameObj = Jim_NewStringObj(interp, filename, -1); + Jim_SetSourceInfo(interp, scriptObjPtr, filenameObj, 1); + + oldFilenameObj = JimPushInterpObj(interp->currentFilenameObj, filenameObj); + + retcode = Jim_EvalObj(interp, scriptObjPtr); + + JimPopInterpObj(interp, interp->currentFilenameObj, oldFilenameObj); + + + if (retcode == JIM_RETURN) { + if (--interp->returnLevel <= 0) { + retcode = interp->returnCode; + interp->returnCode = JIM_OK; + interp->returnLevel = 0; + } + } + + return retcode; +} + +static void JimParseSubst(struct JimParserCtx *pc, int flags) +{ + pc->tstart = pc->p; + pc->tline = pc->linenr; + + if (pc->len == 0) { + pc->tend = pc->p; + pc->tt = JIM_TT_EOL; + pc->eof = 1; + return; + } + if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) { + JimParseCmd(pc); + return; + } + if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { + if (JimParseVar(pc) == JIM_OK) { + return; + } + + pc->tstart = pc->p; + + pc->p++; + pc->len--; + } + while (pc->len) { + if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { + break; + } + if (*pc->p == '[' && !(flags & JIM_SUBST_NOCMD)) { + break; + } + if (*pc->p == '\\' && pc->len > 1) { + pc->p++; + pc->len--; + } + pc->p++; + pc->len--; + } + pc->tend = pc->p - 1; + pc->tt = (flags & JIM_SUBST_NOESC) ? JIM_TT_STR : JIM_TT_ESC; +} + + +static int SetSubstFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, int flags) +{ + int scriptTextLen; + const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); + struct JimParserCtx parser; + struct ScriptObj *script = Jim_Alloc(sizeof(*script)); + ParseTokenList tokenlist; + + + ScriptTokenListInit(&tokenlist); + + JimParserInit(&parser, scriptText, scriptTextLen, 1); + while (1) { + JimParseSubst(&parser, flags); + if (parser.eof) { + + break; + } + ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, + parser.tline); + } + + + script->inUse = 1; + script->substFlags = flags; + script->fileNameObj = interp->emptyObj; + Jim_IncrRefCount(script->fileNameObj); + SubstObjAddTokens(interp, script, &tokenlist); + + + ScriptTokenListFree(&tokenlist); + +#ifdef DEBUG_SHOW_SUBST + { + int i; + + printf("==== Subst ====\n"); + for (i = 0; i < script->len; i++) { + printf("[%2d] %s '%s'\n", i, jim_tt_name(script->token[i].type), + Jim_String(script->token[i].objPtr)); + } + } +#endif + + + Jim_FreeIntRep(interp, objPtr); + Jim_SetIntRepPtr(objPtr, script); + objPtr->typePtr = &scriptObjType; + return JIM_OK; +} + +static ScriptObj *Jim_GetSubst(Jim_Interp *interp, Jim_Obj *objPtr, int flags) +{ + if (objPtr->typePtr != &scriptObjType || ((ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags != flags) + SetSubstFromAny(interp, objPtr, flags); + return (ScriptObj *) Jim_GetIntRepPtr(objPtr); +} + +int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPtr, int flags) +{ + ScriptObj *script; + + JimPanic((substObjPtr->refCount == 0, "Jim_SubstObj() called with zero refcount object")); + + script = Jim_GetSubst(interp, substObjPtr, flags); + + Jim_IncrRefCount(substObjPtr); + script->inUse++; + + *resObjPtrPtr = JimInterpolateTokens(interp, script->token, script->len, flags); + + script->inUse--; + Jim_DecrRefCount(interp, substObjPtr); + if (*resObjPtrPtr == NULL) { + return JIM_ERR; + } + return JIM_OK; +} + +void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg) +{ + Jim_Obj *objPtr; + Jim_Obj *listObjPtr; + + JimPanic((argc == 0, "Jim_WrongNumArgs() called with argc=0")); + + listObjPtr = Jim_NewListObj(interp, argv, argc); + + if (msg && *msg) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1)); + } + Jim_IncrRefCount(listObjPtr); + objPtr = Jim_ListJoin(interp, listObjPtr, " ", 1); + Jim_DecrRefCount(interp, listObjPtr); + + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", objPtr); +} + +typedef void JimHashtableIteratorCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_Obj *keyObjPtr, void *value, Jim_Obj *patternObjPtr, int type); + +#define JimTrivialMatch(pattern) (strpbrk((pattern), "*[?\\") == NULL) + +static Jim_Obj *JimHashtablePatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr, + JimHashtableIteratorCallbackType *callback, int type) +{ + Jim_HashEntry *he; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + + if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) { + he = Jim_FindHashEntry(ht, patternObjPtr); + if (he) { + callback(interp, listObjPtr, Jim_GetHashEntryKey(he), Jim_GetHashEntryVal(he), + patternObjPtr, type); + } + } + else { + Jim_HashTableIterator htiter; + JimInitHashTableIterator(ht, &htiter); + while ((he = Jim_NextHashEntry(&htiter)) != NULL) { + callback(interp, listObjPtr, Jim_GetHashEntryKey(he), Jim_GetHashEntryVal(he), + patternObjPtr, type); + } + } + return listObjPtr; +} + + +#define JIM_CMDLIST_COMMANDS 0 +#define JIM_CMDLIST_PROCS 1 +#define JIM_CMDLIST_CHANNELS 2 + +static void JimCommandMatch(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_Obj *keyObj, void *value, Jim_Obj *patternObj, int type) +{ + Jim_Cmd *cmdPtr = (Jim_Cmd *)value; + + if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) { + + return; + } + + Jim_IncrRefCount(keyObj); + + if (type != JIM_CMDLIST_CHANNELS || Jim_AioFilehandle(interp, keyObj) >= 0) { + int match = 1; + if (patternObj) { + int plen, slen; + const char *pattern = Jim_GetStringNoQualifier(patternObj, &plen); + const char *str = Jim_GetStringNoQualifier(keyObj, &slen); +#ifdef JIM_NO_INTROSPECTION + + match = (JimStringCompareUtf8(pattern, plen, str, slen, 0) == 0); +#else + match = JimGlobMatch(pattern, plen, str, slen, 0); +#endif + } + if (match) { + Jim_ListAppendElement(interp, listObjPtr, keyObj); + } + } + Jim_DecrRefCount(interp, keyObj); +} + +static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int type) +{ + return JimHashtablePatternMatch(interp, &interp->commands, patternObjPtr, JimCommandMatch, type); +} + + +#define JIM_VARLIST_GLOBALS 0 +#define JIM_VARLIST_LOCALS 1 +#define JIM_VARLIST_VARS 2 +#define JIM_VARLIST_MASK 0x000f + +#define JIM_VARLIST_VALUES 0x1000 + +static void JimVariablesMatch(Jim_Interp *interp, Jim_Obj *listObjPtr, + Jim_Obj *keyObj, void *value, Jim_Obj *patternObj, int type) +{ + Jim_VarVal *vv = (Jim_VarVal *)value; + + if ((type & JIM_VARLIST_MASK) != JIM_VARLIST_LOCALS || vv->linkFramePtr == NULL) { + if (patternObj == NULL || Jim_StringMatchObj(interp, patternObj, keyObj, 0)) { + Jim_ListAppendElement(interp, listObjPtr, keyObj); + if (type & JIM_VARLIST_VALUES) { + Jim_ListAppendElement(interp, listObjPtr, vv->objPtr); + } + } + } +} + + +static Jim_Obj *JimVariablesList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int mode) +{ + if (mode == JIM_VARLIST_LOCALS && interp->framePtr == interp->topFramePtr) { + return interp->emptyObj; + } + else { + Jim_CallFrame *framePtr = (mode == JIM_VARLIST_GLOBALS) ? interp->topFramePtr : interp->framePtr; + return JimHashtablePatternMatch(interp, &framePtr->vars, patternObjPtr, JimVariablesMatch, + mode); + } +} + +static int JimInfoLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr, Jim_Obj **objPtrPtr) +{ + long level; + + if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) { + Jim_CallFrame *targetCallFrame = JimGetCallFrameByInteger(interp, level); + if (targetCallFrame && targetCallFrame != interp->topFramePtr) { +#ifdef JIM_NO_INTROSPECTION + + *objPtrPtr = Jim_NewListObj(interp, targetCallFrame->argv, 1); +#else + *objPtrPtr = Jim_NewListObj(interp, targetCallFrame->argv, targetCallFrame->argc); +#endif + return JIM_OK; + } + } + Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr); + return JIM_ERR; +} + +static int JimInfoFrame(Jim_Interp *interp, Jim_Obj *levelObjPtr, Jim_Obj **objPtrPtr) +{ + long level; + + if (Jim_GetLong(interp, levelObjPtr, &level) == JIM_OK) { + Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, level); + if (frame) { + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "type", -1)); + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "source", -1)); + if (frame->scriptObj) { + ScriptObj *script = JimGetScript(interp, frame->scriptObj); + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "line", -1)); + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, script->linenr)); + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "file", -1)); + Jim_ListAppendElement(interp, listObj, script->fileNameObj); + } +#ifndef JIM_NO_INTROSPECTION + { + Jim_Obj *cmdObj = Jim_NewListObj(interp, frame->argv, frame->argc); + + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "cmd", -1)); + Jim_ListAppendElement(interp, listObj, cmdObj); + } +#endif + { + Jim_Obj *procNameObj = JimProcForEvalFrame(interp, frame); + if (procNameObj) { + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "proc", -1)); + Jim_ListAppendElement(interp, listObj, procNameObj); + } + } + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "level", -1)); + Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, interp->framePtr->level - frame->framePtr->level)); + + *objPtrPtr = listObj; + return JIM_OK; + } + } + Jim_SetResultFormatted(interp, "bad level \"%#s\"", levelObjPtr); + return JIM_ERR; +} + + +static int Jim_PutsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "?-nonewline? string"); + return JIM_ERR; + } + if (argc == 3) { + if (!Jim_CompareStringImmediate(interp, argv[1], "-nonewline")) { + Jim_SetResultString(interp, "The second argument must " "be -nonewline", -1); + return JIM_ERR; + } + else { + fputs(Jim_String(argv[2]), stdout); + } + } + else { + puts(Jim_String(argv[1])); + } + return JIM_OK; +} + + +static int JimAddMulHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int op) +{ + jim_wide wideValue, res; + double doubleValue, doubleRes; + int i; + + res = (op == JIM_EXPROP_ADD) ? 0 : 1; + + for (i = 1; i < argc; i++) { + if (Jim_GetWide(interp, argv[i], &wideValue) != JIM_OK) + goto trydouble; + if (op == JIM_EXPROP_ADD) + res += wideValue; + else + res *= wideValue; + } + Jim_SetResultInt(interp, res); + return JIM_OK; + trydouble: + doubleRes = (double)res; + for (; i < argc; i++) { + if (Jim_GetDouble(interp, argv[i], &doubleValue) != JIM_OK) + return JIM_ERR; + if (op == JIM_EXPROP_ADD) + doubleRes += doubleValue; + else + doubleRes *= doubleValue; + } + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; +} + + +static int JimSubDivHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int op) +{ + jim_wide wideValue, res = 0; + double doubleValue, doubleRes = 0; + int i = 2; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "number ?number ... number?"); + return JIM_ERR; + } + else if (argc == 2) { + if (Jim_GetWide(interp, argv[1], &wideValue) != JIM_OK) { + if (Jim_GetDouble(interp, argv[1], &doubleValue) != JIM_OK) { + return JIM_ERR; + } + else { + if (op == JIM_EXPROP_SUB) + doubleRes = -doubleValue; + else + doubleRes = 1.0 / doubleValue; + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; + } + } + if (op == JIM_EXPROP_SUB) { + res = -wideValue; + Jim_SetResultInt(interp, res); + } + else { + doubleRes = 1.0 / wideValue; + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + } + return JIM_OK; + } + else { + if (Jim_GetWide(interp, argv[1], &res) != JIM_OK) { + if (Jim_GetDouble(interp, argv[1], &doubleRes) + != JIM_OK) { + return JIM_ERR; + } + else { + goto trydouble; + } + } + } + for (i = 2; i < argc; i++) { + if (Jim_GetWide(interp, argv[i], &wideValue) != JIM_OK) { + doubleRes = (double)res; + goto trydouble; + } + if (op == JIM_EXPROP_SUB) + res -= wideValue; + else { + if (wideValue == 0) { + Jim_SetResultString(interp, "Division by zero", -1); + return JIM_ERR; + } + res /= wideValue; + } + } + Jim_SetResultInt(interp, res); + return JIM_OK; + trydouble: + for (; i < argc; i++) { + if (Jim_GetDouble(interp, argv[i], &doubleValue) != JIM_OK) + return JIM_ERR; + if (op == JIM_EXPROP_SUB) + doubleRes -= doubleValue; + else + doubleRes /= doubleValue; + } + Jim_SetResult(interp, Jim_NewDoubleObj(interp, doubleRes)); + return JIM_OK; +} + + + +static int Jim_AddCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimAddMulHelper(interp, argc, argv, JIM_EXPROP_ADD); +} + + +static int Jim_MulCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimAddMulHelper(interp, argc, argv, JIM_EXPROP_MUL); +} + + +static int Jim_SubCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimSubDivHelper(interp, argc, argv, JIM_EXPROP_SUB); +} + + +static int Jim_DivCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimSubDivHelper(interp, argc, argv, JIM_EXPROP_DIV); +} + + +static int Jim_SetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?newValue?"); + return JIM_ERR; + } + if (argc == 2) { + Jim_Obj *objPtr; + + objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + if (!objPtr) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + return JIM_OK; +} + +static int Jim_UnsetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i = 1; + int complain = 1; + + while (i < argc) { + if (Jim_CompareStringImmediate(interp, argv[i], "--")) { + i++; + break; + } + if (Jim_CompareStringImmediate(interp, argv[i], "-nocomplain")) { + complain = 0; + i++; + continue; + } + break; + } + + while (i < argc) { + if (Jim_UnsetVariable(interp, argv[i], complain ? JIM_ERRMSG : JIM_NONE) != JIM_OK + && complain) { + return JIM_ERR; + } + i++; + } + + Jim_SetEmptyResult(interp); + return JIM_OK; +} + +static int JimCheckLoopRetcode(Jim_Interp *interp, int retval) +{ + if (retval == JIM_BREAK || retval == JIM_CONTINUE) { + if (--interp->break_level > 0) { + return 1; + } + } + return 0; +} + + +static int Jim_WhileCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "condition body"); + return JIM_ERR; + } + + + while (1) { + int boolean = 0, retval; + + if ((retval = Jim_GetBoolFromExpr(interp, argv[1], &boolean)) != JIM_OK) + return retval; + if (!boolean) + break; + + if ((retval = Jim_EvalObj(interp, argv[2])) != JIM_OK) { + if (JimCheckLoopRetcode(interp, retval)) { + return retval; + } + switch (retval) { + case JIM_BREAK: + goto out; + case JIM_CONTINUE: + continue; + default: + return retval; + } + } + } + out: + Jim_SetEmptyResult(interp); + return JIM_OK; +} + + +static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + int boolean = 1; + int immediate = 0; + Jim_Obj *varNamePtr = NULL; + Jim_Obj *stopVarNamePtr = NULL; + + if (argc != 5) { + Jim_WrongNumArgs(interp, 1, argv, "start test next body"); + return JIM_ERR; + } + + + if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) { + return retval; + } + + retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); + + +#ifdef JIM_OPTIMIZATION + if (retval == JIM_OK && boolean) { + ScriptObj *incrScript; + struct ExprTree *expr; + jim_wide stop, currentVal; + Jim_Obj *objPtr; + int cmpOffset; + + + expr = JimGetExpression(interp, argv[2]); + incrScript = JimGetScript(interp, argv[3]); + + + if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) { + goto evalstart; + } + + if (incrScript->token[1].type != JIM_TT_ESC) { + goto evalstart; + } + + if (expr->expr->type == JIM_EXPROP_LT) { + cmpOffset = 0; + } + else if (expr->expr->type == JIM_EXPROP_LTE) { + cmpOffset = 1; + } + else { + goto evalstart; + } + + if (expr->expr->left->type != JIM_TT_VAR) { + goto evalstart; + } + + if (expr->expr->right->type != JIM_TT_VAR && expr->expr->right->type != JIM_TT_EXPR_INT) { + goto evalstart; + } + + + if (!Jim_CompareStringImmediate(interp, incrScript->token[1].objPtr, "incr")) { + goto evalstart; + } + + + if (!Jim_StringEqObj(incrScript->token[2].objPtr, expr->expr->left->objPtr)) { + goto evalstart; + } + + + if (expr->expr->right->type == JIM_TT_EXPR_INT) { + if (Jim_GetWideExpr(interp, expr->expr->right->objPtr, &stop) == JIM_ERR) { + goto evalstart; + } + } + else { + stopVarNamePtr = expr->expr->right->objPtr; + Jim_IncrRefCount(stopVarNamePtr); + + stop = 0; + } + + + varNamePtr = expr->expr->left->objPtr; + Jim_IncrRefCount(varNamePtr); + + objPtr = Jim_GetVariable(interp, varNamePtr, JIM_NONE); + if (objPtr == NULL || Jim_GetWide(interp, objPtr, ¤tVal) != JIM_OK) { + goto testcond; + } + + + while (retval == JIM_OK) { + + + + + if (stopVarNamePtr) { + objPtr = Jim_GetVariable(interp, stopVarNamePtr, JIM_NONE); + if (objPtr == NULL || Jim_GetWide(interp, objPtr, &stop) != JIM_OK) { + goto testcond; + } + } + + if (currentVal >= stop + cmpOffset) { + break; + } + + + retval = Jim_EvalObj(interp, argv[4]); + if (JimCheckLoopRetcode(interp, retval)) { + immediate++; + goto out; + } + if (retval == JIM_OK || retval == JIM_CONTINUE) { + retval = JIM_OK; + + objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG); + + + if (objPtr == NULL) { + retval = JIM_ERR; + goto out; + } + if (!Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + currentVal = ++JimWideValue(objPtr); + Jim_InvalidateStringRep(objPtr); + } + else { + if (Jim_GetWide(interp, objPtr, ¤tVal) != JIM_OK || + Jim_SetVariable(interp, varNamePtr, Jim_NewIntObj(interp, + ++currentVal)) != JIM_OK) { + goto evalnext; + } + } + } + } + goto out; + } + evalstart: +#endif + + while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) { + + retval = Jim_EvalObj(interp, argv[4]); + if (JimCheckLoopRetcode(interp, retval)) { + immediate++; + break; + } + if (retval == JIM_OK || retval == JIM_CONTINUE) { + +JIM_IF_OPTIM(evalnext:) + retval = Jim_EvalObj(interp, argv[3]); + if (retval == JIM_OK || retval == JIM_CONTINUE) { + +JIM_IF_OPTIM(testcond:) + retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); + } + } + } +JIM_IF_OPTIM(out:) + if (stopVarNamePtr) { + Jim_DecrRefCount(interp, stopVarNamePtr); + } + if (varNamePtr) { + Jim_DecrRefCount(interp, varNamePtr); + } + + if (!immediate) { + if (retval == JIM_CONTINUE || retval == JIM_BREAK || retval == JIM_OK) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + } + + return retval; +} + + +static int Jim_LoopCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + jim_wide i; + jim_wide limit; + jim_wide incr = 1; + Jim_Obj *bodyObjPtr; + + if (argc < 4 || argc > 6) { + Jim_WrongNumArgs(interp, 1, argv, "var ?first? limit ?incr? body"); + return JIM_ERR; + } + + retval = Jim_GetWideExpr(interp, argv[2], &i); + if (argc > 4 && retval == JIM_OK) { + retval = Jim_GetWideExpr(interp, argv[3], &limit); + } + if (argc > 5 && retval == JIM_OK) { + Jim_GetWideExpr(interp, argv[4], &incr); + } + if (retval != JIM_OK) { + return retval; + } + if (argc == 4) { + limit = i; + i = 0; + } + bodyObjPtr = argv[argc - 1]; + + retval = Jim_SetVariable(interp, argv[1], Jim_NewIntObj(interp, i)); + + while (((i < limit && incr > 0) || (i > limit && incr < 0)) && retval == JIM_OK) { + retval = Jim_EvalObj(interp, bodyObjPtr); + if (JimCheckLoopRetcode(interp, retval)) { + return retval; + } + if (retval == JIM_OK || retval == JIM_CONTINUE) { + Jim_Obj *objPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + + retval = JIM_OK; + + + i += incr; + + if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) { + if (argv[1]->typePtr != &variableObjType) { + if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { + return JIM_ERR; + } + } + JimWideValue(objPtr) = i; + Jim_InvalidateStringRep(objPtr); + + if (argv[1]->typePtr != &variableObjType) { + if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { + retval = JIM_ERR; + break; + } + } + } + else { + objPtr = Jim_NewIntObj(interp, i); + retval = Jim_SetVariable(interp, argv[1], objPtr); + if (retval != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + } + } + } + } + + if (retval == JIM_OK || retval == JIM_CONTINUE || retval == JIM_BREAK) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + return retval; +} + +typedef struct { + Jim_Obj *objPtr; + int idx; +} Jim_ListIter; + +static void JimListIterInit(Jim_ListIter *iter, Jim_Obj *objPtr) +{ + iter->objPtr = objPtr; + iter->idx = 0; +} + +static Jim_Obj *JimListIterNext(Jim_Interp *interp, Jim_ListIter *iter) +{ + if (iter->idx >= Jim_ListLength(interp, iter->objPtr)) { + return NULL; + } + return iter->objPtr->internalRep.listValue.ele[iter->idx++]; +} + +static int JimListIterDone(Jim_Interp *interp, Jim_ListIter *iter) +{ + return iter->idx >= Jim_ListLength(interp, iter->objPtr); +} + + +static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap) +{ + int result = JIM_OK; + int i, numargs; + Jim_ListIter twoiters[2]; + Jim_ListIter *iters; + Jim_Obj *script; + Jim_Obj *resultObj; + + if (argc < 4 || argc % 2 != 0) { + Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script"); + return JIM_ERR; + } + script = argv[argc - 1]; + numargs = (argc - 1 - 1); + + if (numargs == 2) { + iters = twoiters; + } + else { + iters = Jim_Alloc(numargs * sizeof(*iters)); + } + for (i = 0; i < numargs; i++) { + JimListIterInit(&iters[i], argv[i + 1]); + if (i % 2 == 0 && JimListIterDone(interp, &iters[i])) { + result = JIM_ERR; + } + } + if (result != JIM_OK) { + Jim_SetResultString(interp, "foreach varlist is empty", -1); + goto empty_varlist; + } + + if (doMap) { + resultObj = Jim_NewListObj(interp, NULL, 0); + } + else { + resultObj = interp->emptyObj; + } + Jim_IncrRefCount(resultObj); + + while (1) { + + for (i = 0; i < numargs; i += 2) { + if (!JimListIterDone(interp, &iters[i + 1])) { + break; + } + } + if (i == numargs) { + + break; + } + + + for (i = 0; i < numargs; i += 2) { + Jim_Obj *varName; + + + JimListIterInit(&iters[i], argv[i + 1]); + while ((varName = JimListIterNext(interp, &iters[i])) != NULL) { + Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]); + if (!valObj) { + + valObj = interp->emptyObj; + } + + Jim_IncrRefCount(valObj); + result = Jim_SetVariable(interp, varName, valObj); + Jim_DecrRefCount(interp, valObj); + if (result != JIM_OK) { + goto err; + } + } + } + result = Jim_EvalObj(interp, script); + if (JimCheckLoopRetcode(interp, result)) { + goto err; + } + switch (result) { + case JIM_OK: + if (doMap) { + Jim_ListAppendElement(interp, resultObj, interp->result); + } + break; + case JIM_CONTINUE: + break; + case JIM_BREAK: + goto out; + default: + goto err; + } + } + out: + result = JIM_OK; + Jim_SetResult(interp, resultObj); + err: + Jim_DecrRefCount(interp, resultObj); + empty_varlist: + if (numargs > 2) { + Jim_Free(iters); + } + return result; +} + + +static int Jim_ForeachCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimForeachMapHelper(interp, argc, argv, 0); +} + + +static int Jim_LmapCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimForeachMapHelper(interp, argc, argv, 1); +} + + +static int Jim_LassignCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int result = JIM_ERR; + int i; + Jim_ListIter iter; + Jim_Obj *resultObj; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varList list ?varName ...?"); + return JIM_ERR; + } + + JimListIterInit(&iter, argv[1]); + + for (i = 2; i < argc; i++) { + Jim_Obj *valObj = JimListIterNext(interp, &iter); + result = Jim_SetVariable(interp, argv[i], valObj ? valObj : interp->emptyObj); + if (result != JIM_OK) { + return result; + } + } + + resultObj = Jim_NewListObj(interp, NULL, 0); + while (!JimListIterDone(interp, &iter)) { + Jim_ListAppendElement(interp, resultObj, JimListIterNext(interp, &iter)); + } + + Jim_SetResult(interp, resultObj); + + return JIM_OK; +} + + +static int Jim_IfCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int boolean, retval, current = 1, falsebody = 0; + + if (argc >= 3) { + while (1) { + + if (current >= argc) + goto err; + if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean)) + != JIM_OK) + return retval; + + if (current >= argc) + goto err; + if (Jim_CompareStringImmediate(interp, argv[current], "then")) + current++; + + if (current >= argc) + goto err; + if (boolean) + return Jim_EvalObj(interp, argv[current]); + + if (++current >= argc) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + return JIM_OK; + } + falsebody = current++; + if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) { + + if (current != argc - 1) + goto err; + return Jim_EvalObj(interp, argv[current]); + } + else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif")) + continue; + + else if (falsebody != argc - 1) + goto err; + return Jim_EvalObj(interp, argv[falsebody]); + } + return JIM_OK; + } + err: + Jim_WrongNumArgs(interp, 1, argv, "condition ?then? trueBody ?elseif ...? ?else? falseBody"); + return JIM_ERR; +} + + +int Jim_CommandMatchObj(Jim_Interp *interp, Jim_Obj *commandObj, Jim_Obj *patternObj, + Jim_Obj *stringObj, int flags) +{ + Jim_Obj *parms[5]; + int argc = 0; + long eq; + int rc; + + parms[argc++] = commandObj; + if (flags & JIM_NOCASE) { + parms[argc++] = Jim_NewStringObj(interp, "-nocase", -1); + } + if (flags & JIM_OPT_END) { + parms[argc++] = Jim_NewStringObj(interp, "--", -1); + } + parms[argc++] = patternObj; + parms[argc++] = stringObj; + + rc = Jim_EvalObjVector(interp, argc, parms); + + if (rc != JIM_OK || Jim_GetLong(interp, Jim_GetResult(interp), &eq) != JIM_OK) { + eq = -rc; + } + + return eq; +} + + +static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + enum { SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD }; + int matchOpt = SWITCH_EXACT, opt = 1, patCount, i; + int match_flags = 0; + Jim_Obj *command = NULL, *scriptObj = NULL, *strObj; + Jim_Obj **caseList; + + if (argc < 3) { + wrongnumargs: + Jim_WrongNumArgs(interp, 1, argv, "?options? string " + "pattern body ... ?default body? or " "{pattern body ?pattern body ...?}"); + return JIM_ERR; + } + for (opt = 1; opt < argc; ++opt) { + const char *option = Jim_String(argv[opt]); + + if (*option != '-') + break; + else if (strncmp(option, "--", 2) == 0) { + ++opt; + break; + } + else if (strncmp(option, "-exact", 2) == 0) + matchOpt = SWITCH_EXACT; + else if (strncmp(option, "-glob", 2) == 0) + matchOpt = SWITCH_GLOB; + else if (strncmp(option, "-regexp", 2) == 0) { + matchOpt = SWITCH_RE; + match_flags |= JIM_OPT_END; + } + else if (strncmp(option, "-command", 2) == 0) { + matchOpt = SWITCH_CMD; + if ((argc - opt) < 2) + goto wrongnumargs; + command = argv[++opt]; + } + else { + Jim_SetResultFormatted(interp, + "bad option \"%#s\": must be -exact, -glob, -regexp, -command procname or --", + argv[opt]); + return JIM_ERR; + } + if ((argc - opt) < 2) + goto wrongnumargs; + } + strObj = argv[opt++]; + patCount = argc - opt; + if (patCount == 1) { + JimListGetElements(interp, argv[opt], &patCount, &caseList); + } + else + caseList = (Jim_Obj **)&argv[opt]; + if (patCount == 0 || patCount % 2 != 0) + goto wrongnumargs; + for (i = 0; scriptObj == NULL && i < patCount; i += 2) { + Jim_Obj *patObj = caseList[i]; + + if (!Jim_CompareStringImmediate(interp, patObj, "default") + || i < (patCount - 2)) { + switch (matchOpt) { + case SWITCH_EXACT: + if (Jim_StringEqObj(strObj, patObj)) + scriptObj = caseList[i + 1]; + break; + case SWITCH_GLOB: + if (Jim_StringMatchObj(interp, patObj, strObj, 0)) + scriptObj = caseList[i + 1]; + break; + case SWITCH_RE: + command = Jim_NewStringObj(interp, "regexp", -1); + + case SWITCH_CMD:{ + int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, match_flags); + + if (argc - opt == 1) { + JimListGetElements(interp, argv[opt], &patCount, &caseList); + } + + if (rc < 0) { + return -rc; + } + if (rc) + scriptObj = caseList[i + 1]; + break; + } + } + } + else { + scriptObj = caseList[i + 1]; + } + } + for (; i < patCount && Jim_CompareStringImmediate(interp, scriptObj, "-"); i += 2) + scriptObj = caseList[i + 1]; + if (scriptObj && Jim_CompareStringImmediate(interp, scriptObj, "-")) { + Jim_SetResultFormatted(interp, "no body specified for pattern \"%#s\"", caseList[i - 2]); + return JIM_ERR; + } + Jim_SetEmptyResult(interp); + if (scriptObj) { + return Jim_EvalObj(interp, scriptObj); + } + return JIM_OK; +} + + +static int Jim_ListCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + + listObjPtr = Jim_NewListObj(interp, argv + 1, argc - 1); + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} + + +static int Jim_LindexCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int ret; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "list ?index ...?"); + return JIM_ERR; + } + ret = Jim_ListIndices(interp, argv[1], argv + 2, argc - 2, &objPtr, JIM_NONE); + if (ret < 0) { + ret = JIM_OK; + Jim_SetEmptyResult(interp); + } + else if (ret == JIM_OK) { + Jim_SetResult(interp, objPtr); + } + return ret; +} + + +static int Jim_LlengthCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "list"); + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_ListLength(interp, argv[1])); + return JIM_OK; +} + + +static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + static const char * const options[] = { + "-bool", "-not", "-nocase", "-exact", "-glob", "-regexp", "-all", "-inline", "-command", + "-stride", "-index", NULL + }; + enum + { OPT_BOOL, OPT_NOT, OPT_NOCASE, OPT_EXACT, OPT_GLOB, OPT_REGEXP, OPT_ALL, OPT_INLINE, + OPT_COMMAND, OPT_STRIDE, OPT_INDEX }; + int i; + int opt_bool = 0; + int opt_not = 0; + int opt_all = 0; + int opt_inline = 0; + int opt_match = OPT_EXACT; + int listlen; + int rc = JIM_OK; + Jim_Obj *listObjPtr = NULL; + Jim_Obj *commandObj = NULL; + Jim_Obj *indexObj = NULL; + int match_flags = 0; + long stride = 1; + + if (argc < 3) { + wrongargs: + Jim_WrongNumArgs(interp, 1, argv, + "?-exact|-glob|-regexp|-command 'command'? ?-bool|-inline? ?-not? ?-nocase? ?-all? ?-stride len? ?-index val? list value"); + return JIM_ERR; + } + + for (i = 1; i < argc - 2; i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_BOOL: + opt_bool = 1; + opt_inline = 0; + break; + case OPT_NOT: + opt_not = 1; + break; + case OPT_NOCASE: + match_flags |= JIM_NOCASE; + break; + case OPT_INLINE: + opt_inline = 1; + opt_bool = 0; + break; + case OPT_ALL: + opt_all = 1; + break; + case OPT_REGEXP: + opt_match = option; + match_flags |= JIM_OPT_END; + break; + case OPT_COMMAND: + if (i >= argc - 2) { + goto wrongargs; + } + commandObj = argv[++i]; + + case OPT_EXACT: + case OPT_GLOB: + opt_match = option; + break; + case OPT_INDEX: + if (i >= argc - 2) { + goto wrongargs; + } + indexObj = argv[++i]; + break; + case OPT_STRIDE: + if (i >= argc - 2) { + goto wrongargs; + } + if (Jim_GetLong(interp, argv[++i], &stride) != JIM_OK) { + return JIM_ERR; + } + if (stride < 1) { + Jim_SetResultString(interp, "stride length must be at least 1", -1); + return JIM_ERR; + } + break; + } + } + + argc -= i; + if (argc < 2) { + goto wrongargs; + } + argv += i; + + listlen = Jim_ListLength(interp, argv[0]); + if (listlen % stride) { + Jim_SetResultString(interp, "list size must be a multiple of the stride length", -1); + return JIM_ERR; + } + + if (opt_all) { + listObjPtr = Jim_NewListObj(interp, NULL, 0); + } + if (opt_match == OPT_REGEXP) { + commandObj = Jim_NewStringObj(interp, "regexp", -1); + } + if (commandObj) { + Jim_IncrRefCount(commandObj); + } + + for (i = 0; i < listlen; i += stride) { + int eq = 0; + Jim_Obj *searchListObj; + Jim_Obj *objPtr; + int offset; + + if (indexObj) { + int indexlen = Jim_ListLength(interp, indexObj); + if (stride == 1) { + searchListObj = Jim_ListGetIndex(interp, argv[0], i); + } + else { + searchListObj = Jim_NewListObj(interp, argv[0]->internalRep.listValue.ele + i, stride); + } + Jim_IncrRefCount(searchListObj); + rc = Jim_ListIndices(interp, searchListObj, indexObj->internalRep.listValue.ele, indexlen, &objPtr, JIM_ERRMSG); + if (rc != JIM_OK) { + Jim_DecrRefCount(interp, searchListObj); + rc = JIM_ERR; + goto done; + } + + offset = 0; + } + else { + + searchListObj = argv[0]; + offset = i; + objPtr = Jim_ListGetIndex(interp, searchListObj, i); + Jim_IncrRefCount(searchListObj); + } + + switch (opt_match) { + case OPT_EXACT: + eq = Jim_StringCompareObj(interp, argv[1], objPtr, match_flags) == 0; + break; + + case OPT_GLOB: + eq = Jim_StringMatchObj(interp, argv[1], objPtr, match_flags); + break; + + case OPT_REGEXP: + case OPT_COMMAND: + eq = Jim_CommandMatchObj(interp, commandObj, argv[1], objPtr, match_flags); + if (eq < 0) { + Jim_DecrRefCount(interp, searchListObj); + rc = JIM_ERR; + goto done; + } + break; + } + + + if ((!opt_bool && eq == !opt_not) || (opt_bool && (eq || opt_all))) { + Jim_Obj *resultObj; + + if (opt_bool) { + resultObj = Jim_NewIntObj(interp, eq ^ opt_not); + } + else if (!opt_inline) { + resultObj = Jim_NewIntObj(interp, i); + } + else if (stride == 1) { + resultObj = objPtr; + } + else if (opt_all) { + + ListInsertElements(listObjPtr, -1, stride, + searchListObj->internalRep.listValue.ele + offset); + + resultObj = NULL; + } + else { + resultObj = Jim_NewListObj(interp, searchListObj->internalRep.listValue.ele + offset, stride); + } + + if (opt_all) { + + if (stride == 1) { + Jim_ListAppendElement(interp, listObjPtr, resultObj); + } + } + else { + Jim_SetResult(interp, resultObj); + Jim_DecrRefCount(interp, searchListObj); + goto done; + } + } + Jim_DecrRefCount(interp, searchListObj); + } + + if (opt_all) { + Jim_SetResult(interp, listObjPtr); + listObjPtr = NULL; + } + else { + + if (opt_bool) { + Jim_SetResultBool(interp, opt_not); + } + else if (!opt_inline) { + Jim_SetResultInt(interp, -1); + } + } + + done: + if (listObjPtr) { + Jim_FreeNewObj(interp, listObjPtr); + } + if (commandObj) { + Jim_DecrRefCount(interp, commandObj); + } + return rc; +} + + +static int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObjPtr; + int new_obj = 0; + int i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); + return JIM_ERR; + } + listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!listObjPtr) { + + listObjPtr = Jim_NewListObj(interp, NULL, 0); + new_obj = 1; + } + else if (Jim_IsShared(listObjPtr)) { + listObjPtr = Jim_DuplicateObj(interp, listObjPtr); + new_obj = 1; + } + for (i = 2; i < argc; i++) + Jim_ListAppendElement(interp, listObjPtr, argv[i]); + if (Jim_SetVariable(interp, argv[1], listObjPtr) != JIM_OK) { + if (new_obj) + Jim_FreeNewObj(interp, listObjPtr); + return JIM_ERR; + } + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} + + +static int Jim_LinsertCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int idx, len; + Jim_Obj *listPtr; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "list index ?element ...?"); + return JIM_ERR; + } + listPtr = argv[1]; + if (Jim_IsShared(listPtr)) + listPtr = Jim_DuplicateObj(interp, listPtr); + if (Jim_GetIndex(interp, argv[2], &idx) != JIM_OK) + goto err; + len = Jim_ListLength(interp, listPtr); + if (idx >= len) + idx = len; + else if (idx < 0) + idx = len + idx + 1; + Jim_ListInsertElements(interp, listPtr, idx, argc - 3, &argv[3]); + Jim_SetResult(interp, listPtr); + return JIM_OK; + err: + if (listPtr != argv[1]) { + Jim_FreeNewObj(interp, listPtr); + } + return JIM_ERR; +} + + +static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int first, last, len, rangeLen; + Jim_Obj *listObj; + Jim_Obj *newListObj; + + if (argc < 4) { + Jim_WrongNumArgs(interp, 1, argv, "list first last ?element ...?"); + return JIM_ERR; + } + if (Jim_GetIndex(interp, argv[2], &first) != JIM_OK || + Jim_GetIndex(interp, argv[3], &last) != JIM_OK) { + return JIM_ERR; + } + + listObj = argv[1]; + len = Jim_ListLength(interp, listObj); + + first = JimRelToAbsIndex(len, first); + last = JimRelToAbsIndex(len, last); + JimRelToAbsRange(len, &first, &last, &rangeLen); + + + if (first > len) { + first = len; + } + + + newListObj = Jim_NewListObj(interp, listObj->internalRep.listValue.ele, first); + + + ListInsertElements(newListObj, -1, argc - 4, argv + 4); + + + ListInsertElements(newListObj, -1, len - first - rangeLen, listObj->internalRep.listValue.ele + first + rangeLen); + + Jim_SetResult(interp, newListObj); + return JIM_OK; +} + + +static int Jim_LsetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "listVar ?index ...? value"); + return JIM_ERR; + } + else if (argc == 3) { + + if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[2]); + return JIM_OK; + } + return Jim_ListSetIndex(interp, argv[1], argv + 2, argc - 3, argv[argc - 1]); +} + + +static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const argv[]) +{ + static const char * const options[] = { + "-ascii", "-nocase", "-increasing", "-decreasing", "-command", "-integer", "-real", "-index", "-unique", + "-stride", "-dictionary", NULL + }; + enum { + OPT_ASCII, OPT_NOCASE, OPT_INCREASING, OPT_DECREASING, OPT_COMMAND, OPT_INTEGER, OPT_REAL, OPT_INDEX, OPT_UNIQUE, + OPT_STRIDE, OPT_DICT + }; + Jim_Obj *resObj; + int i; + int retCode; + int shared; + long stride = 1; + Jim_Obj **elements; + int listlen; + + struct lsort_info info; + + if (argc < 2) { +wrongargs: + Jim_WrongNumArgs(interp, 1, argv, "?options? list"); + return JIM_ERR; + } + + info.type = JIM_LSORT_ASCII; + info.order = 1; + info.indexc = 0; + info.unique = 0; + info.command = NULL; + info.interp = interp; + + for (i = 1; i < (argc - 1); i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, JIM_ENUM_ABBREV | JIM_ERRMSG) + != JIM_OK) + return JIM_ERR; + switch (option) { + case OPT_ASCII: + info.type = JIM_LSORT_ASCII; + break; + case OPT_DICT: + info.type = JIM_LSORT_DICT; + break; + case OPT_NOCASE: + info.type = JIM_LSORT_NOCASE; + break; + case OPT_INTEGER: + info.type = JIM_LSORT_INTEGER; + break; + case OPT_REAL: + info.type = JIM_LSORT_REAL; + break; + case OPT_INCREASING: + info.order = 1; + break; + case OPT_DECREASING: + info.order = -1; + break; + case OPT_UNIQUE: + info.unique = 1; + break; + case OPT_COMMAND: + if (i >= (argc - 2)) { + Jim_SetResultString(interp, "\"-command\" option must be followed by comparison command", -1); + return JIM_ERR; + } + info.type = JIM_LSORT_COMMAND; + info.command = argv[i + 1]; + i++; + break; + case OPT_STRIDE: + if (i >= argc - 2) { + goto wrongargs; + } + if (Jim_GetLong(interp, argv[++i], &stride) != JIM_OK) { + return JIM_ERR; + } + if (stride < 2) { + Jim_SetResultString(interp, "stride length must be at least 2", -1); + return JIM_ERR; + } + break; + case OPT_INDEX: + if (i >= (argc - 2)) { +badindex: + Jim_SetResultString(interp, "\"-index\" option must be followed by list index", -1); + return JIM_ERR; + } + JimListGetElements(interp, argv[i + 1], &info.indexc, &info.indexv); + if (info.indexc == 0) { + goto badindex; + } + i++; + break; + } + } + resObj = argv[argc - 1]; + JimListGetElements(interp, resObj, &listlen, &elements); + if (listlen <= 1) { + + Jim_SetResult(interp, resObj); + return JIM_OK; + } + + if (stride > 1) { + Jim_Obj *tmpListObj; + int i; + + if (listlen % stride) { + Jim_SetResultString(interp, "list size must be a multiple of the stride length", -1); + return JIM_ERR; + } + + tmpListObj = Jim_NewListObj(interp, NULL, 0); + Jim_IncrRefCount(tmpListObj); + for (i = 0; i < listlen; i += stride) { + Jim_ListAppendElement(interp, tmpListObj, Jim_NewListObj(interp, elements + i, stride)); + } + retCode = ListSortElements(interp, tmpListObj, &info); + if (retCode == JIM_OK) { + resObj = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; i < listlen; i += stride) { + Jim_ListAppendList(interp, resObj, Jim_ListGetIndex(interp, tmpListObj, i / stride)); + } + Jim_SetResult(interp, resObj); + } + Jim_DecrRefCount(interp, tmpListObj); + } + else { + if ((shared = Jim_IsShared(resObj))) { + resObj = Jim_DuplicateObj(interp, resObj); + } + retCode = ListSortElements(interp, resObj, &info); + if (retCode == JIM_OK) { + Jim_SetResult(interp, resObj); + } + else if (shared) { + Jim_FreeNewObj(interp, resObj); + } + } + return retCode; +} + + +static int Jim_AppendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *stringObjPtr; + int i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?value ...?"); + return JIM_ERR; + } + if (argc == 2) { + stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); + if (!stringObjPtr) + return JIM_ERR; + } + else { + int new_obj = 0; + stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); + if (!stringObjPtr) { + + stringObjPtr = Jim_NewEmptyStringObj(interp); + new_obj = 1; + } + else if (Jim_IsShared(stringObjPtr)) { + new_obj = 1; + stringObjPtr = Jim_DuplicateObj(interp, stringObjPtr); + } + for (i = 2; i < argc; i++) { + Jim_AppendObj(interp, stringObjPtr, argv[i]); + } + if (Jim_SetVariable(interp, argv[1], stringObjPtr) != JIM_OK) { + if (new_obj) { + Jim_FreeNewObj(interp, stringObjPtr); + } + return JIM_ERR; + } + } + Jim_SetResult(interp, stringObjPtr); + return JIM_OK; +} + + + + + +static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int rc; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "arg ?arg ...?"); + return JIM_ERR; + } + + if (argc == 2) { + rc = Jim_EvalObj(interp, argv[1]); + } + else { + rc = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); + } + + return rc; +} + + +static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc >= 2) { + int retcode; + Jim_CallFrame *savedCallFrame, *targetCallFrame; + const char *str; + + + savedCallFrame = interp->framePtr; + + + str = Jim_String(argv[1]); + if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') { + targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); + argc--; + argv++; + } + else { + targetCallFrame = Jim_GetCallFrameByLevel(interp, NULL); + } + if (targetCallFrame == NULL) { + return JIM_ERR; + } + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?"); + return JIM_ERR; + } + + interp->framePtr = targetCallFrame; + if (argc == 2) { + retcode = Jim_EvalObj(interp, argv[1]); + } + else { + retcode = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); + } + interp->framePtr = savedCallFrame; + return retcode; + } + else { + Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?"); + return JIM_ERR; + } +} + + +static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retcode; + + if (argc == 2) { + retcode = Jim_EvalExpression(interp, argv[1]); + } +#ifndef JIM_COMPAT + else { + Jim_WrongNumArgs(interp, 1, argv, "expression"); + retcode = JIM_ERR; + } +#else + else if (argc > 2) { + Jim_Obj *objPtr; + + objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1); + Jim_IncrRefCount(objPtr); + retcode = Jim_EvalExpression(interp, objPtr); + Jim_DecrRefCount(interp, objPtr); + } + else { + Jim_WrongNumArgs(interp, 1, argv, "expression ?...?"); + return JIM_ERR; + } +#endif + return retcode; +} + +static int JimBreakContinueHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int retcode) +{ + if (argc != 1 && argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "?level?"); + return JIM_ERR; + } + if (argc == 2) { + long level; + int ret = Jim_GetLong(interp, argv[1], &level); + if (ret != JIM_OK) { + return ret; + } + interp->break_level = level; + } + return retcode; +} + + +static int Jim_BreakCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimBreakContinueHelper(interp, argc, argv, JIM_BREAK); +} + + +static int Jim_ContinueCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimBreakContinueHelper(interp, argc, argv, JIM_CONTINUE); +} + + +static int Jim_StacktraceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listObj; + int i; + jim_wide skip = 0; + jim_wide last = 0; + + if (argc > 1) { + if (Jim_GetWideExpr(interp, argv[1], &skip) != JIM_OK) { + return JIM_ERR; + } + } + if (argc > 2) { + if (Jim_GetWideExpr(interp, argv[2], &last) != JIM_OK) { + return JIM_ERR; + } + } + + listObj = Jim_NewListObj(interp, NULL, 0); + for (i = skip; i <= interp->procLevel; i++) { + Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, -i); + if (frame->procLevel < last) { + break; + } + JimAddStackFrame(interp, frame, listObj); + } + Jim_SetResult(interp, listObj); + return JIM_OK; +} + + +static int Jim_ReturnCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + Jim_Obj *stackTraceObj = NULL; + Jim_Obj *errorCodeObj = NULL; + int returnCode = JIM_OK; + long level = 1; + + for (i = 1; i < argc - 1; i += 2) { + if (Jim_CompareStringImmediate(interp, argv[i], "-code")) { + if (Jim_GetReturnCode(interp, argv[i + 1], &returnCode) == JIM_ERR) { + return JIM_ERR; + } + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-errorinfo")) { + stackTraceObj = argv[i + 1]; + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-errorcode")) { + errorCodeObj = argv[i + 1]; + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-level")) { + if (Jim_GetLong(interp, argv[i + 1], &level) != JIM_OK || level < 0) { + Jim_SetResultFormatted(interp, "bad level \"%#s\"", argv[i + 1]); + return JIM_ERR; + } + } + else { + break; + } + } + + if (i != argc - 1 && i != argc) { + Jim_WrongNumArgs(interp, 1, argv, + "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?"); + } + + + if (stackTraceObj && returnCode == JIM_ERR) { + JimSetStackTrace(interp, stackTraceObj); + } + + if (errorCodeObj && returnCode == JIM_ERR) { + Jim_SetGlobalVariableStr(interp, "errorCode", errorCodeObj); + } + interp->returnCode = returnCode; + interp->returnLevel = level; + + if (i == argc - 1) { + Jim_SetResult(interp, argv[i]); + } + return level == 0 ? returnCode : JIM_RETURN; +} + + +static int Jim_TailcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (interp->framePtr->level == 0) { + Jim_SetResultString(interp, "tailcall can only be called from a proc or lambda", -1); + return JIM_ERR; + } + else if (argc >= 2) { + + Jim_CallFrame *cf = interp->framePtr->parent; + + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); + if (cmdPtr == NULL) { + return JIM_ERR; + } + + JimPanic((cf->tailcallCmd != NULL, "Already have a tailcallCmd")); + + + JimIncrCmdRefCount(cmdPtr); + cf->tailcallCmd = cmdPtr; + + + JimPanic((cf->tailcallObj != NULL, "Already have a tailcallobj")); + + cf->tailcallObj = Jim_NewListObj(interp, argv + 1, argc - 1); + Jim_IncrRefCount(cf->tailcallObj); + + + return JIM_EVAL; + } + return JIM_OK; +} + +static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *cmdList; + Jim_Obj *prefixListObj = Jim_CmdPrivData(interp); + + + cmdList = Jim_DuplicateObj(interp, prefixListObj); + Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1); + + return JimEvalObjList(interp, cmdList); +} + +static void JimAliasCmdDelete(Jim_Interp *interp, void *privData) +{ + Jim_Obj *prefixListObj = privData; + Jim_DecrRefCount(interp, prefixListObj); +} + +static int Jim_AliasCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *prefixListObj; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "newname command ?args ...?"); + return JIM_ERR; + } + + prefixListObj = Jim_NewListObj(interp, argv + 2, argc - 2); + Jim_IncrRefCount(prefixListObj); + Jim_SetResult(interp, argv[1]); + + return Jim_CreateCommandObj(interp, argv[1], JimAliasCmd, prefixListObj, JimAliasCmdDelete); +} + + +static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Cmd *cmd; + + if (argc != 4 && argc != 5) { + Jim_WrongNumArgs(interp, 1, argv, "name arglist ?statics? body"); + return JIM_ERR; + } + + if (argc == 4) { + cmd = JimCreateProcedureCmd(interp, argv[2], NULL, argv[3], NULL); + } + else { + cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL); + } + + if (cmd) { + + Jim_Obj *nameObjPtr = JimQualifyName(interp, argv[1]); + JimCreateCommand(interp, nameObjPtr, cmd); + + + JimUpdateProcNamespace(interp, cmd, nameObjPtr); + Jim_DecrRefCount(interp, nameObjPtr); + + + Jim_SetResult(interp, argv[1]); + return JIM_OK; + } + return JIM_ERR; +} + + +static int Jim_XtraceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "callback"); + return JIM_ERR; + } + + if (interp->traceCmdObj) { + Jim_DecrRefCount(interp, interp->traceCmdObj); + interp->traceCmdObj = NULL; + } + + if (Jim_Length(argv[1])) { + + interp->traceCmdObj = argv[1]; + Jim_IncrRefCount(interp->traceCmdObj); + } + return JIM_OK; +} + + +static int Jim_LocalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retcode; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?"); + return JIM_ERR; + } + + + interp->local++; + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); + interp->local--; + + + + if (retcode == 0) { + Jim_Obj *cmdNameObj = Jim_GetResult(interp); + + if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) { + return JIM_ERR; + } + if (interp->framePtr->localCommands == NULL) { + interp->framePtr->localCommands = Jim_Alloc(sizeof(*interp->framePtr->localCommands)); + Jim_InitStack(interp->framePtr->localCommands); + } + Jim_IncrRefCount(cmdNameObj); + Jim_StackPush(interp->framePtr->localCommands, cmdNameObj); + } + + return retcode; +} + + +static int Jim_UpcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?"); + return JIM_ERR; + } + else { + int retcode; + + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); + if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) { + Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]); + return JIM_ERR; + } + + cmdPtr->u.proc.upcall++; + JimIncrCmdRefCount(cmdPtr); + + + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); + + + cmdPtr->u.proc.upcall--; + JimDecrCmdRefCount(interp, cmdPtr); + + return retcode; + } +} + + +static int Jim_ApplyCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "lambdaExpr ?arg ...?"); + return JIM_ERR; + } + else { + int ret; + Jim_Cmd *cmd; + Jim_Obj *argListObjPtr; + Jim_Obj *bodyObjPtr; + Jim_Obj *nsObj = NULL; + Jim_Obj **nargv; + + int len = Jim_ListLength(interp, argv[1]); + if (len != 2 && len != 3) { + Jim_SetResultFormatted(interp, "can't interpret \"%#s\" as a lambda expression", argv[1]); + return JIM_ERR; + } + + if (len == 3) { +#ifdef jim_ext_namespace + + nsObj = Jim_ListGetIndex(interp, argv[1], 2); +#else + Jim_SetResultString(interp, "namespaces not enabled", -1); + return JIM_ERR; +#endif + } + argListObjPtr = Jim_ListGetIndex(interp, argv[1], 0); + bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1); + + cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj); + + if (cmd) { + + nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv)); + nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1); + Jim_IncrRefCount(nargv[0]); + memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv)); + ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv); + Jim_DecrRefCount(interp, nargv[0]); + Jim_Free(nargv); + + JimDecrCmdRefCount(interp, cmd); + return ret; + } + return JIM_ERR; + } +} + + + +static int Jim_ConcatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_SetResult(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); + return JIM_OK; +} + + +static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + Jim_CallFrame *targetCallFrame; + + + if (argc > 3 && (argc % 2 == 0)) { + targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); + argc--; + argv++; + } + else { + targetCallFrame = Jim_GetCallFrameByLevel(interp, NULL); + } + if (targetCallFrame == NULL) { + return JIM_ERR; + } + + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?"); + return JIM_ERR; + } + + + for (i = 1; i < argc; i += 2) { + if (Jim_SetVariableLink(interp, argv[i + 1], argv[i], targetCallFrame) != JIM_OK) + return JIM_ERR; + } + return JIM_OK; +} + + +static int Jim_GlobalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int i; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?"); + return JIM_ERR; + } + + if (interp->framePtr->level == 0) + return JIM_OK; + for (i = 1; i < argc; i++) { + + const char *name = Jim_String(argv[i]); + if (name[0] != ':' || name[1] != ':') { + if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK) + return JIM_ERR; + } + } + return JIM_OK; +} + +static Jim_Obj *JimStringMap(Jim_Interp *interp, Jim_Obj *mapListObjPtr, + Jim_Obj *objPtr, int nocase) +{ + int numMaps; + const char *str, *noMatchStart = NULL; + int strLen, i; + Jim_Obj *resultObjPtr; + + numMaps = Jim_ListLength(interp, mapListObjPtr); + if (numMaps % 2) { + Jim_SetResultString(interp, "list must contain an even number of elements", -1); + return NULL; + } + + str = Jim_String(objPtr); + strLen = Jim_Utf8Length(interp, objPtr); + + + resultObjPtr = Jim_NewStringObj(interp, "", 0); + while (strLen) { + for (i = 0; i < numMaps; i += 2) { + Jim_Obj *eachObjPtr; + const char *k; + int kl; + + eachObjPtr = Jim_ListGetIndex(interp, mapListObjPtr, i); + k = Jim_String(eachObjPtr); + kl = Jim_Utf8Length(interp, eachObjPtr); + + if (strLen >= kl && kl) { + int rc; + rc = JimStringCompareUtf8(str, kl, k, kl, nocase); + if (rc == 0) { + if (noMatchStart) { + Jim_AppendString(interp, resultObjPtr, noMatchStart, str - noMatchStart); + noMatchStart = NULL; + } + Jim_AppendObj(interp, resultObjPtr, Jim_ListGetIndex(interp, mapListObjPtr, i + 1)); + str += utf8_index(str, kl); + strLen -= kl; + break; + } + } + } + if (i == numMaps) { + int c; + if (noMatchStart == NULL) + noMatchStart = str; + str += utf8_tounicode(str, &c); + strLen--; + } + } + if (noMatchStart) { + Jim_AppendString(interp, resultObjPtr, noMatchStart, str - noMatchStart); + } + return resultObjPtr; +} + + +static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int len; + int opt_case = 1; + int option; + static const char * const nocase_options[] = { + "-nocase", NULL + }; + static const char * const nocase_length_options[] = { + "-nocase", "-length", NULL + }; + + enum { + OPT_BYTELENGTH, + OPT_BYTERANGE, + OPT_CAT, + OPT_COMPARE, + OPT_EQUAL, + OPT_FIRST, + OPT_INDEX, + OPT_IS, + OPT_LAST, + OPT_LENGTH, + OPT_MAP, + OPT_MATCH, + OPT_RANGE, + OPT_REPEAT, + OPT_REPLACE, + OPT_REVERSE, + OPT_TOLOWER, + OPT_TOTITLE, + OPT_TOUPPER, + OPT_TRIM, + OPT_TRIMLEFT, + OPT_TRIMRIGHT, + OPT_COUNT + }; + static const jim_subcmd_type cmds[OPT_COUNT + 1] = { + JIM_DEF_SUBCMD("bytelength", "string", 1, 1), + JIM_DEF_SUBCMD("byterange", "string first last", 3, 3), + JIM_DEF_SUBCMD("cat", "?...?", 0, -1), + JIM_DEF_SUBCMD("compare", "?-nocase? ?-length int? string1 string2", 2, 5), + JIM_DEF_SUBCMD("equal", "?-nocase? ?-length int? string1 string2", 2, 5), + JIM_DEF_SUBCMD("first", "subString string ?index?", 2, 3), + JIM_DEF_SUBCMD("index", "string index", 2, 2), + JIM_DEF_SUBCMD("is", "class ?-strict? str", 2, 3), + JIM_DEF_SUBCMD("last", "subString string ?index?", 2, 3), + JIM_DEF_SUBCMD("length","string", 1, 1), + JIM_DEF_SUBCMD("map", "?-nocase? mapList string", 2, 3), + JIM_DEF_SUBCMD("match", "?-nocase? pattern string", 2, 3), + JIM_DEF_SUBCMD("range", "string first last", 3, 3), + JIM_DEF_SUBCMD("repeat", "string count", 2, 2), + JIM_DEF_SUBCMD("replace", "string first last ?string?", 3, 4), + JIM_DEF_SUBCMD("reverse", "string", 1, 1), + JIM_DEF_SUBCMD("tolower", "string", 1, 1), + JIM_DEF_SUBCMD("totitle", "string", 1, 1), + JIM_DEF_SUBCMD("toupper", "string", 1, 1), + JIM_DEF_SUBCMD("trim", "string ?trimchars?", 1, 2), + JIM_DEF_SUBCMD("trimleft", "string ?trimchars?", 1, 2), + JIM_DEF_SUBCMD("trimright", "string ?trimchars?", 1, 2), + { } + }; + const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, cmds, argc, argv); + if (!ct) { + return JIM_ERR; + } + if (ct->function) { + + return ct->function(interp, argc, argv); + } + + option = ct - cmds; + + switch (option) { + case OPT_LENGTH: + Jim_SetResultInt(interp, Jim_Utf8Length(interp, argv[2])); + return JIM_OK; + + case OPT_BYTELENGTH: + Jim_SetResultInt(interp, Jim_Length(argv[2])); + return JIM_OK; + + case OPT_CAT:{ + Jim_Obj *objPtr; + if (argc == 3) { + + objPtr = argv[2]; + } + else { + int i; + + objPtr = Jim_NewStringObj(interp, "", 0); + + for (i = 2; i < argc; i++) { + Jim_AppendObj(interp, objPtr, argv[i]); + } + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_COMPARE: + case OPT_EQUAL: + { + + long opt_length = -1; + int n = argc - 4; + int i = 2; + while (n > 0) { + int subopt; + if (Jim_GetEnum(interp, argv[i++], nocase_length_options, &subopt, NULL, + JIM_ENUM_ABBREV) != JIM_OK) { +badcompareargs: + Jim_SubCmdArgError(interp, ct, argv[0]); + return JIM_ERR; + } + if (subopt == 0) { + + opt_case = 0; + n--; + } + else { + + if (n < 2) { + goto badcompareargs; + } + if (Jim_GetLong(interp, argv[i++], &opt_length) != JIM_OK) { + return JIM_ERR; + } + n -= 2; + } + } + if (n) { + goto badcompareargs; + } + argv += argc - 2; + if (opt_length < 0 && option != OPT_COMPARE && opt_case) { + + Jim_SetResultBool(interp, Jim_StringEqObj(argv[0], argv[1])); + } + else { + const char *s1 = Jim_String(argv[0]); + int l1 = Jim_Utf8Length(interp, argv[0]); + const char *s2 = Jim_String(argv[1]); + int l2 = Jim_Utf8Length(interp, argv[1]); + if (opt_length >= 0) { + if (l1 > opt_length) { + l1 = opt_length; + } + if (l2 > opt_length) { + l2 = opt_length; + } + } + n = JimStringCompareUtf8(s1, l1, s2, l2, !opt_case); + Jim_SetResultInt(interp, option == OPT_COMPARE ? n : n == 0); + } + return JIM_OK; + } + + case OPT_MATCH: + if (argc != 4 && + (argc != 5 || + Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL, + JIM_ENUM_ABBREV) != JIM_OK)) { + Jim_WrongNumArgs(interp, 2, argv, "?-nocase? pattern string"); + return JIM_ERR; + } + if (opt_case == 0) { + argv++; + } + Jim_SetResultBool(interp, Jim_StringMatchObj(interp, argv[2], argv[3], !opt_case)); + return JIM_OK; + + case OPT_MAP:{ + Jim_Obj *objPtr; + + if (argc != 4 && + (argc != 5 || + Jim_GetEnum(interp, argv[2], nocase_options, &opt_case, NULL, + JIM_ENUM_ABBREV) != JIM_OK)) { + Jim_WrongNumArgs(interp, 2, argv, "?-nocase? mapList string"); + return JIM_ERR; + } + + if (opt_case == 0) { + argv++; + } + objPtr = JimStringMap(interp, argv[2], argv[3], !opt_case); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_RANGE:{ + Jim_Obj *objPtr = Jim_StringRangeObj(interp, argv[2], argv[3], argv[4]); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_BYTERANGE:{ + Jim_Obj *objPtr = Jim_StringByteRangeObj(interp, argv[2], argv[3], argv[4]); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_REPLACE:{ + Jim_Obj *objPtr = JimStringReplaceObj(interp, argv[2], argv[3], argv[4], argc == 6 ? argv[5] : NULL); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + + case OPT_REPEAT:{ + Jim_Obj *objPtr; + jim_wide count; + + if (Jim_GetWideExpr(interp, argv[3], &count) != JIM_OK) { + return JIM_ERR; + } + objPtr = Jim_NewStringObj(interp, "", 0); + if (count > 0) { + while (count--) { + Jim_AppendObj(interp, objPtr, argv[2]); + } + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + + case OPT_REVERSE:{ + char *buf, *p; + const char *str; + int i; + + str = Jim_GetString(argv[2], &len); + buf = Jim_Alloc(len + 1); + assert(buf); + p = buf + len; + *p = 0; + for (i = 0; i < len; ) { + int c; + int l = utf8_tounicode(str, &c); + memcpy(p - l, str, l); + p -= l; + i += l; + str += l; + } + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len)); + return JIM_OK; + } + + case OPT_INDEX:{ + int idx; + const char *str; + + if (Jim_GetIndex(interp, argv[3], &idx) != JIM_OK) { + return JIM_ERR; + } + str = Jim_String(argv[2]); + len = Jim_Utf8Length(interp, argv[2]); + idx = JimRelToAbsIndex(len, idx); + if (idx < 0 || idx >= len || str == NULL) { + Jim_SetResultString(interp, "", 0); + } + else if (len == Jim_Length(argv[2])) { + + Jim_SetResultString(interp, str + idx, 1); + } + else { + int c; + int i = utf8_index(str, idx); + Jim_SetResultString(interp, str + i, utf8_tounicode(str + i, &c)); + } + return JIM_OK; + } + + case OPT_FIRST: + case OPT_LAST:{ + int idx = 0, l1, l2; + const char *s1, *s2; + + s1 = Jim_String(argv[2]); + s2 = Jim_String(argv[3]); + l1 = Jim_Utf8Length(interp, argv[2]); + l2 = Jim_Utf8Length(interp, argv[3]); + if (argc == 5) { + if (Jim_GetIndex(interp, argv[4], &idx) != JIM_OK) { + return JIM_ERR; + } + idx = JimRelToAbsIndex(l2, idx); + if (idx < 0) { + idx = 0; + } + } + else if (option == OPT_LAST) { + idx = l2; + } + if (option == OPT_FIRST) { + Jim_SetResultInt(interp, JimStringFirst(s1, l1, s2, l2, idx)); + } + else { +#ifdef JIM_UTF8 + Jim_SetResultInt(interp, JimStringLastUtf8(s1, l1, s2, idx)); +#else + Jim_SetResultInt(interp, JimStringLast(s1, l1, s2, idx)); +#endif + } + return JIM_OK; + } + + case OPT_TRIM: + Jim_SetResult(interp, JimStringTrim(interp, argv[2], argc == 4 ? argv[3] : NULL)); + return JIM_OK; + case OPT_TRIMLEFT: + Jim_SetResult(interp, JimStringTrimLeft(interp, argv[2], argc == 4 ? argv[3] : NULL)); + return JIM_OK; + case OPT_TRIMRIGHT:{ + Jim_SetResult(interp, JimStringTrimRight(interp, argv[2], argc == 4 ? argv[3] : NULL)); + return JIM_OK; + } + + case OPT_TOLOWER: + Jim_SetResult(interp, JimStringToLower(interp, argv[2])); + return JIM_OK; + case OPT_TOUPPER: + Jim_SetResult(interp, JimStringToUpper(interp, argv[2])); + return JIM_OK; + case OPT_TOTITLE: + Jim_SetResult(interp, JimStringToTitle(interp, argv[2])); + return JIM_OK; + + case OPT_IS: + if (argc == 5 && !Jim_CompareStringImmediate(interp, argv[3], "-strict")) { + Jim_SubCmdArgError(interp, ct, argv[0]); + return JIM_ERR; + } + return JimStringIs(interp, argv[argc - 1], argv[2], argc == 5); + } + return JIM_OK; +} + + +static int Jim_TimeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + long i, count = 1; + jim_wide start, elapsed; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "script ?count?"); + return JIM_ERR; + } + if (argc == 3) { + if (Jim_GetLong(interp, argv[2], &count) != JIM_OK) + return JIM_ERR; + } + if (count < 0) + return JIM_OK; + i = count; + start = Jim_GetTimeUsec(CLOCK_MONOTONIC_RAW); + while (i-- > 0) { + int retval; + + retval = Jim_EvalObj(interp, argv[1]); + if (retval != JIM_OK) { + return retval; + } + } + elapsed = Jim_GetTimeUsec(CLOCK_MONOTONIC_RAW) - start; + if (elapsed < count * 10) { + Jim_SetResult(interp, Jim_NewDoubleObj(interp, elapsed * 1.0 / count)); + } + else { + Jim_SetResultInt(interp, count == 0 ? 0 : elapsed / count); + } + Jim_AppendString(interp, Jim_GetResult(interp)," microseconds per iteration", -1); + return JIM_OK; +} + + +static int Jim_TimeRateCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + long us = 0; + jim_wide start, delta, overhead; + Jim_Obj *objPtr; + double us_per_iter; + int count; + int n; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "script ?milliseconds?"); + return JIM_ERR; + } + if (argc == 3) { + if (Jim_GetLong(interp, argv[2], &us) != JIM_OK) + return JIM_ERR; + us *= 1000; + } + if (us < 1) { + + us = 1000 * 1000; + } + + + start = Jim_GetTimeUsec(CLOCK_MONOTONIC_RAW); + count = 0; + do { + int retval = Jim_EvalObj(interp, argv[1]); + delta = Jim_GetTimeUsec(CLOCK_MONOTONIC_RAW) - start; + if (retval != JIM_OK) { + return retval; + } + count++; + } while (delta < us); + + + start = Jim_GetTimeUsec(CLOCK_MONOTONIC_RAW); + n = 0; + do { + int retval = Jim_EvalObj(interp, interp->nullScriptObj); + overhead = Jim_GetTimeUsec(CLOCK_MONOTONIC_RAW) - start; + if (retval != JIM_OK) { + return retval; + } + n++; + } while (n < count); + + delta -= overhead; + + us_per_iter = (double)delta / count; + objPtr = Jim_NewListObj(interp, NULL, 0); + + Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, "us_per_iter", -1)); + Jim_ListAppendElement(interp, objPtr, Jim_NewDoubleObj(interp, us_per_iter)); + Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, "iters_per_sec", -1)); + Jim_ListAppendElement(interp, objPtr, Jim_NewDoubleObj(interp, 1e6 / us_per_iter)); + Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, "count", -1)); + Jim_ListAppendElement(interp, objPtr, Jim_NewIntObj(interp, count)); + Jim_ListAppendElement(interp, objPtr, Jim_NewStringObj(interp, "elapsed_us", -1)); + Jim_ListAppendElement(interp, objPtr, Jim_NewIntObj(interp, delta)); + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + + +static int Jim_ExitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + long exitCode = 0; + + if (argc > 2) { + Jim_WrongNumArgs(interp, 1, argv, "?exitCode?"); + return JIM_ERR; + } + if (argc == 2) { + if (Jim_GetLong(interp, argv[1], &exitCode) != JIM_OK) + return JIM_ERR; + Jim_SetResult(interp, argv[1]); + } + interp->exitCode = exitCode; + return JIM_EXIT; +} + +static int JimMatchReturnCodes(Jim_Interp *interp, Jim_Obj *retcodeListObj, int rc) +{ + int len = Jim_ListLength(interp, retcodeListObj); + int i; + for (i = 0; i < len; i++) { + int returncode; + if (Jim_GetReturnCode(interp, Jim_ListGetIndex(interp, retcodeListObj, i), &returncode) != JIM_OK) { + return JIM_ERR; + } + if (rc == returncode) { + return JIM_OK; + } + } + return -1; +} + + +static int JimCatchTryHelper(Jim_Interp *interp, int istry, int argc, Jim_Obj *const *argv) +{ + static const char * const wrongargs_catchtry[2] = { + "?-?no?code ... --? script ?resultVarName? ?optionVarName?", + "?-?no?code ... --? script ?on|trap codes vars script? ... ?finally script?" + }; + int exitCode = 0; + int i; + int sig = 0; + int ok; + Jim_Obj *finallyScriptObj = NULL; + Jim_Obj *msgVarObj = NULL; + Jim_Obj *optsVarObj = NULL; + Jim_Obj *handlerScriptObj = NULL; + Jim_Obj *errorCodeObj; + int idx; + + + jim_wide ignore_mask = (1 << JIM_EXIT) | (1 << JIM_EVAL) | (1 << JIM_SIGNAL); + static const int max_ignore_code = sizeof(ignore_mask) * 8; + + JimPanic((istry != 0 && istry != 1, "wrong args to JimCatchTryHelper")); + + Jim_SetGlobalVariableStr(interp, "errorCode", Jim_NewStringObj(interp, "NONE", -1)); + + for (i = 1; i < argc - 1; i++) { + const char *arg = Jim_String(argv[i]); + jim_wide option; + int ignore; + + + if (strcmp(arg, "--") == 0) { + i++; + break; + } + if (*arg != '-') { + break; + } + + if (strncmp(arg, "-no", 3) == 0) { + arg += 3; + ignore = 1; + } + else { + arg++; + ignore = 0; + } + + if (Jim_StringToWide(arg, &option, 10) != JIM_OK) { + option = -1; + } + if (option < 0) { + option = Jim_FindByName(arg, jimReturnCodes, jimReturnCodesSize); + } + if (option < 0) { + goto wrongargs; + } + + if (ignore) { + ignore_mask |= ((jim_wide)1 << option); + } + else { + ignore_mask &= (~((jim_wide)1 << option)); + } + } + + idx = i; + + if (argc - idx < 1) { +wrongargs: + Jim_WrongNumArgs(interp, 1, argv, wrongargs_catchtry[istry]); + return JIM_ERR; + } + + if ((ignore_mask & (1 << JIM_SIGNAL)) == 0) { + sig++; + } + + interp->signal_level += sig; + if (Jim_CheckSignal(interp)) { + + exitCode = JIM_SIGNAL; + } + else { + exitCode = Jim_EvalObj(interp, argv[idx]); + + interp->errorFlag = 0; + } + interp->signal_level -= sig; + + errorCodeObj = Jim_GetGlobalVariableStr(interp, "errorCode", JIM_NONE); + + idx++; + if (istry) { + while (idx < argc) { + int option; + int ret; + static const char * const try_options[] = { "on", "trap", "finally", NULL }; + enum { TRY_ON, TRY_TRAP, TRY_FINALLY, }; + + if (Jim_GetEnum(interp, argv[idx], try_options, &option, "handler", JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case TRY_ON: + case TRY_TRAP: + if (idx + 4 > argc) { + goto wrongargs; + } + if (option == TRY_ON) { + ret = JimMatchReturnCodes(interp, argv[idx + 1], exitCode); + if (ret > JIM_OK) { + goto wrongargs; + } + } + else if (errorCodeObj) { + int len = Jim_ListLength(interp, argv[idx + 1]); + int i; + + ret = JIM_OK; + + for (i = 0; i < len; i++) { + Jim_Obj *matchObj = Jim_ListGetIndex(interp, argv[idx + 1], i); + Jim_Obj *objPtr = Jim_ListGetIndex(interp, errorCodeObj, i); + if (Jim_StringCompareObj(interp, matchObj, objPtr, 0) != 0) { + ret = -1; + break; + } + } + } + else { + + ret = -1; + } + + if (ret == JIM_OK && handlerScriptObj == NULL) { + msgVarObj = Jim_ListGetIndex(interp, argv[idx + 2], 0); + optsVarObj = Jim_ListGetIndex(interp, argv[idx + 2], 1); + handlerScriptObj = argv[idx + 3]; + } + idx += 4; + break; + case TRY_FINALLY: + if (idx + 2 != argc) { + goto wrongargs; + } + finallyScriptObj = argv[idx + 1]; + idx += 2; + break; + } + } + } + else { + if (argc - idx >= 1) { + msgVarObj = argv[idx]; + idx++; + if (argc - idx >= 1) { + optsVarObj = argv[idx]; + idx++; + } + } + } + + + if (exitCode >= 0 && exitCode < max_ignore_code && (((unsigned jim_wide)1 << exitCode) & ignore_mask)) { + + if (finallyScriptObj) { + Jim_EvalObj(interp, finallyScriptObj); + } + return exitCode; + } + + if (sig && exitCode == JIM_SIGNAL) { + + if (interp->signal_set_result) { + interp->signal_set_result(interp, interp->sigmask); + } + else if (!istry) { + Jim_SetResultInt(interp, interp->sigmask); + } + interp->sigmask = 0; + } + + ok = 1; + if (msgVarObj && Jim_Length(msgVarObj)) { + if (Jim_SetVariable(interp, msgVarObj, Jim_GetResult(interp)) != JIM_OK) { + ok = 0; + } + } + if (ok && optsVarObj && Jim_Length(optsVarObj)) { + Jim_Obj *optListObj = Jim_NewListObj(interp, NULL, 0); + + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-code", -1)); + Jim_ListAppendElement(interp, optListObj, + Jim_NewIntObj(interp, exitCode == JIM_RETURN ? interp->returnCode : exitCode)); + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-level", -1)); + Jim_ListAppendElement(interp, optListObj, Jim_NewIntObj(interp, interp->returnLevel)); + if (exitCode == JIM_ERR) { + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-errorinfo", + -1)); + Jim_ListAppendElement(interp, optListObj, interp->stackTrace); + + if (errorCodeObj) { + Jim_ListAppendElement(interp, optListObj, Jim_NewStringObj(interp, "-errorcode", -1)); + Jim_ListAppendElement(interp, optListObj, errorCodeObj); + } + } + if (Jim_SetVariable(interp, optsVarObj, optListObj) != JIM_OK) { + ok = 0; + } + } + if (ok && handlerScriptObj) { + + exitCode = Jim_EvalObj(interp, handlerScriptObj); + } + + if (finallyScriptObj) { + + Jim_Obj *prevResultObj = Jim_GetResult(interp); + Jim_IncrRefCount(prevResultObj); + int ret = Jim_EvalObj(interp, finallyScriptObj); + if (ret == JIM_OK) { + Jim_SetResult(interp, prevResultObj); + } + else { + exitCode = ret; + } + Jim_DecrRefCount(interp, prevResultObj); + } + if (!istry) { + Jim_SetResultInt(interp, exitCode); + exitCode = JIM_OK; + } + return exitCode; +} + + +static int Jim_CatchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimCatchTryHelper(interp, 0, argc, argv); +} + + +static int Jim_TryCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return JimCatchTryHelper(interp, 1, argc, argv); +} + + + +static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "oldName newName"); + return JIM_ERR; + } + + return Jim_RenameCommand(interp, argv[1], argv[2]); +} + +#define JIM_DICTMATCH_KEYS 0x0001 +#define JIM_DICTMATCH_VALUES 0x002 + +int Jim_DictMatchTypes(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj, int match_type, int return_types) +{ + Jim_Obj *listObjPtr; + Jim_Dict *dict; + int i; + + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + dict = objPtr->internalRep.dictValue; + + listObjPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; i < dict->len; i += 2 ) { + Jim_Obj *keyObj = dict->table[i]; + Jim_Obj *valObj = dict->table[i + 1]; + if (patternObj) { + Jim_Obj *matchObj = (match_type == JIM_DICTMATCH_KEYS) ? keyObj : valObj; + if (!Jim_StringMatchObj(interp, patternObj, matchObj, 0)) { + + continue; + } + } + if (return_types & JIM_DICTMATCH_KEYS) { + Jim_ListAppendElement(interp, listObjPtr, keyObj); + } + if (return_types & JIM_DICTMATCH_VALUES) { + Jim_ListAppendElement(interp, listObjPtr, valObj); + } + } + + Jim_SetResult(interp, listObjPtr); + return JIM_OK; +} + +int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr) +{ + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return -1; + } + return objPtr->internalRep.dictValue->len / 2; +} + +Jim_Obj *Jim_DictMerge(Jim_Interp *interp, int objc, Jim_Obj *const *objv) +{ + Jim_Obj *objPtr = Jim_NewDictObj(interp, NULL, 0); + int i; + + JimPanic((objc == 0, "Jim_DictMerge called with objc=0")); + + + + for (i = 0; i < objc; i++) { + Jim_Obj **table; + int tablelen; + int j; + + table = Jim_DictPairs(interp, objv[i], &tablelen); + if (tablelen && !table) { + Jim_FreeNewObj(interp, objPtr); + return NULL; + } + for (j = 0; j < tablelen; j += 2) { + DictAddElement(interp, objPtr, table[j], table[j + 1]); + } + } + return objPtr; +} + +int Jim_DictInfo(Jim_Interp *interp, Jim_Obj *objPtr) +{ + char buffer[100]; + Jim_Obj *output; + Jim_Dict *dict; + + if (SetDictFromAny(interp, objPtr) != JIM_OK) { + return JIM_ERR; + } + + dict = objPtr->internalRep.dictValue; + + + snprintf(buffer, sizeof(buffer), "%d entries in table, %d buckets", dict->len, dict->size); + output = Jim_NewStringObj(interp, buffer, -1); + Jim_SetResult(interp, output); + return JIM_OK; +} + +static int Jim_EvalEnsemble(Jim_Interp *interp, const char *basecmd, const char *subcmd, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *prefixObj = Jim_NewStringObj(interp, basecmd, -1); + + Jim_AppendString(interp, prefixObj, " ", 1); + Jim_AppendString(interp, prefixObj, subcmd, -1); + + return Jim_EvalObjPrefix(interp, prefixObj, argc, argv); +} + +static int JimDictWith(Jim_Interp *interp, Jim_Obj *dictVarName, Jim_Obj *const *keyv, int keyc, Jim_Obj *scriptObj) +{ + int i; + Jim_Obj *objPtr; + Jim_Obj *dictObj; + Jim_Obj **dictValues; + int len; + int ret = JIM_OK; + + + dictObj = Jim_GetVariable(interp, dictVarName, JIM_ERRMSG); + if (dictObj == NULL || Jim_DictKeysVector(interp, dictObj, keyv, keyc, &objPtr, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + + dictValues = Jim_DictPairs(interp, objPtr, &len); + if (len && dictValues == NULL) { + return JIM_ERR; + } + for (i = 0; i < len; i += 2) { + if (Jim_SetVariable(interp, dictValues[i], dictValues[i + 1]) == JIM_ERR) { + return JIM_ERR; + } + } + + + if (Jim_Length(scriptObj)) { + ret = Jim_EvalObj(interp, scriptObj); + + + if (ret == JIM_OK && Jim_GetVariable(interp, dictVarName, 0) != NULL) { + + Jim_Obj **newkeyv = Jim_Alloc(sizeof(*newkeyv) * (keyc + 1)); + for (i = 0; i < keyc; i++) { + newkeyv[i] = keyv[i]; + } + + for (i = 0; i < len; i += 2) { + + if (Jim_StringCompareObj(interp, dictVarName, dictValues[i], 0) != 0) { + + objPtr = Jim_GetVariable(interp, dictValues[i], 0); + newkeyv[keyc] = dictValues[i]; + Jim_SetDictKeysVector(interp, dictVarName, newkeyv, keyc + 1, objPtr, JIM_NORESULT); + } + } + Jim_Free(newkeyv); + } + } + + return ret; +} + + +static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int types = JIM_DICTMATCH_KEYS; + + enum { + OPT_CREATE, + OPT_GET, + OPT_GETDEF, + OPT_GETWITHDEFAULT, + OPT_SET, + OPT_UNSET, + OPT_EXISTS, + OPT_KEYS, + OPT_SIZE, + OPT_INFO, + OPT_MERGE, + OPT_WITH, + OPT_APPEND, + OPT_LAPPEND, + OPT_INCR, + OPT_REMOVE, + OPT_VALUES, + OPT_FOR, + OPT_REPLACE, + OPT_UPDATE, + OPT_COUNT + }; + static const jim_subcmd_type cmds[OPT_COUNT + 1] = { + JIM_DEF_SUBCMD("create", "?key value ...?", 0, -2), + JIM_DEF_SUBCMD("get", "dictionary ?key ...?", 1, -1), + JIM_DEF_SUBCMD_HIDDEN("getdef", "dictionary ?key ...? key default", 3, -1), + JIM_DEF_SUBCMD("getwithdefault", "dictionary ?key ...? key default", 3, -1), + JIM_DEF_SUBCMD("set", "varName key ?key ...? value", 3, -1), + JIM_DEF_SUBCMD("unset", "varName key ?key ...?", 2, -1), + JIM_DEF_SUBCMD("exists", "dictionary key ?key ...?", 2, -1), + JIM_DEF_SUBCMD("keys", "dictionary ?pattern?", 1, 2), + JIM_DEF_SUBCMD("size", "dictionary", 1, 1), + JIM_DEF_SUBCMD("info", "dictionary", 1, 1), + JIM_DEF_SUBCMD("merge", "?...?", 0, -1), + JIM_DEF_SUBCMD("with", "dictVar ?key ...? script", 2, -1), + JIM_DEF_SUBCMD("append", "varName key ?value ...?", 2, -1), + JIM_DEF_SUBCMD("lappend", "varName key ?value ...?", 2, -1), + JIM_DEF_SUBCMD("incr", "varName key ?increment?", 2, 3), + JIM_DEF_SUBCMD("remove", "dictionary ?key ...?", 1, -1), + JIM_DEF_SUBCMD("values", "dictionary ?pattern?", 1, 2), + JIM_DEF_SUBCMD("for", "vars dictionary script", 3, 3), + JIM_DEF_SUBCMD("replace", "dictionary ?key value ...?", 1, -1), + JIM_DEF_SUBCMD("update", "varName ?arg ...? script", 2, -1), + { } + }; + const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, cmds, argc, argv); + if (!ct) { + return JIM_ERR; + } + if (ct->function) { + + return ct->function(interp, argc, argv); + } + + + switch (ct - cmds) { + case OPT_GET: + if (Jim_DictKeysVector(interp, argv[2], argv + 3, argc - 3, &objPtr, + JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + + case OPT_GETDEF: + case OPT_GETWITHDEFAULT:{ + int rc = Jim_DictKeysVector(interp, argv[2], argv + 3, argc - 4, &objPtr, JIM_ERRMSG); + if (rc == -1) { + + return JIM_ERR; + } + if (rc == JIM_ERR) { + Jim_SetResult(interp, argv[argc - 1]); + } + else { + Jim_SetResult(interp, objPtr); + } + return JIM_OK; + } + + case OPT_SET: + return Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 4, argv[argc - 1], JIM_ERRMSG); + + case OPT_EXISTS:{ + int rc = Jim_DictKeysVector(interp, argv[2], argv + 3, argc - 3, &objPtr, JIM_NONE); + if (rc < 0) { + return JIM_ERR; + } + Jim_SetResultBool(interp, rc == JIM_OK); + return JIM_OK; + } + + case OPT_UNSET: + if (Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 3, NULL, JIM_NONE) != JIM_OK) { + return JIM_ERR; + } + return JIM_OK; + + case OPT_VALUES: + types = JIM_DICTMATCH_VALUES; + + case OPT_KEYS: + return Jim_DictMatchTypes(interp, argv[2], argc == 4 ? argv[3] : NULL, types, types); + + case OPT_SIZE: + if (Jim_DictSize(interp, argv[2]) < 0) { + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_DictSize(interp, argv[2])); + return JIM_OK; + + case OPT_MERGE: + if (argc == 2) { + return JIM_OK; + } + objPtr = Jim_DictMerge(interp, argc - 2, argv + 2); + if (objPtr == NULL) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; + + case OPT_CREATE: + objPtr = Jim_NewDictObj(interp, argv + 2, argc - 2); + Jim_SetResult(interp, objPtr); + return JIM_OK; + + case OPT_INFO: + return Jim_DictInfo(interp, argv[2]); + + case OPT_WITH: + return JimDictWith(interp, argv[2], argv + 3, argc - 4, argv[argc - 1]); + + case OPT_UPDATE: + if (argc < 6 || argc % 2) { + + argc = 2; + } + + default: + return Jim_EvalEnsemble(interp, "dict", Jim_String(argv[1]), argc - 2, argv + 2); + } +} + + +static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + static const char * const options[] = { + "-nobackslashes", "-nocommands", "-novariables", NULL + }; + enum + { OPT_NOBACKSLASHES, OPT_NOCOMMANDS, OPT_NOVARIABLES }; + int i; + int flags = JIM_SUBST_FLAG; + Jim_Obj *objPtr; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "?options? string"); + return JIM_ERR; + } + for (i = 1; i < (argc - 1); i++) { + int option; + + if (Jim_GetEnum(interp, argv[i], options, &option, NULL, + JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + switch (option) { + case OPT_NOBACKSLASHES: + flags |= JIM_SUBST_NOESC; + break; + case OPT_NOCOMMANDS: + flags |= JIM_SUBST_NOCMD; + break; + case OPT_NOVARIABLES: + flags |= JIM_SUBST_NOVAR; + break; + } + } + if (Jim_SubstObj(interp, argv[argc - 1], &objPtr, flags) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +#ifdef jim_ext_namespace +static int JimIsGlobalNamespace(Jim_Obj *objPtr) +{ + int len; + const char *str = Jim_GetString(objPtr, &len); + return len >= 2 && str[0] == ':' && str[1] == ':'; +} +#endif + + +static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int mode = 0; + + + enum { + INFO_ALIAS, + INFO_ARGS, + INFO_BODY, + INFO_CHANNELS, + INFO_COMMANDS, + INFO_COMPLETE, + INFO_EXISTS, + INFO_FRAME, + INFO_GLOBALS, + INFO_HOSTNAME, + INFO_LEVEL, + INFO_LOCALS, + INFO_NAMEOFEXECUTABLE, + INFO_PATCHLEVEL, + INFO_PROCS, + INFO_REFERENCES, + INFO_RETURNCODES, + INFO_SCRIPT, + INFO_SOURCE, + INFO_STACKTRACE, + INFO_STATICS, + INFO_VARS, + INFO_VERSION, + INFO_COUNT + }; + static const jim_subcmd_type cmds[INFO_COUNT + 1] = { + JIM_DEF_SUBCMD("alias", "command", 1, 1), + JIM_DEF_SUBCMD("args", "procname", 1, 1), + JIM_DEF_SUBCMD("body", "procname", 1, 1), + JIM_DEF_SUBCMD("channels", "?pattern?", 0, 1), + JIM_DEF_SUBCMD("commands", "?pattern?", 0, 1), + JIM_DEF_SUBCMD("complete", "script ?missing?", 1, 2), + JIM_DEF_SUBCMD("exists", "varName", 1, 1), + JIM_DEF_SUBCMD("frame", "?levelNum?", 0, 1), + JIM_DEF_SUBCMD("globals", "?pattern?", 0, 1), + JIM_DEF_SUBCMD("hostname", NULL, 0, 0), + JIM_DEF_SUBCMD("level", "?levelNum?", 0, 1), + JIM_DEF_SUBCMD("locals", "?pattern?", 0, 1), + JIM_DEF_SUBCMD("nameofexecutable", NULL, 0, 0), + JIM_DEF_SUBCMD("patchlevel", NULL, 0, 0), + JIM_DEF_SUBCMD("procs", "?pattern?", 0, 1), + JIM_DEF_SUBCMD("references", NULL, 0, 0), + JIM_DEF_SUBCMD("returncodes", "?code?", 0, 1), + JIM_DEF_SUBCMD("script", "?filename?", 0, 1), + JIM_DEF_SUBCMD("source", "source ?filename line?", 1, 3), + JIM_DEF_SUBCMD("stacktrace", NULL, 0, 0), + JIM_DEF_SUBCMD("statics", "procname", 1, 1), + JIM_DEF_SUBCMD("vars", "?pattern?", 0, 1), + JIM_DEF_SUBCMD("version", NULL, 0, 0), + { } + }; + const jim_subcmd_type *ct; +#ifdef jim_ext_namespace + int nons = 0; + + if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) { + + argc--; + argv++; + nons = 1; + } +#endif + ct = Jim_ParseSubCmd(interp, cmds, argc, argv); + if (!ct) { + return JIM_ERR; + } + if (ct->function) { + + return ct->function(interp, argc, argv); + } + + int option = ct - cmds; + + switch (option) { + case INFO_EXISTS: + Jim_SetResultBool(interp, Jim_GetVariable(interp, argv[2], 0) != NULL); + return JIM_OK; + + case INFO_ALIAS:{ + Jim_Cmd *cmdPtr; + + if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) { + return JIM_ERR; + } + if (cmdPtr->isproc || cmdPtr->u.native.cmdProc != JimAliasCmd) { + Jim_SetResultFormatted(interp, "command \"%#s\" is not an alias", argv[2]); + return JIM_ERR; + } + Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData); + return JIM_OK; + } + + case INFO_CHANNELS: + mode++; +#ifndef jim_ext_aio + Jim_SetResultString(interp, "aio not enabled", -1); + return JIM_ERR; +#endif + + case INFO_PROCS: + mode++; + + case INFO_COMMANDS: + +#ifdef jim_ext_namespace + if (!nons) { + if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimIsGlobalNamespace(argv[2]))) { + return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1); + } + } +#endif + Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode)); + return JIM_OK; + + case INFO_VARS: + mode++; + + case INFO_LOCALS: + mode++; + + case INFO_GLOBALS: + +#ifdef jim_ext_namespace + if (!nons) { + if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimIsGlobalNamespace(argv[2]))) { + return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1); + } + } +#endif + Jim_SetResult(interp, JimVariablesList(interp, argc == 3 ? argv[2] : NULL, mode)); + return JIM_OK; + + case INFO_SCRIPT: + if (argc == 3) { + Jim_IncrRefCount(argv[2]); + Jim_DecrRefCount(interp, interp->currentFilenameObj); + interp->currentFilenameObj = argv[2]; + } + Jim_SetResult(interp, interp->currentFilenameObj); + return JIM_OK; + + case INFO_SOURCE:{ + Jim_Obj *resObjPtr; + Jim_Obj *fileNameObj; + + if (argc == 4) { + Jim_SubCmdArgError(interp, ct, argv[0]); + return JIM_ERR; + } + if (argc == 5) { + jim_wide line; + if (Jim_GetWide(interp, argv[4], &line) != JIM_OK) { + return JIM_ERR; + } + resObjPtr = Jim_NewStringObj(interp, Jim_String(argv[2]), Jim_Length(argv[2])); + Jim_SetSourceInfo(interp, resObjPtr, argv[3], line); + } + else { + int line; + fileNameObj = Jim_GetSourceInfo(interp, argv[2], &line); + resObjPtr = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, resObjPtr, fileNameObj); + Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line)); + } + Jim_SetResult(interp, resObjPtr); + return JIM_OK; + } + + case INFO_STACKTRACE: + Jim_SetResult(interp, interp->stackTrace); + return JIM_OK; + + case INFO_LEVEL: + if (argc == 2) { + Jim_SetResultInt(interp, interp->framePtr->level); + } + else { + if (JimInfoLevel(interp, argv[2], &objPtr) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + } + return JIM_OK; + + case INFO_FRAME: + if (argc == 2) { + Jim_SetResultInt(interp, interp->procLevel + 1); + } + else { + if (JimInfoFrame(interp, argv[2], &objPtr) != JIM_OK) { + return JIM_ERR; + } + Jim_SetResult(interp, objPtr); + } + return JIM_OK; + + case INFO_BODY: + case INFO_STATICS: + case INFO_ARGS:{ + Jim_Cmd *cmdPtr; + + if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) { + return JIM_ERR; + } + if (!cmdPtr->isproc) { + Jim_SetResultFormatted(interp, "command \"%#s\" is not a procedure", argv[2]); + return JIM_ERR; + } + switch (option) { +#ifdef JIM_NO_INTROSPECTION + default: + Jim_SetResultString(interp, "unsupported", -1); + return JIM_ERR; +#else + case INFO_BODY: + Jim_SetResult(interp, cmdPtr->u.proc.bodyObjPtr); + break; + case INFO_ARGS: + Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr); + break; +#endif + case INFO_STATICS: + if (cmdPtr->u.proc.staticVars) { + Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars, + NULL, JimVariablesMatch, JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES)); + } + break; + } + return JIM_OK; + } + + case INFO_VERSION: + case INFO_PATCHLEVEL:{ + char buf[(JIM_INTEGER_SPACE * 2) + 1]; + + sprintf(buf, "%d.%d", JIM_VERSION / 100, JIM_VERSION % 100); + Jim_SetResultString(interp, buf, -1); + return JIM_OK; + } + + case INFO_COMPLETE: { + char missing; + + Jim_SetResultBool(interp, Jim_ScriptIsComplete(interp, argv[2], &missing)); + if (missing != ' ' && argc == 4) { + Jim_SetVariable(interp, argv[3], Jim_NewStringObj(interp, &missing, 1)); + } + return JIM_OK; + } + + case INFO_HOSTNAME: + + return Jim_Eval(interp, "os.gethostname"); + + case INFO_NAMEOFEXECUTABLE: + + return Jim_Eval(interp, "{info nameofexecutable}"); + + case INFO_RETURNCODES: + if (argc == 2) { + int i; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; jimReturnCodes[i]; i++) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewIntObj(interp, i)); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, + jimReturnCodes[i], -1)); + } + + Jim_SetResult(interp, listObjPtr); + } + else if (argc == 3) { + long code; + const char *name; + + if (Jim_GetLong(interp, argv[2], &code) != JIM_OK) { + return JIM_ERR; + } + name = Jim_ReturnCode(code); + if (*name == '?') { + Jim_SetResultInt(interp, code); + } + else { + Jim_SetResultString(interp, name, -1); + } + } + return JIM_OK; + case INFO_REFERENCES: +#ifdef JIM_REFERENCES + return JimInfoReferences(interp, argc, argv); +#else + Jim_SetResultString(interp, "not supported", -1); + return JIM_ERR; +#endif + default: + abort(); + } +} + + +static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + int result = 0; + + static const char * const options[] = { + "-command", "-proc", "-alias", "-var", NULL + }; + enum + { + OPT_COMMAND, OPT_PROC, OPT_ALIAS, OPT_VAR + }; + int option; + + if (argc == 2) { + option = OPT_VAR; + objPtr = argv[1]; + } + else if (argc == 3) { + if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_ERR; + } + objPtr = argv[2]; + } + else { + Jim_WrongNumArgs(interp, 1, argv, "?option? name"); + return JIM_ERR; + } + + if (option == OPT_VAR) { + result = Jim_GetVariable(interp, objPtr, 0) != NULL; + } + else { + + Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE); + + if (cmd) { + switch (option) { + case OPT_COMMAND: + result = 1; + break; + + case OPT_ALIAS: + result = cmd->isproc == 0 && cmd->u.native.cmdProc == JimAliasCmd; + break; + + case OPT_PROC: + result = cmd->isproc; + break; + } + } + } + Jim_SetResultBool(interp, result); + return JIM_OK; +} + + +static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *str, *splitChars, *noMatchStart; + int splitLen, strLen; + Jim_Obj *resObjPtr; + int c; + int len; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "string ?splitChars?"); + return JIM_ERR; + } + + str = Jim_GetString(argv[1], &len); + if (len == 0) { + return JIM_OK; + } + strLen = Jim_Utf8Length(interp, argv[1]); + + + if (argc == 2) { + splitChars = " \n\t\r"; + splitLen = 4; + } + else { + splitChars = Jim_String(argv[2]); + splitLen = Jim_Utf8Length(interp, argv[2]); + } + + noMatchStart = str; + resObjPtr = Jim_NewListObj(interp, NULL, 0); + + + if (splitLen) { + Jim_Obj *objPtr; + while (strLen--) { + const char *sc = splitChars; + int scLen = splitLen; + int sl = utf8_tounicode(str, &c); + while (scLen--) { + int pc; + sc += utf8_tounicode(sc, &pc); + if (c == pc) { + objPtr = Jim_NewStringObj(interp, noMatchStart, (str - noMatchStart)); + Jim_ListAppendElement(interp, resObjPtr, objPtr); + noMatchStart = str + sl; + break; + } + } + str += sl; + } + objPtr = Jim_NewStringObj(interp, noMatchStart, (str - noMatchStart)); + Jim_ListAppendElement(interp, resObjPtr, objPtr); + } + else { + Jim_Obj **commonObj = NULL; +#define NUM_COMMON (128 - 9) + while (strLen--) { + int n = utf8_tounicode(str, &c); +#ifdef JIM_OPTIMIZATION + if (c >= 9 && c < 128) { + + c -= 9; + if (!commonObj) { + commonObj = Jim_Alloc(sizeof(*commonObj) * NUM_COMMON); + memset(commonObj, 0, sizeof(*commonObj) * NUM_COMMON); + } + if (!commonObj[c]) { + commonObj[c] = Jim_NewStringObj(interp, str, 1); + } + Jim_ListAppendElement(interp, resObjPtr, commonObj[c]); + str++; + continue; + } +#endif + Jim_ListAppendElement(interp, resObjPtr, Jim_NewStringObjUtf8(interp, str, 1)); + str += n; + } + Jim_Free(commonObj); + } + + Jim_SetResult(interp, resObjPtr); + return JIM_OK; +} + + +static int Jim_JoinCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *joinStr; + int joinStrLen; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?"); + return JIM_ERR; + } + + if (argc == 2) { + joinStr = " "; + joinStrLen = 1; + } + else { + joinStr = Jim_GetString(argv[2], &joinStrLen); + } + Jim_SetResult(interp, Jim_ListJoin(interp, argv[1], joinStr, joinStrLen)); + return JIM_OK; +} + + +static int Jim_FormatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + + if (argc < 2) { + Jim_WrongNumArgs(interp, 1, argv, "formatString ?arg arg ...?"); + return JIM_ERR; + } + objPtr = Jim_FormatString(interp, argv[1], argc - 2, argv + 2); + if (objPtr == NULL) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + + +static int Jim_ScanCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *listPtr, **outVec; + int outc, i; + + if (argc < 3) { + Jim_WrongNumArgs(interp, 1, argv, "string format ?varName varName ...?"); + return JIM_ERR; + } + if (argv[2]->typePtr != &scanFmtStringObjType) + SetScanFmtFromAny(interp, argv[2]); + if (FormatGetError(argv[2]) != 0) { + Jim_SetResultString(interp, FormatGetError(argv[2]), -1); + return JIM_ERR; + } + if (argc > 3) { + int maxPos = FormatGetMaxPos(argv[2]); + int count = FormatGetCnvCount(argv[2]); + + if (maxPos > argc - 3) { + Jim_SetResultString(interp, "\"%n$\" argument index out of range", -1); + return JIM_ERR; + } + else if (count > argc - 3) { + Jim_SetResultString(interp, "different numbers of variable names and " + "field specifiers", -1); + return JIM_ERR; + } + else if (count < argc - 3) { + Jim_SetResultString(interp, "variable is not assigned by any " + "conversion specifiers", -1); + return JIM_ERR; + } + } + listPtr = Jim_ScanString(interp, argv[1], argv[2], JIM_ERRMSG); + if (listPtr == 0) + return JIM_ERR; + if (argc > 3) { + int rc = JIM_OK; + int count = 0; + + if (listPtr != 0 && listPtr != (Jim_Obj *)EOF) { + int len = Jim_ListLength(interp, listPtr); + + if (len != 0) { + JimListGetElements(interp, listPtr, &outc, &outVec); + for (i = 0; i < outc; ++i) { + if (Jim_Length(outVec[i]) > 0) { + ++count; + if (Jim_SetVariable(interp, argv[3 + i], outVec[i]) != JIM_OK) { + rc = JIM_ERR; + } + } + } + } + Jim_FreeNewObj(interp, listPtr); + } + else { + count = -1; + } + if (rc == JIM_OK) { + Jim_SetResultInt(interp, count); + } + return rc; + } + else { + if (listPtr == (Jim_Obj *)EOF) { + Jim_SetResult(interp, Jim_NewListObj(interp, 0, 0)); + return JIM_OK; + } + Jim_SetResult(interp, listPtr); + } + return JIM_OK; +} + + +static int Jim_ErrorCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "message ?stacktrace?"); + return JIM_ERR; + } + Jim_SetResult(interp, argv[1]); + if (argc == 3) { + JimSetStackTrace(interp, argv[2]); + return JIM_ERR; + } + return JIM_ERR; +} + + +static int Jim_LrangeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + + if (argc != 4) { + Jim_WrongNumArgs(interp, 1, argv, "list first last"); + return JIM_ERR; + } + if ((objPtr = Jim_ListRange(interp, argv[1], argv[2], argv[3])) == NULL) + return JIM_ERR; + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + + +static int Jim_LrepeatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + jim_wide count; + + if (argc < 2 || Jim_GetWideExpr(interp, argv[1], &count) != JIM_OK || count < 0) { + Jim_WrongNumArgs(interp, 1, argv, "count ?value ...?"); + return JIM_ERR; + } + if (count == 0 || argc == 2) { + Jim_SetEmptyResult(interp); + return JIM_OK; + } + + argc -= 2; + argv += 2; + + objPtr = Jim_NewListObj(interp, NULL, 0); + ListEnsureLength(objPtr, argc * count); + while (count--) { + ListInsertElements(objPtr, -1, argc, argv); + } + + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + +char **Jim_GetEnviron(void) +{ +#if defined(HAVE__NSGETENVIRON) + return *_NSGetEnviron(); +#else + #if !defined(NO_ENVIRON_EXTERN) + extern char **environ; + #endif + + return environ; +#endif +} + +void Jim_SetEnviron(char **env) +{ +#if defined(HAVE__NSGETENVIRON) + *_NSGetEnviron() = env; +#else + #if !defined(NO_ENVIRON_EXTERN) + extern char **environ; + #endif + + environ = env; +#endif +} + + +static int Jim_EnvCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const char *key; + const char *val; + + if (argc == 1) { + char **e = Jim_GetEnviron(); + + int i; + Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0); + + for (i = 0; e[i]; i++) { + const char *equals = strchr(e[i], '='); + + if (equals) { + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, e[i], + equals - e[i])); + Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, equals + 1, -1)); + } + } + + Jim_SetResult(interp, listObjPtr); + return JIM_OK; + } + + if (argc > 3) { + Jim_WrongNumArgs(interp, 1, argv, "varName ?default?"); + return JIM_ERR; + } + key = Jim_String(argv[1]); + val = getenv(key); + if (val == NULL) { + if (argc < 3) { + Jim_SetResultFormatted(interp, "environment variable \"%#s\" does not exist", argv[1]); + return JIM_ERR; + } + val = Jim_String(argv[2]); + } + Jim_SetResult(interp, Jim_NewStringObj(interp, val, -1)); + return JIM_OK; +} + + +static int Jim_SourceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int retval; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "fileName"); + return JIM_ERR; + } + retval = Jim_EvalFile(interp, Jim_String(argv[1])); + if (retval == JIM_RETURN) + return JIM_OK; + return retval; +} + + +static int Jim_LreverseCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *revObjPtr, **ele; + int len; + + if (argc != 2) { + Jim_WrongNumArgs(interp, 1, argv, "list"); + return JIM_ERR; + } + JimListGetElements(interp, argv[1], &len, &ele); + revObjPtr = Jim_NewListObj(interp, NULL, 0); + ListEnsureLength(revObjPtr, len); + len--; + while (len >= 0) + ListAppendElement(revObjPtr, ele[len--]); + Jim_SetResult(interp, revObjPtr); + return JIM_OK; +} + +static int JimRangeLen(jim_wide start, jim_wide end, jim_wide step) +{ + jim_wide len; + + if (step == 0) + return -1; + if (start == end) + return 0; + else if (step > 0 && start > end) + return -1; + else if (step < 0 && end > start) + return -1; + len = end - start; + if (len < 0) + len = -len; + if (step < 0) + step = -step; + len = 1 + ((len - 1) / step); + if (len > INT_MAX) + len = INT_MAX; + return (int)((len < 0) ? -1 : len); +} + + +static int Jim_RangeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide start = 0, end, step = 1; + int len, i; + Jim_Obj *objPtr; + + if (argc < 2 || argc > 4) { + Jim_WrongNumArgs(interp, 1, argv, "?start? end ?step?"); + return JIM_ERR; + } + if (argc == 2) { + if (Jim_GetWideExpr(interp, argv[1], &end) != JIM_OK) + return JIM_ERR; + } + else { + if (Jim_GetWideExpr(interp, argv[1], &start) != JIM_OK || + Jim_GetWideExpr(interp, argv[2], &end) != JIM_OK) + return JIM_ERR; + if (argc == 4 && Jim_GetWideExpr(interp, argv[3], &step) != JIM_OK) + return JIM_ERR; + } + if ((len = JimRangeLen(start, end, step)) == -1) { + Jim_SetResultString(interp, "Invalid (infinite?) range specified", -1); + return JIM_ERR; + } + objPtr = Jim_NewListObj(interp, NULL, 0); + ListEnsureLength(objPtr, len); + for (i = 0; i < len; i++) + ListAppendElement(objPtr, Jim_NewIntObj(interp, start + i * step)); + Jim_SetResult(interp, objPtr); + return JIM_OK; +} + + +static int Jim_RandCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_wide min = 0, max = 0, len, maxMul; + + if (argc < 1 || argc > 3) { + Jim_WrongNumArgs(interp, 1, argv, "?min? max"); + return JIM_ERR; + } + if (argc == 1) { + max = JIM_WIDE_MAX; + } else if (argc == 2) { + if (Jim_GetWideExpr(interp, argv[1], &max) != JIM_OK) + return JIM_ERR; + } else if (argc == 3) { + if (Jim_GetWideExpr(interp, argv[1], &min) != JIM_OK || + Jim_GetWideExpr(interp, argv[2], &max) != JIM_OK) + return JIM_ERR; + } + len = max-min; + if (len < 0) { + Jim_SetResultString(interp, "Invalid arguments (max < min)", -1); + return JIM_ERR; + } + maxMul = JIM_WIDE_MAX - (len ? (JIM_WIDE_MAX%len) : 0); + while (1) { + jim_wide r; + + JimRandomBytes(interp, &r, sizeof(jim_wide)); + if (r < 0 || r >= maxMul) continue; + r = (len == 0) ? 0 : r%len; + Jim_SetResultInt(interp, min+r); + return JIM_OK; + } +} + +static const struct { + const char *name; + Jim_CmdProc *cmdProc; +} Jim_CoreCommandsTable[] = { + {"alias", Jim_AliasCoreCommand}, + {"set", Jim_SetCoreCommand}, + {"unset", Jim_UnsetCoreCommand}, + {"puts", Jim_PutsCoreCommand}, + {"+", Jim_AddCoreCommand}, + {"*", Jim_MulCoreCommand}, + {"-", Jim_SubCoreCommand}, + {"/", Jim_DivCoreCommand}, + {"incr", Jim_IncrCoreCommand}, + {"while", Jim_WhileCoreCommand}, + {"loop", Jim_LoopCoreCommand}, + {"for", Jim_ForCoreCommand}, + {"foreach", Jim_ForeachCoreCommand}, + {"lmap", Jim_LmapCoreCommand}, + {"lassign", Jim_LassignCoreCommand}, + {"if", Jim_IfCoreCommand}, + {"switch", Jim_SwitchCoreCommand}, + {"list", Jim_ListCoreCommand}, + {"lindex", Jim_LindexCoreCommand}, + {"lset", Jim_LsetCoreCommand}, + {"lsearch", Jim_LsearchCoreCommand}, + {"llength", Jim_LlengthCoreCommand}, + {"lappend", Jim_LappendCoreCommand}, + {"linsert", Jim_LinsertCoreCommand}, + {"lreplace", Jim_LreplaceCoreCommand}, + {"lsort", Jim_LsortCoreCommand}, + {"append", Jim_AppendCoreCommand}, + {"eval", Jim_EvalCoreCommand}, + {"uplevel", Jim_UplevelCoreCommand}, + {"expr", Jim_ExprCoreCommand}, + {"break", Jim_BreakCoreCommand}, + {"continue", Jim_ContinueCoreCommand}, + {"proc", Jim_ProcCoreCommand}, + {"xtrace", Jim_XtraceCoreCommand}, + {"concat", Jim_ConcatCoreCommand}, + {"return", Jim_ReturnCoreCommand}, + {"upvar", Jim_UpvarCoreCommand}, + {"global", Jim_GlobalCoreCommand}, + {"string", Jim_StringCoreCommand}, + {"time", Jim_TimeCoreCommand}, + {"timerate", Jim_TimeRateCoreCommand}, + {"exit", Jim_ExitCoreCommand}, + {"catch", Jim_CatchCoreCommand}, + {"try", Jim_TryCoreCommand}, +#ifdef JIM_REFERENCES + {"ref", Jim_RefCoreCommand}, + {"getref", Jim_GetrefCoreCommand}, + {"setref", Jim_SetrefCoreCommand}, + {"finalize", Jim_FinalizeCoreCommand}, + {"collect", Jim_CollectCoreCommand}, +#endif + {"rename", Jim_RenameCoreCommand}, + {"dict", Jim_DictCoreCommand}, + {"subst", Jim_SubstCoreCommand}, + {"info", Jim_InfoCoreCommand}, + {"exists", Jim_ExistsCoreCommand}, + {"split", Jim_SplitCoreCommand}, + {"join", Jim_JoinCoreCommand}, + {"format", Jim_FormatCoreCommand}, + {"scan", Jim_ScanCoreCommand}, + {"error", Jim_ErrorCoreCommand}, + {"lrange", Jim_LrangeCoreCommand}, + {"lrepeat", Jim_LrepeatCoreCommand}, + {"env", Jim_EnvCoreCommand}, + {"source", Jim_SourceCoreCommand}, + {"lreverse", Jim_LreverseCoreCommand}, + {"range", Jim_RangeCoreCommand}, + {"rand", Jim_RandCoreCommand}, + {"tailcall", Jim_TailcallCoreCommand}, + {"local", Jim_LocalCoreCommand}, + {"upcall", Jim_UpcallCoreCommand}, + {"apply", Jim_ApplyCoreCommand}, + {"stacktrace", Jim_StacktraceCoreCommand}, + {NULL, NULL}, +}; + +void Jim_RegisterCoreCommands(Jim_Interp *interp) +{ + int i = 0; + + while (Jim_CoreCommandsTable[i].name != NULL) { + Jim_CreateCommand(interp, + Jim_CoreCommandsTable[i].name, Jim_CoreCommandsTable[i].cmdProc, NULL, NULL); + i++; + } +} + +void Jim_MakeErrorMessage(Jim_Interp *interp) +{ + Jim_Obj *argv[2]; + + argv[0] = Jim_NewStringObj(interp, "errorInfo", -1); + argv[1] = interp->result; + + Jim_EvalObjVector(interp, 2, argv); +} + +static char **JimSortStringTable(const char *const *tablePtr) +{ + int count; + char **tablePtrSorted; + + + for (count = 0; tablePtr[count]; count++) { + } + + + tablePtrSorted = Jim_Alloc(sizeof(char *) * (count + 1)); + memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count); + qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers); + tablePtrSorted[count] = NULL; + + return tablePtrSorted; +} + +static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype, + const char *prefix, const char *const *tablePtr, const char *name) +{ + char **tablePtrSorted; + int i; + + if (name == NULL) { + name = "option"; + } + + Jim_SetResultFormatted(interp, "%s%s \"%s\": must be ", badtype, name, arg); + tablePtrSorted = JimSortStringTable(tablePtr); + for (i = 0; tablePtrSorted[i]; i++) { + if (tablePtrSorted[i + 1] == NULL && i > 0) { + Jim_AppendString(interp, Jim_GetResult(interp), "or ", -1); + } + Jim_AppendStrings(interp, Jim_GetResult(interp), prefix, tablePtrSorted[i], NULL); + if (tablePtrSorted[i + 1]) { + Jim_AppendString(interp, Jim_GetResult(interp), ", ", -1); + } + } + Jim_Free(tablePtrSorted); +} + + +int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, const char *const *tablePtr) +{ + if (Jim_CompareStringImmediate(interp, objPtr, "-commands")) { + int i; + char **tablePtrSorted = JimSortStringTable(tablePtr); + Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); + for (i = 0; tablePtrSorted[i]; i++) { + Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, tablePtrSorted[i], -1)); + } + Jim_Free(tablePtrSorted); + return JIM_OK; + } + return JIM_ERR; +} + +static const Jim_ObjType getEnumObjType = { + "get-enum", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES +}; + +int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr, + const char *const *tablePtr, int *indexPtr, const char *name, int flags) +{ + const char *bad = "bad "; + const char *const *entryPtr = NULL; + int i; + int match = -1; + int arglen; + const char *arg; + + if (objPtr->typePtr == &getEnumObjType) { + if (objPtr->internalRep.ptrIntValue.ptr == tablePtr && objPtr->internalRep.ptrIntValue.int1 == flags) { + *indexPtr = objPtr->internalRep.ptrIntValue.int2; + return JIM_OK; + } + } + + arg = Jim_GetString(objPtr, &arglen); + + *indexPtr = -1; + + for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) { + if (Jim_CompareStringImmediate(interp, objPtr, *entryPtr)) { + + match = i; + goto found; + } + if (flags & JIM_ENUM_ABBREV) { + if (strncmp(arg, *entryPtr, arglen) == 0) { + if (*arg == '-' && arglen == 1) { + break; + } + if (match >= 0) { + bad = "ambiguous "; + goto ambiguous; + } + match = i; + } + } + } + + + if (match >= 0) { + found: + + Jim_FreeIntRep(interp, objPtr); + objPtr->typePtr = &getEnumObjType; + objPtr->internalRep.ptrIntValue.ptr = (void *)tablePtr; + objPtr->internalRep.ptrIntValue.int1 = flags; + objPtr->internalRep.ptrIntValue.int2 = match; + + *indexPtr = match; + return JIM_OK; + } + + ambiguous: + if (flags & JIM_ERRMSG) { + JimSetFailedEnumResult(interp, arg, bad, "", tablePtr, name); + } + return JIM_ERR; +} + +int Jim_FindByName(const char *name, const char * const array[], size_t len) +{ + int i; + + for (i = 0; i < (int)len; i++) { + if (array[i] && strcmp(array[i], name) == 0) { + return i; + } + } + return -1; +} + +int Jim_IsDict(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &dictObjType; +} + +int Jim_IsList(Jim_Obj *objPtr) +{ + return objPtr->typePtr == &listObjType; +} + +void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...) +{ + + int len = strlen(format); + int extra = 0; + int n = 0; + const char *params[5]; + int nobjparam = 0; + Jim_Obj *objparam[5]; + char *buf; + va_list args; + int i; + + va_start(args, format); + + for (i = 0; i < len && n < 5; i++) { + int l; + + if (strncmp(format + i, "%s", 2) == 0) { + params[n] = va_arg(args, char *); + + l = strlen(params[n]); + } + else if (strncmp(format + i, "%#s", 3) == 0) { + Jim_Obj *objPtr = va_arg(args, Jim_Obj *); + + params[n] = Jim_GetString(objPtr, &l); + objparam[nobjparam++] = objPtr; + Jim_IncrRefCount(objPtr); + } + else { + if (format[i] == '%') { + i++; + } + continue; + } + n++; + extra += l; + } + + len += extra; + buf = Jim_Alloc(len + 1); + len = snprintf(buf, len + 1, format, params[0], params[1], params[2], params[3], params[4]); + + va_end(args); + + Jim_SetResult(interp, Jim_NewStringObjNoAlloc(interp, buf, len)); + + for (i = 0; i < nobjparam; i++) { + Jim_DecrRefCount(interp, objparam[i]); + } +} + +int Jim_CheckAbiVersion(Jim_Interp *interp, int abi_version) +{ + if (abi_version != JIM_ABI_VERSION) { + Jim_SetResultString(interp, "ABI version mismatch", -1); + return JIM_ERR; + } + return JIM_OK; +} + + +#ifndef jim_ext_package +int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver, int flags) +{ + return JIM_OK; +} +#endif +#ifndef jim_ext_aio +int Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *fhObj) +{ + return -1; +} +#endif + + +#include +#include + + +static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + + return JIM_OK; +} + +static const jim_subcmd_type dummy_subcmd = { + "dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN +}; + +static Jim_Obj *subcmd_cmd_list(Jim_Interp *interp, const jim_subcmd_type * ct, const char *sep) +{ + + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + Jim_Obj *sortCmd[2]; + + for (; ct->cmd; ct++) { + if (!(ct->flags & JIM_MODFLAG_HIDDEN)) { + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, ct->cmd, -1)); + } + } + + + sortCmd[0] = Jim_NewStringObj(interp, "lsort", -1); + sortCmd[1] = listObj; + + if (Jim_EvalObjVector(interp, 2, sortCmd) == JIM_OK) { + return Jim_ListJoin(interp, Jim_GetResult(interp), sep, strlen(sep)); + } + + return Jim_GetResult(interp); +} + +static void bad_subcmd(Jim_Interp *interp, const jim_subcmd_type * command_table, const char *type, + Jim_Obj *cmd, Jim_Obj *subcmd) +{ + Jim_SetResultFormatted(interp, "%#s, %s command \"%#s\": should be %#s", cmd, type, + subcmd, subcmd_cmd_list(interp, command_table, ", ")); +} + +static void show_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc, + Jim_Obj *const *argv) +{ + Jim_SetResultFormatted(interp, "Usage: \"%#s command ... \", where command is one of: %#s", + argv[0], subcmd_cmd_list(interp, command_table, ", ")); +} + +static void add_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * ct, Jim_Obj *cmd) +{ + if (cmd) { + Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), " ", NULL); + } + Jim_AppendStrings(interp, Jim_GetResult(interp), ct->cmd, NULL); + if (ct->args && *ct->args) { + Jim_AppendStrings(interp, Jim_GetResult(interp), " ", ct->args, NULL); + } +} + +void Jim_SubCmdArgError(Jim_Interp *interp, const jim_subcmd_type * ct, Jim_Obj *subcmd) +{ + Jim_SetResultString(interp, "wrong # args: should be \"", -1); + add_cmd_usage(interp, ct, subcmd); + Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); +} + +static const Jim_ObjType subcmdLookupObjType = { + "subcmd-lookup", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES +}; + +const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table, + int argc, Jim_Obj *const *argv) +{ + const jim_subcmd_type *ct; + const jim_subcmd_type *partial = 0; + int cmdlen; + Jim_Obj *cmd; + const char *cmdstr; + int help = 0; + int argsok = 1; + + if (argc < 2) { + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s command ...\"\n" + "Use \"%#s -help ?command?\" for help", argv[0], argv[0]); + return 0; + } + + cmd = argv[1]; + + + if (cmd->typePtr == &subcmdLookupObjType) { + if (cmd->internalRep.ptrIntValue.ptr == command_table) { + ct = command_table + cmd->internalRep.ptrIntValue.int1; + goto found; + } + } + + + if (Jim_CompareStringImmediate(interp, cmd, "-help")) { + if (argc == 2) { + + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + help = 1; + + + cmd = argv[2]; + } + + + if (Jim_CompareStringImmediate(interp, cmd, "-commands")) { + Jim_SetResult(interp, subcmd_cmd_list(interp, command_table, " ")); + return &dummy_subcmd; + } + + cmdstr = Jim_GetString(cmd, &cmdlen); + + for (ct = command_table; ct->cmd; ct++) { + if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) { + + break; + } + if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) { + if (partial) { + + if (help) { + + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]); + return 0; + } + partial = ct; + } + continue; + } + + + if (partial && !ct->cmd) { + ct = partial; + } + + if (!ct->cmd) { + + if (help) { + + show_cmd_usage(interp, command_table, argc, argv); + return &dummy_subcmd; + } + bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]); + return 0; + } + + if (help) { + Jim_SetResultString(interp, "Usage: ", -1); + + add_cmd_usage(interp, ct, argv[0]); + return &dummy_subcmd; + } + + + Jim_FreeIntRep(interp, cmd); + cmd->typePtr = &subcmdLookupObjType; + cmd->internalRep.ptrIntValue.ptr = (void *)command_table; + cmd->internalRep.ptrIntValue.int1 = ct - command_table; + +found: + + + if (argc - 2 < ct->minargs) { + argsok = 0; + } + else if (ct->maxargs >= 0 && argc - 2 > ct->maxargs) { + argsok = 0; + } + else if (ct->maxargs < -1 && (argc - 2) % -ct->maxargs != 0) { + + argsok = 0; + } + if (!argsok) { + Jim_SetResultString(interp, "wrong # args: should be \"", -1); + + add_cmd_usage(interp, ct, argv[0]); + Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); + + return 0; + } + + + return ct; +} + +int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv) +{ + int ret = JIM_ERR; + + if (ct) { + if (ct->flags & JIM_MODFLAG_FULLARGV) { + ret = ct->function(interp, argc, argv); + } + else { + ret = ct->function(interp, argc - 2, argv + 2); + } + if (ret < 0) { + Jim_SubCmdArgError(interp, ct, argv[0]); + ret = JIM_ERR; + } + } + return ret; +} + +int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + const jim_subcmd_type *ct = + Jim_ParseSubCmd(interp, (const jim_subcmd_type *)Jim_CmdPrivData(interp), argc, argv); + + return Jim_CallSubCmd(interp, ct, argc, argv); +} + +#include +#include +#include +#include +#include + + +int utf8_fromunicode(char *p, unsigned uc) +{ + if (uc <= 0x7f) { + *p = uc; + return 1; + } + else if (uc <= 0x7ff) { + *p++ = 0xc0 | ((uc & 0x7c0) >> 6); + *p = 0x80 | (uc & 0x3f); + return 2; + } + else if (uc <= 0xffff) { + *p++ = 0xe0 | ((uc & 0xf000) >> 12); + *p++ = 0x80 | ((uc & 0xfc0) >> 6); + *p = 0x80 | (uc & 0x3f); + return 3; + } + + else { + *p++ = 0xf0 | ((uc & 0x1c0000) >> 18); + *p++ = 0x80 | ((uc & 0x3f000) >> 12); + *p++ = 0x80 | ((uc & 0xfc0) >> 6); + *p = 0x80 | (uc & 0x3f); + return 4; + } +} + +#include +#include +#include + + +#define JIM_INTEGER_SPACE 24 +#define MAX_FLOAT_WIDTH 320 + +Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_Obj *const *objv) +{ + const char *span, *format, *formatEnd, *msg; + int numBytes = 0, objIndex = 0, gotXpg = 0, gotSequential = 0; + static const char * const mixedXPG = + "cannot mix \"%\" and \"%n$\" conversion specifiers"; + static const char * const badIndex[2] = { + "not enough arguments for all format specifiers", + "\"%n$\" argument index out of range" + }; + int formatLen; + Jim_Obj *resultPtr; + + char *num_buffer = NULL; + int num_buffer_size = 0; + + span = format = Jim_GetString(fmtObjPtr, &formatLen); + formatEnd = format + formatLen; + resultPtr = Jim_NewEmptyStringObj(interp); + + while (format != formatEnd) { + char *end; + int gotMinus, sawFlag; + int gotPrecision, useShort; + long width, precision; + int newXpg; + int ch; + int step; + int doubleType; + char pad = ' '; + char spec[2*JIM_INTEGER_SPACE + 12]; + char *p; + + int formatted_chars; + int formatted_bytes; + const char *formatted_buf; + + step = utf8_tounicode(format, &ch); + format += step; + if (ch != '%') { + numBytes += step; + continue; + } + if (numBytes) { + Jim_AppendString(interp, resultPtr, span, numBytes); + numBytes = 0; + } + + + step = utf8_tounicode(format, &ch); + if (ch == '%') { + span = format; + numBytes = step; + format += step; + continue; + } + + + newXpg = 0; + if (isdigit(ch)) { + int position = strtoul(format, &end, 10); + if (*end == '$') { + newXpg = 1; + objIndex = position - 1; + format = end + 1; + step = utf8_tounicode(format, &ch); + } + } + if (newXpg) { + if (gotSequential) { + msg = mixedXPG; + goto errorMsg; + } + gotXpg = 1; + } else { + if (gotXpg) { + msg = mixedXPG; + goto errorMsg; + } + gotSequential = 1; + } + if ((objIndex < 0) || (objIndex >= objc)) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + + p = spec; + *p++ = '%'; + + gotMinus = 0; + sawFlag = 1; + do { + switch (ch) { + case '-': + gotMinus = 1; + break; + case '0': + pad = ch; + break; + case ' ': + case '+': + case '#': + break; + default: + sawFlag = 0; + continue; + } + *p++ = ch; + format += step; + step = utf8_tounicode(format, &ch); + + } while (sawFlag && (p - spec <= 5)); + + + width = 0; + if (isdigit(ch)) { + width = strtoul(format, &end, 10); + format = end; + step = utf8_tounicode(format, &ch); + } else if (ch == '*') { + if (objIndex >= objc - 1) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + if (Jim_GetLong(interp, objv[objIndex], &width) != JIM_OK) { + goto error; + } + if (width < 0) { + width = -width; + if (!gotMinus) { + *p++ = '-'; + gotMinus = 1; + } + } + objIndex++; + format += step; + step = utf8_tounicode(format, &ch); + } + + + gotPrecision = precision = 0; + if (ch == '.') { + gotPrecision = 1; + format += step; + step = utf8_tounicode(format, &ch); + } + if (isdigit(ch)) { + precision = strtoul(format, &end, 10); + format = end; + step = utf8_tounicode(format, &ch); + } else if (ch == '*') { + if (objIndex >= objc - 1) { + msg = badIndex[gotXpg]; + goto errorMsg; + } + if (Jim_GetLong(interp, objv[objIndex], &precision) != JIM_OK) { + goto error; + } + + + if (precision < 0) { + precision = 0; + } + objIndex++; + format += step; + step = utf8_tounicode(format, &ch); + } + + + useShort = 0; + if (ch == 'h') { + useShort = 1; + format += step; + step = utf8_tounicode(format, &ch); + } else if (ch == 'l') { + + format += step; + step = utf8_tounicode(format, &ch); + if (ch == 'l') { + format += step; + step = utf8_tounicode(format, &ch); + } + } + + format += step; + span = format; + + + if (ch == 'i') { + ch = 'd'; + } + + doubleType = 0; + + switch (ch) { + case '\0': + msg = "format string ended in middle of field specifier"; + goto errorMsg; + case 's': { + formatted_buf = Jim_GetString(objv[objIndex], &formatted_bytes); + formatted_chars = Jim_Utf8Length(interp, objv[objIndex]); + if (gotPrecision && (precision < formatted_chars)) { + + formatted_chars = precision; + formatted_bytes = utf8_index(formatted_buf, precision); + } + break; + } + case 'c': { + jim_wide code; + + if (Jim_GetWide(interp, objv[objIndex], &code) != JIM_OK) { + goto error; + } + + formatted_bytes = utf8_getchars(spec, code); + formatted_buf = spec; + formatted_chars = 1; + break; + } + case 'b': { + unsigned jim_wide w; + int length; + int i; + int j; + + if (Jim_GetWide(interp, objv[objIndex], (jim_wide *)&w) != JIM_OK) { + goto error; + } + length = sizeof(w) * 8; + + + + if (num_buffer_size < length + 1) { + num_buffer_size = length + 1; + num_buffer = Jim_Realloc(num_buffer, num_buffer_size); + } + + j = 0; + for (i = length; i > 0; ) { + i--; + if (w & ((unsigned jim_wide)1 << i)) { + num_buffer[j++] = '1'; + } + else if (j || i == 0) { + num_buffer[j++] = '0'; + } + } + num_buffer[j] = 0; + formatted_chars = formatted_bytes = j; + formatted_buf = num_buffer; + break; + } + + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + doubleType = 1; + + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': { + jim_wide w; + double d; + int length; + + + if (width) { + p += sprintf(p, "%ld", width); + } + if (gotPrecision) { + p += sprintf(p, ".%ld", precision); + } + + + if (doubleType) { + if (Jim_GetDouble(interp, objv[objIndex], &d) != JIM_OK) { + goto error; + } + length = MAX_FLOAT_WIDTH; + } + else { + if (Jim_GetWide(interp, objv[objIndex], &w) != JIM_OK) { + goto error; + } + length = JIM_INTEGER_SPACE; + if (useShort) { + if (ch == 'd') { + w = (short)w; + } + else { + w = (unsigned short)w; + } + } + *p++ = 'l'; +#ifdef HAVE_LONG_LONG + if (sizeof(long long) == sizeof(jim_wide)) { + *p++ = 'l'; + } +#endif + } + + *p++ = (char) ch; + *p = '\0'; + + + if (width > 10000 || length > 10000 || precision > 10000) { + Jim_SetResultString(interp, "format too long", -1); + goto error; + } + + + + if (width > length) { + length = width; + } + if (gotPrecision) { + length += precision; + } + + + if (num_buffer_size < length + 1) { + num_buffer_size = length + 1; + num_buffer = Jim_Realloc(num_buffer, num_buffer_size); + } + + if (doubleType) { + snprintf(num_buffer, length + 1, spec, d); + } + else { + formatted_bytes = snprintf(num_buffer, length + 1, spec, w); + } + formatted_chars = formatted_bytes = strlen(num_buffer); + formatted_buf = num_buffer; + break; + } + + default: { + + spec[0] = ch; + spec[1] = '\0'; + Jim_SetResultFormatted(interp, "bad field specifier \"%s\"", spec); + goto error; + } + } + + if (!gotMinus) { + while (formatted_chars < width) { + Jim_AppendString(interp, resultPtr, &pad, 1); + formatted_chars++; + } + } + + Jim_AppendString(interp, resultPtr, formatted_buf, formatted_bytes); + + while (formatted_chars < width) { + Jim_AppendString(interp, resultPtr, &pad, 1); + formatted_chars++; + } + + objIndex += gotSequential; + } + if (numBytes) { + Jim_AppendString(interp, resultPtr, span, numBytes); + } + + Jim_Free(num_buffer); + return resultPtr; + + errorMsg: + Jim_SetResultString(interp, msg, -1); + error: + Jim_FreeNewObj(interp, resultPtr); + Jim_Free(num_buffer); + return NULL; +} + + +#if defined(JIM_REGEXP) +#include +#include +#include +#include + + + +#define REG_MAX_PAREN 100 + + + +#define END 0 +#define BOL 1 +#define EOL 2 +#define ANY 3 +#define ANYOF 4 +#define ANYBUT 5 +#define BRANCH 6 +#define BACK 7 +#define EXACTLY 8 +#define NOTHING 9 +#define REP 10 +#define REPMIN 11 +#define REPX 12 +#define REPXMIN 13 +#define BOLX 14 +#define EOLX 15 +#define WORDA 16 +#define WORDZ 17 + +#define OPENNC 1000 +#define OPEN 1001 + + + + +#define CLOSENC 2000 +#define CLOSE 2001 +#define CLOSE_END (CLOSE+REG_MAX_PAREN) + +#define REG_MAGIC 0xFADED00D + + +#define OP(preg, p) (preg->program[p]) +#define NEXT(preg, p) (preg->program[p + 1]) +#define OPERAND(p) ((p) + 2) + + + + +#define FAIL(R,M) { (R)->err = (M); return (M); } +#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?' || (c) == '{') +#define META "^$.[()|?{+*" + +#define HASWIDTH 1 +#define SIMPLE 2 +#define SPSTART 4 +#define WORST 0 + +#define MAX_REP_COUNT 1000000 + +static int reg(regex_t *preg, int paren, int *flagp ); +static int regpiece(regex_t *preg, int *flagp ); +static int regbranch(regex_t *preg, int *flagp ); +static int regatom(regex_t *preg, int *flagp ); +static int regnode(regex_t *preg, int op ); +static int regnext(regex_t *preg, int p ); +static void regc(regex_t *preg, int b ); +static int reginsert(regex_t *preg, int op, int size, int opnd ); +static void regtail(regex_t *preg, int p, int val); +static void regoptail(regex_t *preg, int p, int val ); +static int regopsize(regex_t *preg, int p ); + +static int reg_range_find(const int *string, int c); +static const char *str_find(const char *string, int c, int nocase); +static int prefix_cmp(const int *prog, int proglen, const char *string, int nocase); + + +#ifdef DEBUG +static int regnarrate = 0; +static void regdump(regex_t *preg); +static const char *regprop( int op ); +#endif + + +static int str_int_len(const int *seq) +{ + int n = 0; + while (*seq++) { + n++; + } + return n; +} + +int jim_regcomp(regex_t *preg, const char *exp, int cflags) +{ + int scan; + int longest; + unsigned len; + int flags; + +#ifdef DEBUG + fprintf(stderr, "Compiling: '%s'\n", exp); +#endif + memset(preg, 0, sizeof(*preg)); + + if (exp == NULL) + FAIL(preg, REG_ERR_NULL_ARGUMENT); + + + preg->cflags = cflags; + preg->regparse = exp; + + + preg->proglen = (strlen(exp) + 1) * 5; + preg->program = malloc(preg->proglen * sizeof(int)); + if (preg->program == NULL) + FAIL(preg, REG_ERR_NOMEM); + + regc(preg, REG_MAGIC); + if (reg(preg, 0, &flags) == 0) { + return preg->err; + } + + + if (preg->re_nsub >= REG_MAX_PAREN) + FAIL(preg,REG_ERR_TOO_BIG); + + + preg->regstart = 0; + preg->reganch = 0; + preg->regmust = 0; + preg->regmlen = 0; + scan = 1; + if (OP(preg, regnext(preg, scan)) == END) { + scan = OPERAND(scan); + + + if (OP(preg, scan) == EXACTLY) { + preg->regstart = preg->program[OPERAND(scan)]; + } + else if (OP(preg, scan) == BOL) + preg->reganch++; + + if (flags&SPSTART) { + longest = 0; + len = 0; + for (; scan != 0; scan = regnext(preg, scan)) { + if (OP(preg, scan) == EXACTLY) { + int plen = str_int_len(preg->program + OPERAND(scan)); + if (plen >= len) { + longest = OPERAND(scan); + len = plen; + } + } + } + preg->regmust = longest; + preg->regmlen = len; + } + } + +#ifdef DEBUG + regdump(preg); +#endif + + return 0; +} + +static int reg(regex_t *preg, int paren, int *flagp ) +{ + int ret; + int br; + int ender; + int parno = 0; + int flags; + + *flagp = HASWIDTH; + + + if (paren) { + if (preg->regparse[0] == '?' && preg->regparse[1] == ':') { + + preg->regparse += 2; + parno = -1; + } + else { + parno = ++preg->re_nsub; + } + ret = regnode(preg, OPEN+parno); + } else + ret = 0; + + + br = regbranch(preg, &flags); + if (br == 0) + return 0; + if (ret != 0) + regtail(preg, ret, br); + else + ret = br; + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + while (*preg->regparse == '|') { + preg->regparse++; + br = regbranch(preg, &flags); + if (br == 0) + return 0; + regtail(preg, ret, br); + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + } + + + ender = regnode(preg, (paren) ? CLOSE+parno : END); + regtail(preg, ret, ender); + + + for (br = ret; br != 0; br = regnext(preg, br)) + regoptail(preg, br, ender); + + + if (paren && *preg->regparse++ != ')') { + preg->err = REG_ERR_UNMATCHED_PAREN; + return 0; + } else if (!paren && *preg->regparse != '\0') { + if (*preg->regparse == ')') { + preg->err = REG_ERR_UNMATCHED_PAREN; + return 0; + } else { + preg->err = REG_ERR_JUNK_ON_END; + return 0; + } + } + + return(ret); +} + +static int regbranch(regex_t *preg, int *flagp ) +{ + int ret; + int chain; + int latest; + int flags; + + *flagp = WORST; + + ret = regnode(preg, BRANCH); + chain = 0; + while (*preg->regparse != '\0' && *preg->regparse != ')' && + *preg->regparse != '|') { + latest = regpiece(preg, &flags); + if (latest == 0) + return 0; + *flagp |= flags&HASWIDTH; + if (chain == 0) { + *flagp |= flags&SPSTART; + } + else { + regtail(preg, chain, latest); + } + chain = latest; + } + if (chain == 0) + (void) regnode(preg, NOTHING); + + return(ret); +} + +static int regpiece(regex_t *preg, int *flagp) +{ + int ret; + char op; + int next; + int flags; + int min; + int max; + + ret = regatom(preg, &flags); + if (ret == 0) + return 0; + + op = *preg->regparse; + if (!ISMULT(op)) { + *flagp = flags; + return(ret); + } + + if (!(flags&HASWIDTH) && op != '?') { + preg->err = REG_ERR_OPERAND_COULD_BE_EMPTY; + return 0; + } + + + if (op == '{') { + char *end; + + min = strtoul(preg->regparse + 1, &end, 10); + if (end == preg->regparse + 1) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + if (*end == '}') { + max = min; + } + else if (*end == '\0') { + preg->err = REG_ERR_UNMATCHED_BRACES; + return 0; + } + else { + preg->regparse = end; + max = strtoul(preg->regparse + 1, &end, 10); + if (*end != '}') { + preg->err = REG_ERR_UNMATCHED_BRACES; + return 0; + } + } + if (end == preg->regparse + 1) { + max = MAX_REP_COUNT; + } + else if (max < min || max >= 100) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + if (min >= 100) { + preg->err = REG_ERR_BAD_COUNT; + return 0; + } + + preg->regparse = strchr(preg->regparse, '}'); + } + else { + min = (op == '+'); + max = (op == '?' ? 1 : MAX_REP_COUNT); + } + + if (preg->regparse[1] == '?') { + preg->regparse++; + next = reginsert(preg, flags & SIMPLE ? REPMIN : REPXMIN, 5, ret); + } + else { + next = reginsert(preg, flags & SIMPLE ? REP: REPX, 5, ret); + } + preg->program[ret + 2] = max; + preg->program[ret + 3] = min; + preg->program[ret + 4] = 0; + + *flagp = (min) ? (WORST|HASWIDTH) : (WORST|SPSTART); + + if (!(flags & SIMPLE)) { + int back = regnode(preg, BACK); + regtail(preg, back, ret); + regtail(preg, next, back); + } + + preg->regparse++; + if (ISMULT(*preg->regparse)) { + preg->err = REG_ERR_NESTED_COUNT; + return 0; + } + + return ret; +} + +static void reg_addrange(regex_t *preg, int lower, int upper) +{ + if (lower > upper) { + reg_addrange(preg, upper, lower); + } + + regc(preg, upper - lower + 1); + regc(preg, lower); +} + +static void reg_addrange_str(regex_t *preg, const char *str) +{ + while (*str) { + reg_addrange(preg, *str, *str); + str++; + } +} + +static int reg_utf8_tounicode_case(const char *s, int *uc, int upper) +{ + int l = utf8_tounicode(s, uc); + if (upper) { + *uc = utf8_upper(*uc); + } + return l; +} + +static int hexdigitval(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int parse_hex(const char *s, int n, int *uc) +{ + int val = 0; + int k; + + for (k = 0; k < n; k++) { + int c = hexdigitval(*s++); + if (c == -1) { + break; + } + val = (val << 4) | c; + } + if (k) { + *uc = val; + } + return k; +} + +static int reg_decode_escape(const char *s, int *ch) +{ + int n; + const char *s0 = s; + + *ch = *s++; + + switch (*ch) { + case 'b': *ch = '\b'; break; + case 'e': *ch = 27; break; + case 'f': *ch = '\f'; break; + case 'n': *ch = '\n'; break; + case 'r': *ch = '\r'; break; + case 't': *ch = '\t'; break; + case 'v': *ch = '\v'; break; + case 'u': + if (*s == '{') { + + n = parse_hex(s + 1, 6, ch); + if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) { + s += n + 2; + } + else { + + *ch = 'u'; + } + } + else if ((n = parse_hex(s, 4, ch)) > 0) { + s += n; + } + break; + case 'U': + if ((n = parse_hex(s, 8, ch)) > 0) { + s += n; + } + break; + case 'x': + if ((n = parse_hex(s, 2, ch)) > 0) { + s += n; + } + break; + case '\0': + s--; + *ch = '\\'; + break; + } + return s - s0; +} + +static int regatom(regex_t *preg, int *flagp) +{ + int ret; + int flags; + int nocase = (preg->cflags & REG_ICASE); + + int ch; + int n = reg_utf8_tounicode_case(preg->regparse, &ch, nocase); + + *flagp = WORST; + + preg->regparse += n; + switch (ch) { + + case '^': + ret = regnode(preg, BOL); + break; + case '$': + ret = regnode(preg, EOL); + break; + case '.': + ret = regnode(preg, ANY); + *flagp |= HASWIDTH|SIMPLE; + break; + case '[': { + const char *pattern = preg->regparse; + + if (*pattern == '^') { + ret = regnode(preg, ANYBUT); + pattern++; + } else + ret = regnode(preg, ANYOF); + + + if (*pattern == ']' || *pattern == '-') { + reg_addrange(preg, *pattern, *pattern); + pattern++; + } + + while (*pattern != ']') { + + int start; + int end; + + enum { + CC_ALPHA, CC_ALNUM, CC_SPACE, CC_BLANK, CC_UPPER, CC_LOWER, + CC_DIGIT, CC_XDIGIT, CC_CNTRL, CC_GRAPH, CC_PRINT, CC_PUNCT, + CC_NUM + }; + int cc; + + if (!*pattern) { + preg->err = REG_ERR_UNMATCHED_BRACKET; + return 0; + } + + pattern += reg_utf8_tounicode_case(pattern, &start, nocase); + if (start == '\\') { + + switch (*pattern) { + case 's': + pattern++; + cc = CC_SPACE; + goto cc_switch; + case 'd': + pattern++; + cc = CC_DIGIT; + goto cc_switch; + case 'w': + pattern++; + reg_addrange(preg, '_', '_'); + cc = CC_ALNUM; + goto cc_switch; + } + pattern += reg_decode_escape(pattern, &start); + if (start == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + if (start == '\\' && *pattern == 0) { + preg->err = REG_ERR_INVALID_ESCAPE; + return 0; + } + } + if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') { + + pattern += utf8_tounicode(pattern, &end); + pattern += reg_utf8_tounicode_case(pattern, &end, nocase); + if (end == '\\') { + pattern += reg_decode_escape(pattern, &end); + if (end == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + if (end == '\\' && *pattern == 0) { + preg->err = REG_ERR_INVALID_ESCAPE; + return 0; + } + } + + reg_addrange(preg, start, end); + continue; + } + if (start == '[' && pattern[0] == ':') { + static const char *character_class[] = { + ":alpha:", ":alnum:", ":space:", ":blank:", ":upper:", ":lower:", + ":digit:", ":xdigit:", ":cntrl:", ":graph:", ":print:", ":punct:", + }; + + for (cc = 0; cc < CC_NUM; cc++) { + n = strlen(character_class[cc]); + if (strncmp(pattern, character_class[cc], n) == 0) { + if (pattern[n] != ']') { + preg->err = REG_ERR_UNMATCHED_BRACKET; + return 0; + } + + pattern += n + 1; + break; + } + } + if (cc != CC_NUM) { +cc_switch: + switch (cc) { + case CC_ALNUM: + reg_addrange(preg, '0', '9'); + + case CC_ALPHA: + if ((preg->cflags & REG_ICASE) == 0) { + reg_addrange(preg, 'a', 'z'); + } + reg_addrange(preg, 'A', 'Z'); + break; + case CC_SPACE: + reg_addrange_str(preg, " \t\r\n\f\v"); + break; + case CC_BLANK: + reg_addrange_str(preg, " \t"); + break; + case CC_UPPER: + reg_addrange(preg, 'A', 'Z'); + break; + case CC_LOWER: + reg_addrange(preg, 'a', 'z'); + break; + case CC_XDIGIT: + reg_addrange(preg, 'a', 'f'); + reg_addrange(preg, 'A', 'F'); + + case CC_DIGIT: + reg_addrange(preg, '0', '9'); + break; + case CC_CNTRL: + reg_addrange(preg, 0, 31); + reg_addrange(preg, 127, 127); + break; + case CC_PRINT: + reg_addrange(preg, ' ', '~'); + break; + case CC_GRAPH: + reg_addrange(preg, '!', '~'); + break; + case CC_PUNCT: + reg_addrange(preg, '!', '/'); + reg_addrange(preg, ':', '@'); + reg_addrange(preg, '[', '`'); + reg_addrange(preg, '{', '~'); + break; + } + continue; + } + } + + reg_addrange(preg, start, start); + } + regc(preg, '\0'); + + if (*pattern) { + pattern++; + } + preg->regparse = pattern; + + *flagp |= HASWIDTH|SIMPLE; + } + break; + case '(': + ret = reg(preg, 1, &flags); + if (ret == 0) + return 0; + *flagp |= flags&(HASWIDTH|SPSTART); + break; + case '\0': + case '|': + case ')': + preg->err = REG_ERR_INTERNAL; + return 0; + case '?': + case '+': + case '*': + case '{': + preg->err = REG_ERR_COUNT_FOLLOWS_NOTHING; + return 0; + case '\\': + ch = *preg->regparse++; + switch (ch) { + case '\0': + preg->err = REG_ERR_INVALID_ESCAPE; + return 0; + case 'A': + ret = regnode(preg, BOLX); + break; + case 'Z': + ret = regnode(preg, EOLX); + break; + case '<': + case 'm': + ret = regnode(preg, WORDA); + break; + case '>': + case 'M': + ret = regnode(preg, WORDZ); + break; + case 'd': + case 'D': + ret = regnode(preg, ch == 'd' ? ANYOF : ANYBUT); + reg_addrange(preg, '0', '9'); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + case 'w': + case 'W': + ret = regnode(preg, ch == 'w' ? ANYOF : ANYBUT); + if ((preg->cflags & REG_ICASE) == 0) { + reg_addrange(preg, 'a', 'z'); + } + reg_addrange(preg, 'A', 'Z'); + reg_addrange(preg, '0', '9'); + reg_addrange(preg, '_', '_'); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + case 's': + case 'S': + ret = regnode(preg, ch == 's' ? ANYOF : ANYBUT); + reg_addrange_str(preg," \t\r\n\f\v"); + regc(preg, '\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + + default: + + + preg->regparse--; + goto de_fault; + } + break; + de_fault: + default: { + int added = 0; + + + preg->regparse -= n; + + ret = regnode(preg, EXACTLY); + + + + while (*preg->regparse && strchr(META, *preg->regparse) == NULL) { + n = reg_utf8_tounicode_case(preg->regparse, &ch, (preg->cflags & REG_ICASE)); + if (ch == '\\' && preg->regparse[n]) { + if (strchr("<>mMwWdDsSAZ", preg->regparse[n])) { + + break; + } + n += reg_decode_escape(preg->regparse + n, &ch); + if (ch == 0) { + preg->err = REG_ERR_NULL_CHAR; + return 0; + } + } + + + if (ISMULT(preg->regparse[n])) { + + if (added) { + + break; + } + + regc(preg, ch); + added++; + preg->regparse += n; + break; + } + + + regc(preg, ch); + added++; + preg->regparse += n; + } + regc(preg, '\0'); + + *flagp |= HASWIDTH; + if (added == 1) + *flagp |= SIMPLE; + break; + } + break; + } + + return(ret); +} + +static void reg_grow(regex_t *preg, int n) +{ + if (preg->p + n >= preg->proglen) { + preg->proglen = (preg->p + n) * 2; + preg->program = realloc(preg->program, preg->proglen * sizeof(int)); + } +} + + +static int regnode(regex_t *preg, int op) +{ + reg_grow(preg, 2); + + + preg->program[preg->p++] = op; + preg->program[preg->p++] = 0; + + + return preg->p - 2; +} + +static void regc(regex_t *preg, int b ) +{ + reg_grow(preg, 1); + preg->program[preg->p++] = b; +} + +static int reginsert(regex_t *preg, int op, int size, int opnd ) +{ + reg_grow(preg, size); + + + memmove(preg->program + opnd + size, preg->program + opnd, sizeof(int) * (preg->p - opnd)); + + memset(preg->program + opnd, 0, sizeof(int) * size); + + preg->program[opnd] = op; + + preg->p += size; + + return opnd + size; +} + +static void regtail(regex_t *preg, int p, int val) +{ + int scan; + int temp; + int offset; + + + scan = p; + for (;;) { + temp = regnext(preg, scan); + if (temp == 0) + break; + scan = temp; + } + + if (OP(preg, scan) == BACK) + offset = scan - val; + else + offset = val - scan; + + preg->program[scan + 1] = offset; +} + + +static void regoptail(regex_t *preg, int p, int val ) +{ + + if (p != 0 && OP(preg, p) == BRANCH) { + regtail(preg, OPERAND(p), val); + } +} + + +static int regtry(regex_t *preg, const char *string ); +static int regmatch(regex_t *preg, int prog); +static int regrepeat(regex_t *preg, int p, int max); + +int jim_regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) +{ + const char *s; + int scan; + + + if (preg == NULL || preg->program == NULL || string == NULL) { + return REG_ERR_NULL_ARGUMENT; + } + + + if (*preg->program != REG_MAGIC) { + return REG_ERR_CORRUPTED; + } + +#ifdef DEBUG + fprintf(stderr, "regexec: %s\n", string); + regdump(preg); +#endif + + preg->eflags = eflags; + preg->pmatch = pmatch; + preg->nmatch = nmatch; + preg->start = string; + + + for (scan = OPERAND(1); scan != 0; scan += regopsize(preg, scan)) { + int op = OP(preg, scan); + if (op == END) + break; + if (op == REPX || op == REPXMIN) + preg->program[scan + 4] = 0; + } + + + if (preg->regmust != 0) { + s = string; + while ((s = str_find(s, preg->program[preg->regmust], preg->cflags & REG_ICASE)) != NULL) { + if (prefix_cmp(preg->program + preg->regmust, preg->regmlen, s, preg->cflags & REG_ICASE) >= 0) { + break; + } + s++; + } + if (s == NULL) + return REG_NOMATCH; + } + + + preg->regbol = string; + + + if (preg->reganch) { + if (eflags & REG_NOTBOL) { + + goto nextline; + } + while (1) { + if (regtry(preg, string)) { + return REG_NOERROR; + } + if (*string) { +nextline: + if (preg->cflags & REG_NEWLINE) { + + string = strchr(string, '\n'); + if (string) { + preg->regbol = ++string; + continue; + } + } + } + return REG_NOMATCH; + } + } + + + s = string; + if (preg->regstart != '\0') { + + while ((s = str_find(s, preg->regstart, preg->cflags & REG_ICASE)) != NULL) { + if (regtry(preg, s)) + return REG_NOERROR; + s++; + } + } + else + + while (1) { + if (regtry(preg, s)) + return REG_NOERROR; + if (*s == '\0') { + break; + } + else { + int c; + s += utf8_tounicode(s, &c); + } + } + + + return REG_NOMATCH; +} + + +static int regtry( regex_t *preg, const char *string ) +{ + int i; + + preg->reginput = string; + + for (i = 0; i < preg->nmatch; i++) { + preg->pmatch[i].rm_so = -1; + preg->pmatch[i].rm_eo = -1; + } + if (regmatch(preg, 1)) { + preg->pmatch[0].rm_so = string - preg->start; + preg->pmatch[0].rm_eo = preg->reginput - preg->start; + return(1); + } else + return(0); +} + +static int prefix_cmp(const int *prog, int proglen, const char *string, int nocase) +{ + const char *s = string; + while (proglen && *s) { + int ch; + int n = reg_utf8_tounicode_case(s, &ch, nocase); + if (ch != *prog) { + return -1; + } + prog++; + s += n; + proglen--; + } + if (proglen == 0) { + return s - string; + } + return -1; +} + +static int reg_range_find(const int *range, int c) +{ + while (*range) { + + if (c >= range[1] && c <= (range[0] + range[1] - 1)) { + return 1; + } + range += 2; + } + return 0; +} + +static const char *str_find(const char *string, int c, int nocase) +{ + if (nocase) { + + c = utf8_upper(c); + } + while (*string) { + int ch; + int n = reg_utf8_tounicode_case(string, &ch, nocase); + if (c == ch) { + return string; + } + string += n; + } + return NULL; +} + +static int reg_iseol(regex_t *preg, int ch) +{ + if (preg->cflags & REG_NEWLINE) { + return ch == '\0' || ch == '\n'; + } + else { + return ch == '\0'; + } +} + +static int regmatchsimplerepeat(regex_t *preg, int scan, int matchmin) +{ + int nextch = '\0'; + const char *save; + int no; + int c; + + int max = preg->program[scan + 2]; + int min = preg->program[scan + 3]; + int next = regnext(preg, scan); + + if (OP(preg, next) == EXACTLY) { + nextch = preg->program[OPERAND(next)]; + } + save = preg->reginput; + no = regrepeat(preg, scan + 5, max); + if (no < min) { + return 0; + } + if (matchmin) { + + max = no; + no = min; + } + + while (1) { + if (matchmin) { + if (no > max) { + break; + } + } + else { + if (no < min) { + break; + } + } + preg->reginput = save + utf8_index(save, no); + reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); + + if (reg_iseol(preg, nextch) || c == nextch) { + if (regmatch(preg, next)) { + return(1); + } + } + if (matchmin) { + + no++; + } + else { + + no--; + } + } + return(0); +} + +static int regmatchrepeat(regex_t *preg, int scan, int matchmin) +{ + int *scanpt = preg->program + scan; + + int max = scanpt[2]; + int min = scanpt[3]; + + + if (scanpt[4] < min) { + + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + return 0; + } + if (scanpt[4] > max) { + return 0; + } + + if (matchmin) { + + if (regmatch(preg, regnext(preg, scan))) { + return 1; + } + + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + return 0; + } + + if (scanpt[4] < max) { + scanpt[4]++; + if (regmatch(preg, scan + 5)) { + return 1; + } + scanpt[4]--; + } + + return regmatch(preg, regnext(preg, scan)); +} + + +static int regmatch(regex_t *preg, int prog) +{ + int scan; + int next; + const char *save; + + scan = prog; + +#ifdef DEBUG + if (scan != 0 && regnarrate) + fprintf(stderr, "%s(\n", regprop(scan)); +#endif + while (scan != 0) { + int n; + int c; +#ifdef DEBUG + if (regnarrate) { + fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan))); + } +#endif + next = regnext(preg, scan); + n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); + + switch (OP(preg, scan)) { + case BOLX: + if ((preg->eflags & REG_NOTBOL)) { + return(0); + } + + case BOL: + if (preg->reginput != preg->regbol) { + return(0); + } + break; + case EOLX: + if (c != 0) { + + return 0; + } + break; + case EOL: + if (!reg_iseol(preg, c)) { + return(0); + } + break; + case WORDA: + + if ((!isalnum(UCHAR(c))) && c != '_') + return(0); + + if (preg->reginput > preg->regbol && + (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_')) + return(0); + break; + case WORDZ: + + if (preg->reginput > preg->regbol) { + + if (reg_iseol(preg, c) || !(isalnum(UCHAR(c)) || c == '_')) { + c = preg->reginput[-1]; + + if (isalnum(UCHAR(c)) || c == '_') { + break; + } + } + } + + return(0); + + case ANY: + if (reg_iseol(preg, c)) + return 0; + preg->reginput += n; + break; + case EXACTLY: { + int opnd; + int len; + int slen; + + opnd = OPERAND(scan); + len = str_int_len(preg->program + opnd); + + slen = prefix_cmp(preg->program + opnd, len, preg->reginput, preg->cflags & REG_ICASE); + if (slen < 0) { + return(0); + } + preg->reginput += slen; + } + break; + case ANYOF: + if (reg_iseol(preg, c) || reg_range_find(preg->program + OPERAND(scan), c) == 0) { + return(0); + } + preg->reginput += n; + break; + case ANYBUT: + if (reg_iseol(preg, c) || reg_range_find(preg->program + OPERAND(scan), c) != 0) { + return(0); + } + preg->reginput += n; + break; + case NOTHING: + break; + case BACK: + break; + case BRANCH: + if (OP(preg, next) != BRANCH) + next = OPERAND(scan); + else { + do { + save = preg->reginput; + if (regmatch(preg, OPERAND(scan))) { + return(1); + } + preg->reginput = save; + scan = regnext(preg, scan); + } while (scan != 0 && OP(preg, scan) == BRANCH); + return(0); + + } + break; + case REP: + case REPMIN: + return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN); + + case REPX: + case REPXMIN: + return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN); + + case END: + return 1; + + case OPENNC: + case CLOSENC: + return regmatch(preg, next); + + default: + if (OP(preg, scan) >= OPEN+1 && OP(preg, scan) < CLOSE_END) { + save = preg->reginput; + if (regmatch(preg, next)) { + if (OP(preg, scan) < CLOSE) { + int no = OP(preg, scan) - OPEN; + if (no < preg->nmatch && preg->pmatch[no].rm_so == -1) { + preg->pmatch[no].rm_so = save - preg->start; + } + } + else { + int no = OP(preg, scan) - CLOSE; + if (no < preg->nmatch && preg->pmatch[no].rm_eo == -1) { + preg->pmatch[no].rm_eo = save - preg->start; + } + } + return(1); + } + + preg->reginput = save; + return(0); + } + return REG_ERR_INTERNAL; + } + + scan = next; + } + + return REG_ERR_INTERNAL; +} + +static int regrepeat(regex_t *preg, int p, int max) +{ + int count = 0; + const char *scan; + int opnd; + int ch; + int n; + + scan = preg->reginput; + opnd = OPERAND(p); + switch (OP(preg, p)) { + case ANY: + while (!reg_iseol(preg, *scan) && count < max) { + count++; + scan += utf8_charlen(*scan); + } + break; + case EXACTLY: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (preg->program[opnd] != ch) { + break; + } + count++; + scan += n; + } + break; + case ANYOF: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (reg_iseol(preg, ch) || reg_range_find(preg->program + opnd, ch) == 0) { + break; + } + count++; + scan += n; + } + break; + case ANYBUT: + while (count < max) { + n = reg_utf8_tounicode_case(scan, &ch, preg->cflags & REG_ICASE); + if (reg_iseol(preg, ch) || reg_range_find(preg->program + opnd, ch) != 0) { + break; + } + count++; + scan += n; + } + break; + default: + preg->err = REG_ERR_INTERNAL; + count = 0; + break; + } + preg->reginput = scan; + + return(count); +} + +static int regnext(regex_t *preg, int p ) +{ + int offset; + + offset = NEXT(preg, p); + + if (offset == 0) + return 0; + + if (OP(preg, p) == BACK) + return(p-offset); + else + return(p+offset); +} + +static int regopsize(regex_t *preg, int p ) +{ + + switch (OP(preg, p)) { + case REP: + case REPMIN: + case REPX: + case REPXMIN: + return 5; + + case ANYOF: + case ANYBUT: + case EXACTLY: { + int s = p + 2; + while (preg->program[s++]) { + } + return s - p; + } + } + return 2; +} + + +size_t jim_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +{ + static const char *error_strings[] = { + "success", + "no match", + "bad pattern", + "null argument", + "unknown error", + "too big", + "out of memory", + "too many ()", + "parentheses () not balanced", + "braces {} not balanced", + "invalid repetition count(s)", + "extra characters", + "*+ of empty atom", + "nested count", + "internal error", + "count follows nothing", + "invalid escape \\ sequence", + "corrupted program", + "contains null char", + "brackets [] not balanced", + }; + const char *err; + + if (errcode < 0 || errcode >= REG_ERR_NUM) { + err = "Bad error code"; + } + else { + err = error_strings[errcode]; + } + + return snprintf(errbuf, errbuf_size, "%s", err); +} + +void jim_regfree(regex_t *preg) +{ + free(preg->program); +} + +#endif +#include + +void Jim_SetResultErrno(Jim_Interp *interp, const char *msg) +{ + Jim_SetResultFormatted(interp, "%s: %s", msg, strerror(Jim_Errno())); +} + +#if defined(__MINGW32__) +#include + +int Jim_Errno(void) +{ + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: return ENOENT; + case ERROR_PATH_NOT_FOUND: return ENOENT; + case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; + case ERROR_ACCESS_DENIED: return EACCES; + case ERROR_INVALID_HANDLE: return EBADF; + case ERROR_BAD_ENVIRONMENT: return E2BIG; + case ERROR_BAD_FORMAT: return ENOEXEC; + case ERROR_INVALID_ACCESS: return EACCES; + case ERROR_INVALID_DRIVE: return ENOENT; + case ERROR_CURRENT_DIRECTORY: return EACCES; + case ERROR_NOT_SAME_DEVICE: return EXDEV; + case ERROR_NO_MORE_FILES: return ENOENT; + case ERROR_WRITE_PROTECT: return EROFS; + case ERROR_BAD_UNIT: return ENXIO; + case ERROR_NOT_READY: return EBUSY; + case ERROR_BAD_COMMAND: return EIO; + case ERROR_CRC: return EIO; + case ERROR_BAD_LENGTH: return EIO; + case ERROR_SEEK: return EIO; + case ERROR_WRITE_FAULT: return EIO; + case ERROR_READ_FAULT: return EIO; + case ERROR_GEN_FAILURE: return EIO; + case ERROR_SHARING_VIOLATION: return EACCES; + case ERROR_LOCK_VIOLATION: return EACCES; + case ERROR_SHARING_BUFFER_EXCEEDED: return ENFILE; + case ERROR_HANDLE_DISK_FULL: return ENOSPC; + case ERROR_NOT_SUPPORTED: return ENODEV; + case ERROR_REM_NOT_LIST: return EBUSY; + case ERROR_DUP_NAME: return EEXIST; + case ERROR_BAD_NETPATH: return ENOENT; + case ERROR_NETWORK_BUSY: return EBUSY; + case ERROR_DEV_NOT_EXIST: return ENODEV; + case ERROR_TOO_MANY_CMDS: return EAGAIN; + case ERROR_ADAP_HDW_ERR: return EIO; + case ERROR_BAD_NET_RESP: return EIO; + case ERROR_UNEXP_NET_ERR: return EIO; + case ERROR_NETNAME_DELETED: return ENOENT; + case ERROR_NETWORK_ACCESS_DENIED: return EACCES; + case ERROR_BAD_DEV_TYPE: return ENODEV; + case ERROR_BAD_NET_NAME: return ENOENT; + case ERROR_TOO_MANY_NAMES: return ENFILE; + case ERROR_TOO_MANY_SESS: return EIO; + case ERROR_SHARING_PAUSED: return EAGAIN; + case ERROR_REDIR_PAUSED: return EAGAIN; + case ERROR_FILE_EXISTS: return EEXIST; + case ERROR_CANNOT_MAKE: return ENOSPC; + case ERROR_OUT_OF_STRUCTURES: return ENFILE; + case ERROR_ALREADY_ASSIGNED: return EEXIST; + case ERROR_INVALID_PASSWORD: return EPERM; + case ERROR_NET_WRITE_FAULT: return EIO; + case ERROR_NO_PROC_SLOTS: return EAGAIN; + case ERROR_DISK_CHANGE: return EXDEV; + case ERROR_BROKEN_PIPE: return EPIPE; + case ERROR_OPEN_FAILED: return ENOENT; + case ERROR_DISK_FULL: return ENOSPC; + case ERROR_NO_MORE_SEARCH_HANDLES: return EMFILE; + case ERROR_INVALID_TARGET_HANDLE: return EBADF; + case ERROR_INVALID_NAME: return ENOENT; + case ERROR_PROC_NOT_FOUND: return ESRCH; + case ERROR_WAIT_NO_CHILDREN: return ECHILD; + case ERROR_CHILD_NOT_COMPLETE: return ECHILD; + case ERROR_DIRECT_ACCESS_HANDLE: return EBADF; + case ERROR_SEEK_ON_DEVICE: return ESPIPE; + case ERROR_BUSY_DRIVE: return EAGAIN; + case ERROR_DIR_NOT_EMPTY: return EEXIST; + case ERROR_NOT_LOCKED: return EACCES; + case ERROR_BAD_PATHNAME: return ENOENT; + case ERROR_LOCK_FAILED: return EACCES; + case ERROR_ALREADY_EXISTS: return EEXIST; + case ERROR_FILENAME_EXCED_RANGE: return ENAMETOOLONG; + case ERROR_BAD_PIPE: return EPIPE; + case ERROR_PIPE_BUSY: return EAGAIN; + case ERROR_PIPE_NOT_CONNECTED: return EPIPE; + case ERROR_DIRECTORY: return ENOTDIR; + } + return EINVAL; +} + +long JimProcessPid(phandle_t pid) +{ + if (pid == INVALID_HANDLE_VALUE) { + return -1; + } + return GetProcessId(pid); +} + +phandle_t JimWaitPid(long pid, int *status, int nohang) +{ + if (pid > 0) { + HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, pid); + if (h) { + long pid = waitpid(h, status, nohang); + CloseHandle(h); + if (pid > 0) { + return h; + } + } + } + return JIM_BAD_PHANDLE; +} + +long waitpid(phandle_t phandle, int *status, int nohang) +{ + long pid; + DWORD ret = WaitForSingleObject(phandle, nohang ? 0 : INFINITE); + if (ret == WAIT_TIMEOUT || ret == WAIT_FAILED) { + + return -1; + } + GetExitCodeProcess(phandle, &ret); + *status = ret; + + pid = GetProcessId(phandle); + CloseHandle(phandle); + return pid; +} + +int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file) +{ + char name[MAX_PATH]; + HANDLE handle; + + if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, filename_template ? filename_template : "JIM", 0, name)) { + return -1; + } + + handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | (unlink_file ? FILE_FLAG_DELETE_ON_CLOSE : 0), + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + goto error; + } + + Jim_SetResultString(interp, name, -1); + return _open_osfhandle((intptr_t)handle, _O_RDWR | _O_TEXT); + + error: + Jim_SetResultErrno(interp, name); + DeleteFile(name); + return -1; +} + +int Jim_OpenForWrite(const char *filename, int append) +{ + if (strcmp(filename, "/dev/null") == 0) { + filename = "nul:"; + } + int fd = _open(filename, _O_WRONLY | _O_CREAT | _O_TEXT | (append ? _O_APPEND : _O_TRUNC), _S_IREAD | _S_IWRITE); + if (fd >= 0 && append) { + + _lseek(fd, 0L, SEEK_END); + } + return fd; +} + +int Jim_OpenForRead(const char *filename) +{ + if (strcmp(filename, "/dev/null") == 0) { + filename = "nul:"; + } + return _open(filename, _O_RDONLY | _O_TEXT, 0); +} + +#elif defined(HAVE_UNISTD_H) + + + +int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file) +{ + int fd; + mode_t mask; + Jim_Obj *filenameObj; + + if (filename_template == NULL) { + const char *tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL || *tmpdir == '\0' || access(tmpdir, W_OK) != 0) { + tmpdir = "/tmp/"; + } + filenameObj = Jim_NewStringObj(interp, tmpdir, -1); + if (tmpdir[0] && tmpdir[strlen(tmpdir) - 1] != '/') { + Jim_AppendString(interp, filenameObj, "/", 1); + } + Jim_AppendString(interp, filenameObj, "tcl.tmp.XXXXXX", -1); + } + else { + filenameObj = Jim_NewStringObj(interp, filename_template, -1); + } + + +#ifdef HAVE_UMASK + mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); +#endif +#ifdef HAVE_MKSTEMP + fd = mkstemp(filenameObj->bytes); +#else + if (mktemp(filenameObj->bytes) == NULL) { + fd = -1; + } + else { + fd = open(filenameObj->bytes, O_RDWR | O_CREAT | O_TRUNC); + } +#endif +#ifdef HAVE_UMASK + umask(mask); +#endif + if (fd < 0) { + Jim_SetResultErrno(interp, Jim_String(filenameObj)); + Jim_FreeNewObj(interp, filenameObj); + return -1; + } + if (unlink_file) { + remove(Jim_String(filenameObj)); + } + + Jim_SetResult(interp, filenameObj); + return fd; +} + +int Jim_OpenForWrite(const char *filename, int append) +{ + return open(filename, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0666); +} + +int Jim_OpenForRead(const char *filename) +{ + return open(filename, O_RDONLY, 0); +} + +#endif + +#if defined(_WIN32) || defined(WIN32) +#ifndef STRICT +#define STRICT +#endif +#define WIN32_LEAN_AND_MEAN +#include + +#if defined(HAVE_DLOPEN_COMPAT) +void *dlopen(const char *path, int mode) +{ + JIM_NOTUSED(mode); + + return (void *)LoadLibraryA(path); +} + +int dlclose(void *handle) +{ + FreeLibrary((HANDLE)handle); + return 0; +} + +void *dlsym(void *handle, const char *symbol) +{ + return GetProcAddress((HMODULE)handle, symbol); +} + +char *dlerror(void) +{ + static char msg[121]; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + LANG_NEUTRAL, msg, sizeof(msg) - 1, NULL); + return msg; +} +#endif + +#ifdef _MSC_VER + +#include + + +int gettimeofday(struct timeval *tv, void *unused) +{ + struct _timeb tb; + + _ftime(&tb); + tv->tv_sec = tb.time; + tv->tv_usec = tb.millitm * 1000; + + return 0; +} + + +DIR *opendir(const char *name) +{ + DIR *dir = 0; + + if (name && name[0]) { + size_t base_length = strlen(name); + const char *all = + strchr("/\\", name[base_length - 1]) ? "*" : "/*"; + + if ((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 && + (dir->name = (char *)Jim_Alloc(base_length + strlen(all) + 1)) != 0) { + strcat(strcpy(dir->name, name), all); + + if ((dir->handle = (long)_findfirst(dir->name, &dir->info)) != -1) + dir->result.d_name = 0; + else { + Jim_Free(dir->name); + Jim_Free(dir); + dir = 0; + } + } + else { + Jim_Free(dir); + dir = 0; + errno = ENOMEM; + } + } + else { + errno = EINVAL; + } + return dir; +} + +int closedir(DIR * dir) +{ + int result = -1; + + if (dir) { + if (dir->handle != -1) + result = _findclose(dir->handle); + Jim_Free(dir->name); + Jim_Free(dir); + } + if (result == -1) + errno = EBADF; + return result; +} + +struct dirent *readdir(DIR * dir) +{ + struct dirent *result = 0; + + if (dir && dir->handle != -1) { + if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) { + result = &dir->result; + result->d_name = dir->info.name; + } + } + else { + errno = EBADF; + } + return result; +} +#endif +#endif +#include +#include + + + + + + +#ifndef SIGPIPE +#define SIGPIPE 13 +#endif +#ifndef SIGINT +#define SIGINT 2 +#endif + +const char *Jim_SignalId(int sig) +{ + static char buf[10]; + switch (sig) { + case SIGINT: return "SIGINT"; + case SIGPIPE: return "SIGPIPE"; + + } + snprintf(buf, sizeof(buf), "%d", sig); + return buf; +} +#ifndef JIM_BOOTSTRAP_LIB_ONLY +#include +#include +#include + + +#ifdef USE_LINENOISE +#ifdef HAVE_UNISTD_H + #include +#endif +#ifdef HAVE_SYS_STAT_H + #include +#endif +#include "linenoise.h" +#else +#define MAX_LINE_LEN 512 +#endif + +#ifdef USE_LINENOISE +struct JimCompletionInfo { + Jim_Interp *interp; + Jim_Obj *completion_command; + Jim_Obj *hints_command; + +}; + +static struct JimCompletionInfo *JimGetCompletionInfo(Jim_Interp *interp); +static void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata); +static const char completion_callback_assoc_key[] = "interactive-completion"; +static char *JimHintsCallback(const char *prefix, int *color, int *bold, void *userdata); +static void JimFreeHintsCallback(void *hint, void *userdata); +#endif + +char *Jim_HistoryGetline(Jim_Interp *interp, const char *prompt) +{ +#ifdef USE_LINENOISE + struct JimCompletionInfo *compinfo = JimGetCompletionInfo(interp); + char *result; + Jim_Obj *objPtr; + long mlmode = 0; + if (compinfo->completion_command) { + linenoiseSetCompletionCallback(JimCompletionCallback, compinfo); + } + if (compinfo->hints_command) { + linenoiseSetHintsCallback(JimHintsCallback, compinfo); + linenoiseSetFreeHintsCallback(JimFreeHintsCallback); + } + objPtr = Jim_GetVariableStr(interp, "history::multiline", JIM_NONE); + if (objPtr && Jim_GetLong(interp, objPtr, &mlmode) == JIM_NONE) { + linenoiseSetMultiLine(mlmode); + } + + result = linenoise(prompt); + + linenoiseSetCompletionCallback(NULL, NULL); + linenoiseSetHintsCallback(NULL, NULL); + linenoiseSetFreeHintsCallback(NULL); + return result; +#else + int len; + char *line = Jim_Alloc(MAX_LINE_LEN); + + fputs(prompt, stdout); + fflush(stdout); + + if (fgets(line, MAX_LINE_LEN, stdin) == NULL) { + Jim_Free(line); + return NULL; + } + len = strlen(line); + if (len && line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + return line; +#endif +} + +void Jim_HistoryLoad(const char *filename) +{ +#ifdef USE_LINENOISE + linenoiseHistoryLoad(filename); +#endif +} + +void Jim_HistoryAdd(const char *line) +{ +#ifdef USE_LINENOISE + linenoiseHistoryAdd(line); +#endif +} + +void Jim_HistorySave(const char *filename) +{ +#ifdef USE_LINENOISE +#ifdef HAVE_UMASK + mode_t mask; + + mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); +#endif + linenoiseHistorySave(filename); +#ifdef HAVE_UMASK + umask(mask); +#endif +#endif +} + +void Jim_HistoryShow(void) +{ +#ifdef USE_LINENOISE + + int i; + int len; + char **history = linenoiseHistory(&len); + for (i = 0; i < len; i++) { + printf("%4d %s\n", i + 1, history[i]); + } +#endif +} + +void Jim_HistorySetMaxLen(int length) +{ +#ifdef USE_LINENOISE + linenoiseHistorySetMaxLen(length); +#endif +} + +int Jim_HistoryGetMaxLen(void) +{ +#ifdef USE_LINENOISE + return linenoiseHistoryGetMaxLen(); +#endif + return 0; +} + +#ifdef USE_LINENOISE +static void JimCompletionCallback(const char *prefix, linenoiseCompletions *comp, void *userdata) +{ + struct JimCompletionInfo *info = (struct JimCompletionInfo *)userdata; + Jim_Obj *objv[2]; + int ret; + + objv[0] = info->completion_command; + objv[1] = Jim_NewStringObj(info->interp, prefix, -1); + + ret = Jim_EvalObjVector(info->interp, 2, objv); + + + if (ret == JIM_OK) { + int i; + Jim_Obj *listObj = Jim_GetResult(info->interp); + int len = Jim_ListLength(info->interp, listObj); + for (i = 0; i < len; i++) { + linenoiseAddCompletion(comp, Jim_String(Jim_ListGetIndex(info->interp, listObj, i))); + } + } +} + +static char *JimHintsCallback(const char *prefix, int *color, int *bold, void *userdata) +{ + struct JimCompletionInfo *info = (struct JimCompletionInfo *)userdata; + Jim_Obj *objv[2]; + int ret; + char *result = NULL; + + objv[0] = info->hints_command; + objv[1] = Jim_NewStringObj(info->interp, prefix, -1); + + ret = Jim_EvalObjVector(info->interp, 2, objv); + + + if (ret == JIM_OK) { + Jim_Obj *listObj = Jim_GetResult(info->interp); + Jim_IncrRefCount(listObj); + + int len = Jim_ListLength(info->interp, listObj); + if (len >= 1) { + long x; + result = Jim_StrDup(Jim_String(Jim_ListGetIndex(info->interp, listObj, 0))); + if (len >= 2 && Jim_GetLong(info->interp, Jim_ListGetIndex(info->interp, listObj, 1), &x) == JIM_OK) { + *color = x; + } + if (len >= 3 && Jim_GetLong(info->interp, Jim_ListGetIndex(info->interp, listObj, 2), &x) == JIM_OK) { + *bold = x; + } + } + Jim_DecrRefCount(info->interp, listObj); + } + return result; +} + +static void JimFreeHintsCallback(void *hint, void *userdata) +{ + Jim_Free(hint); +} + +static void JimHistoryFreeCompletion(Jim_Interp *interp, void *data) +{ + struct JimCompletionInfo *compinfo = data; + + if (compinfo->completion_command) { + Jim_DecrRefCount(interp, compinfo->completion_command); + } + if (compinfo->hints_command) { + Jim_DecrRefCount(interp, compinfo->hints_command); + } + + Jim_Free(compinfo); +} + +static struct JimCompletionInfo *JimGetCompletionInfo(Jim_Interp *interp) +{ + struct JimCompletionInfo *compinfo = Jim_GetAssocData(interp, completion_callback_assoc_key); + if (compinfo == NULL) { + compinfo = Jim_Alloc(sizeof(*compinfo)); + compinfo->interp = interp; + compinfo->completion_command = NULL; + compinfo->hints_command = NULL; + Jim_SetAssocData(interp, completion_callback_assoc_key, JimHistoryFreeCompletion, compinfo); + } + return compinfo; +} +#endif + +void Jim_HistorySetCompletion(Jim_Interp *interp, Jim_Obj *completionCommandObj) +{ +#ifdef USE_LINENOISE + struct JimCompletionInfo *compinfo = JimGetCompletionInfo(interp); + + if (completionCommandObj) { + + Jim_IncrRefCount(completionCommandObj); + } + if (compinfo->completion_command) { + Jim_DecrRefCount(interp, compinfo->completion_command); + } + compinfo->completion_command = completionCommandObj; +#endif +} + +void Jim_HistorySetHints(Jim_Interp *interp, Jim_Obj *hintsCommandObj) +{ +#ifdef USE_LINENOISE + struct JimCompletionInfo *compinfo = JimGetCompletionInfo(interp); + + if (hintsCommandObj) { + + Jim_IncrRefCount(hintsCommandObj); + } + if (compinfo->hints_command) { + Jim_DecrRefCount(interp, compinfo->hints_command); + } + compinfo->hints_command = hintsCommandObj; +#endif +} + +int Jim_InteractivePrompt(Jim_Interp *interp) +{ + int retcode = JIM_OK; + char *history_file = NULL; +#ifdef USE_LINENOISE + const char *home; + + home = getenv("HOME"); + if (home && isatty(STDIN_FILENO)) { + int history_len = strlen(home) + sizeof("/.jim_history"); + history_file = Jim_Alloc(history_len); + snprintf(history_file, history_len, "%s/.jim_history", home); + Jim_HistoryLoad(history_file); + } + + Jim_HistorySetCompletion(interp, Jim_NewStringObj(interp, "tcl::autocomplete", -1)); + Jim_HistorySetHints(interp, Jim_NewStringObj(interp, "tcl::stdhint", -1)); +#endif + + printf("Welcome to Jim version %d.%d\n", + JIM_VERSION / 100, JIM_VERSION % 100); + Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1"); + + while (1) { + Jim_Obj *scriptObjPtr; + const char *result; + int reslen; + char prompt[20]; + + if (retcode != JIM_OK) { + const char *retcodestr = Jim_ReturnCode(retcode); + + if (*retcodestr == '?') { + snprintf(prompt, sizeof(prompt) - 3, "[%d] . ", retcode); + } + else { + snprintf(prompt, sizeof(prompt) - 3, "[%s] . ", retcodestr); + } + } + else { + strcpy(prompt, ". "); + } + + scriptObjPtr = Jim_NewStringObj(interp, "", 0); + Jim_IncrRefCount(scriptObjPtr); + while (1) { + char state; + char *line; + + line = Jim_HistoryGetline(interp, prompt); + if (line == NULL) { + if (errno == EINTR) { + continue; + } + Jim_DecrRefCount(interp, scriptObjPtr); + retcode = JIM_OK; + goto out; + } + if (Jim_Length(scriptObjPtr) != 0) { + + Jim_AppendString(interp, scriptObjPtr, "\n", 1); + } + Jim_AppendString(interp, scriptObjPtr, line, -1); + Jim_Free(line); + if (Jim_ScriptIsComplete(interp, scriptObjPtr, &state)) + break; + + snprintf(prompt, sizeof(prompt), "%c> ", state); + } +#ifdef USE_LINENOISE + if (strcmp(Jim_String(scriptObjPtr), "h") == 0) { + + Jim_HistoryShow(); + Jim_DecrRefCount(interp, scriptObjPtr); + continue; + } + + Jim_HistoryAdd(Jim_String(scriptObjPtr)); + if (history_file) { + Jim_HistorySave(history_file); + } +#endif + retcode = Jim_EvalObj(interp, scriptObjPtr); + Jim_DecrRefCount(interp, scriptObjPtr); + + if (retcode == JIM_EXIT) { + break; + } + if (retcode == JIM_ERR) { + Jim_MakeErrorMessage(interp); + } + result = Jim_GetString(Jim_GetResult(interp), &reslen); + if (reslen) { + if (fwrite(result, reslen, 1, stdout) == 0) { + + } + putchar('\n'); + } + } + out: + Jim_Free(history_file); + + return retcode; +} + +#include +#include +#include + + + +extern int Jim_initjimshInit(Jim_Interp *interp); + +static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[]) +{ + int n; + Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); + + + for (n = 0; n < argc; n++) { + Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1); + + Jim_ListAppendElement(interp, listObj, obj); + } + + Jim_SetVariableStr(interp, "argv", listObj); + Jim_SetVariableStr(interp, "argc", Jim_NewIntObj(interp, argc)); +} + +static void JimPrintErrorMessage(Jim_Interp *interp) +{ + Jim_MakeErrorMessage(interp); + fprintf(stderr, "%s\n", Jim_String(Jim_GetResult(interp))); +} + +void usage(const char* executable_name) +{ + printf("jimsh version %d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100); + printf("Usage: %s\n", executable_name); + printf("or : %s [options] [filename]\n", executable_name); + printf("\n"); + printf("Without options: Interactive mode\n"); + printf("\n"); + printf("Options:\n"); + printf(" --version : prints the version string\n"); + printf(" --help : prints this text\n"); + printf(" -e CMD : executes command CMD\n"); + printf(" NOTE: all subsequent options will be passed as arguments to the command\n"); + printf(" [filename|-] : executes the script contained in the named file, or from stdin if \"-\"\n"); + printf(" NOTE: all subsequent options will be passed to the script\n\n"); +} + +int main(int argc, char *const argv[]) +{ + int retcode; + Jim_Interp *interp; + char *const orig_argv0 = argv[0]; + + + if (argc > 1 && strcmp(argv[1], "--version") == 0) { + printf("%d.%d\n", JIM_VERSION / 100, JIM_VERSION % 100); + return 0; + } + else if (argc > 1 && strcmp(argv[1], "--help") == 0) { + usage(argv[0]); + return 0; + } + + + interp = Jim_CreateInterp(); + Jim_RegisterCoreCommands(interp); + + + if (Jim_InitStaticExtensions(interp) != JIM_OK) { + JimPrintErrorMessage(interp); + } + + Jim_SetVariableStrWithStr(interp, "jim::argv0", orig_argv0); + Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0"); +#ifdef USE_LINENOISE + Jim_SetVariableStrWithStr(interp, "jim::lineedit", "1"); +#else + Jim_SetVariableStrWithStr(interp, "jim::lineedit", "0"); +#endif + retcode = Jim_initjimshInit(interp); + + if (argc == 1) { + + if (retcode == JIM_ERR) { + JimPrintErrorMessage(interp); + } + if (retcode != JIM_EXIT) { + JimSetArgv(interp, 0, NULL); + retcode = Jim_InteractivePrompt(interp); + } + } + else { + + if (argc > 2 && strcmp(argv[1], "-e") == 0) { + + JimSetArgv(interp, argc - 3, argv + 3); + retcode = Jim_Eval(interp, argv[2]); + if (retcode != JIM_ERR) { + int len; + const char *msg = Jim_GetString(Jim_GetResult(interp), &len); + if (fwrite(msg, len, 1, stdout) == 0) { + + } + putchar('\n'); + } + } + else { + Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); + JimSetArgv(interp, argc - 2, argv + 2); + if (strcmp(argv[1], "-") == 0) { + retcode = Jim_Eval(interp, "eval [info source [stdin read] stdin 1]"); + } else { + retcode = Jim_EvalFile(interp, argv[1]); + } + } + if (retcode == JIM_ERR) { + JimPrintErrorMessage(interp); + } + } + if (retcode == JIM_EXIT) { + retcode = Jim_GetExitCode(interp); + } + else if (retcode == JIM_ERR) { + retcode = 1; + } + else { + retcode = 0; + } + Jim_FreeInterp(interp); + return retcode; +} +#endif diff --git a/autosetup/pkg-config.tcl b/autosetup/pkg-config.tcl new file mode 100644 index 0000000000..9ce7111f55 --- /dev/null +++ b/autosetup/pkg-config.tcl @@ -0,0 +1,168 @@ +# Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# The 'pkg-config' module allows package information to be found via 'pkg-config'. +# +# If not cross-compiling, the package path should be determined automatically +# by 'pkg-config'. +# If cross-compiling, the default package path is the compiler sysroot. +# If the C compiler doesn't support '-print-sysroot', the path can be supplied +# by the '--sysroot' option or by defining 'SYSROOT'. +# +# 'PKG_CONFIG' may be set to use an alternative to 'pkg-config'. + +use cc + +options { + sysroot:dir => "Override compiler sysroot for pkg-config search path" +} + +# @pkg-config-init ?required? +# +# Initialises the 'pkg-config' system. Unless '$required' is set to 0, +# it is a fatal error if a usable 'pkg-config' is not found . +# +# This command will normally be called automatically as required, +# but it may be invoked explicitly if lack of 'pkg-config' is acceptable. +# +# Returns 1 if ok, or 0 if 'pkg-config' not found/usable (only if '$required' is 0). +# +proc pkg-config-init {{required 1}} { + if {[is-defined HAVE_PKG_CONFIG]} { + return [get-define HAVE_PKG_CONFIG] + } + set found 0 + + define PKG_CONFIG [get-env PKG_CONFIG pkg-config] + msg-checking "Checking for pkg-config..." + + if {[catch {exec [get-define PKG_CONFIG] --version} version]} { + msg-result "[get-define PKG_CONFIG] (not found)" + if {$required} { + user-error "No usable pkg-config" + } + } else { + msg-result $version + define PKG_CONFIG_VERSION $version + + set found 1 + + if {[opt-str sysroot o]} { + define SYSROOT [file-normalize $o] + msg-result "Using specified sysroot [get-define SYSROOT]" + } elseif {[get-define build] ne [get-define host]} { + if {[catch {exec-with-stderr {*}[get-define CC] -print-sysroot} result errinfo] == 0} { + # Use the compiler sysroot, if there is one + define SYSROOT $result + msg-result "Found compiler sysroot $result" + } else { + configlog "[get-define CC] -print-sysroot: $result" + set msg "pkg-config: Cross compiling, but no compiler sysroot and no --sysroot supplied" + if {$required} { + user-error $msg + } else { + msg-result $msg + } + set found 0 + } + } + if {[is-defined SYSROOT]} { + set sysroot [get-define SYSROOT] + + # XXX: It's possible that these should be set only when invoking pkg-config + global env + set env(PKG_CONFIG_DIR) "" + # Supposedly setting PKG_CONFIG_LIBDIR means that PKG_CONFIG_PATH is ignored, + # but it doesn't seem to work that way in practice + set env(PKG_CONFIG_PATH) "" + # Do we need to try /usr/local as well or instead? + set env(PKG_CONFIG_LIBDIR) $sysroot/usr/lib/pkgconfig:$sysroot/usr/share/pkgconfig + set env(PKG_CONFIG_SYSROOT_DIR) $sysroot + } + } + define HAVE_PKG_CONFIG $found + return $found +} + +# @pkg-config module ?requirements? +# +# Use 'pkg-config' to find the given module meeting the given requirements. +# e.g. +# +## pkg-config pango >= 1.37.0 +# +# If found, returns 1 and sets 'HAVE_PKG_PANGO' to 1 along with: +# +## PKG_PANGO_VERSION to the found version +## PKG_PANGO_LIBS to the required libs (--libs-only-l) +## PKG_PANGO_LDFLAGS to the required linker flags (--libs-only-L) +## PKG_PANGO_CFLAGS to the required compiler flags (--cflags) +# +# If not found, returns 0. +# +proc pkg-config {module args} { + set ok [pkg-config-init] + + msg-checking "Checking for $module $args..." + + if {!$ok} { + msg-result "no pkg-config" + return 0 + } + + set pkgconfig [get-define PKG_CONFIG] + + set ret [catch {exec $pkgconfig --modversion "$module $args"} version] + configlog "$pkgconfig --modversion $module $args: $version" + if {$ret} { + msg-result "not found" + return 0 + } + # Sometimes --modversion succeeds but because of dependencies it isn't usable + # This seems to show up with --cflags + set ret [catch {exec $pkgconfig --cflags $module} cflags] + if {$ret} { + msg-result "unusable ($version - see config.log)" + configlog "$pkgconfig --cflags $module" + configlog $cflags + return 0 + } + msg-result $version + set prefix [feature-define-name $module PKG_] + define HAVE_${prefix} + define ${prefix}_VERSION $version + define ${prefix}_CFLAGS $cflags + define ${prefix}_LIBS [exec $pkgconfig --libs-only-l $module] + define ${prefix}_LDFLAGS [exec $pkgconfig --libs-only-L $module] + return 1 +} + +# @pkg-config-get module setting +# +# Convenience access to the results of 'pkg-config'. +# +# For example, '[pkg-config-get pango CFLAGS]' returns +# the value of 'PKG_PANGO_CFLAGS', or '""' if not defined. +proc pkg-config-get {module name} { + set prefix [feature-define-name $module PKG_] + get-define ${prefix}_${name} "" +} + +# @pkg-config-get-var module variable +# +# Return the value of the given variable from the given pkg-config module. +# The module must already have been successfully detected with pkg-config. +# e.g. +# +## if {[pkg-config harfbuzz >= 2.5]} { +## define harfbuzz_libdir [pkg-config-get-var harfbuzz libdir] +## } +# +# Returns the empty string if the variable isn't defined. +proc pkg-config-get-var {module variable} { + set pkgconfig [get-define PKG_CONFIG] + set prefix [feature-define-name $module HAVE_PKG_] + exec $pkgconfig $module --variable $variable +} diff --git a/autosetup/system.tcl b/autosetup/system.tcl new file mode 100644 index 0000000000..f23781b5da --- /dev/null +++ b/autosetup/system.tcl @@ -0,0 +1,412 @@ +# Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# This module supports common system interrogation and options +# such as '--host', '--build', '--prefix', and setting 'srcdir', 'builddir', and 'EXEEXT'. +# +# It also support the "feature" naming convention, where searching +# for a feature such as 'sys/type.h' defines 'HAVE_SYS_TYPES_H'. +# +# It defines the following variables, based on '--prefix' unless overridden by the user: +# +## datadir +## sysconfdir +## sharedstatedir +## localstatedir +## infodir +## mandir +## includedir +# +# If '--prefix' is not supplied, it defaults to '/usr/local' unless 'options-defaults { prefix ... }' is used *before* +# including the 'system' module. + +if {[is-defined defaultprefix]} { + user-notice "Note: defaultprefix is deprecated. Use options-defaults to set default options" + options-defaults [list prefix [get-define defaultprefix]] +} + +options { + host:host-alias => {a complete or partial cpu-vendor-opsys for the system where + the application will run (defaults to the same value as --build)} + build:build-alias => {a complete or partial cpu-vendor-opsys for the system + where the application will be built (defaults to the + result of running config.guess)} + prefix:dir=/usr/local => {the target directory for the build (default: '@default@')} + + # These (hidden) options are supported for autoconf/automake compatibility + exec-prefix: + bindir: + sbindir: + includedir: + mandir: + infodir: + libexecdir: + datadir: + libdir: + sysconfdir: + sharedstatedir: + localstatedir: + runstatedir: + maintainer-mode=0 + dependency-tracking=0 + silent-rules=0 + program-prefix: + program-suffix: + program-transform-name: +} + +# @check-feature name { script } +# +# defines feature '$name' to the return value of '$script', +# which should be 1 if found or 0 if not found. +# +# e.g. the following will define 'HAVE_CONST' to 0 or 1. +# +## check-feature const { +## cctest -code {const int _x = 0;} +## } +proc check-feature {name code} { + msg-checking "Checking for $name..." + set r [uplevel 1 $code] + define-feature $name $r + if {$r} { + msg-result "ok" + } else { + msg-result "not found" + } + return $r +} + +# @have-feature name ?default=0? +# +# Returns the value of feature '$name' if defined, or '$default' if not. +# +# See 'feature-define-name' for how the "feature" name +# is translated into the "define" name. +# +proc have-feature {name {default 0}} { + get-define [feature-define-name $name] $default +} + +# @define-feature name ?value=1? +# +# Sets the feature 'define' to '$value'. +# +# See 'feature-define-name' for how the "feature" name +# is translated into the "define" name. +# +proc define-feature {name {value 1}} { + define [feature-define-name $name] $value +} + +# @feature-checked name +# +# Returns 1 if feature '$name' has been checked, whether true or not. +# +proc feature-checked {name} { + is-defined [feature-define-name $name] +} + +# @feature-define-name name ?prefix=HAVE_? +# +# Converts a "feature" name to the corresponding "define", +# e.g. 'sys/stat.h' becomes 'HAVE_SYS_STAT_H'. +# +# Converts '*' to 'P' and all non-alphanumeric to underscore. +# +proc feature-define-name {name {prefix HAVE_}} { + string toupper $prefix[regsub -all {[^a-zA-Z0-9]} [regsub -all {[*]} $name p] _] +} + +# @write-if-changed filename contents ?script? +# +# If '$filename' doesn't exist, or it's contents are different to '$contents', +# the file is written and '$script' is evaluated. +# +# Otherwise a "file is unchanged" message is displayed. +proc write-if-changed {file buf {script {}}} { + set old [readfile $file ""] + if {$old eq $buf && [file exists $file]} { + msg-result "$file is unchanged" + } else { + writefile $file $buf\n + uplevel 1 $script + } +} + + +# @include-file infile mapping +# +# The core of make-template, called recursively for each @include +# directive found within that template so that this proc's result +# is the fully-expanded template. +# +# The mapping parameter is how we expand @varname@ within the template. +# We do that inline within this step only for @include directives which +# can have variables in the filename arg. A separate substitution pass +# happens when this recursive function returns, expanding the rest of +# the variables. +# +proc include-file {infile mapping} { + # A stack of true/false conditions, one for each nested conditional + # starting with "true" + set condstack {1} + set result {} + set linenum 0 + foreach line [split [readfile $infile] \n] { + incr linenum + if {[regexp {^@(if|else|endif)(\s*)(.*)} $line -> condtype condspace condargs]} { + if {$condtype eq "if"} { + if {[string length $condspace] == 0} { + autosetup-error "$infile:$linenum: Invalid expression: $line" + } + if {[llength $condargs] == 1} { + # ABC => [get-define ABC] ni {0 ""} + # !ABC => [get-define ABC] in {0 ""} + lassign $condargs condvar + if {[regexp {^!(.*)} $condvar -> condvar]} { + set op in + } else { + set op ni + } + set condexpr "\[[list get-define $condvar]\] $op {0 {}}" + } else { + # Translate alphanumeric ABC into [get-define ABC] and leave the + # rest of the expression untouched + regsub -all {([A-Z][[:alnum:]_]*)} $condargs {[get-define \1]} condexpr + } + if {[catch [list expr $condexpr] condval]} { + dputs $condval + autosetup-error "$infile:$linenum: Invalid expression: $line" + } + dputs "@$condtype: $condexpr => $condval" + } + if {$condtype ne "if"} { + if {[llength $condstack] <= 1} { + autosetup-error "$infile:$linenum: Error: @$condtype missing @if" + } elseif {[string length $condargs] && [string index $condargs 0] ne "#"} { + autosetup-error "$infile:$linenum: Error: Extra arguments after @$condtype" + } + } + switch -exact $condtype { + if { + # push condval + lappend condstack $condval + } + else { + # Toggle the last entry + set condval [lpop condstack] + set condval [expr {!$condval}] + lappend condstack $condval + } + endif { + if {[llength $condstack] == 0} { + user-notice "$infile:$linenum: Error: @endif missing @if" + } + lpop condstack + } + } + continue + } + # Only continue if the stack contains all "true" + if {"0" in $condstack} { + continue + } + if {[regexp {^@include\s+(.*)} $line -> filearg]} { + set incfile [string map $mapping $filearg] + if {[file exists $incfile]} { + lappend ::autosetup(deps) [file-normalize $incfile] + lappend result {*}[include-file $incfile $mapping] + } else { + user-error "$infile:$linenum: Include file $incfile is missing" + } + continue + } + if {[regexp {^@define\s+(\w+)\s+(.*)} $line -> var val]} { + define $var $val + continue + } + lappend result $line + } + return $result +} + + +# @make-template template ?outfile? +# +# Reads the input file '/$template' and writes the output file '$outfile' +# (unless unchanged). +# If '$outfile' is blank/omitted, '$template' should end with '.in' which +# is removed to create the output file name. +# +# Each pattern of the form '@define@' is replaced with the corresponding +# "define", if it exists, or left unchanged if not. +# +# The special value '@srcdir@' is substituted with the relative +# path to the source directory from the directory where the output +# file is created, while the special value '@top_srcdir@' is substituted +# with the relative path to the top level source directory. +# +# Conditional sections may be specified as follows: +## @if NAME eq "value" +## lines +## @else +## lines +## @endif +# +# Where 'NAME' is a defined variable name and '@else' is optional. +# Note that variables names *must* start with an uppercase letter. +# If the expression does not match, all lines through '@endif' are ignored. +# +# The alternative forms may also be used: +## @if NAME (true if the variable is defined, but not empty and not "0") +## @if !NAME (opposite of the form above) +## @if +# +# In the general Tcl expression, any words beginning with an uppercase letter +# are translated into [get-define NAME] +# +# Expressions may be nested +# +proc make-template {template {out {}}} { + set infile [file join $::autosetup(srcdir) $template] + + if {![file exists $infile]} { + user-error "Template $template is missing" + } + + # Define this as late as possible + define AUTODEPS $::autosetup(deps) + + if {$out eq ""} { + if {[file ext $template] ne ".in"} { + autosetup-error "make_template $template has no target file and can't guess" + } + set out [file rootname $template] + } + + set outdir [file dirname $out] + + # Make sure the directory exists + file mkdir $outdir + + # Set up srcdir and top_srcdir to be relative to the target dir + define srcdir [relative-path [file join $::autosetup(srcdir) $outdir] $outdir] + define top_srcdir [relative-path $::autosetup(srcdir) $outdir] + + # Build map from global defines to their values so they can be + # substituted into @include file names. + proc build-define-mapping {} { + set mapping {} + foreach {n v} [array get ::define] { + lappend mapping @$n@ $v + } + return $mapping + } + set mapping [build-define-mapping] + + set result [include-file $infile $mapping] + + # Rebuild the define mapping in case we ran across @define + # directives in the template or a file it @included, then + # apply that mapping to the expanded template. + set mapping [build-define-mapping] + write-if-changed $out [string map $mapping [join $result \n]] { + msg-result "Created [relative-path $out] from [relative-path $template]" + } +} + +# build/host tuples and cross-compilation prefix +opt-str build build "" +define build_alias $build +if {$build eq ""} { + define build [config_guess] +} else { + define build [config_sub $build] +} + +opt-str host host "" +define host_alias $host +if {$host eq ""} { + define host [get-define build] + set cross "" +} else { + define host [config_sub $host] + set cross $host- +} +define cross [get-env CROSS $cross] + +# build/host _cpu, _vendor and _os +foreach type {build host} { + set v [get-define $type] + if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} { + user-error "Invalid canonical $type: $v" + } + define ${type}_cpu $cpu + define ${type}_vendor $vendor + define ${type}_os $os +} + +opt-str prefix prefix /usr/local + +# These are for compatibility with autoconf +define target [get-define host] +define prefix $prefix +define builddir $autosetup(builddir) +define srcdir $autosetup(srcdir) +define top_srcdir $autosetup(srcdir) +define abs_top_srcdir [file-normalize $autosetup(srcdir)] +define abs_top_builddir [file-normalize $autosetup(builddir)] + +# autoconf supports all of these +define exec_prefix [opt-str exec-prefix exec_prefix $prefix] +foreach {name defpath} { + bindir /bin + sbindir /sbin + libexecdir /libexec + libdir /lib +} { + define $name [opt-str $name o $exec_prefix$defpath] +} +foreach {name defpath} { + datadir /share + sharedstatedir /com + infodir /share/info + mandir /share/man + includedir /include +} { + define $name [opt-str $name o $prefix$defpath] +} +if {$prefix ne {/usr}} { + opt-str sysconfdir sysconfdir $prefix/etc +} else { + opt-str sysconfdir sysconfdir /etc +} +define sysconfdir $sysconfdir + +define localstatedir [opt-str localstatedir o /var] +define runstatedir [opt-str runstatedir o /run] + +define SHELL [get-env SHELL [find-an-executable sh bash ksh]] + +# These could be used to generate Makefiles following some automake conventions +define AM_SILENT_RULES [opt-bool silent-rules] +define AM_MAINTAINER_MODE [opt-bool maintainer-mode] +define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking] + +# Windows vs. non-Windows +switch -glob -- [get-define host] { + *-*-ming* - *-*-cygwin - *-*-msys { + define-feature windows + define EXEEXT .exe + } + default { + define EXEEXT "" + } +} + +# Display +msg-result "Host System...[get-define host]" +msg-result "Build System...[get-define build]" diff --git a/autosetup/tmake.auto b/autosetup/tmake.auto new file mode 100644 index 0000000000..448d317229 --- /dev/null +++ b/autosetup/tmake.auto @@ -0,0 +1,73 @@ +# Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# Auto-load module for 'tmake' build system integration + +use init + +autosetup_add_init_type tmake "Tcl-based tmake build system" { + autosetup_check_create auto.def \ +{# Initial auto.def created by 'autosetup --init=tmake' +# vim:set syntax=tcl: + +use cc cc-lib cc-db cc-shared +use tmake + +# Add any user options here +# Really want a --configure that takes over the rest of the command line +options { +} + +cc-check-tools ar ranlib + +set objdir [get-env BUILDDIR objdir] + +make-config-header $objdir/include/autoconf.h +make-tmake-settings $objdir/settings.conf {[A-Z]*} *dir lib_* +} + + autosetup_check_create project.spec \ +{# Initial project.spec created by 'autosetup --init=tmake' + +tmake-require-version 0.7.3 + +# vim:set syntax=tcl: +define? DESTDIR _install + +# XXX If configure creates additional/different files than include/autoconf.h +# that should be reflected here +Autosetup include/autoconf.h + +# e.g. for autoconf.h +IncludePaths include + +ifconfig !CONFIGURED { + # Not configured, so don't process subdirs + AutoSubDirs off + # And don't process this file any further + ifconfig false +} +} + + set configure [readfile configure] + # XXX Do we need also need to support a system install of tmake? + if {[string first {#@TMAKEUPDATED@} $configure] < 0} { + if {[regsub {#@@INITCHECK@@#} $configure \ + {test -z "$TMAKE" -a -x "$dir/tmake" \&\& exec "$dir/tmake" --force --configure "$@"; #@TMAKEUPDATED@} configure]} { + writefile configure $configure\n + exec chmod +x configure + puts "Updated configure to invoke local tmake." + if {![file exec autosetup/tmake]} { + puts "Warning: autosetup/tmake is missing." + puts " Install it with: tmake --install=autosetup" + } + } else { + puts "Warning: configure isn't created by a recent autosetup, not updating." + } + } else { + puts "I see configure for tmake already exists." + } + if {![file exists build.spec]} { + puts "Note: I don't see build.spec. Try running: tmake --genie" + } +} diff --git a/autosetup/tmake.tcl b/autosetup/tmake.tcl new file mode 100644 index 0000000000..3269193aa7 --- /dev/null +++ b/autosetup/tmake.tcl @@ -0,0 +1,52 @@ +# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ +# All rights reserved + +# @synopsis: +# +# The 'tmake' module makes it easy to support the tmake build system. +# +# The following variables are set: +# +## CONFIGURED - to indicate that the project is configured + +use system + +options {} + +define CONFIGURED + +# @make-tmake-settings outfile patterns ... +# +# Examines all defined variables which match the given patterns (defaults to '*') +# and writes a tmake-compatible .conf file defining those variables. +# For example, if 'ABC' is '"3 monkeys"' and 'ABC' matches a pattern, then the file will include: +# +## define ABC {3 monkeys} +# +# If the file would be unchanged, it is not written. +# +# Typical usage is: +# +## make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*} +proc make-tmake-settings {file args} { + file mkdir [file dirname $file] + set lines {} + + if {[llength $args] == 0} { + set args * + } + + foreach n [lsort [dict keys [all-defines]]] { + foreach p $args { + if {[string match $p $n]} { + set value [get-define $n] + lappend lines "define $n [list $value]" + break + } + } + } + set buf [join $lines \n] + write-if-changed $file $buf { + msg-result "Created $file" + } +} diff --git a/configure b/configure index 22b961e554..64b60f8b35 100755 --- a/configure +++ b/configure @@ -1,14077 +1,4 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.47.0. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$lt_ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` - ;; -esac - -ECHO=${lt_ECHO-echo} -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then - # Yippee, $ECHO works! - : -else - # Restart under the correct shell. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <<_LT_EOF -$* -_LT_EOF - exit 0 -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test -z "$lt_ECHO"; then - if test "X${echo_test_string+set}" != Xset; then - # find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if { echo_test_string=`eval $cmd`; } 2>/dev/null && - { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null - then - break - fi - done - fi - - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : - else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$ECHO" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - ECHO='print -r' - elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} - else - # Try using printf. - ECHO='printf %s\n' - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - ECHO="$CONFIG_SHELL $0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$CONFIG_SHELL $0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do - if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "$0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} - else - # Oops. We lost completely, so just stick with echo. - ECHO=echo - fi - fi - fi - fi - fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -lt_ECHO=$ECHO -if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then - lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" -fi - - - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='sqlite' -PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.47.0' -PACKAGE_STRING='sqlite 3.47.0' -PACKAGE_BUGREPORT='' -PACKAGE_URL='' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='LTLIBOBJS -LIBOBJS -BUILD_CFLAGS -AMALGAMATION_LINE_MACROS -USE_GCOV -OPT_FEATURE_FLAGS -HAVE_ZLIB -USE_AMALGAMATION -TARGET_DEBUG -TARGET_HAVE_LINENOISE -TARGET_HAVE_EDITLINE -TARGET_HAVE_READLINE -TARGET_READLINE_INC -TARGET_READLINE_LIBS -TARGET_EXEEXT -SQLITE_OS_WIN -SQLITE_OS_UNIX -BUILD_EXEEXT -TEMP_STORE -ALLOWRELEASE -SQLITE_THREADSAFE -BUILD_CC -HAVE_WASI_SDK -RELEASE -VERSION -program_prefix -TSTRNNR_OPTS -TCLLIBDIR -HAVE_TCL -TCL_STUB_LIB_SPEC -TCL_LIB_SPEC -TCL_INCLUDE_SPEC -TCLSH_CMD -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -CPP -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -lt_ECHO -RANLIB -STRIP -AR -OBJDUMP -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -EGREP -GREP -SED -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -LIBTOOL -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_shared -enable_static -with_pic -enable_fast_install -with_gnu_ld -enable_libtool_lock -enable_largefile -with_tclsh -with_tcl -enable_tcl -enable_test_status -with_wasi_sdk -enable_threadsafe -enable_releasemode -enable_tempstore -enable_editline -enable_readline -with_readline_lib -with_readline_inc -with_linenoise -enable_debug -enable_amalgamation -enable_load_extension -enable_math -enable_json -enable_all -enable_memsys5 -enable_memsys3 -enable_fts3 -enable_fts4 -enable_fts5 -enable_update_limit -enable_geopoly -enable_rtree -enable_session -enable_gcov -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP -TCLLIBDIR' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures sqlite 3.47.0 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/sqlite] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.47.0:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-shared[=PKGS] build shared libraries [default=yes] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - --disable-largefile omit support for large files - --disable-tcl omit building accessory programs that require - TCL-dev - --enable-test-status Full-screen status of tests - --disable-threadsafe Disable mutexing - --enable-releasemode Support libtool link to release mode - --enable-tempstore Use an in-ram database for temporary tables - (never,no,yes,always) - --enable-editline enable BSD editline support - --disable-readline disable readline support - --enable-debug enable debugging & verbose explain - --disable-amalgamation Disable the amalgamation and instead build all files - separately - --disable-load-extension - Disable loading of external extensions - --disable-math Disable math functions - --disable-json Disable JSON functions - --enable-all Enable FTS4, FTS5, Geopoly, RTree, Sessions - --enable-memsys5 Enable MEMSYS5 - --enable-memsys3 Enable MEMSYS3 - --enable-fts3 Enable the FTS3 extension - --enable-fts4 Enable the FTS4 extension - --enable-fts5 Enable the FTS5 extension - --enable-update-limit Enable the UPDATE/DELETE LIMIT clause - --enable-geopoly Enable the GEOPOLY extension - --enable-rtree Enable the RTREE extension - --enable-session Enable the SESSION extension - --enable-gcov Enable coverage testing using gcov - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-pic try to use only PIC/non-PIC objects [default=use - both] - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-tclsh=PATHNAME full pathname of a tclsh to use - --with-tcl=DIR directory containing (tclConfig.sh) - --with-wasi-sdk=DIR directory containing the WASI SDK. Triggers - cross-compile to WASM. - --with-readline-lib specify readline library - --with-readline-inc specify readline include paths - --with-linenoise=DIR source directory for linenoise library - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - TCLLIBDIR Where to install tcl plugin - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to the package provider. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -sqlite configure 3.47.0 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by sqlite $as_me 3.47.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'` -if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then -as_fn_error $? "configure script is out of date: - configure \$PACKAGE_VERSION = $PACKAGE_VERSION - top level VERSION file = $sqlite_version_sanity_check -please regen with autoconf" "$LINENO" 5 -fi - -######### -# Programs needed -# -case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.2.6' -macro_revision='1.3012' - - - - - - - - - - - - - -ltmain="$ac_aux_dir/ltmain.sh" - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 - then ac_cv_path_FGREP="$GREP -F" - else - if test -z "$FGREP"; then - ac_path_FGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_FGREP" || continue -# Check for GNU ac_path_FGREP and select it if it is found. - # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in -*GNU*) - ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'FGREP' >> "conftest.nl" - "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_FGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_FGREP="$ac_path_FGREP" - ac_path_FGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_FGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_FGREP=$FGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } - FGREP="$ac_cv_path_FGREP" - - -test -z "$GREP" && GREP=grep - - - - - - - - - - - - - - - - - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if ${lt_cv_path_NM+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -$as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$ac_tool_prefix"; then - for ac_prog in "dumpbin -symbols" "link -dump -symbols" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DUMPBIN"; then - ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DUMPBIN=$ac_cv_prog_DUMPBIN -if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -$as_echo "$DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DUMPBIN" && break - done -fi -if test -z "$DUMPBIN"; then - ac_ct_DUMPBIN=$DUMPBIN - for ac_prog in "dumpbin -symbols" "link -dump -symbols" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DUMPBIN"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN -if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -$as_echo "$ac_ct_DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_DUMPBIN" && break -done - - if test "x$ac_ct_DUMPBIN" = x; then - DUMPBIN=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DUMPBIN=$ac_ct_DUMPBIN - fi -fi - - - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -$as_echo_n "checking the name lister ($NM) interface... " >&6; } -if ${lt_cv_nm_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3945: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 - (eval echo "\"\$as_me:3948: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 - (eval echo "\"\$as_me:3951: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -$as_echo "$lt_cv_nm_interface" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -# find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -$as_echo_n "checking the maximum length of command line arguments... " >&6; } -if ${lt_cv_sys_max_cmd_len+:} false; then : - $as_echo_n "(cached) " >&6 -else - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ - = "XX$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac - -fi - -if test -n $lt_cv_sys_max_cmd_len ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -$as_echo "$lt_cv_sys_max_cmd_len" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } -fi -max_cmd_len=$lt_cv_sys_max_cmd_len - - - - - - -: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi - - - - - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -$as_echo_n "checking for $LD option to reload object files... " >&6; } -if ${lt_cv_ld_reload_flag+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_reload_flag='-r' -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -$as_echo "$lt_cv_ld_reload_flag" >&6; } -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -$as_echo_n "checking how to recognize dependent libraries... " >&6; } -if ${lt_cv_deplibs_check_method+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[4-9]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - if ( file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[3-9]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -$as_echo "$lt_cv_deplibs_check_method" >&6; } -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_AR"; then - ac_ct_AR=$AR - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -else - AR="$ac_cv_prog_AR" -fi - -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -test -z "$STRIP" && STRIP=: - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if ${lt_cv_sys_global_symbol_pipe+:} false; then : - $as_echo_n "(cached) " >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[ABCDGISTW]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[ABCDEGRST]' - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris*) - symcode='[BDRT]' - ;; -sco3.2v5*) - symcode='[DT]' - ;; -sysv4.2uw2*) - symcode='[DT]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[ABDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK '"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -$as_echo "failed" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -$as_echo "ok" >&6; } -fi - - - - - - - - - - - - - - - - - - - - - - - -# Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : - enableval=$enable_libtool_lock; -fi - -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '#line 5157 "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -$as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if ${lt_cv_cc_needs_belf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_cc_needs_belf=yes -else - lt_cv_cc_needs_belf=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -$as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" - - - case $host_os in - rhapsody* | darwin*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. -set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DSYMUTIL"; then - ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DSYMUTIL=$ac_cv_prog_DSYMUTIL -if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -$as_echo "$DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DSYMUTIL"; then - ac_ct_DSYMUTIL=$DSYMUTIL - # Extract the first word of "dsymutil", so it can be a program name with args. -set dummy dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DSYMUTIL"; then - ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL -if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -$as_echo "$ac_ct_DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DSYMUTIL" = x; then - DSYMUTIL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DSYMUTIL=$ac_ct_DSYMUTIL - fi -else - DSYMUTIL="$ac_cv_prog_DSYMUTIL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. -set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NMEDIT"; then - ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -NMEDIT=$ac_cv_prog_NMEDIT -if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -$as_echo "$NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_NMEDIT"; then - ac_ct_NMEDIT=$NMEDIT - # Extract the first word of "nmedit", so it can be a program name with args. -set dummy nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_NMEDIT"; then - ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_NMEDIT="nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT -if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -$as_echo "$ac_ct_NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_NMEDIT" = x; then - NMEDIT=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - NMEDIT=$ac_ct_NMEDIT - fi -else - NMEDIT="$ac_cv_prog_NMEDIT" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. -set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LIPO"; then - ac_cv_prog_LIPO="$LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LIPO=$ac_cv_prog_LIPO -if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -$as_echo "$LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_LIPO"; then - ac_ct_LIPO=$LIPO - # Extract the first word of "lipo", so it can be a program name with args. -set dummy lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_LIPO"; then - ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_LIPO="lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO -if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -$as_echo "$ac_ct_LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_LIPO" = x; then - LIPO=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIPO=$ac_ct_LIPO - fi -else - LIPO="$ac_cv_prog_LIPO" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL"; then - ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL=$ac_cv_prog_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL"; then - ac_ct_OTOOL=$OTOOL - # Extract the first word of "otool", so it can be a program name with args. -set dummy otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL"; then - ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL="otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL -if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -$as_echo "$ac_ct_OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL" = x; then - OTOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL=$ac_ct_OTOOL - fi -else - OTOOL="$ac_cv_prog_OTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL64"; then - ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL64=$ac_cv_prog_OTOOL64 -if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -$as_echo "$OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL64"; then - ac_ct_OTOOL64=$OTOOL64 - # Extract the first word of "otool64", so it can be a program name with args. -set dummy otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL64"; then - ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL64="otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 -if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -$as_echo "$ac_ct_OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL64" = x; then - OTOOL64=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL64=$ac_ct_OTOOL64 - fi -else - OTOOL64="$ac_cv_prog_OTOOL64" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -$as_echo_n "checking for -single_module linker flag... " >&6; } -if ${lt_cv_apple_cc_single_mod+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&5 - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -$as_echo "$lt_cv_apple_cc_single_mod" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if ${lt_cv_ld_exported_symbols_list+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_ld_exported_symbols_list=yes -else - lt_cv_ld_exported_symbols_list=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 -_ACEOF - -fi - -done - - - -# Set options - - - - enable_dlopen=no - - - enable_win32_dll=no - - - # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_shared=yes -fi - - - - - - - - - - # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : - enableval=$enable_static; p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_static=yes -fi - - - - - - - - - - -# Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : - withval=$with_pic; pic_mode="$withval" -else - pic_mode=default -fi - - -test -z "$pic_mode" && pic_mode=default - - - - - - - - # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : - enableval=$enable_fast_install; p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_fast_install=yes -fi - - - - - - - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - - - - - - - - - - - - - - - - - - - - - - - - - -test -z "$LN_S" && LN_S="ln -s" - - - - - - - - - - - - - - -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -$as_echo_n "checking for objdir... " >&6; } -if ${lt_cv_objdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -$as_echo "$lt_cv_objdir" >&6; } -objdir=$lt_cv_objdir - - - - - -cat >>confdefs.h <<_ACEOF -#define LT_OBJDIR "$lt_cv_objdir/" -_ACEOF - - - - - - - - - - - - - - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -$as_echo_n "checking for file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Use C for the default configuration in the libtool script - -lt_save_CC="$CC" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - -if test -n "$compiler"; then - -lt_prog_compiler_no_builtin_flag= - -if test "$GCC" = yes; then - lt_prog_compiler_no_builtin_flag=' -fno-builtin' - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6682: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:6686: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - - - - - - - lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } - - if test "$GCC" = yes; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - linux* | k*bsd*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='--shared' - lt_prog_compiler_static='--static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - xl*) - # IBM XL C 8.0/Fortran 10.1 on PPC - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-qpic' - lt_prog_compiler_static='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C 5.9 - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Wl,' - ;; - *Sun\ F*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='' - ;; - esac - ;; - esac - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - rdos*) - lt_prog_compiler_static='-non_shared' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 -$as_echo "$lt_prog_compiler_pic" >&6; } - - - - - - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if ${lt_cv_prog_compiler_pic_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7021: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:7025: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } - -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi - - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works=yes - fi - else - lt_cv_prog_compiler_static_works=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -$as_echo "$lt_cv_prog_compiler_static_works" >&6; } - -if test x"$lt_cv_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7126: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:7130: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7181: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:7185: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - runpath_var= - allow_undefined_flag= - always_export_symbols=no - archive_cmds= - archive_expsym_cmds= - compiler_needs_object=no - enable_shared_with_static_runtimes=no - export_dynamic_flag_spec= - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - hardcode_automatic=no - hardcode_direct=no - hardcode_direct_absolute=no - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld= - hardcode_libdir_separator= - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - inherit_rpath=no - link_all_deplibs=unknown - module_cmds= - module_expsym_cmds= - old_archive_from_new_cmds= - old_archive_from_expsyms_cmds= - thread_safe_flag_spec= - whole_archive_flag_spec= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs=no - fi - ;; - - interix[3-9]*) - hardcode_direct=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag= - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - whole_archive_flag_spec= - tmp_sharedflag='--shared' ;; - xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld='-rpath $libdir' - archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - ld_shlibs=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = no; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_direct_absolute=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - file_list_spec='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - export_dynamic_flag_spec='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec='$convenience' - archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes=yes - ;; - - darwin* | rhapsody*) - - - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - whole_archive_flag_spec='' - link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=echo - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else - ld_shlibs=no - fi - - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - *) - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo(void) {} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - inherit_rpath=yes - link_all_deplibs=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - hardcode_shlibpath_var=no - hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - else - ld_shlibs=no - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - archive_cmds_need_lc='no' - hardcode_libdir_separator=: - ;; - - solaris*) - no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' - fi - ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' - hardcode_libdir_separator=':' - link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' - ;; - esac - fi - fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -$as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no - -with_gnu_ld=$with_gnu_ld - - - - - - - - - - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - pic_flag=$lt_prog_compiler_pic - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - archive_cmds_need_lc=no - else - archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 -$as_echo "$archive_cmds_need_lc" >&6; } - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` - else - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[lt_foo]++; } - if (lt_freq[lt_foo] == 1) { print lt_foo; } -}'` - sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[4-9]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[123]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - # Handle Gentoo/FreeBSD as it was Linux - case $host_vendor in - gentoo) - version_type=linux ;; - *) - version_type=freebsd-$objformat ;; - esac - - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - linux) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - need_lib_prefix=no - need_version=no - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -interix[3-9]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # Some binutils ld are patched to set DT_RUNPATH - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || - test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -$as_echo "$hardcode_action" >&6; } - -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_shl_load=yes -else - ac_cv_lib_dld_shl_load=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -$as_echo_n "checking for dlopen in -lsvld... " >&6; } -if ${ac_cv_lib_svld_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_svld_dlopen=yes -else - ac_cv_lib_svld_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -$as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -$as_echo_n "checking for dld_link in -ldld... " >&6; } -if ${ac_cv_lib_dld_dld_link+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_dld_link=yes -else - ac_cv_lib_dld_dld_link=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -$as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -$as_echo_n "checking whether a program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line 9561 "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -$as_echo "$lt_cv_dlopen_self" >&6; } - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self_static+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line 9657 "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - - - - - - - - - - - - - - - - -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi - - - - - - - - - - - - - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } - - - - -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - - - - - - - - - - - - - ac_config_commands="$ac_config_commands libtool" - - - - -# Only expand once: - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -######### -# Enable large file support (if special flags are necessary) -# -# Check whether --enable-largefile was given. -if test "${enable_largefile+set}" = set; then : - enableval=$enable_largefile; -fi - -if test "$enable_largefile" != no; then - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 -$as_echo_n "checking for special C compiler options needed for large files... " >&6; } -if ${ac_cv_sys_largefile_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_sys_largefile_CC=no - if test "$GCC" != yes; then - ac_save_CC=$CC - while :; do - # IRIX 6.2 and later do not support large files by default, - # so use the C compiler's -n32 option if that helps. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF - if ac_fn_c_try_compile "$LINENO"; then : - break -fi -rm -f core conftest.err conftest.$ac_objext - CC="$CC -n32" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_largefile_CC=' -n32'; break -fi -rm -f core conftest.err conftest.$ac_objext - break - done - CC=$ac_save_CC - rm -f conftest.$ac_ext - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 -$as_echo "$ac_cv_sys_largefile_CC" >&6; } - if test "$ac_cv_sys_largefile_CC" != no; then - CC=$CC$ac_cv_sys_largefile_CC - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 -$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } -if ${ac_cv_sys_file_offset_bits+:} false; then : - $as_echo_n "(cached) " >&6 -else - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_file_offset_bits=no; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define _FILE_OFFSET_BITS 64 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_file_offset_bits=64; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cv_sys_file_offset_bits=unknown - break -done -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 -$as_echo "$ac_cv_sys_file_offset_bits" >&6; } -case $ac_cv_sys_file_offset_bits in #( - no | unknown) ;; - *) -cat >>confdefs.h <<_ACEOF -#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits -_ACEOF -;; -esac -rm -rf conftest* - if test $ac_cv_sys_file_offset_bits = unknown; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 -$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } -if ${ac_cv_sys_large_files+:} false; then : - $as_echo_n "(cached) " >&6 -else - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_large_files=no; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define _LARGE_FILES 1 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_large_files=1; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cv_sys_large_files=unknown - break -done -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 -$as_echo "$ac_cv_sys_large_files" >&6; } -case $ac_cv_sys_large_files in #( - no | unknown) ;; - *) -cat >>confdefs.h <<_ACEOF -#define _LARGE_FILES $ac_cv_sys_large_files -_ACEOF -;; -esac -rm -rf conftest* - fi - - -fi - - -######### -# Check for needed/wanted data types -ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" -if test "x$ac_cv_type_int8_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT8_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" -if test "x$ac_cv_type_int16_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT16_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" -if test "x$ac_cv_type_int32_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT32_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default" -if test "x$ac_cv_type_int64_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT64_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" -if test "x$ac_cv_type_intptr_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INTPTR_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" -if test "x$ac_cv_type_uint8_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT8_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" -if test "x$ac_cv_type_uint16_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT16_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" -if test "x$ac_cv_type_uint32_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT32_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" -if test "x$ac_cv_type_uint64_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT64_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" -if test "x$ac_cv_type_uintptr_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINTPTR_T 1 -_ACEOF - - -fi - - -######### -# Check for needed/wanted headers -for ac_header in sys/types.h stdlib.h stdint.h inttypes.h malloc.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -######### -# Figure out whether or not we have these functions -# -for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -######### -# By default, we use the amalgamation (this may be changed below...) -# -USE_AMALGAMATION=1 - -######### -# Figure out all the name of a working tclsh and parameters needed to compile against Tcl. -# The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. -# - -# Check whether --with-tclsh was given. -if test "${with_tclsh+set}" = set; then : - withval=$with_tclsh; -fi - - -# Check whether --with-tcl was given. -if test "${with_tcl+set}" = set; then : - withval=$with_tcl; -fi - -# Check whether --enable-tcl was given. -if test "${enable_tcl+set}" = set; then : - enableval=$enable_tcl; use_tcl=$enableval -else - use_tcl=yes -fi - -original_use_tcl=${use_tcl} -if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then - for ac_prog in tclsh8.6 tclsh tclsh9.0 -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_TCLSH_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$TCLSH_CMD"; then - ac_cv_prog_TCLSH_CMD="$TCLSH_CMD" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_TCLSH_CMD="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -TCLSH_CMD=$ac_cv_prog_TCLSH_CMD -if test -n "$TCLSH_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_CMD" >&5 -$as_echo "$TCLSH_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$TCLSH_CMD" && break -done -test -n "$TCLSH_CMD" || TCLSH_CMD="none" - - with_tclsh=${TCLSH_CMD} -fi -if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then - TCLSH_CMD=${with_tclsh} - { $as_echo "$as_me:${as_lineno-$LINENO}: result: using tclsh at \"$TCLSH_CMD\"" >&5 -$as_echo "using tclsh at \"$TCLSH_CMD\"" >&6; } - if test x"${use_tcl}" = "xyes"; then - with_tcl=`${with_tclsh} <${srcdir}/tool/find_tclconfig.tcl` - if test x"${with_tcl}" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}" >&5 -$as_echo "$TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $TCLSH_CMD is unable to recommend a tclConfig.sh" >&5 -$as_echo "$as_me: WARNING: $TCLSH_CMD is unable to recommend a tclConfig.sh" >&2;} - use_tcl=no - fi - fi -fi -if test x"${use_tcl}" = "xyes"; then - if test x"${with_tcl}" != x; then - if test -r ${with_tcl}/tclConfig.sh; then - tclconfig="${with_tcl}/tclConfig.sh" - else - for i in tcl8.6 tcl9.0 lib; do - if test -r ${with_tcl}/$i/tclConfig.sh; then - tclconfig=${with_tcl}/$i/tclConfig.sh - break - fi - done - fi - if test ! -r "${tclconfig}"; then - as_fn_error $? "no tclConfig.sh file found under ${with_tcl}" "$LINENO" 5 - fi - else - # If we have not yet found a tclConfig.sh file, look in $libdir whic is - # set automatically by autoconf or by the --prefix command-line option. - # See https://sqlite.org/forum/forumpost/e04e693439a22457 - libdir=${prefix}/lib - if test -r ${libdir}/tclConfig.sh; then - tclconfig=${libdir}/tclConfig.sh - else - for i in tcl8.6 tcl9.0 lib; do - if test -r ${libdir}/$i/tclConfig.sh; then - tclconfig=${libdir}/$i/tclConfig.sh - break - fi - done - fi - if test ! -r "${tclconfig}"; then - as_fn_error $? "cannot find a usable tclConfig.sh file. - Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. - SQLite does not use TCL internally, but TCL is required to build SQLite - from canonical sources and TCL is required for testing." "$LINENO" 5 - fi - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading TCL configuration from ${tclconfig}" >&5 -$as_echo "loading TCL configuration from ${tclconfig}" >&6; } - . ${tclconfig} - - - - # There are lots of other configuration variables that are provided by the - # tclConfig.sh file and that could be included here. But as of right now, - # TCL_LIB_SPEC is the only what that the Makefile uses. - HAVE_TCL=1 -elif test x"${original_use_tcl}" = "xno"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to run tests because of --disable-tcl" >&5 -$as_echo "unable to run tests because of --disable-tcl" >&6; } - HAVE_TCL=0 -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to run tests because no tclConfig.sh file could be located" >&5 -$as_echo "unable to run tests because no tclConfig.sh file could be located" >&6; } - HAVE_TCL=0 -fi - -if test x"$TCLSH_CMD" == x; then - TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION} - if test ! -x ${TCLSH_CMD}; then - TCLSH_CMD_2=${TCL_EXEC_PREFIX}/bin/tclsh - if test ! -x ${TCLSH_CMD_2}; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find a usable tclsh at either ${TCLSH_CMD} or ${TCLSH_CMD_2}" >&5 -$as_echo "$as_me: WARNING: cannot find a usable tclsh at either ${TCLSH_CMD} or ${TCLSH_CMD_2}" >&2;} - TCLSH_CMD=none - else - TCLSH_CMD=${TCLSH_CMD_2} - fi - fi -fi -if test "$TCLSH_CMD" = "none"; then - # If we can't find a local tclsh, then building the amalgamation will fail. - # We act as though --disable-amalgamation has been used. - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Warning: can't find tclsh - defaulting to non-amalgamation build." >&5 -$as_echo "$as_me: WARNING: Warning: can't find tclsh - defaulting to non-amalgamation build." >&2;} - USE_AMALGAMATION=0 - TCLSH_CMD="tclsh" -fi - - - -if test "x${TCLLIBDIR+set}" != "xset" ; then - for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do - if test -d $i ; then - TCLLIBDIR=$i - break - fi - done - TCLLIBDIR="${TCLLIBDIR}/sqlite3" -fi - -######### -# Set up options for running tests. -# -# Check whether --enable-test-status was given. -if test "${enable_test_status+set}" = set; then : - enableval=$enable_test_status; use_vt100=$enableval -else - use_vt100=no -fi - -if test $use_vt100 != no; then - TSTRNNR_OPTS=--status -else - TSTRNNR_OPTS= -fi - - - -######### -# Set up an appropriate program prefix -# -if test "$program_prefix" = "NONE"; then - program_prefix="" -fi - - -VERSION=`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'` -{ $as_echo "$as_me:${as_lineno-$LINENO}: Version set to $VERSION" >&5 -$as_echo "$as_me: Version set to $VERSION" >&6;} - -RELEASE=`cat $srcdir/VERSION` -{ $as_echo "$as_me:${as_lineno-$LINENO}: Release set to $RELEASE" >&5 -$as_echo "$as_me: Release set to $RELEASE" >&6;} - - -########## -# Handle --with-wasi-sdk=DIR -# -# This must be early because it changes the toolchain. -# - -# Check whether --with-wasi-sdk was given. -if test "${with_wasi_sdk+set}" = set; then : - withval=$with_wasi_sdk; with_wasisdk=${withval} -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for WASI SDK directory" >&5 -$as_echo_n "checking for WASI SDK directory... " >&6; } -if ${ac_cv_c_wasi_sdk+:} false; then : - $as_echo_n "(cached) " >&6 -else - - # First check to see if --with-tcl was specified. - if test x"${with_wasi_sdk}" != x ; then - if ! test -d "${with_wasi_sdk}" ; then - as_fn_error $? "${with_wasi_sdk} directory doesn't exist" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL" >&5 -$as_echo "${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL" >&6; } - use_wasi_sdk=yes - else - use_wasi_sdk=no - fi - -fi - -if test "${use_wasi_sdk}" = "no" ; then - HAVE_WASI_SDK="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - HAVE_WASI_SDK=1 -# Changing --host and --target have no effect here except to possibly -# cause confusion. autoconf has finished processing them by this -# point. -# -# host_alias=wasm32-wasi -# target=wasm32-wasi -# -# Merely changing CC and LD to the wasi-sdk's is enough to get -# sqlite3.o building in WASM format. - CC="${with_wasi_sdk}/bin/clang" - LD="${with_wasi_sdk}/bin/wasm-ld" - RANLIB="${with_wasi_sdk}/bin/llvm-ranlib" - cross_compiling=yes - enable_threadsafe=no - use_tcl=no - enable_tcl=no - # libtool is apparently hard-coded to use gcc for linking DLLs, so - # we disable the DLL build... - enable_shared=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi - - - -######### -# Locate a compiler for the build machine. This compiler should -# generate command-line programs that run on the build machine. -# -if test x"$cross_compiling" = xno; then - BUILD_CC=$CC - BUILD_CFLAGS=$CFLAGS -else - if test "${BUILD_CC+set}" != set; then - for ac_prog in gcc cc cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BUILD_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$BUILD_CC"; then - ac_cv_prog_BUILD_CC="$BUILD_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_BUILD_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -BUILD_CC=$ac_cv_prog_BUILD_CC -if test -n "$BUILD_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_CC" >&5 -$as_echo "$BUILD_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$BUILD_CC" && break -done - - fi - if test "${BUILD_CFLAGS+set}" != set; then - BUILD_CFLAGS="-g" - fi -fi - - -########## -# Do we want to support multithreaded use of sqlite -# -# Check whether --enable-threadsafe was given. -if test "${enable_threadsafe+set}" = set; then : - enableval=$enable_threadsafe; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support threadsafe operation" >&5 -$as_echo_n "checking whether to support threadsafe operation... " >&6; } -if test "$enable_threadsafe" = "no"; then - SQLITE_THREADSAFE=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - SQLITE_THREADSAFE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi - - -if test "$SQLITE_THREADSAFE" = "1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 -$as_echo_n "checking for library containing pthread_create... " >&6; } -if ${ac_cv_search_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_create (); -int -main () -{ -return pthread_create (); - ; - return 0; -} -_ACEOF -for ac_lib in '' pthread; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_pthread_create=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_pthread_create+:} false; then : - break -fi -done -if ${ac_cv_search_pthread_create+:} false; then : - -else - ac_cv_search_pthread_create=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 -$as_echo "$ac_cv_search_pthread_create" >&6; } -ac_res=$ac_cv_search_pthread_create -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_mutexattr_init" >&5 -$as_echo_n "checking for library containing pthread_mutexattr_init... " >&6; } -if ${ac_cv_search_pthread_mutexattr_init+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_mutexattr_init (); -int -main () -{ -return pthread_mutexattr_init (); - ; - return 0; -} -_ACEOF -for ac_lib in '' pthread; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_pthread_mutexattr_init=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_pthread_mutexattr_init+:} false; then : - break -fi -done -if ${ac_cv_search_pthread_mutexattr_init+:} false; then : - -else - ac_cv_search_pthread_mutexattr_init=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_mutexattr_init" >&5 -$as_echo "$ac_cv_search_pthread_mutexattr_init" >&6; } -ac_res=$ac_cv_search_pthread_mutexattr_init -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - -########## -# Do we want to support release -# -# Check whether --enable-releasemode was given. -if test "${enable_releasemode+set}" = set; then : - enableval=$enable_releasemode; -else - enable_releasemode=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support shared library linked as release mode or not" >&5 -$as_echo_n "checking whether to support shared library linked as release mode or not... " >&6; } -if test "$enable_releasemode" = "no"; then - ALLOWRELEASE="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - ALLOWRELEASE="-release `cat $srcdir/VERSION`" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi - - -########## -# Do we want temporary databases in memory -# -# Check whether --enable-tempstore was given. -if test "${enable_tempstore+set}" = set; then : - enableval=$enable_tempstore; -else - enable_tempstore=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use an in-ram database for temporary tables" >&5 -$as_echo_n "checking whether to use an in-ram database for temporary tables... " >&6; } -case "$enable_tempstore" in - never ) - TEMP_STORE=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: never" >&5 -$as_echo "never" >&6; } - ;; - no ) - TEMP_STORE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - yes ) - TEMP_STORE=2 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - ;; - always ) - TEMP_STORE=3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: always" >&5 -$as_echo "always" >&6; } - ;; - * ) - TEMP_STORE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; -esac - - - -########### -# Lots of things are different if we are compiling for Windows using -# the CYGWIN environment. So check for that special case and handle -# things accordingly. -# -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if executables have the .exe suffix" >&5 -$as_echo_n "checking if executables have the .exe suffix... " >&6; } -if test "$config_BUILD_EXEEXT" = ".exe"; then - CYGWIN=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5 -$as_echo "unknown" >&6; } -fi -if test "$CYGWIN" != "yes"; then - -case $host_os in - *cygwin* ) CYGWIN=yes;; - * ) CYGWIN=no;; -esac - -fi -if test "$CYGWIN" = "yes"; then - BUILD_EXEEXT=.exe -else - BUILD_EXEEXT=$EXEEXT -fi -if test x"$cross_compiling" = xno; then - TARGET_EXEEXT=$BUILD_EXEEXT -else - TARGET_EXEEXT=$config_TARGET_EXEEXT -fi -if test "$TARGET_EXEEXT" = ".exe"; then - SQLITE_OS_UNIX=0 - SQLITE_OS_WIN=1 - CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1" -else - SQLITE_OS_UNIX=1 - SQLITE_OS_WIN=0 - CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1" -fi - - - - - - -########## -# Figure out what C libraries are required to compile programs -# that use "readline()" library. -# -TARGET_READLINE_LIBS="" -TARGET_READLINE_INC="" -TARGET_HAVE_READLINE=0 -TARGET_HAVE_EDITLINE=0 -# Check whether --enable-editline was given. -if test "${enable_editline+set}" = set; then : - enableval=$enable_editline; with_editline=$enableval -else - with_editline=auto -fi - -# Check whether --enable-readline was given. -if test "${enable_readline+set}" = set; then : - enableval=$enable_readline; with_readline=$enableval -else - with_readline=auto -fi - - -if test x"$with_editline" != xno; then - sLIBS=$LIBS - LIBS="" - TARGET_HAVE_EDITLINE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing readline" >&5 -$as_echo_n "checking for library containing readline... " >&6; } -if ${ac_cv_search_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -for ac_lib in '' edit; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_readline=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_readline+:} false; then : - break -fi -done -if ${ac_cv_search_readline+:} false; then : - -else - ac_cv_search_readline=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_readline" >&5 -$as_echo "$ac_cv_search_readline" >&6; } -ac_res=$ac_cv_search_readline -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - with_readline=no -else - TARGET_HAVE_EDITLINE=0 -fi - - TARGET_READLINE_LIBS=$LIBS - LIBS=$sLIBS -fi -if test x"$with_readline" != xno; then - found="yes" - - -# Check whether --with-readline-lib was given. -if test "${with_readline_lib+set}" = set; then : - withval=$with_readline_lib; with_readline_lib=$withval -else - with_readline_lib="auto" -fi - - if test "x$with_readline_lib" = xauto; then - save_LIBS="$LIBS" - LIBS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5 -$as_echo_n "checking for library containing tgetent... " >&6; } -if ${ac_cv_search_tgetent+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char tgetent (); -int -main () -{ -return tgetent (); - ; - return 0; -} -_ACEOF -for ac_lib in '' readline ncurses curses termcap; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_tgetent=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_tgetent+:} false; then : - break -fi -done -if ${ac_cv_search_tgetent+:} false; then : - -else - ac_cv_search_tgetent=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tgetent" >&5 -$as_echo "$ac_cv_search_tgetent" >&6; } -ac_res=$ac_cv_search_tgetent -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - term_LIBS="$LIBS" -else - term_LIBS="" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - TARGET_READLINE_LIBS="-lreadline" -else - found="no" -fi - - TARGET_READLINE_LIBS="$TARGET_READLINE_LIBS $term_LIBS" - LIBS="$save_LIBS" - else - TARGET_READLINE_LIBS="$with_readline_lib" - fi - - -# Check whether --with-readline-inc was given. -if test "${with_readline_inc+set}" = set; then : - withval=$with_readline_inc; with_readline_inc=$withval -else - with_readline_inc="auto" -fi - - if test "x$with_readline_inc" = xauto; then - ac_fn_c_check_header_mongrel "$LINENO" "readline.h" "ac_cv_header_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_h" = xyes; then : - found="yes" -else - - found="no" - if test "$cross_compiling" != yes; then - for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do - for subdir in include include/readline; do - as_ac_File=`$as_echo "ac_cv_file_$dir/$subdir/readline.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $dir/$subdir/readline.h" >&5 -$as_echo_n "checking for $dir/$subdir/readline.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$dir/$subdir/readline.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - found=yes -fi - - if test "$found" = "yes"; then - TARGET_READLINE_INC="-I$dir/$subdir" - break - fi - done - test "$found" = "yes" && break - done - fi - -fi - - - else - TARGET_READLINE_INC="$with_readline_inc" - fi - - if test x"$found" = xno; then - TARGET_READLINE_LIBS="" - TARGET_READLINE_INC="" - TARGET_HAVE_READLINE=0 - else - TARGET_HAVE_READLINE=1 - fi -fi - -# Check whether --with-linenoise was given. -if test "${with_linenoise+set}" = set; then : - withval=$with_linenoise; with_linenoise=$withval -else - with_linenoise="no" -fi - -if test "x$with_linenoise" != "xno"; then - TARGET_HAVE_READLINE=0 - TARGET_HAVE_EDITLINE=0 - TARGET_HAVE_LINENOISE=1 - TARGET_READLINE_INC="-I${with_linenoise}" - TARGET_READLINE_LIBS="${with_linenoise}/linenoise.c" - echo "using linenoise source code at ${with_linenoise}" -else - TARGET_HAVE_LINENOISE=0 - echo "not using linenoise" -fi - - - - - - - - -########## -# Figure out what C libraries are required to compile programs -# that use "fdatasync()" function. -# -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fdatasync" >&5 -$as_echo_n "checking for library containing fdatasync... " >&6; } -if ${ac_cv_search_fdatasync+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char fdatasync (); -int -main () -{ -return fdatasync (); - ; - return 0; -} -_ACEOF -for ac_lib in '' rt; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_fdatasync=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_fdatasync+:} false; then : - break -fi -done -if ${ac_cv_search_fdatasync+:} false; then : - -else - ac_cv_search_fdatasync=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fdatasync" >&5 -$as_echo "$ac_cv_search_fdatasync" >&6; } -ac_res=$ac_cv_search_fdatasync -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - -######### -# check for debug enabled -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : - enableval=$enable_debug; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build type" >&5 -$as_echo_n "checking build type... " >&6; } -if test "${enable_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5 -$as_echo "debug" >&6; } -else - TARGET_DEBUG="-DNDEBUG" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: release" >&5 -$as_echo "release" >&6; } -fi - - -######### -# See whether we should use the amalgamation to build - -# Check whether --enable-amalgamation was given. -if test "${enable_amalgamation+set}" = set; then : - enableval=$enable_amalgamation; -fi - -if test "${enable_amalgamation}" = "no" ; then - USE_AMALGAMATION=0 -fi - - -######### -# Look for zlib. Only needed by extensions and by the sqlite3.exe shell -for ac_header in zlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ZLIB_H 1 -_ACEOF - -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5 -$as_echo_n "checking for library containing deflate... " >&6; } -if ${ac_cv_search_deflate+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char deflate (); -int -main () -{ -return deflate (); - ; - return 0; -} -_ACEOF -for ac_lib in '' z; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_deflate=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_deflate+:} false; then : - break -fi -done -if ${ac_cv_search_deflate+:} false; then : - -else - ac_cv_search_deflate=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflate" >&5 -$as_echo "$ac_cv_search_deflate" >&6; } -ac_res=$ac_cv_search_deflate -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - HAVE_ZLIB="-DSQLITE_HAVE_ZLIB=1" -else - HAVE_ZLIB="" -fi - - - -######### -# See whether we should allow loadable extensions -# Check whether --enable-load-extension was given. -if test "${enable_load_extension+set}" = set; then : - enableval=$enable_load_extension; -else - enable_load_extension=yes -fi - -if test "${enable_load_extension}" = "yes" ; then - OPT_FEATURE_FLAGS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 -$as_echo_n "checking for library containing dlopen... " >&6; } -if ${ac_cv_search_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dl; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_dlopen=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_dlopen+:} false; then : - break -fi -done -if ${ac_cv_search_dlopen+:} false; then : - -else - ac_cv_search_dlopen=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 -$as_echo "$ac_cv_search_dlopen" >&6; } -ac_res=$ac_cv_search_dlopen -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" -fi - -########## -# Do we want to support math functions -# -# Check whether --enable-math was given. -if test "${enable_math+set}" = set; then : - enableval=$enable_math; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support math functions" >&5 -$as_echo_n "checking whether to support math functions... " >&6; } -if test "$enable_math" = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ceil" >&5 -$as_echo_n "checking for library containing ceil... " >&6; } -if ${ac_cv_search_ceil+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char ceil (); -int -main () -{ -return ceil (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_ceil=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_ceil+:} false; then : - break -fi -done -if ${ac_cv_search_ceil+:} false; then : - -else - ac_cv_search_ceil=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ceil" >&5 -$as_echo "$ac_cv_search_ceil" >&6; } -ac_res=$ac_cv_search_ceil -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - -########## -# Do we want to support JSON functions -# -# Check whether --enable-json was given. -if test "${enable_json+set}" = set; then : - enableval=$enable_json; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support JSON functions" >&5 -$as_echo_n "checking whether to support JSON functions... " >&6; } -if test "$enable_json" = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi - -######## -# The --enable-all argument is short-hand to enable -# multiple extensions. -# Check whether --enable-all was given. -if test "${enable_all+set}" = set; then : - enableval=$enable_all; -fi - - -########## -# Do we want to support memsys3 and/or memsys5 -# -# Check whether --enable-memsys5 was given. -if test "${enable_memsys5+set}" = set; then : - enableval=$enable_memsys5; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5 -$as_echo_n "checking whether to support MEMSYS5... " >&6; } -if test "${enable_memsys5}" = "yes"; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -# Check whether --enable-memsys3 was given. -if test "${enable_memsys3+set}" = set; then : - enableval=$enable_memsys3; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 -$as_echo_n "checking whether to support MEMSYS3... " >&6; } -if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable Full Text Search extensions -# Check whether --enable-fts3 was given. -if test "${enable_fts3+set}" = set; then : - enableval=$enable_fts3; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS3" >&5 -$as_echo_n "checking whether to support FTS3... " >&6; } -if test "${enable_fts3}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -# Check whether --enable-fts4 was given. -if test "${enable_fts4+set}" = set; then : - enableval=$enable_fts4; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS4" >&5 -$as_echo_n "checking whether to support FTS4... " >&6; } -if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 -$as_echo_n "checking for library containing log... " >&6; } -if ${ac_cv_search_log+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char log (); -int -main () -{ -return log (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_log=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_log+:} false; then : - break -fi -done -if ${ac_cv_search_log+:} false; then : - -else - ac_cv_search_log=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5 -$as_echo "$ac_cv_search_log" >&6; } -ac_res=$ac_cv_search_log -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -# Check whether --enable-fts5 was given. -if test "${enable_fts5+set}" = set; then : - enableval=$enable_fts5; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS5" >&5 -$as_echo_n "checking whether to support FTS5... " >&6; } -if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 -$as_echo_n "checking for library containing log... " >&6; } -if ${ac_cv_search_log+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char log (); -int -main () -{ -return log (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_log=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_log+:} false; then : - break -fi -done -if ${ac_cv_search_log+:} false; then : - -else - ac_cv_search_log=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5 -$as_echo "$ac_cv_search_log" >&6; } -ac_res=$ac_cv_search_log -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable the LIMIT clause on UPDATE and DELETE -# statements. -# Check whether --enable-update-limit was given. -if test "${enable_update_limit+set}" = set; then : - enableval=$enable_update_limit; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support LIMIT on UPDATE and DELETE statements" >&5 -$as_echo_n "checking whether to support LIMIT on UPDATE and DELETE statements... " >&6; } -if test "${enable_update_limit}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable GEOPOLY -# Check whether --enable-geopoly was given. -if test "${enable_geopoly+set}" = set; then : - enableval=$enable_geopoly; enable_geopoly=yes -else - enable_geopoly=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support GEOPOLY" >&5 -$as_echo_n "checking whether to support GEOPOLY... " >&6; } -if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" - enable_rtree=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable RTREE -# Check whether --enable-rtree was given. -if test "${enable_rtree+set}" = set; then : - enableval=$enable_rtree; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support RTREE" >&5 -$as_echo_n "checking whether to support RTREE... " >&6; } -if test "${enable_rtree}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable the SESSION extension -# Check whether --enable-session was given. -if test "${enable_session+set}" = set; then : - enableval=$enable_session; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support SESSION" >&5 -$as_echo_n "checking whether to support SESSION... " >&6; } -if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter -for option in $CFLAGS $CPPFLAGS -do - case $option in - -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; - -DSQLITE_ENABLE*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; - esac -done - - - -# attempt to remove any OMITS and ENABLES from the $(CFLAGS) parameter -ac_temp_CFLAGS="" -for option in $CFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_CFLAGS="$ac_temp_CFLAGS $option";; - esac -done -CFLAGS=$ac_temp_CFLAGS - - -# attempt to remove any OMITS and ENABLES from the $(CPPFLAGS) parameter -ac_temp_CPPFLAGS="" -for option in $CPPFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_CPPFLAGS="$ac_temp_CPPFLAGS $option";; - esac -done -CPPFLAGS=$ac_temp_CPPFLAGS - - -# attempt to remove any OMITS and ENABLES from the $(BUILD_CFLAGS) parameter -ac_temp_BUILD_CFLAGS="" -for option in $BUILD_CFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_BUILD_CFLAGS="$ac_temp_BUILD_CFLAGS $option";; - esac -done -BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS - - -######### -# See whether we should use GCOV -# Check whether --enable-gcov was given. -if test "${enable_gcov+set}" = set; then : - enableval=$enable_gcov; -fi - -if test "${use_gcov}" = "yes" ; then - USE_GCOV=1 -else - USE_GCOV=0 -fi - - -######### -# Enable/disabled amalagamation line macros -######## -AMALGAMATION_LINE_MACROS=--linemacros=0 -if test "${amalgamation_line_macros}" = "yes" ; then - AMALGAMATION_LINE_MACROS=--linemacros=1 -fi -if test "${amalgamation_line_macros}" = "no" ; then - AMALGAMATION_LINE_MACROS=--linemacros=0 -fi - - -######### -# Output the config header -ac_config_headers="$ac_config_headers sqlite_cfg.h" - - -######### -# Generate the output files. -# - -ac_config_files="$ac_config_files Makefile sqlite3.pc" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by sqlite $as_me 3.47.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to the package provider." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -sqlite config.status 3.47.0 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' -macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' -enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' -enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' -pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' -host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' -host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' -host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' -build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' -build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' -build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' -SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' -Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' -GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' -EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' -FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' -LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' -NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' -LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' -ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' -exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' -lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' -reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' -AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' -STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' -RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' -CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' -compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' -GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' -objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' -SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' -ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' -need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' -LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' -OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' -libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' -module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' -fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' -need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' -version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' -runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' -libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' -soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' -finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' -old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' -striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# Quote evaled strings. -for var in SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -OBJDUMP \ -deplibs_check_method \ -file_magic_cmd \ -AR \ -AR_FLAGS \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -SHELL \ -ECHO \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_wl \ -lt_prog_compiler_pic \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_flag_spec_ld \ -hardcode_libdir_separator \ -fix_srcfile_path \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -finish_eval \ -old_striplib \ -striplib; do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec; do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Fix-up fallback echo if it was mangled by the above quoting rules. -case \$lt_ECHO in -*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` - ;; -esac - -ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile' - - - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; - "sqlite_cfg.h") CONFIG_HEADERS="$CONFIG_HEADERS sqlite_cfg.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "sqlite3.pc") CONFIG_FILES="$CONFIG_FILES sqlite3.pc" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "libtool":C) - - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The names of the tagged configurations supported by this script. -available_tags="" - -# ### BEGIN LIBTOOL CONFIG - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# An object symbol dumper. -OBJDUMP=$lt_OBJDUMP - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that does not interpret backslashes. -ECHO=$lt_ECHO - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# If ld is used when linking, flag to hardcode \$libdir into a binary -# during linking. This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path=$lt_fix_srcfile_path - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain="$ac_aux_dir/ltmain.sh" - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - case $xsi_shell in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac -} - -# func_basename file -func_basename () -{ - func_basename_result="${1##*/}" -} - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}" -} - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -func_stripname () -{ - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"} -} - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=${1%%=*} - func_opt_split_arg=${1#*=} -} - -# func_lo2o object -func_lo2o () -{ - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=${1%.*}.lo -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=$(( $* )) -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=${#1} -} - -_LT_EOF - ;; - *) # Bourne compatible functions. - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` -} - - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; - esac -} - -# sed scripts: -my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' -my_sed_long_arg='1s/^-[^=]*=//' - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` - func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` -} - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "$@"` -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` -} - -_LT_EOF -esac - -case $lt_shell_append in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$1+=\$2" -} -_LT_EOF - ;; - *) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$1=\$$1\$2" -} - -_LT_EOF - ;; - esac - - - sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - +#!/bin/sh +dir="`dirname "$0"`/autosetup" +#@@INITCHECK@@# +WRAPPER="$0"; export WRAPPER; exec "`"$dir/autosetup-find-tclsh"`" "$dir/autosetup" "$@" diff --git a/manifest b/manifest index 5a40bbd21d..e94222760f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smemory\sleak\sin\ssqlite3expert.c\sintroduced\sby\s[f1d76c86]. -D 2024-09-24T15:11:34.516 +C Initial\spristine\sautosetup\sbits. +D 2024-09-24T21:08:49.699 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,6 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 +F auto.def 1f07836fdcf7c5048d8d9e60955bfb568989c36fa94dd1e5953fd836fa11a033 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -33,9 +34,26 @@ F autoconf/tea/tclconfig/tcl.m4 c6e5f2fc7178f40d087403daa044ef3b86a8e30793f3b121 F autoconf/tea/win/makefile.vc 2c478a9a962e48b2bf9062734e04d7c63c556e217095419173f9d7938d7d78f7 F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea00342d1a1a7eaa19cb F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5 +F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 +F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e +F autosetup/autosetup 7d7fe206980a6d04113f85e570229953f7e0cd5ef31bb40868653b976f8698af x +F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x +F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x +F autosetup/autosetup-find-tclsh c5053419348cdd1aba824c3701bd97392d987b948c1bd748b32f11bbca2c0d8a x +F autosetup/autosetup-test-tclsh 749d20defee533a3842139df47d700fc7a334a5da7bdbd444ae5331744b06c5f +F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034b10a7b +F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360 +F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 +F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 +F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 +F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d +F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba +F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb +F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f +F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 49523f0a070b583cea040d26eff53a65fb0893eca4663b1343a4d5a9a964da53 x +F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F configure.ac a100ebf7a07f5dedd319ef547dd467d1676ed059b85a7877aa9c44ac309f7000 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -2213,8 +2231,11 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f1d76c8636866424fe0b57d8814b8bb1a0ed4e2ca1b75d8e308d4b962ad8dc3b -R 3c493af72ec7c0caf9ac1da3817622db -U dan -Z 3984c94792299f2aa3da5c0fd5ebea46 +P 42bb941584a1ac922ee6b0b6ecadce71c9259555563cf49913a6f820f3f9b887 +R 84d3f178c5c16f5b308246d776945a8b +T *branch * autosetup +T *sym-autosetup * +T -sym-trunk * Cancelled\sby\sbranch. +U stephan +Z 8191a33bd76375a0780db52c6f42efff # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f9ccf18fa5..8defc94fe6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42bb941584a1ac922ee6b0b6ecadce71c9259555563cf49913a6f820f3f9b887 +dfb1e7f0cce9bc79c43eee7208cad0e2df562b2bc9705d3a36fd78f86c75495b From f4321fff360a62ab8b3bea0cee5c99577c907b65 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 01:39:39 +0000 Subject: [PATCH 003/522] Get skeleton auto.def running, but it doesn't really do much except some standard boilerplate stuff. FossilOrigin-Name: e707634cf755346752bb83b7be5d0c683e39d6e0a497846019323fed31c08b9d --- auto.def | 944 ++++++++++++++++++++++++++++++++++++- autosetup/hwaci-common.tcl | 324 +++++++++++++ configure.ac | 165 +++---- manifest | 18 +- manifest.uuid | 2 +- 5 files changed, 1356 insertions(+), 97 deletions(-) create mode 100644 autosetup/hwaci-common.tcl diff --git a/auto.def b/auto.def index bed7e333f9..32cb94185b 100644 --- a/auto.def +++ b/auto.def @@ -1,10 +1,944 @@ -# Initial auto.def created by 'autosetup --init=make' +# Created by migrate-autoconf - fix items marked XXX -use cc +use cc cc-shared cc-lib hwaci-common +set DUMP_DEFINES_FILE defines.list -# Add any user options here options { + with-tclsh:PATHNAME => {Full pathname of tclsh to use} + with-tcl:DIR => {Directory containing tclConfig.sh} + tcl=1 => {building accessory programs that require TCL-dev} + test-status=0 => {status of tests} + with-wasi-sdk:=/opt/wasi-sdk => {Path to the wasi-dsk} + threadsafe=1 => mutexing + releasemode=0 => {libtool link to release mode} + tempstore=0 => {an in-ram database for temporary tables never,no,yes,always} + editline=0 => {BSD editline support} + readline=1 => {readline support} + with-readline-lib => {readline library} + with-readline-inc => {readline include paths} + with-linenoise:DIR => {} + amalgamation=1 => {Disable the amalgamation and instead build all files separately} + load-extension=1 => {Disable loading of external extensions} + math=1 => {math functions} + json=1 => {JSON functions} + enable-all=0 => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} + enable-memsys5=0 => MEMSYS5 + enable-memsys3=0 => MEMSYS3 + enable-fts3=0 => {Enable the FTS3 extension} + enable-fts4=0 => {Enable the FTS4 extension} + enable-fts5=0 => {Enable the FTS5 extension} + enable-update-limit=0 => {Enable the UPDATE/DELETE LIMIT clause} + enable-geopoly=0 => {Enable the GEOPOLY extension} + enable-rtree=0 => {Enable the RTREE extension} + enable-session=0 => {Enable the SESSION extension} + enable-gcov=0 => {Enable coverage testing using gcov} + dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} } +# debug=0 => {debugging & verbose explain} -make-config-header config.h -make-template Makefile.in +set srcdir $autosetup(srcdir) +puts "srcdir = $srcdir" +set VERSION [readfile $srcdir/VERSION] +puts "VERSION = $VERSION" +puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" + +# +# The build process allows for using a cross-compiler. But the default +# action is to target the same platform that we are running on. The +# configure script needs to discover the following properties of the +# build and target systems: +# +# srcdir +# +# The is the name of the directory that contains the +# "configure" shell script. All source files are +# located relative to this directory. +# +# bindir +# +# The name of the directory where executables should be +# written by the "install" target of the makefile. +# +# program_prefix +# +# Add this prefix to the names of all executables that run +# on the target machine. Default: "" +# +# ENABLE_SHARED +# +# True if shared libraries should be generated. +# +# BUILD_CC +# +# The name of a command that is used to convert C +# source files into executables that run on the build +# platform. +# +# BUILD_CFLAGS +# +# Switches that the build compiler needs in order to construct +# command-line programs. +# +# BUILD_LIBS +# +# Libraries that the build compiler needs in order to construct +# command-line programs. +# +# BUILD_EXEEXT +# +# The filename extension for executables on the build +# platform. "" for Unix and ".exe" for Windows. +# +# TCL_* +# +# Lots of values are read in from the tclConfig.sh script, +# if that script is available. This values are used for +# constructing and installing the TCL extension. +# +# TARGET_READLINE_LIBS +# +# This is the library directives passed to the target linker +# that cause the executable to link against the readline library. +# This might be a switch like "-lreadline" or pathnames of library +# file like "../../src/libreadline.a". +# +# TARGET_READLINE_INC +# +# This variables define the directory that contain header +# files for the readline library. If the compiler is able +# to find on its own, then this can be blank. +# +# TARGET_EXEEXT +# +# The filename extension for executables on the +# target platform. "" for Unix and ".exe" for windows. +# +# This configure.in file is easy to reuse on other projects. Just +# change the argument to AC_INIT. And disable any features that +# you don't need (for example BLT) by erasing or commenting out +# the corresponding code. +# + + +#set sqlite_version_sanity_check `cat $autosetup(srcdir)/VERSION | tr -d '\n'` +# XXX if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then +#user-error "configure script is out of date: +# configure \$PACKAGE_VERSION = $PACKAGE_VERSION +# top level VERSION file = $sqlite_version_sanity_check +#please regen with autoconf" +# XXX fi + +######### +# Programs needed +cc-check-progs install + +######### +# Enable large file support (if special flags are necessary) +cc-check-lfs + +######### +# Check for needed/wanted data types +if {1} { + cc-check-types int8_t int16_t int32_t int64_t intptr_t uint8_t uint16_t uint32_t uint64_t uintptr_t +} + +######### +# Check for needed/wanted headers +cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h + +######### +# Figure out whether or not we have these functions +# +cc-check-functions fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 + +######### +# By default, we use the amalgamation (this may be changed below...) +# +# XXX USE_AMALGAMATION=1 + +if {0} { + ######### + # Figure out all the name of a working tclsh and parameters needed to compile against Tcl. + # The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. + # + # XXX AC_ARG_WITH tclsh AS_HELP_STRING([--with-tclsh=PATHNAME],[full pathname of a tclsh to use]) + # XXX AC_ARG_WITH tcl AS_HELP_STRING([--with-tcl=DIR],[directory containing (tclConfig.sh)]) + # if {![opt-bool tcl]} { + # set use_tcl $enableval + # } else { + # set use_tcl yes + # } + #set original_use_tcl ${use_tcl} + # XXX if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then + # XXX AC_CHECK_PROGS TCLSH_CMD tclsh8.6 tclsh tclsh9.0 none + #set with_tclsh ${TCLSH_CMD} + # XXX fi + # XXX if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then + # XXX TCLSH_CMD=${with_tclsh} + #msg-result "using tclsh at \"$TCLSH_CMD\"" + # XXX if test x"${use_tcl}" = "xyes"; then + #set with_tcl `${with_tclsh} <${srcdir}/tool/find_tclconfig.tcl` + # XXX if test x"${with_tcl}" != x; then + #msg-result "$TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}" + # XXX else + #msg-result Warning: "$TCLSH_CMD is unable to recommend a tclConfig.sh" + #set use_tcl no + # XXX fi + # XXX fi + # XXX fi + # XXX if test x"${use_tcl}" = "xyes"; then + # XXX if test x"${with_tcl}" != x; then + # XXX if test -r ${with_tcl}/tclConfig.sh; then + # set tclconfig "${with_tcl}/tclConfig.sh" + # XXX else + # XXX for i in tcl8.6 tcl9.0 lib; do + # XXX if test -r ${with_tcl}/$i/tclConfig.sh; then + #set tclconfig ${with_tcl}/$i/tclConfig.sh + # XXX break + # XXX fi + # XXX done + # XXX fi + # XXX if test ! -r "${tclconfig}"; then + #user-error "no tclConfig.sh file found under ${with_tcl}" + # XXX fi + # XXX else + # If we have not yet found a tclConfig.sh file, look in $libdir whic is + # set automatically by autoconf or by the --prefix command-line option. + # See https://sqlite.org/forum/forumpost/e04e693439a22457 + #set libdir ${prefix}/lib + # XXX if test -r ${libdir}/tclConfig.sh; then + #set tclconfig ${libdir}/tclConfig.sh + # XXX else + # XXX for i in tcl8.6 tcl9.0 lib; do + # XXX if test -r ${libdir}/$i/tclConfig.sh; then + #set tclconfig ${libdir}/$i/tclConfig.sh + # XXX break + # XXX fi + # XXX done + # XXX fi + # XXX if test ! -r "${tclconfig}"; then + #user-error "cannot find a usable tclConfig.sh file. + # Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. + # SQLite does not use TCL internally, but TCL is required to build SQLite + # from canonical sources and TCL is required for testing." + # XXX fi + # XXX fi + # msg-result "loading TCL configuration from ${tclconfig}" + # XXX . ${tclconfig} + # XXX autosetup automatically substitutes all define'd values + # In general, simply 'define' the value rather than using a shell + # variable and AC_SUBST. + # + # XXX AC_SUBST TCL_INCLUDE_SPEC + # XXX AC_SUBST TCL_LIB_SPEC + # XXX AC_SUBST TCL_STUB_LIB_SPEC + # There are lots of other configuration variables that are provided by the + # tclConfig.sh file and that could be included here. But as of right now, + # TCL_LIB_SPEC is the only what that the Makefile uses. + # XXX HAVE_TCL=1 + # XXX elif test x"${original_use_tcl}" = "xno"; then + # msg-result "unable to run tests because of --disable-tcl" + # XXX HAVE_TCL=0 + # XXX else + # msg-result "unable to run tests because no tclConfig.sh file could be located" + # XXX HAVE_TCL=0 + # XXX fi + # XXX AC_SUBST HAVE_TCL + # XXX if test x"$TCLSH_CMD" == x; then + # XXX TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION} + # XXX if test ! -x ${TCLSH_CMD}; then + # set _2 ${TCL_EXEC_PREFIX}/bin/tclsh + # XXX if test ! -x ${TCLSH_CMD_2}; then + # msg-result Warning: "cannot find a usable tclsh at either ${TCLSH_CMD} or ${TCLSH_CMD_2}" + # XXX TCLSH_CMD=none + # XXX else + # XXX TCLSH_CMD=${TCLSH_CMD_2} + # XXX fi + # XXX fi + # XXX fi + # XXX if test "$TCLSH_CMD" = "none"; then + # If we can't find a local tclsh, then building the amalgamation will fail. + # We act as though --disable-amalgamation has been used. + # msg-result Warning: "Warning: can't find tclsh - defaulting to non-amalgamation build." + # XXX USE_AMALGAMATION=0 + # XXX TCLSH_CMD="tclsh" + # XXX fi + # XXX AC_SUBST TCLSH_CMD + + # XXX AC_ARG_VAR TCLLIBDIR Where to install tcl plugin + # XXX if test "x${TCLLIBDIR+set}" != "xset" ; then + # XXX for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do + # XXX if test -d $i ; then + # XXX TCLLIBDIR=$i + # XXX break + # XXX fi + # XXX done + # XXX TCLLIBDIR="${TCLLIBDIR}/sqlite3" + # XXX fi +} + +if {0} { + ######### + # Set up options for running tests. + # + if {[opt-bool test-status]} { + set use_vt100 $enableval + } else { + set use_vt100 no + } + # XXX if test $use_vt100 != no; then + # XXX TSTRNNR_OPTS=--status + # XXX else + # XXX TSTRNNR_OPTS= + # XXX fi + # XXX AC_SUBST TSTRNNR_OPTS +} + +if {0} { + ######### + # Set up an appropriate program prefix + # + # XXX if test "$program_prefix" = "NONE"; then + set program_prefix "" + # XXX fi + # XXX AC_SUBST program_prefix + + # XXX VERSION=[`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'`] + # msg-result "Version set to $VERSION" + # XXX AC_SUBST VERSION + # XXX RELEASE=`cat $srcdir/VERSION` + # msg-result "Release set to $RELEASE" + # XXX AC_SUBST RELEASE +} + +if {0} { + ########## + # Handle --with-wasi-sdk=DIR + # + # This must be early because it changes the toolchain. + # + if {[opt-val with-wasi-sdk] ne {}} { + set withval [lindex [opt-val with-wasi-sdk] end] + set with_wasisdk ${withval} + } + msg-checking "Checking for WASI SDK directory..." + # First check to see if --with-tcl was specified. + # XXX if test x"${with_wasi_sdk}" != x ; then + # XXX if ! test -d "${with_wasi_sdk}" ; then + user-error "${with_wasi_sdk} directory doesn't exist" + # XXX fi + msg-result "${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL" + set use_wasi_sdk yes + # XXX else + set use_wasi_sdk no + # XXX fi + # XXX if test "${use_wasi_sdk}" = "no" ; then + # XXX HAVE_WASI_SDK="" + msg-result "no" + # XXX else + # XXX HAVE_WASI_SDK=1 + # Changing --host and --target have no effect here except to possibly + # cause confusion. autoconf has finished processing them by this + # point. + # + # host_alias=wasm32-wasi + # target=wasm32-wasi + # + # Merely changing CC and LD to the wasi-sdk's is enough to get + # sqlite3.o building in WASM format. + # XXX CC="${with_wasi_sdk}/bin/clang" + # XXX LD="${with_wasi_sdk}/bin/wasm-ld" + # XXX RANLIB="${with_wasi_sdk}/bin/llvm-ranlib" + set cross_compiling yes + set enable_threadsafe no + set use_tcl no + set enable_tcl no + # libtool is apparently hard-coded to use gcc for linking DLLs, so + # we disable the DLL build... + set enable_shared no + msg-result "yes" + # XXX fi + # XXX AC_SUBST HAVE_WASI_SDK +} + + +######### +# Locate a compiler for the build machine. This compiler should +# generate command-line programs that run on the build machine. +# +# XXX if test x"$cross_compiling" = xno; then +# XXX BUILD_CC=$CC +# XXX BUILD_CFLAGS=$CFLAGS +# XXX else +# XXX if test "${BUILD_CC+set}" != set; then +# XXX AC_CHECK_PROGS BUILD_CC gcc cc cl +# XXX fi +# XXX if test "${BUILD_CFLAGS+set}" != set; then +# XXX BUILD_CFLAGS="-g" +# XXX fi +# XXX fi +# XXX AC_SUBST BUILD_CC + +########## +# Do we want to support multithreaded use of sqlite +# +if {0} { + if {![opt-bool threadsafe]} { + } + msg-checking "Checking whether to support threadsafe operation..." + # XXX if test "$enable_threadsafe" = "no"; then + # XXX SQLITE_THREADSAFE=0 + msg-result "no" + # XXX else + # XXX SQLITE_THREADSAFE=1 + msg-result "yes" + # XXX fi + # XXX AC_SUBST SQLITE_THREADSAFE + + # XXX if test "$SQLITE_THREADSAFE" = "1"; then + cc-check-function-in-lib pthread_create pthread + cc-check-function-in-lib pthread_mutexattr_init pthread + # XXX fi +} + +########## +# Do we want to support release +# +if {[opt-bool releasemode]} { +} else { + set enable_releasemode no +} + +if {0} { + msg-checking "Checking whether to support shared library linked as release mode or not..." + # XXX if test "$enable_releasemode" = "no"; then + # XXX ALLOWRELEASE="" + msg-result "no" + # XXX else + # XXX ALLOWRELEASE="-release `cat $srcdir/VERSION`" + msg-result "yes" + # XXX fi + # XXX AC_SUBST ALLOWRELEASE +} + +########## +# Do we want temporary databases in memory +# +if {0} { + if {[opt-bool tempstore]} { + } else { + set enable_tempstore no + } + msg-checking "Checking whether to use an in-ram database for temporary tables..." + # XXX case "$enable_tempstore" in + # XXX never ) + # XXX TEMP_STORE=0 + msg-result "never" + # XXX ;; + # XXX no ) + # XXX TEMP_STORE=1 + msg-result "no" + # XXX ;; + # XXX yes ) + # XXX TEMP_STORE=2 + msg-result "yes" + # XXX ;; + # XXX always ) + # XXX TEMP_STORE=3 + msg-result "always" + # XXX ;; + # XXX * ) + # XXX TEMP_STORE=1 + msg-result "no" + # XXX ;; + # XXX esac + + # XXX AC_SUBST TEMP_STORE +} + +if {0} { + ########### + # Lots of things are different if we are compiling for Windows using + # the CYGWIN environment. So check for that special case and handle + # things accordingly. + # + msg-checking "Checking if executables have the .exe suffix..." + # XXX if test "$config_BUILD_EXEEXT" = ".exe"; then + # XXX CYGWIN=yes + msg-result "yes" + # XXX else + msg-result "unknown" + # XXX fi + # XXX if test "$CYGWIN" != "yes"; then + # XXX m4_warn([obsolete], + # XXX [AC_CYGWIN is obsolete: use AC_CANONICAL_HOST and check if $host_os + # XXX matches *cygwin*]) + # XXX case $host_os in + # XXX *cygwin* ) CYGWIN=yes;; + # XXX * ) CYGWIN=no;; + # XXX esac + + # XXX fi + # XXX if test "$CYGWIN" = "yes"; then + # XXX BUILD_EXEEXT=.exe + # XXX else + # XXX BUILD_EXEEXT=$EXEEXT + # XXX fi + # XXX if test x"$cross_compiling" = xno; then + # XXX TARGET_EXEEXT=$BUILD_EXEEXT + # XXX else + # XXX TARGET_EXEEXT=$config_TARGET_EXEEXT + # XXX fi + # XXX if test "$TARGET_EXEEXT" = ".exe"; then + # XXX SQLITE_OS_UNIX=0 + # XXX SQLITE_OS_WIN=1 + # XXX CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1" + # XXX else + # XXX SQLITE_OS_UNIX=1 + # XXX SQLITE_OS_WIN=0 + # XXX CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1" + # XXX fi + + # XXX AC_SUBST BUILD_EXEEXT + # XXX AC_SUBST SQLITE_OS_UNIX + # XXX AC_SUBST SQLITE_OS_WIN + # XXX AC_SUBST TARGET_EXEEXT +} + +if {0} { + ########## + # Figure out what C libraries are required to compile programs + # that use "readline()" library. + # + # XXX TARGET_READLINE_LIBS="" + # XXX TARGET_READLINE_INC="" + # XXX TARGET_HAVE_READLINE=0 + # XXX TARGET_HAVE_EDITLINE=0 + if {[opt-bool editline]} { + set with_editline $enableval + } else { + set with_editline auto + } + if {![opt-bool readline]} { + set with_readline $enableval + } else { + set with_readline auto + } + + # XXX if test x"$with_editline" != xno; then + # XXX sLIBS=$LIBS + # XXX LIBS="" + # XXX TARGET_HAVE_EDITLINE=1 + if {[cc-check-function-in-lib readline edit]} { + set with_readline no + } else { + # XXX TARGET_HAVE_EDITLINE=0 + } + # XXX TARGET_READLINE_LIBS=$LIBS + # XXX LIBS=$sLIBS + # XXX fi + # XXX if test x"$with_readline" != xno; then + set found "yes" + + if {[opt-val with-readline-lib] ne {}} { + set withval [lindex [opt-val with-readline-lib] end] + set with_readline_lib $withval + } else { + set with_readline_lib "auto" + } + # XXX if test "x$with_readline_lib" = xauto; then + # XXX save_LIBS="$LIBS" + # XXX LIBS="" + if {[cc-check-function-in-lib tgetent readline ncurses curses termcap]} { + # XXX term_LIBS="$LIBS" + } else { + # XXX term_LIBS="" + } + if {[cc-check-function-in-lib readline readline]} { + # XXX TARGET_READLINE_LIBS="-lreadline" + } else { + set found "no" + } + # XXX TARGET_READLINE_LIBS="$TARGET_READLINE_LIBS $term_LIBS" + # XXX LIBS="$save_LIBS" + # XXX else + # XXX TARGET_READLINE_LIBS="$with_readline_lib" + # XXX fi + + if {[opt-val with-readline-inc] ne {}} { + set withval [lindex [opt-val with-readline-inc] end] + set with_readline_inc $withval + } else { + set with_readline_inc "auto" + } + # XXX if test "x$with_readline_inc" = xauto; then + if {[cc-check-includes readline.h]} { + set found "yes" + } else { + set found "no" + # XXX if test "$cross_compiling" != yes; then + # XXX for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do + # XXX for subdir in include include/readline; do + # XXX AC_CHECK_FILE $dir/$subdir/readline.h found=yes + # XXX if test "$found" = "yes"; then + # XXX TARGET_READLINE_INC="-I$dir/$subdir" + # XXX break + # XXX fi + # XXX done + # XXX test "$found" = "yes" && break + # XXX done + # XXX fi + } + # XXX else + # XXX TARGET_READLINE_INC="$with_readline_inc" + # XXX fi + + # XXX if test x"$found" = xno; then + # XXX TARGET_READLINE_LIBS="" + # XXX TARGET_READLINE_INC="" + # XXX TARGET_HAVE_READLINE=0 + # XXX else + # XXX TARGET_HAVE_READLINE=1 + # XXX fi + # XXX fi + if {[opt-val with-linenoise] ne {}} { + set withval [lindex [opt-val with-linenoise] end] + set with_linenoise $withval + } else { + set with_linenoise "no" + } + # XXX if test "x$with_linenoise" != "xno"; then + # XXX TARGET_HAVE_READLINE=0 + # XXX TARGET_HAVE_EDITLINE=0 + # XXX TARGET_HAVE_LINENOISE=1 + # XXX TARGET_READLINE_INC="-I${with_linenoise}" + # XXX TARGET_READLINE_LIBS="${with_linenoise}/linenoise.c" + # XXX echo "using linenoise source code at ${with_linenoise}" + # XXX else + # XXX TARGET_HAVE_LINENOISE=0 + # XXX echo "not using linenoise" + # XXX fi + + # XXX AC_SUBST TARGET_READLINE_LIBS + # XXX AC_SUBST TARGET_READLINE_INC + # XXX AC_SUBST TARGET_HAVE_READLINE + # XXX AC_SUBST TARGET_HAVE_EDITLINE + # XXX AC_SUBST TARGET_HAVE_LINENOISE +} + +if {0} { + ########## + # Figure out what C libraries are required to compile programs + # that use "fdatasync()" function. + # + cc-check-function-in-lib fdatasync rt +} + +if {0} { + ######### + # check for debug enabled + if {[opt-bool debug]} { + } + msg-checking "Checking build type..." + # XXX if test "${enable_debug}" = "yes" ; then + # XXX TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall" + msg-result "debug" + # XXX else + # XXX TARGET_DEBUG="-DNDEBUG" + msg-result "release" + # XXX fi + # XXX AC_SUBST TARGET_DEBUG +} + +if {0} { + ######### + # See whether we should use the amalgamation to build + + if {![opt-bool amalgamation]} { + } + # XXX if test "${enable_amalgamation}" = "no" ; then + # XXX USE_AMALGAMATION=0 + # XXX fi + # XXX AC_SUBST USE_AMALGAMATION +} + +if {0} { + ######### + # Look for zlib. Only needed by extensions and by the sqlite3.exe shell + cc-check-includes zlib.h + if {[cc-check-function-in-lib deflate z]} { + define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" + } else { + define HAVE_ZLIB 0; # HAVE_ZLIB="" + } + # XXX AC_SUBST HAVE_ZLIB +} + +if {0} { + ######### + # See whether we should allow loadable extensions + if {![opt-bool load-extension]} { + } else { + set enable_load_extension yes + } + # XXX if test "${enable_load_extension}" = "yes" ; then + # XXX OPT_FEATURE_FLAGS="" + cc-check-function-in-lib dlopen dl + # XXX else + # XXX OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" + # XXX fi +} + +if {0} { + ########## + # Do we want to support math functions + # + if {![opt-bool math]} { + } + msg-checking "Checking whether to support math functions..." + # XXX if test "$enable_math" = "no"; then + msg-result "no" + # XXX else + msg-result "yes" + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" + cc-check-function-in-lib ceil m + # XXX fi +} + +if {0} { + ########## + # Do we want to support JSON functions + # + if {![opt-bool json]} { + } + msg-checking "Checking whether to support JSON functions..." + # XXX if test "$enable_json" = "no"; then + msg-result "no" + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON" + # XXX else + msg-result "yes" + # XXX fi +} + +######## +# The --enable-all argument is short-hand to enable +# multiple extensions. +if {[opt-bool enable-all]} { +} + +if {0} { + ########## + # Do we want to support memsys3 and/or memsys5 + # + if {[opt-bool memsys5]} { + } + msg-checking "Checking whether to support MEMSYS5..." + # XXX if test "${enable_memsys5}" = "yes"; then + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5" + msg-result "yes" + # XXX else + msg-result "no" + # XXX fi + if {[opt-bool memsys3]} { + } + msg-checking "Checking whether to support MEMSYS3..." + # XXX if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3" + msg-result "yes" + # XXX else + msg-result "no" + # XXX fi +} + +if {0} { + ######### + # See whether we should enable Full Text Search extensions + if {[opt-bool fts3]} { + } + msg-checking "Checking whether to support FTS3..." + # XXX if test "${enable_fts3}" = "yes" ; then + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3" + msg-result "yes" + # XXX else + msg-result "no" + # XXX fi + if {[opt-bool fts4]} { + } + msg-checking "Checking whether to support FTS4..." + # XXX if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then + msg-result "yes" + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" + cc-check-function-in-lib log m + # XXX else + msg-result "no" + # XXX fi + if {[opt-bool fts5]} { + } + msg-checking "Checking whether to support FTS5..." + # XXX if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then + msg-result "yes" + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" + cc-check-function-in-lib log m + # XXX else + msg-result "no" + # XXX fi +} + + +if {0} { + ######### + # See whether we should enable the LIMIT clause on UPDATE and DELETE + # statements. + if {[opt-bool update-limit]} { + } + msg-checking "Checking whether to support LIMIT on UPDATE and DELETE statements..." + # XXX if test "${enable_update_limit}" = "yes" ; then + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" + msg-result "yes" + # XXX else + msg-result "no" + # XXX fi +} + +if {0} { + ######### + # See whether we should enable GEOPOLY + if {[opt-bool geopoly]} { + set enable_geopoly yes + } else { + set enable_geopoly no + } + msg-checking "Checking whether to support GEOPOLY..." + # XXX if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" + set enable_rtree yes + msg-result "yes" + # XXX else + msg-result "no" + # XXX fi +} + +if {0} { + ######### + # See whether we should enable RTREE + if {[opt-bool rtree]} { + } + msg-checking "Checking whether to support RTREE..." + # XXX if test "${enable_rtree}" = "yes" ; then + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE" + msg-result "yes" + # XXX else + msg-result "no" + # XXX fi +} + +if {0} { + ######### + # See whether we should enable the SESSION extension + if {[opt-bool session]} { + } + msg-checking "Checking whether to support SESSION..." + # XXX if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" + # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" + msg-result "yes" + # XXX else + msg-result "no" + # XXX fi +} + +######### +# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter +# XXX for option in $CFLAGS $CPPFLAGS +# XXX do +# XXX case $option in +# XXX -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; +# XXX -DSQLITE_ENABLE*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; +# XXX esac +# XXX done +# XXX AC_SUBST OPT_FEATURE_FLAGS + + +# attempt to remove any OMITS and ENABLES from the $(CFLAGS) parameter +# XXX ac_temp_CFLAGS="" +# XXX for option in $CFLAGS +# XXX do +# XXX case $option in +# XXX -DSQLITE_OMIT*) ;; +# XXX -DSQLITE_ENABLE*) ;; +# XXX *) ac_temp_CFLAGS="$ac_temp_CFLAGS $option";; +# XXX esac +# XXX done +# XXX CFLAGS=$ac_temp_CFLAGS + + +# attempt to remove any OMITS and ENABLES from the $(CPPFLAGS) parameter +# XXX ac_temp_CPPFLAGS="" +# XXX for option in $CPPFLAGS +# XXX do +# XXX case $option in +# XXX -DSQLITE_OMIT*) ;; +# XXX -DSQLITE_ENABLE*) ;; +# XXX *) ac_temp_CPPFLAGS="$ac_temp_CPPFLAGS $option";; +# XXX esac +# XXX done +# XXX CPPFLAGS=$ac_temp_CPPFLAGS + + +# attempt to remove any OMITS and ENABLES from the $(BUILD_CFLAGS) parameter +# XXX ac_temp_BUILD_CFLAGS="" +# XXX for option in $BUILD_CFLAGS +# XXX do +# XXX case $option in +# XXX -DSQLITE_OMIT*) ;; +# XXX -DSQLITE_ENABLE*) ;; +# XXX *) ac_temp_BUILD_CFLAGS="$ac_temp_BUILD_CFLAGS $option";; +# XXX esac +# XXX done +# XXX BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS + + +if {0} { + ######### + # See whether we should use GCOV + if {[opt-bool gcov]} { + } + # XXX if test "${use_gcov}" = "yes" ; then + # XXX USE_GCOV=1 + # XXX else + # XXX USE_GCOV=0 + # XXX fi + # XXX AC_SUBST USE_GCOV +} + +if {0} { + ######### + # Enable/disabled amalagamation line macros + ######## + set linemacros 0 + # XXX if test "${amalgamation_line_macros}" = "yes" ; then + set linemacros 1 + # XXX fi + # XXX if test "${amalgamation_line_macros}" = "no" ; then + set linemacros 0 + # XXX fi + # XXX AC_SUBST AMALGAMATION_LINE_MACROS +} + +######### +# Output the config header + +if {0} { + ######### + # Generate the output files. + # + # XXX AC_SUBST BUILD_CFLAGS + make-template Makefile.in + make-template sqlite3.pc.in + make-config-header sqlite_cfg.h +} + +if {[opt-bool dump-defines]} { + msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" + make-config-header $DUMP_DEFINES_FILE -auto {*} +} diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl new file mode 100644 index 0000000000..de2317b100 --- /dev/null +++ b/autosetup/hwaci-common.tcl @@ -0,0 +1,324 @@ +######################################################################## +# 2024 September 25 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# * May you do good and not evil. +# * May you find forgiveness for yourself and forgive others. +# * May you share freely, never taking more than you give. +# +######################################################################## +# Routines for Steve Bennett's autosetup which are common to trees +# managed under the umbrella of the SQLite project. +# +# This file was initially derived from one used in the libfossil +# project, authored by the same person who ported it here (so there's +# no licensing issue despite this code having a twin running around). +######################################################################## + +array set hwaciCache {} ; # used for caching various results. + +######################################################################## +# hwaci-lshift shifts $count elements from the list named $listVar and +# returns them. +# +# Modified slightly from: https://wiki.tcl-lang.org/page/lshift +# +# On an empty list, returns "". +proc hwaci-lshift {listVar {count 1}} { + upvar 1 $listVar l + if {![info exists l]} { + # make the error message show the real variable name + error "can't read \"$listVar\": no such variable" + } + if {![llength $l]} { + # error Empty + return "" + } + set r [lrange $l 0 [incr count -1]] + set l [lreplace $l [set l 0] $count] + return $r +} + +######################################################################## +# A proxy for cc-check-function-in-lib which "undoes" any changes that +# routine makes to the LIBS define. Returns the result of +# cc-check-function-in-lib. +proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { + set _LIBS [get-define LIBS] + set found [cc-check-function-in-lib $function $libs $otherlibs] + define LIBS $_LIBS + return $found +} + +######################################################################## +# Look for binary named $binName and `define`s $defName to that full +# path, or an empty string if not found. Returns the value it defines. +# This caches the result for a given $binName/$defName combination, so +# calls after the first for a given combination will always return the +# same result. +# +# If defName is empty then "BIN_X" is used, where X is the upper-case +# form of $binName with any '-' characters removed. (TODO: map them to +# "_" instead, but i'll need to fix my affected builds in parallel.) +proc hwaci-bin-define {binName {defName {}}} { + global hwaciCache + set cacheName "$binName:$defName" + set check {} + if {[info exists hwaciCache($cacheName)]} { + set check $hwaciCache($cacheName) + } + msg-checking "Looking for $binName ... " + if {"" ne $check} { + set lbl $check + if {" _ 0 _ " eq $check} { + set lbl "not found" + set check "" + } + msg-result "(cached) $lbl" + return $check + } + set check [find-executable-path $binName] + if {"" eq $check} { + msg-result "not found" + set hwaciCache($cacheName) " _ 0 _ " + } else { + msg-result $check + set hwaciCache($cacheName) $check + } + if {"" eq $defName} { + set defName "BIN_[string toupper [string map {- {}} $binName]]" + } + define $defName $check + return $check +} + +######################################################################## +# Looks for `bash` binary and dies if not found. On success, defines +# BIN_BASH to the full path to bash and returns that value. We +# _require_ bash because it's the SHELL value used in our makefiles. +proc hwaci-require-bash {} { + set bash [hwaci-bin-define bash] + if {"" eq $bash} { + user-error "Our Makefiles require the bash shell." + } + return $bash +} + +######################################################################## +# Args: [-v] optName defName {descr {}} +# +# Checks [opt-bool $optName] and does [define $defName X] where X is 0 +# for false and 1 for true. descr is an optional [msg-checking] +# argument which defaults to $defName. Returns X. +# +# If args[0] is -v then the boolean semantics are inverted: if +# the option is set, it gets define'd to 0, else 1. Returns the +# define'd value. +proc hwaci-opt-bool-01 {args} { + set invert 0 + if {[lindex $args 0] eq "-v"} { + set invert 1 + set args [lrange $args 1 end] + } + set optName [hwaci-lshift args] + set defName [hwaci-lshift args] + set descr [hwaci-lshift args] + if {"" eq $descr} { + set descr $defName + } + set rc 0 + msg-checking "$descr ... " + if {[opt-bool $optName]} { + if {0 eq $invert} { + set rc 1 + } else { + set rc 0 + } + } elseif {0 ne $invert} { + set rc 1 + } + msg-result $rc + define $defName $rc + return $rc +} + +######################################################################## +# Check for module-loading APIs (libdl/libltdl)... +# +# Looks for libltdl or dlopen(), the latter either in -ldl or built in +# to libc (as it is on some platforms). Returns 1 if found, else +# 0. Either way, it `define`'s: +# +# - HAVE_LIBLTDL to 1 or 0 if libltdl is found/not found +# - HAVE_LIBDL to 1 or 0 if dlopen() is found/not found +# - LDFLAGS_MODULE_LOADER one of ("-lltdl", "-ldl", or ""), noting +# that -ldl may legally be empty on some platforms even if +# HAVE_LIBDL is true (indicating that dlopen() is available without +# extra link flags). LDFLAGS_MODULE_LOADER also gets "-rdynamic" appended +# to it because otherwise trying to open DLLs will result in undefined +# symbol errors. +# +# Note that if it finds LIBLTDL it does not look for LIBDL, so will +# report only that is has LIBLTDL. +proc hwaci-check-module-loader {} { + msg-checking "Looking for module-loader APIs... " + if {99 ne [get-define LDFLAGS_MODULE_LOADER]} { + if {1 eq [get-define HAVE_LIBLTDL 0]} { + msg-result "(cached) libltdl" + return 1 + } elseif {1 eq [get-define HAVE_LIBDL 0]} { + msg-result "(cached) libdl" + return 1 + } + # else: wha??? + } + set HAVE_LIBLTDL 0 + set HAVE_LIBDL 0 + set LDFLAGS_MODULE_LOADER "" + set rc 0 + puts "" ;# cosmetic kludge for cc-check-XXX + if {[cc-check-includes ltdl.h] && [cc-check-function-in-lib lt_dlopen ltdl]} { + set HAVE_LIBLTDL 1 + set LDFLAGS_MODULE_LOADER "-lltdl -rdynamic" + puts " - Got libltdl." + set rc 1 + } elseif {[cc-with {-includes dlfcn.h} { + cctest -link 1 -declare "extern char* dlerror(void);" -code "dlerror();"}]} { + puts " - This system can use dlopen() without -ldl." + set HAVE_LIBDL 1 + set LDFLAGS_MODULE_LOADER "" + set rc 1 + } elseif {[cc-check-includes dlfcn.h]} { + set HAVE_LIBDL 1 + set rc 1 + if {[cc-check-function-in-lib dlopen dl]} { + puts " - dlopen() needs libdl." + set LDFLAGS_MODULE_LOADER "-ldl -rdynamic" + } else { + puts " - dlopen() not found in libdl. Assuming dlopen() is built-in." + set LDFLAGS_MODULE_LOADER "-rdynamic" + } + } + define HAVE_LIBLTDL $HAVE_LIBLTDL + define HAVE_LIBDL $HAVE_LIBDL + define LDFLAGS_MODULE_LOADER $LDFLAGS_MODULE_LOADER + return $rc +} + +######################################################################## +# Sets all flags which would be set by hwaci-check-module-loader to +# empty/falsy values, as if those checks had failed to find a module +# loader. Intended to be called in place of that function when +# a module loader is explicitly not desired. +proc hwaci-no-check-module-loader {} { + define HAVE_LIBDL 0 + define HAVE_LIBLTDL 0 + define LDFLAGS_MODULE_LOADER "" +} + +######################################################################## +# Opens the given file, reads all of its content, and returns it. +proc hwaci-file-content {fname} { + set fp [open $fname r] + set rc [read $fp] + close $fp + return $rc +} + +######################################################################## +# Returns the contents of the given file as an array of lines, with +# the EOL stripped from each input line. +proc hwaci-file-content-list {fname} { + set fp [open $fname r] + set rc {} + while { [gets $fp line] >= 0 } { + lappend rc $line + } + return $rc +} + +######################################################################## +# Checks the compiler for compile_commands.json support. If passed an +# argument it is assumed to be the name of an autosetup boolean config +# option to explicitly DISABLE the compile_commands.json support. +# +# Returns 1 if supported, else 0. Defines MAKE_COMPILATION_DB to "yes" +# if supported, "no" if not. +proc hwaci-check-compile-commands {{configOpt {}}} { + msg-checking "compile_commands.json support... " + if {"" ne $configOpt && [opt-bool $configOpt]} { + msg-result "explicitly disabled" + define MAKE_COMPILATION_DB no + return 0 + } else { + if {[cctest -lang c -cflags {/dev/null -MJ} -source {}]} { + # This test reportedly incorrectly succeeds on one of + # Martin G.'s older systems. drh also reports a false + # positive on an unspecified older Mac system. + msg-result "compiler supports compile_commands.json" + define MAKE_COMPILATION_DB yes + return 1 + } else { + msg-result "compiler does not support compile_commands.json" + define MAKE_COMPILATION_DB no + return 0 + } + } +} + +######################################################################## +# Uses [make-template] to create makefile(-like) file $filename from +# $filename.in but explicitly makes the output read-only, to avoid +# inadvertent editing (who, me?). +# +# The second argument is an optional boolean specifying whether to +# `touch` the generated files. This can be used as a workaround for +# cases where (A) autosetup does not update the file because it was +# not really modified and (B) the file *really* needs to be updated to +# please the build process. Pass any non-0 value to enable touching. +# +# The argument may be a list of filenames. +# +# Failures when running chmod or touch are silently ignored. +proc hwaci-make-from-dot-in {filename {touch 0}} { + foreach f $filename { + catch { exec chmod u+w $f } + make-template $f.in $f + if {0 != $touch} { + puts "Touching $f" + catch { exec touch $f } + } + catch { exec chmod -w $f } + } +} + +######################################################################## +# Checks for the boolean configure option named by $flagname. If set, +# it checks if $CC seems to refer to gcc. If it does (or appears to) +# then it defines CC_PROFILE_FLAG to "-pg" and returns 1, else it +# defines CC_PROFILE_FLAG to "" and returns 0. +# +# Note that the resulting flag must be added to both CFLAGS and +# LDFLAGS in order for binaries to be able to generate "gmon.out". In +# order to avoid potential problems with escaping, space-containing +# tokens, and interfering with autosetup's use of these vars, this +# routine does not directly modify CFLAGS or LDFLAGS. +proc hwaci-check-profile-flag {{flagname profile}} { + if {[opt-bool $flagname]} { + set CC [get-define CC] + regsub {.*ccache *} $CC "" CC + # ^^^ if CC="ccache gcc" then [exec] treats "ccache gcc" as a + # single binary name and fails. So strip any leading ccache part + # for this purpose. + if { ![catch { exec $CC --version } msg]} { + if {[string first gcc $CC] != -1} { + define CC_PROFILE_FLAG "-pg" + return 1 + } + } + } + define CC_PROFILE_FLAG "" + return 0 +} diff --git a/configure.ac b/configure.ac index b3a0dd299f..40d1dbd07f 100644 --- a/configure.ac +++ b/configure.ac @@ -119,9 +119,12 @@ USE_AMALGAMATION=1 # Figure out all the name of a working tclsh and parameters needed to compile against Tcl. # The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. # -AC_ARG_WITH(tclsh, AS_HELP_STRING([--with-tclsh=PATHNAME],[full pathname of a tclsh to use])) -AC_ARG_WITH(tcl, AS_HELP_STRING([--with-tcl=DIR],[directory containing (tclConfig.sh)])) -AC_ARG_ENABLE(tcl, AS_HELP_STRING([--disable-tcl],[omit building accessory programs that require TCL-dev]), +AC_ARG_WITH(tclsh, + AS_HELP_STRING([--with-tclsh=PATHNAME],[full pathname of a tclsh to use])) +AC_ARG_WITH(tcl, + AS_HELP_STRING([--with-tcl=DIR],[directory containing (tclConfig.sh)])) +AC_ARG_ENABLE(tcl, + AS_HELP_STRING([--disable-tcl],[omit building accessory programs that require TCL-dev]), [use_tcl=$enableval],[use_tcl=yes]) original_use_tcl=${use_tcl} if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then @@ -261,21 +264,21 @@ AC_SUBST(RELEASE) # This must be early because it changes the toolchain. # AC_ARG_WITH(wasi-sdk, -AS_HELP_STRING([--with-wasi-sdk=DIR], + AS_HELP_STRING([--with-wasi-sdk=DIR], [directory containing the WASI SDK. Triggers cross-compile to WASM.]), with_wasisdk=${withval}) -AC_MSG_CHECKING([for WASI SDK directory]) -AC_CACHE_VAL(ac_cv_c_wasi_sdk,[ - # First check to see if --with-tcl was specified. - if test x"${with_wasi_sdk}" != x ; then - if ! test -d "${with_wasi_sdk}" ; then - AC_MSG_ERROR([${with_wasi_sdk} directory doesn't exist]) + AC_MSG_CHECKING([for WASI SDK directory]) + AC_CACHE_VAL(ac_cv_c_wasi_sdk,[ + # First check to see if --with-tcl was specified. + if test x"${with_wasi_sdk}" != x ; then + if ! test -d "${with_wasi_sdk}" ; then + AC_MSG_ERROR([${with_wasi_sdk} directory doesn't exist]) + fi + AC_MSG_RESULT([${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL]) + use_wasi_sdk=yes + else + use_wasi_sdk=no fi - AC_MSG_RESULT([${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL]) - use_wasi_sdk=yes - else - use_wasi_sdk=no - fi -]) + ]) if test "${use_wasi_sdk}" = "no" ; then HAVE_WASI_SDK="" AC_MSG_RESULT([no]) @@ -326,15 +329,15 @@ AC_SUBST(BUILD_CC) # Do we want to support multithreaded use of sqlite # AC_ARG_ENABLE(threadsafe, -AS_HELP_STRING([--disable-threadsafe],[Disable mutexing])) -AC_MSG_CHECKING([whether to support threadsafe operation]) -if test "$enable_threadsafe" = "no"; then - SQLITE_THREADSAFE=0 - AC_MSG_RESULT([no]) -else - SQLITE_THREADSAFE=1 - AC_MSG_RESULT([yes]) -fi + AS_HELP_STRING([--disable-threadsafe],[Disable mutexing])) + AC_MSG_CHECKING([whether to support threadsafe operation]) + if test "$enable_threadsafe" = "no"; then + SQLITE_THREADSAFE=0 + AC_MSG_RESULT([no]) + else + SQLITE_THREADSAFE=1 + AC_MSG_RESULT([yes]) + fi AC_SUBST(SQLITE_THREADSAFE) if test "$SQLITE_THREADSAFE" = "1"; then @@ -346,45 +349,45 @@ fi # Do we want to support release # AC_ARG_ENABLE(releasemode, -AS_HELP_STRING([--enable-releasemode],[Support libtool link to release mode]),,enable_releasemode=no) -AC_MSG_CHECKING([whether to support shared library linked as release mode or not]) -if test "$enable_releasemode" = "no"; then - ALLOWRELEASE="" - AC_MSG_RESULT([no]) -else - ALLOWRELEASE="-release `cat $srcdir/VERSION`" - AC_MSG_RESULT([yes]) -fi + AS_HELP_STRING([--enable-releasemode],[Support libtool link to release mode]),,enable_releasemode=no) + AC_MSG_CHECKING([whether to support shared library linked as release mode or not]) + if test "$enable_releasemode" = "no"; then + ALLOWRELEASE="" + AC_MSG_RESULT([no]) + else + ALLOWRELEASE="-release `cat $srcdir/VERSION`" + AC_MSG_RESULT([yes]) + fi AC_SUBST(ALLOWRELEASE) ########## # Do we want temporary databases in memory # AC_ARG_ENABLE(tempstore, -AS_HELP_STRING([--enable-tempstore],[Use an in-ram database for temporary tables (never,no,yes,always)]),,enable_tempstore=no) -AC_MSG_CHECKING([whether to use an in-ram database for temporary tables]) -case "$enable_tempstore" in - never ) - TEMP_STORE=0 - AC_MSG_RESULT([never]) - ;; - no ) - TEMP_STORE=1 - AC_MSG_RESULT([no]) - ;; - yes ) - TEMP_STORE=2 - AC_MSG_RESULT([yes]) - ;; - always ) - TEMP_STORE=3 - AC_MSG_RESULT([always]) - ;; - * ) - TEMP_STORE=1 - AC_MSG_RESULT([no]) - ;; -esac + AS_HELP_STRING([--enable-tempstore],[Use an in-ram database for temporary tables (never,no,yes,always)]),,enable_tempstore=no) + AC_MSG_CHECKING([whether to use an in-ram database for temporary tables]) + case "$enable_tempstore" in + never ) + TEMP_STORE=0 + AC_MSG_RESULT([never]) + ;; + no ) + TEMP_STORE=1 + AC_MSG_RESULT([no]) + ;; + yes ) + TEMP_STORE=2 + AC_MSG_RESULT([yes]) + ;; + always ) + TEMP_STORE=3 + AC_MSG_RESULT([always]) + ;; + * ) + TEMP_STORE=1 + AC_MSG_RESULT([no]) + ;; + esac AC_SUBST(TEMP_STORE) @@ -584,28 +587,28 @@ fi # Do we want to support math functions # AC_ARG_ENABLE(math, -AS_HELP_STRING([--disable-math],[Disable math functions])) -AC_MSG_CHECKING([whether to support math functions]) -if test "$enable_math" = "no"; then - AC_MSG_RESULT([no]) -else - AC_MSG_RESULT([yes]) - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" - AC_SEARCH_LIBS(ceil, m) -fi + AS_HELP_STRING([--disable-math],[Disable math functions])) + AC_MSG_CHECKING([whether to support math functions]) + if test "$enable_math" = "no"; then + AC_MSG_RESULT([no]) + else + AC_MSG_RESULT([yes]) + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" + AC_SEARCH_LIBS(ceil, m) + fi ########## # Do we want to support JSON functions # AC_ARG_ENABLE(json, -AS_HELP_STRING([--disable-json],[Disable JSON functions])) -AC_MSG_CHECKING([whether to support JSON functions]) -if test "$enable_json" = "no"; then - AC_MSG_RESULT([no]) - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON" -else - AC_MSG_RESULT([yes]) -fi + AS_HELP_STRING([--disable-json],[Disable JSON functions])) + AC_MSG_CHECKING([whether to support JSON functions]) + if test "$enable_json" = "no"; then + AC_MSG_RESULT([no]) + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON" + else + AC_MSG_RESULT([yes]) + fi ######## # The --enable-all argument is short-hand to enable @@ -619,12 +622,12 @@ AC_ARG_ENABLE(all, AS_HELP_STRING([--enable-all], AC_ARG_ENABLE(memsys5, AS_HELP_STRING([--enable-memsys5],[Enable MEMSYS5])) AC_MSG_CHECKING([whether to support MEMSYS5]) -if test "${enable_memsys5}" = "yes"; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi + if test "${enable_memsys5}" = "yes"; then + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi AC_ARG_ENABLE(memsys3, AS_HELP_STRING([--enable-memsys3],[Enable MEMSYS3])) AC_MSG_CHECKING([whether to support MEMSYS3]) diff --git a/manifest b/manifest index e94222760f..5323103370 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\spristine\sautosetup\sbits. -D 2024-09-24T21:08:49.699 +C Get\sskeleton\sauto.def\srunning,\sbut\sit\sdoesn't\sreally\sdo\smuch\sexcept\ssome\sstandard\sboilerplate\sstuff. +D 2024-09-25T01:39:39.297 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 1f07836fdcf7c5048d8d9e60955bfb568989c36fa94dd1e5953fd836fa11a033 +F auto.def eb8f5b72c433ef0d37b1d78b3a06ceb22165aa161a88cfd39d0cbef171dd1bc2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,6 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 +F autosetup/hwaci-common.tcl 120d1cc6f1604fdf9403d730ed5955c18aaac11ce533231d62e22e614b9cbbfd F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -54,7 +55,7 @@ F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d7 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x -F configure.ac a100ebf7a07f5dedd319ef547dd467d1676ed059b85a7877aa9c44ac309f7000 +F configure.ac 934d33880d4c7dbff05c2ebaa3820e344e1321d5fff6d6393963e50c3a613e40 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/compile-for-windows.md 4d4bfafda42a7a33f166d23aed4db1bb4ea1e5751595a5cced2bad349fd14652 @@ -2231,11 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 42bb941584a1ac922ee6b0b6ecadce71c9259555563cf49913a6f820f3f9b887 -R 84d3f178c5c16f5b308246d776945a8b -T *branch * autosetup -T *sym-autosetup * -T -sym-trunk * Cancelled\sby\sbranch. +P dfb1e7f0cce9bc79c43eee7208cad0e2df562b2bc9705d3a36fd78f86c75495b +R dd0ebdea6824f43df28d73bb1d5be9bb U stephan -Z 8191a33bd76375a0780db52c6f42efff +Z 061986ba8b4c5587dccbe2f0a25494b3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8defc94fe6..c9a78ea48e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfb1e7f0cce9bc79c43eee7208cad0e2df562b2bc9705d3a36fd78f86c75495b +e707634cf755346752bb83b7be5d0c683e39d6e0a497846019323fed31c08b9d From e6b41c4641781d14e80e1910440fcb34707f6050 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 02:00:09 +0000 Subject: [PATCH 004/522] Testing libfossil checkin fix for inheritance of privateness. FossilOrigin-Name: 4b104926bf0862a5088e51549c2d688c2af649d45bf0e396cc48e171bed06b0a --- auto.def | 27 ++++++++++++++------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/auto.def b/auto.def index 32cb94185b..c4cc217416 100644 --- a/auto.def +++ b/auto.def @@ -6,21 +6,21 @@ set DUMP_DEFINES_FILE defines.list options { with-tclsh:PATHNAME => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} - tcl=1 => {building accessory programs that require TCL-dev} - test-status=0 => {status of tests} + disable-tcl=0 => {building accessory programs that require TCL-dev} + enable-test-status=0 => {status of tests} with-wasi-sdk:=/opt/wasi-sdk => {Path to the wasi-dsk} - threadsafe=1 => mutexing - releasemode=0 => {libtool link to release mode} - tempstore=0 => {an in-ram database for temporary tables never,no,yes,always} - editline=0 => {BSD editline support} - readline=1 => {readline support} + disable-threadsafe=0 => mutexing + enable-releasemode=0 => {libtool link to release mode} + enable-tempstore=0 => {an in-ram database for temporary tables never,no,yes,always} + enable-editline=0 => {BSD editline support} + disable-readline=0 => {readline support} with-readline-lib => {readline library} with-readline-inc => {readline include paths} with-linenoise:DIR => {} - amalgamation=1 => {Disable the amalgamation and instead build all files separately} - load-extension=1 => {Disable loading of external extensions} - math=1 => {math functions} - json=1 => {JSON functions} + disable-amalgamation=0 => {Disable the amalgamation and instead build all files separately} + disable-load-extension=0 => {Disable loading of external extensions} + disable-math=0 => {math functions} + disable-json=0 => {JSON functions} enable-all=0 => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} enable-memsys5=0 => MEMSYS5 enable-memsys3=0 => MEMSYS3 @@ -404,9 +404,10 @@ if {0} { ########## # Do we want to support release # -if {[opt-bool releasemode]} { +if {[opt-bool enable-releasemode]} { + set enable_releasemode 1 } else { - set enable_releasemode no + set enable_releasemode 0 } if {0} { diff --git a/manifest b/manifest index 5323103370..71e4216f4a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sskeleton\sauto.def\srunning,\sbut\sit\sdoesn't\sreally\sdo\smuch\sexcept\ssome\sstandard\sboilerplate\sstuff. -D 2024-09-25T01:39:39.297 +C Testing\slibfossil\scheckin\sfix\sfor\sinheritance\sof\sprivateness. +D 2024-09-25T02:00:09.512 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def eb8f5b72c433ef0d37b1d78b3a06ceb22165aa161a88cfd39d0cbef171dd1bc2 +F auto.def 3b6d2ee3ddb3fe0c79292f0a84e4fbe9302c23b06388fa2c06ae17ee25283707 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dfb1e7f0cce9bc79c43eee7208cad0e2df562b2bc9705d3a36fd78f86c75495b -R dd0ebdea6824f43df28d73bb1d5be9bb +P e707634cf755346752bb83b7be5d0c683e39d6e0a497846019323fed31c08b9d +R 55f0e3bb43a27631a03061e331dafb41 U stephan -Z 061986ba8b4c5587dccbe2f0a25494b3 +Z 800ded8d31a18a53ba5fd1647482872b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c9a78ea48e..69cfa1b926 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e707634cf755346752bb83b7be5d0c683e39d6e0a497846019323fed31c08b9d +4b104926bf0862a5088e51549c2d688c2af649d45bf0e396cc48e171bed06b0a From 63c4d89ae1bdb37509c201cef43151f4be35c4eb Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 03:37:34 +0000 Subject: [PATCH 005/522] Get several of the --enable/--disable configure flags working. FossilOrigin-Name: fd16d53d3a95cd4f5f81f4b1b09955f04c89116586aa16fa01627ae4904d587b --- auto.def | 271 +++++++++++++++++-------------------- autosetup/hwaci-common.tcl | 49 ++++++- manifest | 14 +- manifest.uuid | 2 +- 4 files changed, 180 insertions(+), 156 deletions(-) diff --git a/auto.def b/auto.def index c4cc217416..e08ba720d7 100644 --- a/auto.def +++ b/auto.def @@ -3,6 +3,17 @@ use cc cc-shared cc-lib hwaci-common set DUMP_DEFINES_FILE defines.list +######################################################################## +# Note that boolean flags... +# +# 1) Are in the form flagname (default=false) or flagname=0 (false) or +# flagname=1 (true). +# +# 2) If they default to false, the actual flag mapped to them is +# --enable-FLAG. +# +# 3) If they default to true, the actual flag mapped to them is +# --disable-FLAG. options { with-tclsh:PATHNAME => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} @@ -18,10 +29,10 @@ options { with-readline-inc => {readline include paths} with-linenoise:DIR => {} disable-amalgamation=0 => {Disable the amalgamation and instead build all files separately} - disable-load-extension=0 => {Disable loading of external extensions} - disable-math=0 => {math functions} - disable-json=0 => {JSON functions} - enable-all=0 => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} + load-extension=1 => {loading of external extensions} + math=1 => {math functions} + json=1 => {JSON functions} + all=0 => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} enable-memsys5=0 => MEMSYS5 enable-memsys3=0 => MEMSYS3 enable-fts3=0 => {Enable the FTS3 extension} @@ -32,7 +43,7 @@ options { enable-rtree=0 => {Enable the RTREE extension} enable-session=0 => {Enable the SESSION extension} enable-gcov=0 => {Enable coverage testing using gcov} - dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} + dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} } # debug=0 => {debugging & verbose explain} @@ -84,11 +95,6 @@ puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" # Libraries that the build compiler needs in order to construct # command-line programs. # -# BUILD_EXEEXT -# -# The filename extension for executables on the build -# platform. "" for Unix and ".exe" for Windows. -# # TCL_* # # Lots of values are read in from the tclConfig.sh script, @@ -107,49 +113,94 @@ puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" # This variables define the directory that contain header # files for the readline library. If the compiler is able # to find on its own, then this can be blank. -# -# TARGET_EXEEXT -# -# The filename extension for executables on the -# target platform. "" for Unix and ".exe" for windows. -# -# This configure.in file is easy to reuse on other projects. Just -# change the argument to AC_INIT. And disable any features that -# you don't need (for example BLT) by erasing or commenting out -# the corresponding code. -# +hwaci-check-exeext -#set sqlite_version_sanity_check `cat $autosetup(srcdir)/VERSION | tr -d '\n'` -# XXX if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then -#user-error "configure script is out of date: -# configure \$PACKAGE_VERSION = $PACKAGE_VERSION -# top level VERSION file = $sqlite_version_sanity_check -#please regen with autoconf" -# XXX fi +######################################################################## +# OPT_FEATURE_FLAGS = -DSQLITE_OMIT/ENABLE flags. +define OPT_FEATURE_FLAGS {} +proc add-feature-flag {flag} { + define-append OPT_FEATURE_FLAGS $flag +} +# add-feature-flag -DSQLITE_JUST_TESTING=3 ######### # Programs needed -cc-check-progs install +if {1} { + if {"" eq [hwaci-bin-define install]} { + msg-result "Cannot find install binary, so 'make install' will not work." + } +} ######### # Enable large file support (if special flags are necessary) -cc-check-lfs +if {1} { + cc-check-lfs +} ######### # Check for needed/wanted data types if {1} { - cc-check-types int8_t int16_t int32_t int64_t intptr_t uint8_t uint16_t uint32_t uint64_t uintptr_t + cc-check-types int8_t int16_t int32_t int64_t intptr_t \ + uint8_t uint16_t uint32_t uint64_t uintptr_t } ######### # Check for needed/wanted headers -cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h +if {1} { + cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h +} ######### # Figure out whether or not we have these functions +if {1} { + cc-check-functions fdatasync gmtime_r isnan localtime_r localtime_s \ + malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 +} + + +########## +# Handle --with-wasi-sdk=DIR +# +# This must be early because it changes the toolchain. # -cc-check-functions fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 +# It's unclear whether we can actually get away with these changes in +# autosetup. +if {1} { + set wasiSdkDir [lindex [opt-val with-wasi-sdk] end] + if {$wasiSdkDir eq ""} { + define HAVE_WASI_SDK 0 + define WASI_SDK_DIR "" + } else { + msg-checking "Checking WASI SDK directory \[$wasiSdkDir]... " + if {![file exists $wasiSdkDir/bin/clang]} { + user-error "--with-wasi-sdk=${wasiSdkDir} directory does not contain bin/clang" + } + msg-result "using wasi-sdk clang, disabling: tcl, CLI shell, DLL" + define HAVE_WASI_SDK 1 + define WASI_SDK_DIR $wasiSdkDir + + # Changing --host and --target have no effect here except to possibly + # cause confusion. autoconf has finished processing them by this + # point. + # + # host_alias=wasm32-wasi + # target=wasm32-wasi + # + # Merely changing CC and LD to the wasi-sdk's is enough to get + # sqlite3.o building in WASM format. + # XXX CC="${with_wasi_sdk}/bin/clang" + # XXX LD="${with_wasi_sdk}/bin/wasm-ld" + # XXX RANLIB="${with_wasi_sdk}/bin/llvm-ranlib" + # set cross_compiling yes + # set enable_threadsafe no + # set use_tcl no + # set enable_tcl no + # libtool is apparently hard-coded to use gcc for linking DLLs, so + # we disable the DLL build... + # set enable_shared no + } +}; # --wasi-sdk-dir ######### # By default, we use the amalgamation (this may be changed below...) @@ -282,9 +333,9 @@ if {0} { # Set up options for running tests. # if {[opt-bool test-status]} { - set use_vt100 $enableval + define TSTRNNR_OPTS {--status} } else { - set use_vt100 no + define TSTRNNR_OPTS {} } # XXX if test $use_vt100 != no; then # XXX TSTRNNR_OPTS=--status @@ -294,74 +345,6 @@ if {0} { # XXX AC_SUBST TSTRNNR_OPTS } -if {0} { - ######### - # Set up an appropriate program prefix - # - # XXX if test "$program_prefix" = "NONE"; then - set program_prefix "" - # XXX fi - # XXX AC_SUBST program_prefix - - # XXX VERSION=[`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'`] - # msg-result "Version set to $VERSION" - # XXX AC_SUBST VERSION - # XXX RELEASE=`cat $srcdir/VERSION` - # msg-result "Release set to $RELEASE" - # XXX AC_SUBST RELEASE -} - -if {0} { - ########## - # Handle --with-wasi-sdk=DIR - # - # This must be early because it changes the toolchain. - # - if {[opt-val with-wasi-sdk] ne {}} { - set withval [lindex [opt-val with-wasi-sdk] end] - set with_wasisdk ${withval} - } - msg-checking "Checking for WASI SDK directory..." - # First check to see if --with-tcl was specified. - # XXX if test x"${with_wasi_sdk}" != x ; then - # XXX if ! test -d "${with_wasi_sdk}" ; then - user-error "${with_wasi_sdk} directory doesn't exist" - # XXX fi - msg-result "${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL" - set use_wasi_sdk yes - # XXX else - set use_wasi_sdk no - # XXX fi - # XXX if test "${use_wasi_sdk}" = "no" ; then - # XXX HAVE_WASI_SDK="" - msg-result "no" - # XXX else - # XXX HAVE_WASI_SDK=1 - # Changing --host and --target have no effect here except to possibly - # cause confusion. autoconf has finished processing them by this - # point. - # - # host_alias=wasm32-wasi - # target=wasm32-wasi - # - # Merely changing CC and LD to the wasi-sdk's is enough to get - # sqlite3.o building in WASM format. - # XXX CC="${with_wasi_sdk}/bin/clang" - # XXX LD="${with_wasi_sdk}/bin/wasm-ld" - # XXX RANLIB="${with_wasi_sdk}/bin/llvm-ranlib" - set cross_compiling yes - set enable_threadsafe no - set use_tcl no - set enable_tcl no - # libtool is apparently hard-coded to use gcc for linking DLLs, so - # we disable the DLL build... - set enable_shared no - msg-result "yes" - # XXX fi - # XXX AC_SUBST HAVE_WASI_SDK -} - - ######### # Locate a compiler for the build machine. This compiler should # generate command-line programs that run on the build machine. @@ -675,56 +658,56 @@ if {0} { # XXX AC_SUBST HAVE_ZLIB } -if {0} { - ######### - # See whether we should allow loadable extensions - if {![opt-bool load-extension]} { +proc if-disabled {boolFlag then {else {}}} { + if {![opt-bool $boolFlag]} { + eval $then } else { - set enable_load_extension yes + eval $else } - # XXX if test "${enable_load_extension}" = "yes" ; then - # XXX OPT_FEATURE_FLAGS="" - cc-check-function-in-lib dlopen dl - # XXX else - # XXX OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" - # XXX fi } -if {0} { - ########## - # Do we want to support math functions - # - if {![opt-bool math]} { +proc if-enabled {boolFlag then {else {}}} { + if {[opt-bool $boolFlag]} { + eval $then + } else { + eval $else } - msg-checking "Checking whether to support math functions..." - # XXX if test "$enable_math" = "no"; then - msg-result "no" - # XXX else - msg-result "yes" - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" - cc-check-function-in-lib ceil m - # XXX fi } -if {0} { - ########## - # Do we want to support JSON functions - # - if {![opt-bool json]} { +if-enabled load-extension { + if {[cc-check-function-in-lib dlopen dl]} { + define LDFLAGS_DLOPEN [get-define lib_dlopen] + } else { + user-error "dlopen() not found. Use --disable-load-extension to bypass this check." } - msg-checking "Checking whether to support JSON functions..." - # XXX if test "$enable_json" = "no"; then - msg-result "no" - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON" - # XXX else - msg-result "yes" - # XXX fi +} { + define LDFLAGS_DLOPEN "" + add-feature-flag {-DSQLITE_OMIT_LOAD_EXTENSION=1} + msg-result "Disabling loadable extensions." +} + +if-enabled math { + if {![cc-check-function-in-lib ceil m]} { + user-error "Cannot find libm functions. Use --disable-math to bypass this." + } + define LDFLAGS_MATH [get-define lib_ceil] + undefine lib_ceil + add-feature-flag {-DSQLITE_ENABLE_MATH_FUNCTIONS} + msg-result "Enabling math functions." +} { + define LDFLAGS_MATH "" + msg-result "Disabling math functions." +} + +if-enabled json { + msg-result "Enabling JSON SQL functions." +} { + add-feature-flag {-DSQLITE_OMIT_JSON} + msg-result "Disabling JSON SQL functions." } -######## -# The --enable-all argument is short-hand to enable -# multiple extensions. -if {[opt-bool enable-all]} { +if-enabled all { + msg-result "TODO: handle --enable-all" } if {0} { @@ -941,5 +924,5 @@ if {0} { if {[opt-bool dump-defines]} { msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" - make-config-header $DUMP_DEFINES_FILE -auto {*} + make-config-header $DUMP_DEFINES_FILE -bare OPT_FEATURE_FLAGS -auto {*} } diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index de2317b100..c95fba218b 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -53,15 +53,14 @@ proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { } ######################################################################## -# Look for binary named $binName and `define`s $defName to that full +# Looks for binary named $binName and `define`s $defName to that full # path, or an empty string if not found. Returns the value it defines. # This caches the result for a given $binName/$defName combination, so # calls after the first for a given combination will always return the # same result. # # If defName is empty then "BIN_X" is used, where X is the upper-case -# form of $binName with any '-' characters removed. (TODO: map them to -# "_" instead, but i'll need to fix my affected builds in parallel.) +# form of $binName with any '-' characters replaced with '_'. proc hwaci-bin-define {binName {defName {}}} { global hwaciCache set cacheName "$binName:$defName" @@ -88,7 +87,7 @@ proc hwaci-bin-define {binName {defName {}}} { set hwaciCache($cacheName) $check } if {"" eq $defName} { - set defName "BIN_[string toupper [string map {- {}} $binName]]" + set defName "BIN_[string toupper [string map {- _} $binName]]" } define $defName $check return $check @@ -322,3 +321,45 @@ proc hwaci-check-profile-flag {{flagname profile}} { define CC_PROFILE_FLAG "" return 0 } + +######################################################################## +# Returns 1 if this appears to be a Windows environment (MinGw, +# Cygwin, MSys), else returns 0. The optional argument is the name of +# an autosetup define which contains platform name info, defaulting to +# "host". The other legal value is "target". +proc hwaci-looks-like-windows {{key host}} { + switch -glob -- [get-define $key] { + *-*-ming* - *-*-cygwin - *-*-msys { + return 1 + } + default { + return 0 + } + } +} + +######################################################################## +# Checks autosetup's "host" and "target" defines to see if the build +# host and target are Windows-esque (Cygwin, MinGW, MSys). If the +# build host is then BUILD_EXEEXT is [define]'d to ".exe", else "". If +# the build target is then TARGET_EXEEXT is [define]'d to ".exe", else +# "". +proc hwaci-check-exeext {} { + msg-checking "Build host is Windows-esque? " + if {[hwaci-looks-like-windows host]} { + define BUILD_EXEEXT ".exe" + msg-result yes + } else { + define BUILD_EXEEXT "" + msg-result no + } + + msg-checking "Build target is Windows-esque? " + if {[hwaci-looks-like-windows target]} { + define TARGET_EXEEXT ".exe" + msg-result yes + } else { + define TARGET_EXEEXT "" + msg-result no + } +} diff --git a/manifest b/manifest index 71e4216f4a..0b72c18d59 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Testing\slibfossil\scheckin\sfix\sfor\sinheritance\sof\sprivateness. -D 2024-09-25T02:00:09.512 +C Get\sseveral\sof\sthe\s--enable/--disable\sconfigure\sflags\sworking. +D 2024-09-25T03:37:34.226 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 3b6d2ee3ddb3fe0c79292f0a84e4fbe9302c23b06388fa2c06ae17ee25283707 +F auto.def 1c121db3f48b25002887220168e1120b5f8865f2d0468d62dca4220192367bef F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 120d1cc6f1604fdf9403d730ed5955c18aaac11ce533231d62e22e614b9cbbfd +F autosetup/hwaci-common.tcl b6f0c57b377898b8837bd031ca9a37c021d4fe859c9d3967dbb36deab6748459 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e707634cf755346752bb83b7be5d0c683e39d6e0a497846019323fed31c08b9d -R 55f0e3bb43a27631a03061e331dafb41 +P 4b104926bf0862a5088e51549c2d688c2af649d45bf0e396cc48e171bed06b0a +R 5abab1c4da63e377666cdbb79ca9e337 U stephan -Z 800ded8d31a18a53ba5fd1647482872b +Z 675f689497b17977048f4ba0ec321727 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 69cfa1b926..2d2859b16a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b104926bf0862a5088e51549c2d688c2af649d45bf0e396cc48e171bed06b0a +fd16d53d3a95cd4f5f81f4b1b09955f04c89116586aa16fa01627ae4904d587b From dd5b962a15d2dcba9620e9ca733b65a9ae9a7299 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 04:20:58 +0000 Subject: [PATCH 006/522] Get --enable-all flag essentially working. FossilOrigin-Name: 0a49436c983848c3d88f3f5ec33fb9ac31cce62e94bf515ab1c357a10f5cd515 --- auto.def | 143 ++++++++++++++++++++++++++++++++------------------ manifest | 12 ++--- manifest.uuid | 2 +- 3 files changed, 98 insertions(+), 59 deletions(-) diff --git a/auto.def b/auto.def index e08ba720d7..a386ecb0ee 100644 --- a/auto.def +++ b/auto.def @@ -14,35 +14,48 @@ set DUMP_DEFINES_FILE defines.list # # 3) If they default to true, the actual flag mapped to them is # --disable-FLAG. +# +# 4) For boolean options, configure will accept any of --flag, --enable-flag, +# or --disable-flag. Unfortunately, it reserves --debug for its own use. +# +# 5) Mapping with their full name, e.g. enable-foo=1 or disable-bar=0, +# will lead to breakage in calls to either [opt-bool foo] or +# [opt-bool enable-foo]. +# +# (2) and (3) mean that the help text for flag=1 should start with +# "Disable" and flag=0 should start with "Enable". +# +# In trying to helpfully map between --foo/--enable-foo/--disable-foo, +# it ends up creating some degree of confusion. options { with-tclsh:PATHNAME => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} - disable-tcl=0 => {building accessory programs that require TCL-dev} - enable-test-status=0 => {status of tests} - with-wasi-sdk:=/opt/wasi-sdk => {Path to the wasi-dsk} - disable-threadsafe=0 => mutexing - enable-releasemode=0 => {libtool link to release mode} - enable-tempstore=0 => {an in-ram database for temporary tables never,no,yes,always} - enable-editline=0 => {BSD editline support} - disable-readline=0 => {readline support} + tcl=1 => {Disable building accessory programs that require TCL-dev} + test-status => {Enable status of tests} + threadsafe=1 => {Disable mutexing} + releasemode => {libtool link to release mode} + tempstore=0 => {an in-ram database for temporary tables never,no,yes,always} + editline=0 => {BSD editline support} + readline=0 => {readline support} with-readline-lib => {readline library} with-readline-inc => {readline include paths} with-linenoise:DIR => {} - disable-amalgamation=0 => {Disable the amalgamation and instead build all files separately} - load-extension=1 => {loading of external extensions} - math=1 => {math functions} - json=1 => {JSON functions} - all=0 => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} - enable-memsys5=0 => MEMSYS5 - enable-memsys3=0 => MEMSYS3 - enable-fts3=0 => {Enable the FTS3 extension} - enable-fts4=0 => {Enable the FTS4 extension} - enable-fts5=0 => {Enable the FTS5 extension} - enable-update-limit=0 => {Enable the UPDATE/DELETE LIMIT clause} - enable-geopoly=0 => {Enable the GEOPOLY extension} - enable-rtree=0 => {Enable the RTREE extension} - enable-session=0 => {Enable the SESSION extension} - enable-gcov=0 => {Enable coverage testing using gcov} + amalgamation=1 => {Disable the amalgamation and instead build all files separately} + load-extension=1 => {Disable loading of external extensions} + math=1 => {Disable math functions} + json=1 => {Disable JSON functions} + all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} + memsys5 => {Enable MEMSYS5} + memsys3 => {Enable MEMSYS3} + fts3 => {Enable the FTS3 extension} + fts4 => {Enable the FTS4 extension} + fts5 => {Enable the FTS5 extension} + update-limit => {Enable the UPDATE/DELETE LIMIT clause} + geopoly => {Enable the GEOPOLY extension} + rtree => {Enable the RTREE extension} + session => {Enable the SESSION extension} + gcov => {Enable coverage testing using gcov} + with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build} dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} } # debug=0 => {debugging & verbose explain} @@ -124,6 +137,29 @@ proc add-feature-flag {flag} { } # add-feature-flag -DSQLITE_JUST_TESTING=3 +######################################################################## +# Force-set autosetup option $flag to $val. +proc opt-bool-set {flag {val 1}} { + if {![dict exists ::autosetup(options) $flag]} { + # We have to add this to autosetup(options) or else future calls + # to [opt-bool $flag] will fail validation of $flag. + dict set ::autosetup(options) $flag {} + } + dict set ::autosetup(optset) $flag $val +} + +######################################################################## +# If [opt-bool $boolFlag] is true, eval $then, else eval $else. +proc if-enabled {boolFlag then {else {}}} { + if {[opt-bool $boolFlag]} {eval $then} else {eval $else} +} + +######################################################################## +# If [opt-bool $boolFlag] is false, eval $then, else eval $else. +proc if-disabled {boolFlag then {else {}}} { + if {![opt-bool $boolFlag]} {eval $then} else {eval $else} +} + ######### # Programs needed if {1} { @@ -158,7 +194,6 @@ if {1} { malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 } - ########## # Handle --with-wasi-sdk=DIR # @@ -362,6 +397,14 @@ if {0} { # XXX fi # XXX AC_SUBST BUILD_CC +if-enabled all { + opt-bool-set fts4 + opt-bool-set fts5 + opt-bool-set geopoly + opt-bool-set rtree + opt-bool-set session +} + ########## # Do we want to support multithreaded use of sqlite # @@ -387,9 +430,11 @@ if {0} { ########## # Do we want to support release # -if {[opt-bool enable-releasemode]} { +if-enabled releasemode { + msg-result "Release-mode build." set enable_releasemode 1 -} else { +} { + msg-result "Non-release-mode build." set enable_releasemode 0 } @@ -658,22 +703,6 @@ if {0} { # XXX AC_SUBST HAVE_ZLIB } -proc if-disabled {boolFlag then {else {}}} { - if {![opt-bool $boolFlag]} { - eval $then - } else { - eval $else - } -} - -proc if-enabled {boolFlag then {else {}}} { - if {[opt-bool $boolFlag]} { - eval $then - } else { - eval $else - } -} - if-enabled load-extension { if {[cc-check-function-in-lib dlopen dl]} { define LDFLAGS_DLOPEN [get-define lib_dlopen] @@ -693,21 +722,17 @@ if-enabled math { define LDFLAGS_MATH [get-define lib_ceil] undefine lib_ceil add-feature-flag {-DSQLITE_ENABLE_MATH_FUNCTIONS} - msg-result "Enabling math functions." + msg-result "Enabling math SQL functions" } { define LDFLAGS_MATH "" - msg-result "Disabling math functions." + msg-result "Disabling math SQL functions" } if-enabled json { - msg-result "Enabling JSON SQL functions." + msg-result "Enabling JSON SQL functions" } { add-feature-flag {-DSQLITE_OMIT_JSON} - msg-result "Disabling JSON SQL functions." -} - -if-enabled all { - msg-result "TODO: handle --enable-all" + msg-result "Disabling JSON SQL functions" } if {0} { @@ -909,8 +934,18 @@ if {0} { # XXX AC_SUBST AMALGAMATION_LINE_MACROS } -######### -# Output the config header +foreach {boolFlag featureFlag} { + fts4 -DSQLITE_ENABLE_FTS4 + fts5 -DSQLITE_ENABLE_FTS5 + geopoly -DSQLITE_ENABLE_GEOPOLY + rtree -DSQLITE_ENABLE_GEOPOLY + session -DSQLITE_ENABLE_GEOPOLY +} { + if {[opt-bool $boolFlag]} { + add-feature-flag $featureFlag + msg-result "Enabling $boolFlag" + } +} if {0} { ######### @@ -922,6 +957,10 @@ if {0} { make-config-header sqlite_cfg.h } +if {"" ne [get-define OPT_FEATURE_FLAGS]} { + msg-result "Final feature flags: [get-define OPT_FEATURE_FLAGS]" +} + if {[opt-bool dump-defines]} { msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" make-config-header $DUMP_DEFINES_FILE -bare OPT_FEATURE_FLAGS -auto {*} diff --git a/manifest b/manifest index 0b72c18d59..b68744013f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sseveral\sof\sthe\s--enable/--disable\sconfigure\sflags\sworking. -D 2024-09-25T03:37:34.226 +C Get\s--enable-all\sflag\sessentially\sworking. +D 2024-09-25T04:20:58.189 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 1c121db3f48b25002887220168e1120b5f8865f2d0468d62dca4220192367bef +F auto.def 0b1a9058f9082f5583b7335eed55bbbfe480b17a0f9f0bac00c7538a82a242c9 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4b104926bf0862a5088e51549c2d688c2af649d45bf0e396cc48e171bed06b0a -R 5abab1c4da63e377666cdbb79ca9e337 +P fd16d53d3a95cd4f5f81f4b1b09955f04c89116586aa16fa01627ae4904d587b +R f6136e043e4d9fa45a54af863cc98153 U stephan -Z 675f689497b17977048f4ba0ec321727 +Z 3a634646a8a85d4b2cf979a7d9e5b89f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2d2859b16a..e5a87b78c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fd16d53d3a95cd4f5f81f4b1b09955f04c89116586aa16fa01627ae4904d587b +0a49436c983848c3d88f3f5ec33fb9ac31cce62e94bf515ab1c357a10f5cd515 From 4b5adfc6ba046ffcfb89c6cf82c0002549867457 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 04:34:16 +0000 Subject: [PATCH 007/522] Correct some copy/paste errors in the previous checkin. FossilOrigin-Name: 9752768d8a83052cb69fa07d51e2c82e710c20482cc02c33a4412ffdfa3dc699 --- auto.def | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index a386ecb0ee..5752e8404b 100644 --- a/auto.def +++ b/auto.def @@ -938,8 +938,8 @@ foreach {boolFlag featureFlag} { fts4 -DSQLITE_ENABLE_FTS4 fts5 -DSQLITE_ENABLE_FTS5 geopoly -DSQLITE_ENABLE_GEOPOLY - rtree -DSQLITE_ENABLE_GEOPOLY - session -DSQLITE_ENABLE_GEOPOLY + rtree -DSQLITE_ENABLE_RTREE + session -DSQLITE_ENABLE_SESSION } { if {[opt-bool $boolFlag]} { add-feature-flag $featureFlag diff --git a/manifest b/manifest index b68744013f..f9f8b35948 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\s--enable-all\sflag\sessentially\sworking. -D 2024-09-25T04:20:58.189 +C Correct\ssome\scopy/paste\serrors\sin\sthe\sprevious\scheckin. +D 2024-09-25T04:34:16.974 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 0b1a9058f9082f5583b7335eed55bbbfe480b17a0f9f0bac00c7538a82a242c9 +F auto.def 6f4df7f8eda3c5e4268eece057dfb8174d0bef3ee187f0d4bc239d691f8ab543 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fd16d53d3a95cd4f5f81f4b1b09955f04c89116586aa16fa01627ae4904d587b -R f6136e043e4d9fa45a54af863cc98153 +P 0a49436c983848c3d88f3f5ec33fb9ac31cce62e94bf515ab1c357a10f5cd515 +R 56e31490266a3fa122787b87ec5fdcc3 U stephan -Z 3a634646a8a85d4b2cf979a7d9e5b89f +Z 843bdfe8c3ebf9cba90f35ae570af0f3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e5a87b78c5..1c5047e03d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a49436c983848c3d88f3f5ec33fb9ac31cce62e94bf515ab1c357a10f5cd515 +9752768d8a83052cb69fa07d51e2c82e710c20482cc02c33a4412ffdfa3dc699 From bbd6ba04b9f18b6e9bfece09603c14c947cbdf13 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 06:07:54 +0000 Subject: [PATCH 008/522] Disable with --enable-all bits, as the helper function it uses is dying for reasons beyond my meager tcl-fu. FossilOrigin-Name: d2b883120e7ab374092d2bdef0faa22eaa9639cb103f9fbbbbfd16639fbfd323 --- auto.def | 225 +++++++++++++++++++------------------------------- manifest | 12 +-- manifest.uuid | 2 +- 3 files changed, 91 insertions(+), 148 deletions(-) diff --git a/auto.def b/auto.def index 5752e8404b..13daca806c 100644 --- a/auto.def +++ b/auto.def @@ -1,5 +1,4 @@ # Created by migrate-autoconf - fix items marked XXX - use cc cc-shared cc-lib hwaci-common set DUMP_DEFINES_FILE defines.list @@ -28,37 +27,39 @@ set DUMP_DEFINES_FILE defines.list # In trying to helpfully map between --foo/--enable-foo/--disable-foo, # it ends up creating some degree of confusion. options { - with-tclsh:PATHNAME => {Full pathname of tclsh to use} - with-tcl:DIR => {Directory containing tclConfig.sh} - tcl=1 => {Disable building accessory programs that require TCL-dev} - test-status => {Enable status of tests} - threadsafe=1 => {Disable mutexing} - releasemode => {libtool link to release mode} - tempstore=0 => {an in-ram database for temporary tables never,no,yes,always} - editline=0 => {BSD editline support} - readline=0 => {readline support} - with-readline-lib => {readline library} - with-readline-inc => {readline include paths} + with-tclsh:PATHNAME => {Full pathname of tclsh to use} + with-tcl:DIR => {Directory containing tclConfig.sh} + tcl=1 => {Disable building accessory programs that require TCL-dev} + test-status => {Enable status of tests} + threadsafe=1 => {Disable mutexing} + releasemode => {libtool link to release mode} + tempstore=0 => {an in-ram database for temporary tables never,no,yes,always} + editline=0 => {BSD editline support} + readline=0 => {readline support} + with-readline-lib => {readline library} + with-readline-inc => {readline include paths} with-linenoise:DIR => {} - amalgamation=1 => {Disable the amalgamation and instead build all files separately} - load-extension=1 => {Disable loading of external extensions} - math=1 => {Disable math functions} - json=1 => {Disable JSON functions} - all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} - memsys5 => {Enable MEMSYS5} - memsys3 => {Enable MEMSYS3} - fts3 => {Enable the FTS3 extension} - fts4 => {Enable the FTS4 extension} - fts5 => {Enable the FTS5 extension} - update-limit => {Enable the UPDATE/DELETE LIMIT clause} - geopoly => {Enable the GEOPOLY extension} - rtree => {Enable the RTREE extension} - session => {Enable the SESSION extension} - gcov => {Enable coverage testing using gcov} - with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build} - dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} -} -# debug=0 => {debugging & verbose explain} + amalgamation=1 => {Disable the amalgamation and instead build all files separately} + load-extension=1 => {Disable loading of external extensions} + math=1 => {Disable math functions} + json=1 => {Disable JSON functions} + all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} + memsys5 => {Enable MEMSYS5} + memsys3 => {Enable MEMSYS3} + fts3 => {Enable the FTS3 extension} + fts4 => {Enable the FTS4 extension} + fts5 => {Enable the FTS5 extension} + update-limit => {Enable the UPDATE/DELETE LIMIT clause} + geopoly => {Enable the GEOPOLY extension} + rtree => {Enable the RTREE extension} + session => {Enable the SESSION extension} + gcov => {Enable coverage testing using gcov} + linemacros => {Enable #line macros in the amalgamation.} + with-wasi-sdk:=/opt/wasi-sdk + => {Top-most dir of the wasi-sdk for a WASI build} + dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} +} +# debug=0 => {debugging & verbose explain} set srcdir $autosetup(srcdir) puts "srcdir = $srcdir" @@ -139,13 +140,20 @@ proc add-feature-flag {flag} { ######################################################################## # Force-set autosetup option $flag to $val. +# +# BUG: dies with "missing value to go with key, which indicates an arg +# count error to [dict exists]. Why it does that is a mystery, though. proc opt-bool-set {flag {val 1}} { - if {![dict exists ::autosetup(options) $flag]} { + global autosetup + #puts "DEBUG: opt-bool-set $flag $val. DICT=<<$::autosetup(options)>>" + if {![dict exists $::autosetup(options) $flag]} { # We have to add this to autosetup(options) or else future calls # to [opt-bool $flag] will fail validation of $flag. dict set ::autosetup(options) $flag {} } dict set ::autosetup(optset) $flag $val + #puts "DEBUG: opt-bool-set $flag $val = [opt-bool $flag]" + #puts "DEBUG: opt-bool-set $flag $val = [dict get $::autosetup(optset) $flag]" } ######################################################################## @@ -199,8 +207,8 @@ if {1} { # # This must be early because it changes the toolchain. # -# It's unclear whether we can actually get away with these changes in -# autosetup. +# It's unclear whether we can actually get away with making these +# changes to the autosetup environment. if {1} { set wasiSdkDir [lindex [opt-val with-wasi-sdk] end] if {$wasiSdkDir eq ""} { @@ -397,13 +405,20 @@ if {0} { # XXX fi # XXX AC_SUBST BUILD_CC -if-enabled all { - opt-bool-set fts4 - opt-bool-set fts5 - opt-bool-set geopoly - opt-bool-set rtree - opt-bool-set session -} +#opt-bool-set why-does-this-puke +#if-enabled all { +# opt-bool-set fts4 +# opt-bool-set fts5 +# opt-bool-set geopoly +# opt-bool-set rtree +# opt-bool-set session +#} + +#if-enabled geopoly {opt-bool-set rtree} +#if {[opt-bool geopoly]} { +# opt-bool-set rtree +#} + ########## # Do we want to support multithreaded use of sqlite @@ -793,69 +808,6 @@ if {0} { # XXX fi } - -if {0} { - ######### - # See whether we should enable the LIMIT clause on UPDATE and DELETE - # statements. - if {[opt-bool update-limit]} { - } - msg-checking "Checking whether to support LIMIT on UPDATE and DELETE statements..." - # XXX if test "${enable_update_limit}" = "yes" ; then - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" - msg-result "yes" - # XXX else - msg-result "no" - # XXX fi -} - -if {0} { - ######### - # See whether we should enable GEOPOLY - if {[opt-bool geopoly]} { - set enable_geopoly yes - } else { - set enable_geopoly no - } - msg-checking "Checking whether to support GEOPOLY..." - # XXX if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" - set enable_rtree yes - msg-result "yes" - # XXX else - msg-result "no" - # XXX fi -} - -if {0} { - ######### - # See whether we should enable RTREE - if {[opt-bool rtree]} { - } - msg-checking "Checking whether to support RTREE..." - # XXX if test "${enable_rtree}" = "yes" ; then - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE" - msg-result "yes" - # XXX else - msg-result "no" - # XXX fi -} - -if {0} { - ######### - # See whether we should enable the SESSION extension - if {[opt-bool session]} { - } - msg-checking "Checking whether to support SESSION..." - # XXX if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" - msg-result "yes" - # XXX else - msg-result "no" - # XXX fi -} - ######### # attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter # XXX for option in $CFLAGS $CPPFLAGS @@ -867,7 +819,6 @@ if {0} { # XXX done # XXX AC_SUBST OPT_FEATURE_FLAGS - # attempt to remove any OMITS and ENABLES from the $(CFLAGS) parameter # XXX ac_temp_CFLAGS="" # XXX for option in $CFLAGS @@ -880,7 +831,6 @@ if {0} { # XXX done # XXX CFLAGS=$ac_temp_CFLAGS - # attempt to remove any OMITS and ENABLES from the $(CPPFLAGS) parameter # XXX ac_temp_CPPFLAGS="" # XXX for option in $CPPFLAGS @@ -893,7 +843,6 @@ if {0} { # XXX done # XXX CPPFLAGS=$ac_temp_CPPFLAGS - # attempt to remove any OMITS and ENABLES from the $(BUILD_CFLAGS) parameter # XXX ac_temp_BUILD_CFLAGS="" # XXX for option in $BUILD_CFLAGS @@ -907,44 +856,37 @@ if {0} { # XXX BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS -if {0} { - ######### - # See whether we should use GCOV - if {[opt-bool gcov]} { - } - # XXX if test "${use_gcov}" = "yes" ; then - # XXX USE_GCOV=1 - # XXX else - # XXX USE_GCOV=0 - # XXX fi - # XXX AC_SUBST USE_GCOV -} - -if {0} { - ######### - # Enable/disabled amalagamation line macros - ######## - set linemacros 0 - # XXX if test "${amalgamation_line_macros}" = "yes" ; then - set linemacros 1 - # XXX fi - # XXX if test "${amalgamation_line_macros}" = "no" ; then - set linemacros 0 - # XXX fi - # XXX AC_SUBST AMALGAMATION_LINE_MACROS +if-enabled gcov { + define USE_GCOV 1 + msg-result "Enabling gcov" +} { + define USE_GCOV 0 } foreach {boolFlag featureFlag} { - fts4 -DSQLITE_ENABLE_FTS4 - fts5 -DSQLITE_ENABLE_FTS5 - geopoly -DSQLITE_ENABLE_GEOPOLY - rtree -DSQLITE_ENABLE_RTREE - session -DSQLITE_ENABLE_SESSION + fts4 -DSQLITE_ENABLE_FTS4 + fts5 -DSQLITE_ENABLE_FTS5 + geopoly -DSQLITE_ENABLE_GEOPOLY + rtree -DSQLITE_ENABLE_RTREE + session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} + update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT } { if {[opt-bool $boolFlag]} { add-feature-flag $featureFlag - msg-result "Enabling $boolFlag" + msg-checking "Enabling " + } else { + msg-checking "Not enabling " } + msg-result "$boolFlag" +} + +msg-checking "Use #line macros in the amalgamation: " +if-enabled linemacros { + define AMALGAMATION_LINE_MACROS {--linemacros=1} + msg-result yes +} { + define AMALGAMATION_LINE_MACROS {--linemacros=0} + msg-result no } if {0} { @@ -961,7 +903,8 @@ if {"" ne [get-define OPT_FEATURE_FLAGS]} { msg-result "Final feature flags: [get-define OPT_FEATURE_FLAGS]" } -if {[opt-bool dump-defines]} { - msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" - make-config-header $DUMP_DEFINES_FILE -bare OPT_FEATURE_FLAGS -auto {*} +if-enabled dump-defines { + global DUMP_DEFINES_FILE + msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" + make-config-header $DUMP_DEFINES_FILE -bare OPT_FEATURE_FLAGS -auto {*} } diff --git a/manifest b/manifest index f9f8b35948..d251b6a143 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\ssome\scopy/paste\serrors\sin\sthe\sprevious\scheckin. -D 2024-09-25T04:34:16.974 +C Disable\swith\s--enable-all\sbits,\sas\sthe\shelper\sfunction\sit\suses\sis\sdying\sfor\sreasons\sbeyond\smy\smeager\stcl-fu. +D 2024-09-25T06:07:54.339 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 6f4df7f8eda3c5e4268eece057dfb8174d0bef3ee187f0d4bc239d691f8ab543 +F auto.def b40b43d5a875219ce95e4f79e2af2e94dda6794499191be2f40bfee2c83f5a7e F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0a49436c983848c3d88f3f5ec33fb9ac31cce62e94bf515ab1c357a10f5cd515 -R 56e31490266a3fa122787b87ec5fdcc3 +P 9752768d8a83052cb69fa07d51e2c82e710c20482cc02c33a4412ffdfa3dc699 +R 0eddc38894d4661d5c3724c85feb2c7f U stephan -Z 843bdfe8c3ebf9cba90f35ae570af0f3 +Z feae9d13f636f6426ad2f0979409e029 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1c5047e03d..f89887f041 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9752768d8a83052cb69fa07d51e2c82e710c20482cc02c33a4412ffdfa3dc699 +d2b883120e7ab374092d2bdef0faa22eaa9639cb103f9fbbbbfd16639fbfd323 From 4e0208fd8ee7746656ac25bdaba179e6730fba41 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 06:25:33 +0000 Subject: [PATCH 009/522] Re-enable the --enable-all bits after figuring out that autosetup(options) is not a dict, but a list. FossilOrigin-Name: beb2a12045447586cc74f243d4f519c967595d929abe6330c2b1049897e8eaad --- auto.def | 34 ++++++++++++---------------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/auto.def b/auto.def index 13daca806c..9693371d9f 100644 --- a/auto.def +++ b/auto.def @@ -140,20 +140,14 @@ proc add-feature-flag {flag} { ######################################################################## # Force-set autosetup option $flag to $val. -# -# BUG: dies with "missing value to go with key, which indicates an arg -# count error to [dict exists]. Why it does that is a mystery, though. -proc opt-bool-set {flag {val 1}} { +proc opt-set {flag {val 1}} { global autosetup - #puts "DEBUG: opt-bool-set $flag $val. DICT=<<$::autosetup(options)>>" - if {![dict exists $::autosetup(options) $flag]} { + if {$flag ni $::autosetup(options)} { # We have to add this to autosetup(options) or else future calls # to [opt-bool $flag] will fail validation of $flag. - dict set ::autosetup(options) $flag {} + lappend ::autosetup(options) $flag } dict set ::autosetup(optset) $flag $val - #puts "DEBUG: opt-bool-set $flag $val = [opt-bool $flag]" - #puts "DEBUG: opt-bool-set $flag $val = [dict get $::autosetup(optset) $flag]" } ######################################################################## @@ -405,19 +399,15 @@ if {0} { # XXX fi # XXX AC_SUBST BUILD_CC -#opt-bool-set why-does-this-puke -#if-enabled all { -# opt-bool-set fts4 -# opt-bool-set fts5 -# opt-bool-set geopoly -# opt-bool-set rtree -# opt-bool-set session -#} - -#if-enabled geopoly {opt-bool-set rtree} -#if {[opt-bool geopoly]} { -# opt-bool-set rtree -#} +if-enabled all { + opt-set fts4 + opt-set fts5 + opt-set geopoly + opt-set rtree + opt-set session +} { + if-enabled geopoly {opt-set rtree} +} ########## diff --git a/manifest b/manifest index d251b6a143..30811fa47f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\swith\s--enable-all\sbits,\sas\sthe\shelper\sfunction\sit\suses\sis\sdying\sfor\sreasons\sbeyond\smy\smeager\stcl-fu. -D 2024-09-25T06:07:54.339 +C Re-enable\sthe\s--enable-all\sbits\safter\sfiguring\sout\sthat\sautosetup(options)\sis\snot\sa\sdict,\sbut\sa\slist. +D 2024-09-25T06:25:33.251 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def b40b43d5a875219ce95e4f79e2af2e94dda6794499191be2f40bfee2c83f5a7e +F auto.def 612211379b4bad517472ffdc7844787ae717555779ba5d4daf91ded4e3580b33 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9752768d8a83052cb69fa07d51e2c82e710c20482cc02c33a4412ffdfa3dc699 -R 0eddc38894d4661d5c3724c85feb2c7f +P d2b883120e7ab374092d2bdef0faa22eaa9639cb103f9fbbbbfd16639fbfd323 +R 6c833ff96fca19f682fd2f436027b582 U stephan -Z feae9d13f636f6426ad2f0979409e029 +Z 12d89494d4ba08947638b55ca875c9aa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f89887f041..084298881a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2b883120e7ab374092d2bdef0faa22eaa9639cb103f9fbbbbfd16639fbfd323 +beb2a12045447586cc74f243d4f519c967595d929abe6330c2b1049897e8eaad From cf9d95002e8e5182602999957544b9e3e0b54ba4 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 07:30:54 +0000 Subject: [PATCH 010/522] Add --enable-tempstore support and document some of the weirdness of trying to use an explicit prefix of --enable with non-boolean flags (autosetup unconditionally handles --enable and --disable prefixes on its own and always treats them as boolean flags). FossilOrigin-Name: fe6fa4ce5271c6265985574e1c406dda5b57f0dc360626800b6173a8f054bdab --- auto.def | 84 +++++++++++++++++++++++++++++---------------------- manifest | 12 ++++---- manifest.uuid | 2 +- 3 files changed, 55 insertions(+), 43 deletions(-) diff --git a/auto.def b/auto.def index 9693371d9f..1a110b49b8 100644 --- a/auto.def +++ b/auto.def @@ -26,6 +26,32 @@ set DUMP_DEFINES_FILE defines.list # # In trying to helpfully map between --foo/--enable-foo/--disable-foo, # it ends up creating some degree of confusion. +# +# Reminders about flag handling quirks.. +# +# 1) autosetup treats prefixes of 'enable' and 'disable' specially, +# leading to some incompatibilities with the historical sqlite3 +# configure script. +# +# Defining non-boolean flags named enable-foo requires different +# downstream handling of those flags. e.g. +# +# enable-tempstore:=no => {...} +# +# requires that [opt-val enable-tempstore], rather than [opt-val +# tempstore], be used, which is in constrast to boolean flags, where +# [opt-bool flag] must be used instead of [opt-bool enable-flag]. +# +# Also, passing --enable-tempstore with no value (to presumably get the +# default value) breaks: autosetup tries to find a boolean-type tempstore +# flag and cannot, so it complains that flag --tempstore is not defined. +# i.e. --enable-tempstore requires that it be passed a value. +# +# An awkward workaround for that, discovered only by random trial and +# error, is to define both {tempstore=1} and {enable-tempstore:}. With +# that in place --enable-tempstore, with no value, works as expected +# (why? Nobody knows!) but --tempstore can only ever be legally passed 0 or +# 1. options { with-tclsh:PATHNAME => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} @@ -33,7 +59,8 @@ options { test-status => {Enable status of tests} threadsafe=1 => {Disable mutexing} releasemode => {libtool link to release mode} - tempstore=0 => {an in-ram database for temporary tables never,no,yes,always} + tempstore=1 => {} + enable-tempstore: => {Use an in-ram database for temporary tables: never,no,yes,always} editline=0 => {BSD editline support} readline=0 => {readline support} with-readline-lib => {readline library} @@ -226,13 +253,13 @@ if {1} { # # Merely changing CC and LD to the wasi-sdk's is enough to get # sqlite3.o building in WASM format. - # XXX CC="${with_wasi_sdk}/bin/clang" - # XXX LD="${with_wasi_sdk}/bin/wasm-ld" - # XXX RANLIB="${with_wasi_sdk}/bin/llvm-ranlib" + # XXX CC="${wasiSdkDir}/bin/clang" + # XXX LD="${wasiSdkDir}/bin/wasm-ld" + # XXX RANLIB="${wasiSdkDir}/bin/llvm-ranlib" # set cross_compiling yes - # set enable_threadsafe no + # opt-set threadsafe 0 # set use_tcl no - # set enable_tcl no + # opt-set tcl 0 # libtool is apparently hard-coded to use gcc for linking DLLs, so # we disable the DLL build... # set enable_shared no @@ -457,37 +484,22 @@ if {0} { ########## # Do we want temporary databases in memory -# -if {0} { - if {[opt-bool tempstore]} { - } else { - set enable_tempstore no +if {1} { + set ts [opt-val enable-tempstore no] + set tsn 1 + msg-checking "Use an in-ram database for temporary tables? " + switch -- $ts { + never { set tsn 0 } + no { set tsn 1 } + yes { set tsn 2 } + always { set tsn 3 } + default { + user-error "Invalid enable-tempstore value \[$ts]. Use one of: no, yes, always, never" + } } - msg-checking "Checking whether to use an in-ram database for temporary tables..." - # XXX case "$enable_tempstore" in - # XXX never ) - # XXX TEMP_STORE=0 - msg-result "never" - # XXX ;; - # XXX no ) - # XXX TEMP_STORE=1 - msg-result "no" - # XXX ;; - # XXX yes ) - # XXX TEMP_STORE=2 - msg-result "yes" - # XXX ;; - # XXX always ) - # XXX TEMP_STORE=3 - msg-result "always" - # XXX ;; - # XXX * ) - # XXX TEMP_STORE=1 - msg-result "no" - # XXX ;; - # XXX esac - - # XXX AC_SUBST TEMP_STORE + msg-result $ts + define TEMP_STORE $tsn + unset ts tsn } if {0} { diff --git a/manifest b/manifest index 30811fa47f..6e023c5e54 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Re-enable\sthe\s--enable-all\sbits\safter\sfiguring\sout\sthat\sautosetup(options)\sis\snot\sa\sdict,\sbut\sa\slist. -D 2024-09-25T06:25:33.251 +C Add\s--enable-tempstore\ssupport\sand\sdocument\ssome\sof\sthe\sweirdness\sof\strying\sto\suse\san\sexplicit\sprefix\sof\s--enable\swith\snon-boolean\sflags\s(autosetup\sunconditionally\shandles\s--enable\sand\s--disable\sprefixes\son\sits\sown\sand\salways\streats\sthem\sas\sboolean\sflags). +D 2024-09-25T07:30:54.847 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 612211379b4bad517472ffdc7844787ae717555779ba5d4daf91ded4e3580b33 +F auto.def bf6823fc39c18f250e1a557fd1693d50907bb7c7bf64bb19c29976fcad8e9ac4 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d2b883120e7ab374092d2bdef0faa22eaa9639cb103f9fbbbbfd16639fbfd323 -R 6c833ff96fca19f682fd2f436027b582 +P beb2a12045447586cc74f243d4f519c967595d929abe6330c2b1049897e8eaad +R cb05e4344f4a5cf418370e9015944c67 U stephan -Z 12d89494d4ba08947638b55ca875c9aa +Z 2790adfba3be68b5a200dbb2ea24a505 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 084298881a..83aa0091d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -beb2a12045447586cc74f243d4f519c967595d929abe6330c2b1049897e8eaad +fe6fa4ce5271c6265985574e1c406dda5b57f0dc360626800b6173a8f054bdab From 2d0b1ae73bfc337841d29c3392d108c6dfc308bf Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 08:04:14 +0000 Subject: [PATCH 011/522] Baby steps towards a working auto.def. FossilOrigin-Name: c223dbb4fb8e800089752617c6c986b6c80be0d180e9d1610f28cf95253e5674 --- auto.def | 60 ++++++++++++++++++++++++++++++--------------------- manifest | 12 +++++------ manifest.uuid | 2 +- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/auto.def b/auto.def index 1a110b49b8..e4b2c9944b 100644 --- a/auto.def +++ b/auto.def @@ -1,6 +1,9 @@ # Created by migrate-autoconf - fix items marked XXX +global autosetup use cc cc-shared cc-lib hwaci-common set DUMP_DEFINES_FILE defines.list +set cross_compiling 0 +set enable_shared 1 ######################################################################## # Note that boolean flags... @@ -31,7 +34,7 @@ set DUMP_DEFINES_FILE defines.list # # 1) autosetup treats prefixes of 'enable' and 'disable' specially, # leading to some incompatibilities with the historical sqlite3 -# configure script. +# configure script flags. # # Defining non-boolean flags named enable-foo requires different # downstream handling of those flags. e.g. @@ -50,8 +53,8 @@ set DUMP_DEFINES_FILE defines.list # An awkward workaround for that, discovered only by random trial and # error, is to define both {tempstore=1} and {enable-tempstore:}. With # that in place --enable-tempstore, with no value, works as expected -# (why? Nobody knows!) but --tempstore can only ever be legally passed 0 or -# 1. +# (why? Nobody knows!) but --tempstore can only ever be legally passed +# a boolean value (0, 1, yes, no, enabled, disabled). options { with-tclsh:PATHNAME => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} @@ -155,8 +158,6 @@ puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" # files for the readline library. If the compiler is able # to find on its own, then this can be blank. -hwaci-check-exeext - ######################################################################## # OPT_FEATURE_FLAGS = -DSQLITE_OMIT/ENABLE flags. define OPT_FEATURE_FLAGS {} @@ -165,6 +166,17 @@ proc add-feature-flag {flag} { } # add-feature-flag -DSQLITE_JUST_TESTING=3 +hwaci-check-exeext +if {".exe" eq [get-define TARGET_EXEEXT]} { + define SQLITE_OS_UNIX 0 + define SQLITE_OS_WIN 1 + # todo? add -DSQLITE_OS_WIN=1 to CFLAGS? +} else { + define SQLITE_OS_UNIX 1 + define SQLITE_OS_WIN 0 + # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS? +} + ######################################################################## # Force-set autosetup option $flag to $val. proc opt-set {flag {val 1}} { @@ -191,37 +203,27 @@ proc if-disabled {boolFlag then {else {}}} { ######### # Programs needed -if {1} { - if {"" eq [hwaci-bin-define install]} { - msg-result "Cannot find install binary, so 'make install' will not work." - } +if {"" eq [hwaci-bin-define install]} { + msg-result "Cannot find install binary, so 'make install' will not work." } ######### # Enable large file support (if special flags are necessary) -if {1} { - cc-check-lfs -} +cc-check-lfs ######### # Check for needed/wanted data types -if {1} { - cc-check-types int8_t int16_t int32_t int64_t intptr_t \ - uint8_t uint16_t uint32_t uint64_t uintptr_t -} +cc-check-types int8_t int16_t int32_t int64_t intptr_t \ + uint8_t uint16_t uint32_t uint64_t uintptr_t ######### # Check for needed/wanted headers -if {1} { - cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h -} +cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h ######### # Figure out whether or not we have these functions -if {1} { - cc-check-functions fdatasync gmtime_r isnan localtime_r localtime_s \ - malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 -} +cc-check-functions fdatasync gmtime_r isnan localtime_r localtime_s \ + malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 ########## # Handle --with-wasi-sdk=DIR @@ -231,7 +233,8 @@ if {1} { # It's unclear whether we can actually get away with making these # changes to the autosetup environment. if {1} { - set wasiSdkDir [lindex [opt-val with-wasi-sdk] end] + set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] + #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" if {$wasiSdkDir eq ""} { define HAVE_WASI_SDK 0 define WASI_SDK_DIR "" @@ -243,6 +246,10 @@ if {1} { msg-result "using wasi-sdk clang, disabling: tcl, CLI shell, DLL" define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir + opt-set tcl 0 + opt-set threadsafe 0 + set cross_compiling 1 + set enable_shared 0 # Changing --host and --target have no effect here except to possibly # cause confusion. autoconf has finished processing them by this @@ -264,6 +271,7 @@ if {1} { # we disable the DLL build... # set enable_shared no } +# unset wasiSdkDir }; # --wasi-sdk-dir ######### @@ -908,5 +916,7 @@ if {"" ne [get-define OPT_FEATURE_FLAGS]} { if-enabled dump-defines { global DUMP_DEFINES_FILE msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" - make-config-header $DUMP_DEFINES_FILE -bare OPT_FEATURE_FLAGS -auto {*} + make-config-header $DUMP_DEFINES_FILE -bare {OPT_FEATURE_FLAGS SQLITE_OS_*} -auto {*} + # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will + # get _undefined_ here unless it's part of the -bare set. } diff --git a/manifest b/manifest index 6e023c5e54..b2eff07807 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s--enable-tempstore\ssupport\sand\sdocument\ssome\sof\sthe\sweirdness\sof\strying\sto\suse\san\sexplicit\sprefix\sof\s--enable\swith\snon-boolean\sflags\s(autosetup\sunconditionally\shandles\s--enable\sand\s--disable\sprefixes\son\sits\sown\sand\salways\streats\sthem\sas\sboolean\sflags). -D 2024-09-25T07:30:54.847 +C Baby\ssteps\stowards\sa\sworking\sauto.def. +D 2024-09-25T08:04:14.465 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def bf6823fc39c18f250e1a557fd1693d50907bb7c7bf64bb19c29976fcad8e9ac4 +F auto.def eb236b4f17149ff8ce2a5dcd68f3f0b9c349fd1c063975e808279cdd376a6ff6 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P beb2a12045447586cc74f243d4f519c967595d929abe6330c2b1049897e8eaad -R cb05e4344f4a5cf418370e9015944c67 +P fe6fa4ce5271c6265985574e1c406dda5b57f0dc360626800b6173a8f054bdab +R 63e04f82879526ec975f0378b679f11b U stephan -Z 2790adfba3be68b5a200dbb2ea24a505 +Z ab45cc0c2e7401e955c33f04a9ab6c02 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 83aa0091d8..376e62181f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe6fa4ce5271c6265985574e1c406dda5b57f0dc360626800b6173a8f054bdab +c223dbb4fb8e800089752617c6c986b6c80be0d180e9d1610f28cf95253e5674 From aaef970446878a137d65f7bead96234fa0d53988 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 12:16:13 +0000 Subject: [PATCH 012/522] Change --enable-tempstore to --with-tempstore to avoid the uphill (and losing) battle with autosetup's built-in handling of the --enable/--disable prefixes. FossilOrigin-Name: 8bea45fbbf8557760e792cdfcede72afa9e25dd7b90e4ce3297efebe8d0cfb1c --- auto.def | 13 ++++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/auto.def b/auto.def index e4b2c9944b..8f8a57bb1d 100644 --- a/auto.def +++ b/auto.def @@ -54,7 +54,11 @@ set enable_shared 1 # error, is to define both {tempstore=1} and {enable-tempstore:}. With # that in place --enable-tempstore, with no value, works as expected # (why? Nobody knows!) but --tempstore can only ever be legally passed -# a boolean value (0, 1, yes, no, enabled, disabled). +# a boolean value (0, 1, yes, no, enabled, disabled). It does, +# however, pollute the --help with a synthetic --disable-tempstore +# option. After an hour of fighting with it, a switch from +# --enable-tempstore to --with-tempstore seems like the better +# approach, in that it doesn't lead to a losing fight with autosetup. options { with-tclsh:PATHNAME => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} @@ -62,8 +66,7 @@ options { test-status => {Enable status of tests} threadsafe=1 => {Disable mutexing} releasemode => {libtool link to release mode} - tempstore=1 => {} - enable-tempstore: => {Use an in-ram database for temporary tables: never,no,yes,always} + with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always} editline=0 => {BSD editline support} readline=0 => {readline support} with-readline-lib => {readline library} @@ -493,7 +496,7 @@ if {0} { ########## # Do we want temporary databases in memory if {1} { - set ts [opt-val enable-tempstore no] + set ts [opt-val with-tempstore no] set tsn 1 msg-checking "Use an in-ram database for temporary tables? " switch -- $ts { @@ -502,7 +505,7 @@ if {1} { yes { set tsn 2 } always { set tsn 3 } default { - user-error "Invalid enable-tempstore value \[$ts]. Use one of: no, yes, always, never" + user-error "Invalid with-tempstore value \[$ts]. Use one of: no, yes, always, never" } } msg-result $ts diff --git a/manifest b/manifest index b2eff07807..5968de4007 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Baby\ssteps\stowards\sa\sworking\sauto.def. -D 2024-09-25T08:04:14.465 +C Change\s--enable-tempstore\sto\s--with-tempstore\sto\savoid\sthe\suphill\s(and\slosing)\sbattle\swith\sautosetup's\sbuilt-in\shandling\sof\sthe\s--enable/--disable\sprefixes. +D 2024-09-25T12:16:13.024 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def eb236b4f17149ff8ce2a5dcd68f3f0b9c349fd1c063975e808279cdd376a6ff6 +F auto.def 46adeff81937896526e074fb26dad88f482f44ab4577468a43da73304158d357 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fe6fa4ce5271c6265985574e1c406dda5b57f0dc360626800b6173a8f054bdab -R 63e04f82879526ec975f0378b679f11b +P c223dbb4fb8e800089752617c6c986b6c80be0d180e9d1610f28cf95253e5674 +R 780005d9a0ea48859fdd0440470d05eb U stephan -Z ab45cc0c2e7401e955c33f04a9ab6c02 +Z 67206b818d975312f9c5773e94dde53e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 376e62181f..d805c5e16f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c223dbb4fb8e800089752617c6c986b6c80be0d180e9d1610f28cf95253e5674 +8bea45fbbf8557760e792cdfcede72afa9e25dd7b90e4ce3297efebe8d0cfb1c From 13aea08683f65ac2fdfa7619c8b268dab5404022 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 14:38:46 +0000 Subject: [PATCH 013/522] Lots of work on auto.def and the utility tcl lib. Still lots more to do. FossilOrigin-Name: 2141527a38ca8170e79b5b5e664378f0d8464055119f5b986e5d7b1be75e919e --- Makefile.in | 3384 ++++++++++++++++++------------------ auto.def | 368 ++-- autosetup/hwaci-common.tcl | 48 +- manifest | 16 +- manifest.uuid | 2 +- 5 files changed, 1922 insertions(+), 1896 deletions(-) diff --git a/Makefile.in b/Makefile.in index dba80d38fb..264b68db9d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3,80 +3,80 @@ # Makefile for SQLITE # # This makefile is suppose to be configured automatically using the -# autoconf. But if that does not work for you, you can configure +# configure script. But if that does not work for you, you can configure # the makefile manually. Just set the parameters below to values that # work well for your system. # -# If the configure script does not work out-of-the-box, you might -# be able to get it to work by giving it some hints. See the comment -# at the beginning of configure.in for additional information. -# + +#XX# Lines starting with #XX# are TODOs for the port to autosetup # The toplevel directory of the source tree. This is the directory -# that contains this "Makefile.in" and the "configure.in" script. +# that contains this "Makefile.in" and the "configure" script. # -TOP = @abs_srcdir@ +TOP = @abs_top_srcdir@ # C Compiler and options for use in building executables that # will run on the platform that is doing the build. # -BCC = @BUILD_CC@ @BUILD_CFLAGS@ - -# TCC is the C Compile and options for use in building executables that -# will run on the target platform. (BCC and TCC are usually the -# same unless your are cross-compiling.) Separate CC and CFLAGS macros -# are provide so that these aspects of the build process can be changed -# on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" +BCC = @CC_FOR_BUILD@ +# TODO: @BUILD_CFLAGS@ # +#XX## TCC is the C Compile and options for use in building executables that +#XX## will run on the target platform. (BCC and TCC are usually the +#XX## same unless your are cross-compiling.) Separate CC and CFLAGS macros +#XX## are provide so that these aspects of the build process can be changed +#XX## on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" +#XX## CC = @CC@ CFLAGS = @CPPFLAGS@ @CFLAGS@ -TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu -TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session -TCC += -I${TOP}/ext/userauth - -# Define this for the autoconf-based build, so that the code knows it can -# include the generated sqlite_cfg.h -# -TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite - -# Define -DNDEBUG to compile without debugging (i.e., for production usage) -# Omitting the define will cause extra debugging code to be inserted and -# includes extra comments when "EXPLAIN stmt" is used. -# -TCC += @TARGET_DEBUG@ - -# Compiler options needed for programs that use the TCL library. -# -TCC += @TCL_INCLUDE_SPEC@ - -# The library that programs using TCL must link against. -# -LIBTCL = @TCL_LIB_SPEC@ - -# Compiler options needed for programs that use the readline() library. -# -READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@ -READLINE_FLAGS += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ -READLINE_FLAGS += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ - -# The library that programs using readline() must link against. -# -LIBREADLINE = @TARGET_READLINE_LIBS@ - -# Should the database engine be compiled threadsafe -# -TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ - -# Any target libraries which libsqlite must be linked against -# -TLIBS = @LIBS@ $(LIBS) - -# Flags controlling use of the in memory btree implementation -# -# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to -# default to file, 2 to default to memory, and 3 to force temporary -# tables to always be in memory. -# +#TODO: figure out how to get autosetup to do CC_FOR_TARGET. +#XX#TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu +#XX#TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session +#XX#TCC += -I${TOP}/ext/userauth +#XX# +#XX## Define this for the autoconf-based build, so that the code knows it can +#XX## include the generated sqlite_cfg.h +#XX## +#XX#TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite +#XX# +#XX## Define -DNDEBUG to compile without debugging (i.e., for production usage) +#XX## Omitting the define will cause extra debugging code to be inserted and +#XX## includes extra comments when "EXPLAIN stmt" is used. +#XX## +#XX#TCC += @TARGET_DEBUG@ +#XX# +#XX## Compiler options needed for programs that use the TCL library. +#XX## +#XX#TCC += @TCL_INCLUDE_SPEC@ +#XX# +#XX## The library that programs using TCL must link against. +#XX## +#XX#LIBTCL = @TCL_LIB_SPEC@ +#XX# +#XX## Compiler options needed for programs that use the readline() library. +#XX## +#XX#READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@ +#XX#READLINE_FLAGS += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ +#XX#READLINE_FLAGS += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ +#XX# +#XX## The library that programs using readline() must link against. +#XX## +#XX#LIBREADLINE = @TARGET_READLINE_LIBS@ +#XX# +#XX## Should the database engine be compiled threadsafe +#XX## +#XX#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ +#XX# +#XX## Any target libraries which libsqlite must be linked against +#XX## +#XX#TLIBS = @LIBS@ $(LIBS) +#XX# +#XX## Flags controlling use of the in memory btree implementation +#XX## +#XX## SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to +#XX## default to file, 2 to default to memory, and 3 to force temporary +#XX## tables to always be in memory. +#XX## TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@ # Enable/disable loadable extensions, and other optional features @@ -85,1635 +85,1637 @@ TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@ # LEMON parser generator and the mkkeywordhash tool as well. # # Add OPTIONS=... on the command line to append additional options -# to the OPT_FEATURE_FLAGS. +# to the OPT_FEATURE_FLAGS. Note that some flags only work if +# the build is specifically configured to account for them. # OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) - -TCC += $(OPT_FEATURE_FLAGS) - -# Add in any optional parameters specified on the make commane line -# ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". -TCC += $(OPTS) - -# Add in compile-time options for some libraries used by extensions -TCC += @HAVE_ZLIB@ - -# Version numbers and release number for the SQLite being compiled. -# -VERSION = @VERSION@ -VERSION_NUMBER = @VERSION_NUMBER@ -RELEASE = @RELEASE@ - -# Filename extensions -# -BEXE = @BUILD_EXEEXT@ -TEXE = @TARGET_EXEEXT@ - -# The following variable is "1" if the configure script was able to locate -# the tclConfig.sh file. It is an empty string otherwise. When this -# variable is "1", the TCL extension library (libtclsqlite3.so) is built -# and installed. -# -HAVE_TCL = @HAVE_TCL@ - -# This is the command to use for tclsh - normally just "tclsh", but we may -# know the specific version we want to use -# -TCLSH_CMD = @TCLSH_CMD@ - -# Additional options when running tests using testrunner.tcl -# This is usually either blank, or else --status -# -TSTRNNR_OPTS = @TSTRNNR_OPTS@ - -# Where do we want to install the tcl plugin -# -TCLLIBDIR = @TCLLIBDIR@ - -# If gcov support was enabled by the configure script, add the appropriate -# flags here. It's not always as easy as just having the user add the right -# CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which -# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs. -# Supposedly GCC does the right thing if you use --coverage, but in -# practice it still fails. See: -# -# http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html -# -# for more info. -# -GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage -GCOV_LDFLAGS1 = -lgcov -USE_GCOV = @USE_GCOV@ -LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) -LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) - - -# The directory into which to store package information for - -# Some standard variables and programs -# -prefix = @prefix@ -exec_prefix = @exec_prefix@ -libdir = @libdir@ -pkgconfigdir = $(libdir)/pkgconfig -bindir = @bindir@ -includedir = @includedir@ -INSTALL = @INSTALL@ -LIBTOOL = ./libtool -ALLOWRELEASE = @ALLOWRELEASE@ - -# libtool compile/link/install -LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS) -LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS) -LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) - -# You should not have to change anything below this line -############################################################################### - -USE_AMALGAMATION = @USE_AMALGAMATION@ -AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@ - -# Object files for the SQLite library (non-amalgamation). -# -LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ - backup.lo bitvec.lo btmutex.lo btree.lo build.lo \ - callback.lo complete.lo ctime.lo \ - date.lo dbpage.lo dbstat.lo delete.lo \ - expr.lo fault.lo fkey.lo \ - fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \ - fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \ - fts3_tokenize_vtab.lo \ - fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \ - fts5.lo \ - func.lo global.lo hash.lo \ - icu.lo insert.lo json.lo legacy.lo loadext.lo \ - main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \ - memdb.lo memjournal.lo \ - mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \ - notify.lo opcodes.lo os.lo os_kv.lo os_unix.lo os_win.lo \ - pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ - random.lo resolve.lo rowset.lo rtree.lo \ - sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \ - table.lo threads.lo tokenize.lo treeview.lo trigger.lo \ - update.lo userauth.lo upsert.lo util.lo vacuum.lo \ - vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ - vdbetrace.lo vdbevtab.lo \ - wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \ - window.lo utf.lo vtab.lo - -# Object files for the amalgamation. -# -LIBOBJS1 = sqlite3.lo - -# Determine the real value of LIBOBJ based on the 'configure' script -# -LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) - - -# All of the source code files. -# -SRC = \ - $(TOP)/src/alter.c \ - $(TOP)/src/analyze.c \ - $(TOP)/src/attach.c \ - $(TOP)/src/auth.c \ - $(TOP)/src/backup.c \ - $(TOP)/src/bitvec.c \ - $(TOP)/src/btmutex.c \ - $(TOP)/src/btree.c \ - $(TOP)/src/btree.h \ - $(TOP)/src/btreeInt.h \ - $(TOP)/src/build.c \ - $(TOP)/src/callback.c \ - $(TOP)/src/complete.c \ - $(TOP)/src/ctime.c \ - $(TOP)/src/date.c \ - $(TOP)/src/dbpage.c \ - $(TOP)/src/dbstat.c \ - $(TOP)/src/delete.c \ - $(TOP)/src/expr.c \ - $(TOP)/src/fault.c \ - $(TOP)/src/fkey.c \ - $(TOP)/src/func.c \ - $(TOP)/src/global.c \ - $(TOP)/src/hash.c \ - $(TOP)/src/hash.h \ - $(TOP)/src/hwtime.h \ - $(TOP)/src/insert.c \ - $(TOP)/src/json.c \ - $(TOP)/src/legacy.c \ - $(TOP)/src/loadext.c \ - $(TOP)/src/main.c \ - $(TOP)/src/malloc.c \ - $(TOP)/src/mem0.c \ - $(TOP)/src/mem1.c \ - $(TOP)/src/mem2.c \ - $(TOP)/src/mem3.c \ - $(TOP)/src/mem5.c \ - $(TOP)/src/memdb.c \ - $(TOP)/src/memjournal.c \ - $(TOP)/src/msvc.h \ - $(TOP)/src/mutex.c \ - $(TOP)/src/mutex.h \ - $(TOP)/src/mutex_noop.c \ - $(TOP)/src/mutex_unix.c \ - $(TOP)/src/mutex_w32.c \ - $(TOP)/src/notify.c \ - $(TOP)/src/os.c \ - $(TOP)/src/os.h \ - $(TOP)/src/os_common.h \ - $(TOP)/src/os_setup.h \ - $(TOP)/src/os_kv.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/os_win.h \ - $(TOP)/src/pager.c \ - $(TOP)/src/pager.h \ - $(TOP)/src/parse.y \ - $(TOP)/src/pcache.c \ - $(TOP)/src/pcache.h \ - $(TOP)/src/pcache1.c \ - $(TOP)/src/pragma.c \ - $(TOP)/src/pragma.h \ - $(TOP)/src/prepare.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/random.c \ - $(TOP)/src/resolve.c \ - $(TOP)/src/rowset.c \ - $(TOP)/src/select.c \ - $(TOP)/src/status.c \ - $(TOP)/src/shell.c.in \ - $(TOP)/src/sqlite.h.in \ - $(TOP)/src/sqlite3ext.h \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/sqliteLimit.h \ - $(TOP)/src/table.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/src/threads.c \ - $(TOP)/src/tokenize.c \ - $(TOP)/src/treeview.c \ - $(TOP)/src/trigger.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/update.c \ - $(TOP)/src/upsert.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vacuum.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/vdbe.h \ - $(TOP)/src/vdbeapi.c \ - $(TOP)/src/vdbeaux.c \ - $(TOP)/src/vdbeblob.c \ - $(TOP)/src/vdbemem.c \ - $(TOP)/src/vdbesort.c \ - $(TOP)/src/vdbetrace.c \ - $(TOP)/src/vdbevtab.c \ - $(TOP)/src/vdbeInt.h \ - $(TOP)/src/vtab.c \ - $(TOP)/src/vxworks.h \ - $(TOP)/src/wal.c \ - $(TOP)/src/wal.h \ - $(TOP)/src/walker.c \ - $(TOP)/src/where.c \ - $(TOP)/src/wherecode.c \ - $(TOP)/src/whereexpr.c \ - $(TOP)/src/whereInt.h \ - $(TOP)/src/window.c - -# Source code for extensions -# -SRC += \ - $(TOP)/ext/fts3/fts3.c \ - $(TOP)/ext/fts3/fts3.h \ - $(TOP)/ext/fts3/fts3Int.h \ - $(TOP)/ext/fts3/fts3_aux.c \ - $(TOP)/ext/fts3/fts3_expr.c \ - $(TOP)/ext/fts3/fts3_hash.c \ - $(TOP)/ext/fts3/fts3_hash.h \ - $(TOP)/ext/fts3/fts3_icu.c \ - $(TOP)/ext/fts3/fts3_porter.c \ - $(TOP)/ext/fts3/fts3_snippet.c \ - $(TOP)/ext/fts3/fts3_tokenizer.h \ - $(TOP)/ext/fts3/fts3_tokenizer.c \ - $(TOP)/ext/fts3/fts3_tokenizer1.c \ - $(TOP)/ext/fts3/fts3_tokenize_vtab.c \ - $(TOP)/ext/fts3/fts3_unicode.c \ - $(TOP)/ext/fts3/fts3_unicode2.c \ - $(TOP)/ext/fts3/fts3_write.c -SRC += \ - $(TOP)/ext/icu/sqliteicu.h \ - $(TOP)/ext/icu/icu.c -SRC += \ - $(TOP)/ext/rtree/rtree.h \ - $(TOP)/ext/rtree/rtree.c \ - $(TOP)/ext/rtree/geopoly.c -SRC += \ - $(TOP)/ext/session/sqlite3session.c \ - $(TOP)/ext/session/sqlite3session.h -SRC += \ - $(TOP)/ext/userauth/userauth.c \ - $(TOP)/ext/userauth/sqlite3userauth.h -SRC += \ - $(TOP)/ext/rbu/sqlite3rbu.h \ - $(TOP)/ext/rbu/sqlite3rbu.c -SRC += \ - $(TOP)/ext/misc/stmt.c - -# Generated source code files -# -SRC += \ - keywordhash.h \ - opcodes.c \ - opcodes.h \ - parse.c \ - parse.h \ - sqlite_cfg.h \ - shell.c \ - sqlite3.h - -# Source code to the test files. -# -TESTSRC = \ - $(TOP)/src/test1.c \ - $(TOP)/src/test2.c \ - $(TOP)/src/test3.c \ - $(TOP)/src/test4.c \ - $(TOP)/src/test5.c \ - $(TOP)/src/test6.c \ - $(TOP)/src/test8.c \ - $(TOP)/src/test9.c \ - $(TOP)/src/test_autoext.c \ - $(TOP)/src/test_async.c \ - $(TOP)/src/test_backup.c \ - $(TOP)/src/test_bestindex.c \ - $(TOP)/src/test_blob.c \ - $(TOP)/src/test_btree.c \ - $(TOP)/src/test_config.c \ - $(TOP)/src/test_delete.c \ - $(TOP)/src/test_demovfs.c \ - $(TOP)/src/test_devsym.c \ - $(TOP)/src/test_fs.c \ - $(TOP)/src/test_func.c \ - $(TOP)/src/test_hexio.c \ - $(TOP)/src/test_init.c \ - $(TOP)/src/test_intarray.c \ - $(TOP)/src/test_journal.c \ - $(TOP)/src/test_malloc.c \ - $(TOP)/src/test_md5.c \ - $(TOP)/src/test_multiplex.c \ - $(TOP)/src/test_mutex.c \ - $(TOP)/src/test_onefile.c \ - $(TOP)/src/test_osinst.c \ - $(TOP)/src/test_pcache.c \ - $(TOP)/src/test_quota.c \ - $(TOP)/src/test_rtree.c \ - $(TOP)/src/test_schema.c \ - $(TOP)/src/test_superlock.c \ - $(TOP)/src/test_syscall.c \ - $(TOP)/src/test_tclsh.c \ - $(TOP)/src/test_tclvar.c \ - $(TOP)/src/test_thread.c \ - $(TOP)/src/test_vdbecov.c \ - $(TOP)/src/test_vfs.c \ - $(TOP)/src/test_windirent.c \ - $(TOP)/src/test_window.c \ - $(TOP)/src/test_wsd.c \ - $(TOP)/ext/fts3/fts3_term.c \ - $(TOP)/ext/fts3/fts3_test.c \ - $(TOP)/ext/session/test_session.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/test_recover.c \ - $(TOP)/ext/intck/test_intck.c \ - $(TOP)/ext/intck/sqlite3intck.c \ - $(TOP)/ext/rbu/test_rbu.c - -# Statically linked extensions -# -TESTSRC += \ - $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/test_expert.c \ - $(TOP)/ext/misc/amatch.c \ - $(TOP)/ext/misc/appendvfs.c \ - $(TOP)/ext/misc/basexx.c \ - $(TOP)/ext/misc/carray.c \ - $(TOP)/ext/misc/cksumvfs.c \ - $(TOP)/ext/misc/closure.c \ - $(TOP)/ext/misc/csv.c \ - $(TOP)/ext/misc/decimal.c \ - $(TOP)/ext/misc/eval.c \ - $(TOP)/ext/misc/explain.c \ - $(TOP)/ext/misc/fileio.c \ - $(TOP)/ext/misc/fuzzer.c \ - $(TOP)/ext/fts5/fts5_tcl.c \ - $(TOP)/ext/fts5/fts5_test_mi.c \ - $(TOP)/ext/fts5/fts5_test_tok.c \ - $(TOP)/ext/misc/ieee754.c \ - $(TOP)/ext/misc/mmapwarm.c \ - $(TOP)/ext/misc/nextchar.c \ - $(TOP)/ext/misc/normalize.c \ - $(TOP)/ext/misc/percentile.c \ - $(TOP)/ext/misc/prefixes.c \ - $(TOP)/ext/misc/qpvtab.c \ - $(TOP)/ext/misc/randomjson.c \ - $(TOP)/ext/misc/regexp.c \ - $(TOP)/ext/misc/remember.c \ - $(TOP)/ext/misc/series.c \ - $(TOP)/ext/misc/spellfix.c \ - $(TOP)/ext/misc/stmtrand.c \ - $(TOP)/ext/misc/totype.c \ - $(TOP)/ext/misc/unionvtab.c \ - $(TOP)/ext/misc/wholenumber.c \ - $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/userauth/userauth.c \ - $(TOP)/ext/rtree/test_rtreedoc.c - -# Source code to the library files needed by the test fixture -# -TESTSRC2 = \ - $(TOP)/src/attach.c \ - $(TOP)/src/backup.c \ - $(TOP)/src/bitvec.c \ - $(TOP)/src/btree.c \ - $(TOP)/src/build.c \ - $(TOP)/src/ctime.c \ - $(TOP)/src/date.c \ - $(TOP)/src/dbpage.c \ - $(TOP)/src/dbstat.c \ - $(TOP)/src/expr.c \ - $(TOP)/src/func.c \ - $(TOP)/src/global.c \ - $(TOP)/src/insert.c \ - $(TOP)/src/wal.c \ - $(TOP)/src/main.c \ - $(TOP)/src/mem5.c \ - $(TOP)/src/os.c \ - $(TOP)/src/os_kv.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/pager.c \ - $(TOP)/src/pragma.c \ - $(TOP)/src/prepare.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/random.c \ - $(TOP)/src/pcache.c \ - $(TOP)/src/pcache1.c \ - $(TOP)/src/select.c \ - $(TOP)/src/tokenize.c \ - $(TOP)/src/treeview.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vdbeapi.c \ - $(TOP)/src/vdbeaux.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/vdbemem.c \ - $(TOP)/src/vdbetrace.c \ - $(TOP)/src/vdbevtab.c \ - $(TOP)/src/where.c \ - $(TOP)/src/wherecode.c \ - $(TOP)/src/whereexpr.c \ - $(TOP)/src/window.c \ - parse.c \ - $(TOP)/ext/fts3/fts3.c \ - $(TOP)/ext/fts3/fts3_aux.c \ - $(TOP)/ext/fts3/fts3_expr.c \ - $(TOP)/ext/fts3/fts3_term.c \ - $(TOP)/ext/fts3/fts3_tokenizer.c \ - $(TOP)/ext/fts3/fts3_write.c \ - $(TOP)/ext/async/sqlite3async.c \ - $(TOP)/ext/session/sqlite3session.c \ - $(TOP)/ext/misc/stmt.c \ - fts5.c - -# Header files used by all library source files. -# -HDR = \ - $(TOP)/src/btree.h \ - $(TOP)/src/btreeInt.h \ - $(TOP)/src/hash.h \ - $(TOP)/src/hwtime.h \ - keywordhash.h \ - $(TOP)/src/msvc.h \ - $(TOP)/src/mutex.h \ - opcodes.h \ - $(TOP)/src/os.h \ - $(TOP)/src/os_common.h \ - $(TOP)/src/os_setup.h \ - $(TOP)/src/os_win.h \ - $(TOP)/src/pager.h \ - $(TOP)/src/pcache.h \ - parse.h \ - $(TOP)/src/pragma.h \ - sqlite3.h \ - $(TOP)/src/sqlite3ext.h \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/sqliteLimit.h \ - $(TOP)/src/vdbe.h \ - $(TOP)/src/vdbeInt.h \ - $(TOP)/src/vxworks.h \ - $(TOP)/src/whereInt.h \ - sqlite_cfg.h - -# Header files used by extensions -# -EXTHDR += \ - $(TOP)/ext/fts3/fts3.h \ - $(TOP)/ext/fts3/fts3Int.h \ - $(TOP)/ext/fts3/fts3_hash.h \ - $(TOP)/ext/fts3/fts3_tokenizer.h -EXTHDR += \ - $(TOP)/ext/rtree/rtree.h \ - $(TOP)/ext/rtree/geopoly.c -EXTHDR += \ - $(TOP)/ext/icu/sqliteicu.h -EXTHDR += \ - $(TOP)/ext/rtree/sqlite3rtree.h -EXTHDR += \ - $(TOP)/ext/userauth/sqlite3userauth.h - -# executables needed for testing -# -TESTPROGS = \ - testfixture$(TEXE) \ - sqlite3$(TEXE) \ - sqlite3_analyzer$(TEXE) \ - sqldiff$(TEXE) \ - dbhash$(TEXE) \ - sqltclsh$(TEXE) - -# Databases containing fuzzer test cases -# -FUZZDATA = \ - $(TOP)/test/fuzzdata1.db \ - $(TOP)/test/fuzzdata2.db \ - $(TOP)/test/fuzzdata3.db \ - $(TOP)/test/fuzzdata4.db \ - $(TOP)/test/fuzzdata5.db \ - $(TOP)/test/fuzzdata6.db \ - $(TOP)/test/fuzzdata7.db \ - $(TOP)/test/fuzzdata8.db - -# Standard options to testfixture -# -TESTOPTS = --verbose=file --output=test-out.txt - -# Extra compiler options for various shell tools -# -SHELL_OPT += -DSQLITE_DQS=0 -SHELL_OPT += -DSQLITE_ENABLE_FTS4 -#SHELL_OPT += -DSQLITE_ENABLE_FTS5 -SHELL_OPT += -DSQLITE_ENABLE_RTREE -SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS -SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB -SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB -SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB -SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB -SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC -SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1 -FUZZERSHELL_OPT = -FUZZCHECK_OPT += -I$(TOP)/test -FUZZCHECK_OPT += -I$(TOP)/ext/recover -FUZZCHECK_OPT += \ - -DSQLITE_OSS_FUZZ \ - -DSQLITE_ENABLE_BYTECODE_VTAB \ - -DSQLITE_ENABLE_DBPAGE_VTAB \ - -DSQLITE_ENABLE_DBSTAT_VTAB \ - -DSQLITE_ENABLE_BYTECODE_VTAB \ - -DSQLITE_ENABLE_DESERIALIZE \ - -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ - -DSQLITE_ENABLE_FTS3_PARENTHESIS \ - -DSQLITE_ENABLE_FTS4 \ - -DSQLITE_ENABLE_FTS5 \ - -DSQLITE_ENABLE_GEOPOLY \ - -DSQLITE_ENABLE_MATH_FUNCTIONS \ - -DSQLITE_ENABLE_MEMSYS5 \ - -DSQLITE_ENABLE_NORMALIZE \ - -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ - -DSQLITE_ENABLE_PREUPDATE_HOOK \ - -DSQLITE_ENABLE_RTREE \ - -DSQLITE_ENABLE_SESSION \ - -DSQLITE_ENABLE_STMTVTAB \ - -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \ - -DSQLITE_ENABLE_STAT4 \ - -DSQLITE_ENABLE_STMT_SCANSTATUS \ - -DSQLITE_MAX_MEMORY=50000000 \ - -DSQLITE_MAX_MMAP_SIZE=0 \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_PRINTF_PRECISION_LIMIT=1000 \ - -DSQLITE_PRIVATE="" \ - -DSQLITE_STRICT_SUBTYPE=1 \ - -DSQLITE_STATIC_RANDOMJSON - -FUZZCHECK_SRC += $(TOP)/test/fuzzcheck.c -FUZZCHECK_SRC += $(TOP)/test/ossfuzz.c -FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c -FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c -FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c -FUZZCHECK_SRC += $(TOP)/test/vt02.c -FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c -FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c -DBFUZZ_OPT = -ST_OPT = -DSQLITE_OS_KV_OPTIONAL - - -# In wasi-sdk builds, disable the CLI shell build in the "all" target. -SQLITE3_SHELL_TARGET_ = sqlite3$(TEXE) -SQLITE3_SHELL_TARGET_1 = -SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@) - -# Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either -# libtclsqlite3.la or an empty value. -libtclsqlite3.la_0 = -libtclsqlite3.la_1 = libtclsqlite3.la - -# This is the default Makefile target. The objects listed here -# are what get build when you type just "make" with no arguments. -# -all: sqlite3.h libsqlite3.la $(SQLITE3_SHELL_TARGET) \ - $(libtclsqlite3.la_$(HAVE_TCL)) - -Makefile: $(TOP)/Makefile.in - ./config.status - -sqlite3.pc: $(TOP)/sqlite3.pc.in - ./config.status - -libsqlite3.la: $(LIBOBJ) - $(LTLINK) -no-undefined -o $@ $(LIBOBJ) $(TLIBS) \ - ${ALLOWRELEASE} -rpath "$(libdir)" -version-info "8:6:8" - -libtclsqlite3.la: tclsqlite.lo libsqlite3.la - $(LTLINK) -no-undefined -o $@ tclsqlite.lo \ - libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \ - -rpath "$(TCLLIBDIR)" \ - -version-info "8:6:8" \ - -avoid-version - -sqlite3$(TEXE): shell.c sqlite3.c - $(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ - shell.c sqlite3.c \ - $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" - -sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h - $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) - -dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h - $(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS) - -RSYNC_SRC = \ - $(TOP)/tool/sqlite3-rsync.c \ - sqlite3.c - -RSYNC_OPT = \ - -DSQLITE_ENABLE_DBPAGE_VTAB \ - -USQLITE_THREADSAFE \ - -DSQLITE_THREADSAFE=0 \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_OMIT_DEPRECATED - -sqlite3-rsync$(TEXE): $(RSYNC_SRC) - $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(TLIBS) - -scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo - $(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \ - $(TOP)/ext/misc/scrub.c sqlite3.lo $(TLIBS) - -srcck1$(BEXE): $(TOP)/tool/srcck1.c - $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c - -sourcetest: srcck1$(BEXE) sqlite3.c - ./srcck1 sqlite3.c - -src-verify: $(TOP)/tool/src-verify.c - $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c - -verify-source: ./src-verify - ./src-verify $(TOP) - -fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h - $(LTLINK) -o $@ $(FUZZERSHELL_OPT) \ - $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) - -fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) - -fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(LTLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) - -fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(LTLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) - -# Usage: FUZZDB=filename make run-fuzzcheck -# -# Where filename is a fuzzcheck database, this target builds and runs -# fuzzcheck, fuzzcheck-asan, and fuzzcheck-ubsan on that database. -# -# FUZZDB can be a glob pattern of two or more databases. Example: -# -# FUZZDB=test/fuzzdata*.db make run-fuzzcheck -# -run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) - @if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi - ./fuzzcheck$(TEXE) --spinner $(FUZZDB) - ./fuzzcheck-asan$(TEXE) --spinner $(FUZZDB) - ./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB) - -ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h - $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ - $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) - -sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h - $(LTLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS) - -dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h - $(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) - -DBFUZZ2_OPTS = \ - -DSQLITE_THREADSAFE=0 \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_DEBUG \ - -DSQLITE_ENABLE_DBSTAT_VTAB \ - -DSQLITE_ENABLE_BYTECODE_VTAB \ - -DSQLITE_ENABLE_RTREE \ - -DSQLITE_ENABLE_FTS4 \ - -DSQLITE_ENABLE_FTS5 - -dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - $(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ - -DSTANDALONE -o dbfuzz2 \ - $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) - mkdir -p dbfuzz2-dir - cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir - -dbfuzz2-asan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ - -fsanitize=fuzzer,undefined,address -o dbfuzz2-asan \ - $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) - mkdir -p dbfuzz2-dir - cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir - -dbfuzz2-msan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ - -fsanitize=fuzzer,undefined,memory -o dbfuzz2-msan \ - $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) - mkdir -p dbfuzz2-dir - cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir - -mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c - $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ - $(TLIBS) -rpath "$(libdir)" - -MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 -MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 -mptest: mptester$(TEXE) - rm -f mptest.db - $(MPTEST1) --journalmode DELETE - $(MPTEST2) --journalmode WAL - $(MPTEST1) --journalmode WAL - $(MPTEST2) --journalmode PERSIST - $(MPTEST1) --journalmode PERSIST - $(MPTEST2) --journalmode TRUNCATE - $(MPTEST1) --journalmode TRUNCATE - $(MPTEST2) --journalmode DELETE - - -has_tclsh84: - sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) - touch has_tclsh84 - -has_tclsh85: - sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) - touch has_tclsh85 - -has_tclconfig: - @ if test x"$(HAVE_TCL)" != "x1"; then echo 'ERROR: Requires access to "tclConfig.sh" which "configure" was not able to locate'; exit 1; fi - touch has_tclconfig - - -# This target creates a directory named "tsrc" and fills it with -# copies of all of the C source code and header files needed to -# build on the target system. Some of the C source code and header -# files are automatically generated. This target takes care of -# all that automatic generation. -# -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl has_tclsh84 fts5.c - rm -rf tsrc - mkdir tsrc - cp -f $(SRC) tsrc - rm tsrc/sqlite.h.in tsrc/parse.y - $(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new - mv vdbe.new tsrc/vdbe.c - cp fts5.c fts5.h tsrc - touch .target_source - -sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) - cp tsrc/sqlite3ext.h . - cp $(TOP)/ext/session/sqlite3session.h . - -sqlite3r.h: sqlite3.h has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h - -sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84 - cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ - cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ - cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) - -sqlite3ext.h: .target_source - cp tsrc/sqlite3ext.h . - -tclsqlite3.c: sqlite3.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 - -sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl - -# Rule to build the amalgamation -# -sqlite3.lo: sqlite3.c - $(LTCOMPILE) $(TEMP_STORE) -c sqlite3.c - -# Rules to build the LEMON compiler generator -# -lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c - $(BCC) -o $@ $(TOP)/tool/lemon.c - cp $(TOP)/tool/lempar.c . - -# Rules to build the program that generates the source-id -# -mksourceid$(BEXE): $(TOP)/tool/mksourceid.c - $(BCC) -o $@ $(TOP)/tool/mksourceid.c - -# Rules to build individual *.o files from generated *.c files. This -# applies to: -# -# parse.o -# opcodes.o -# -parse.lo: parse.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c parse.c - -opcodes.lo: opcodes.c - $(LTCOMPILE) $(TEMP_STORE) -c opcodes.c - -# Rules to build individual *.o files from files in the src directory. -# -alter.lo: $(TOP)/src/alter.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c - -analyze.lo: $(TOP)/src/analyze.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c - -attach.lo: $(TOP)/src/attach.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c - -auth.lo: $(TOP)/src/auth.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c - -backup.lo: $(TOP)/src/backup.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c - -bitvec.lo: $(TOP)/src/bitvec.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c - -btmutex.lo: $(TOP)/src/btmutex.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c - -btree.lo: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c - -build.lo: $(TOP)/src/build.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c - -callback.lo: $(TOP)/src/callback.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c - -complete.lo: $(TOP)/src/complete.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c - -ctime.lo: $(TOP)/src/ctime.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c - -date.lo: $(TOP)/src/date.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c - -dbpage.lo: $(TOP)/src/dbpage.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c - -dbstat.lo: $(TOP)/src/dbstat.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c - -delete.lo: $(TOP)/src/delete.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c - -expr.lo: $(TOP)/src/expr.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c - -fault.lo: $(TOP)/src/fault.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c - -fkey.lo: $(TOP)/src/fkey.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c - -func.lo: $(TOP)/src/func.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c - -global.lo: $(TOP)/src/global.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c - -hash.lo: $(TOP)/src/hash.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c - -insert.lo: $(TOP)/src/insert.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c - -json.lo: $(TOP)/src/json.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c - -legacy.lo: $(TOP)/src/legacy.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c - -loadext.lo: $(TOP)/src/loadext.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c - -main.lo: $(TOP)/src/main.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c - -malloc.lo: $(TOP)/src/malloc.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c - -mem0.lo: $(TOP)/src/mem0.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c - -mem1.lo: $(TOP)/src/mem1.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c - -mem2.lo: $(TOP)/src/mem2.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c - -mem3.lo: $(TOP)/src/mem3.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c - -mem5.lo: $(TOP)/src/mem5.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c - -memdb.lo: $(TOP)/src/memdb.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c - -memjournal.lo: $(TOP)/src/memjournal.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c - -mutex.lo: $(TOP)/src/mutex.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c - -mutex_noop.lo: $(TOP)/src/mutex_noop.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c - -mutex_unix.lo: $(TOP)/src/mutex_unix.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c - -mutex_w32.lo: $(TOP)/src/mutex_w32.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c - -notify.lo: $(TOP)/src/notify.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c - -pager.lo: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c - -pcache.lo: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c - -pcache1.lo: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c - -os.lo: $(TOP)/src/os.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c - -os_kv.lo: $(TOP)/src/os_kv.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c - -os_unix.lo: $(TOP)/src/os_unix.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c - -os_win.lo: $(TOP)/src/os_win.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c - -pragma.lo: $(TOP)/src/pragma.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c - -prepare.lo: $(TOP)/src/prepare.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c - -printf.lo: $(TOP)/src/printf.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c - -random.lo: $(TOP)/src/random.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c - -resolve.lo: $(TOP)/src/resolve.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c - -rowset.lo: $(TOP)/src/rowset.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c - -select.lo: $(TOP)/src/select.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c - -status.lo: $(TOP)/src/status.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c - -table.lo: $(TOP)/src/table.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c - -threads.lo: $(TOP)/src/threads.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c - -tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c - -treeview.lo: $(TOP)/src/treeview.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/treeview.c - -trigger.lo: $(TOP)/src/trigger.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c - -update.lo: $(TOP)/src/update.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c - -upsert.lo: $(TOP)/src/upsert.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c - -utf.lo: $(TOP)/src/utf.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c - -util.lo: $(TOP)/src/util.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c - -vacuum.lo: $(TOP)/src/vacuum.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c - -vdbe.lo: $(TOP)/src/vdbe.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c - -vdbeapi.lo: $(TOP)/src/vdbeapi.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c - -vdbeaux.lo: $(TOP)/src/vdbeaux.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c - -vdbeblob.lo: $(TOP)/src/vdbeblob.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c - -vdbemem.lo: $(TOP)/src/vdbemem.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c - -vdbesort.lo: $(TOP)/src/vdbesort.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c - -vdbetrace.lo: $(TOP)/src/vdbetrace.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c - -vdbevtab.lo: $(TOP)/src/vdbevtab.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c - -vtab.lo: $(TOP)/src/vtab.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c - -wal.lo: $(TOP)/src/wal.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c - -walker.lo: $(TOP)/src/walker.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c - -where.lo: $(TOP)/src/where.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c - -wherecode.lo: $(TOP)/src/wherecode.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c - -whereexpr.lo: $(TOP)/src/whereexpr.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c - -window.lo: $(TOP)/src/window.c $(HDR) - $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c - -tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c - -tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c - -tclsqlite-stubs.lo: $(TOP)/src/tclsqlite.c $(HDR) - $(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c - -tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.lo libsqlite3.la - $(LTLINK) -o $@ tclsqlite-shell.lo \ - libsqlite3.la $(LIBTCL) - -# Rules to build opcodes.c and opcodes.h -# -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c - -opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl has_tclsh84 - cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h - -# Rules to build parse.c and parse.h - the outputs of lemon. -# -parse.h: parse.c - -parse.c: $(TOP)/src/parse.y lemon$(BEXE) - cp $(TOP)/src/parse.y . - ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y - -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h - -sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 - echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ - echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ - cat $(TOP)/VERSION | $(TCLSH_CMD) $(TOP)/tool/replace.tcl exact . , >>$@ - echo '#endif' >>sqlite3rc.h - -keywordhash.h: $(TOP)/tool/mkkeywordhash.c - $(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c - ./mkkeywordhash$(BEXE) >keywordhash.h - -# Source and header files that shell.c depends on -SHELL_DEP = \ - $(TOP)/src/shell.c.in \ - $(TOP)/ext/consio/console_io.c \ - $(TOP)/ext/consio/console_io.h \ - $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/sqlite3expert.h \ - $(TOP)/ext/intck/sqlite3intck.c \ - $(TOP)/ext/intck/sqlite3intck.h \ - $(TOP)/ext/misc/appendvfs.c \ - $(TOP)/ext/misc/base64.c \ - $(TOP)/ext/misc/base85.c \ - $(TOP)/ext/misc/completion.c \ - $(TOP)/ext/misc/decimal.c \ - $(TOP)/ext/misc/fileio.c \ - $(TOP)/ext/misc/ieee754.c \ - $(TOP)/ext/misc/memtrace.c \ - $(TOP)/ext/misc/pcachetrace.c \ - $(TOP)/ext/misc/percentile.c \ - $(TOP)/ext/misc/regexp.c \ - $(TOP)/ext/misc/series.c \ - $(TOP)/ext/misc/sha1.c \ - $(TOP)/ext/misc/shathree.c \ - $(TOP)/ext/misc/sqlar.c \ - $(TOP)/ext/misc/uint.c \ - $(TOP)/ext/misc/vfstrace.c \ - $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/sqlite3recover.h \ - $(TOP)/src/test_windirent.c \ - $(TOP)/src/test_windirent.h - -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c - - - - -# Rules to build the extension objects. -# -icu.lo: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c - -fts3.lo: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c - -fts3_aux.lo: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c - -fts3_expr.lo: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c - -fts3_hash.lo: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c - -fts3_icu.lo: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c - -fts3_porter.lo: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c - -fts3_snippet.lo: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c - -fts3_tokenizer.lo: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c - -fts3_tokenizer1.lo: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c - -fts3_tokenize_vtab.lo: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c - -fts3_unicode.lo: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c - -fts3_unicode2.lo: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c - -fts3_write.lo: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c - -rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c - -userauth.lo: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c - -sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c - -stmt.lo: $(TOP)/ext/misc/stmt.c - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c - -# FTS5 things -# -FTS5_SRC = \ - $(TOP)/ext/fts5/fts5.h \ - $(TOP)/ext/fts5/fts5Int.h \ - $(TOP)/ext/fts5/fts5_aux.c \ - $(TOP)/ext/fts5/fts5_buffer.c \ - $(TOP)/ext/fts5/fts5_main.c \ - $(TOP)/ext/fts5/fts5_config.c \ - $(TOP)/ext/fts5/fts5_expr.c \ - $(TOP)/ext/fts5/fts5_hash.c \ - $(TOP)/ext/fts5/fts5_index.c \ - fts5parse.c fts5parse.h \ - $(TOP)/ext/fts5/fts5_storage.c \ - $(TOP)/ext/fts5/fts5_tokenize.c \ - $(TOP)/ext/fts5/fts5_unicode2.c \ - $(TOP)/ext/fts5/fts5_varint.c \ - $(TOP)/ext/fts5/fts5_vocab.c \ - -fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) - cp $(TOP)/ext/fts5/fts5parse.y . - rm -f fts5parse.h - ./lemon$(BEXE) $(OPTS) -S fts5parse.y - -fts5parse.h: fts5parse.c - -fts5.c: $(FTS5_SRC) has_tclsh84 - $(TCLSH_CMD) $(TOP)/ext/fts5/tool/mkfts5c.tcl - cp $(TOP)/ext/fts5/fts5.h . - -fts5.lo: fts5.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c fts5.c - -sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c - - -# Rules to build the 'testfixture' application. -# -# If using the amalgamation, use sqlite3.c directly to build the test -# fixture. Otherwise link against libsqlite3.la. (This distinction is -# necessary because the test fixture requires non-API symbols which are -# hidden when the library is built via the amalgamation). -# -TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 -TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit -TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE -TESTFIXTURE_FLAGS += -DBUILD_sqlite -TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 -TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB -TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC -TESTFIXTURE_FLAGS += -DSQLITE_STATIC_RANDOMJSON -TESTFIXTURE_FLAGS += -DSQLITE_STRICT_SUBTYPE=1 - -TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la -TESTFIXTURE_SRC1 = sqlite3.c -TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c -TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) - -testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) - $(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ - -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS) - -coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) - -testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) - -# A very detailed test running most or all test cases -fulltest: alltest fuzztest - -# Run most or all tcl test cases -alltest: $(TESTPROGS) - ./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS) - -# Really really long testing -soaktest: $(TESTPROGS) - ./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS) - -# Do extra testing but not everything. -fulltestonly: $(TESTPROGS) fuzztest - ./testfixture$(TEXE) $(TOP)/test/full.test - -# Fuzz testing -# -# WARNING: When the "fuzztest" target is run by the testrunner.tcl script, -# it does not actually run this code. Instead, it schedules equivalent -# commands. Therefore, if this target is updated, then code in -# testrunner_data.tcl (search for "trd_fuzztest_data") must also be updated. -# -fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) - ./fuzzcheck$(TEXE) $(FUZZDATA) - ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db - -valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) - valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) - valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db - -# The veryquick.test TCL tests. -# -tcltest: ./testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) - -# Runs all the same tests cases as the "tcltest" target but uses -# the testrunner.tcl script to run them in multiple cores -# concurrently. -testrunner: testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl - -# This is the testing target preferred by the core SQLite developers. -# It runs tests under a standard configuration, regardless of how -# ./configure was run. The devs run "make devtest" prior to each -# check-in, at a minimum. Probably other tests too, but at least this -# one. -# -devtest: srctree-check sourcetest - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) - -mdevtest: srctree-check has_tclsh85 - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) - -sdevtest: has_tclsh85 - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS) - -# Validate that various generated files in the source tree -# are up-to-date. -# -srctree-check: $(TOP)/tool/srctree-check.tcl - $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl - -# Testing for a release -# -releasetest: srctree-check has_tclsh85 verify-source - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS) - -# Minimal testing that runs in less than 3 minutes -# -quicktest: ./testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS) - -# Try to run tests on whatever options are specified by the -# ./configure. The developers seldom use this target. Instead -# they use "make devtest" which runs tests on a standard set of -# options regardless of how SQLite is configured. This "test" -# target is provided for legacy only. -# -test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest - -# Run a test using valgrind. This can take a really long time -# because valgrind is so much slower than a native machine. -# -valgrindtest: $(TESTPROGS) valgrindfuzz - OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) - -# A very fast test that checks basic sanity. The name comes from -# the 60s-era electronics testing: "Turn it on and see if smoke -# comes out." -# -smoketest: $(TESTPROGS) fuzzcheck$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS) - -shelltest: - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell - -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 - $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c - -sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c - $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(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 has_tclsh85 - $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c - -sqltclsh$(TEXE): has_tclconfig sqltclsh.c - $(LTLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS) - -sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c - $(LTLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(TLIBS) - -CHECKER_DEPS =\ - $(TOP)/tool/mkccode.tcl \ - sqlite3.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/ext/repair/sqlite3_checker.tcl \ - $(TOP)/ext/repair/checkindex.c \ - $(TOP)/ext/repair/checkfreelist.c \ - $(TOP)/ext/misc/btreeinfo.c \ - $(TOP)/ext/repair/sqlite3_checker.c.in - -sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 - $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ - -sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c - $(LTLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS) - -dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo - $(LTLINK) -DDBDUMP_STANDALONE -o $@ \ - $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS) - -dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c - $(LTLINK)-o $@ $(TOP)/tool/dbtotxt.c - -showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS) - -showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(TLIBS) - -showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(TLIBS) - -showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(TLIBS) - -showshm$(TEXE): $(TOP)/tool/showshm.c - $(LTLINK) -o $@ $(TOP)/tool/showshm.c - -index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo - $(LTLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(TLIBS) - -changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) - -changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS) - -rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) - -atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS) - -LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h - $(LTLINK) -I. -o $@ $(TOP)/tool/logest.c - -wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS) - -speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile - $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) - -startup$(TEXE): $(TOP)/test/startup.c sqlite3.c - $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) - -KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ - -kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c - $(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS) - -rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo - $(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS) - -loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la - $(LTLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(TLIBS) - -# This target will fail if the SQLite amalgamation contains any exported -# symbols that do not begin with "sqlite3_". It is run as part of the -# releasetest.tcl script. -# -VALIDIDS=' sqlite3(changeset|changegroup|session)?_' -checksymbols: sqlite3.o - nm -g --defined-only sqlite3.o - nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 - echo '0 errors out of 1 tests' - -# Build the amalgamation-autoconf package. The amalamgation-tarball target builds -# a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. -# The snapshot-tarball target builds a tarball named by the SHA1 hash -# -amalgamation-tarball: sqlite3.c sqlite3rc.h - TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal - -snapshot-tarball: sqlite3.c sqlite3rc.h - TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot - -# Build a ZIP archive containing various command-line tools. -# -tool-zip: testfixture sqlite3 sqldiff sqlite3_analyzer $(TOP)/tool/mktoolzip.tcl - ./testfixture $(TOP)/tool/mktoolzip.tcl - -# The next two rules are used to support the "threadtest" target. Building -# threadtest runs a few thread-safety tests that are implemented in C. This -# target is invoked by the releasetest.tcl script. -# -THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ - $(TOP)/test/tt3_checkpoint.c \ - $(TOP)/test/tt3_index.c \ - $(TOP)/test/tt3_vacuum.c \ - $(TOP)/test/tt3_stress.c \ - $(TOP)/test/tt3_lookaside1.c - -threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC) - $(LTLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(TLIBS) - -threadtest: threadtest3$(TEXE) - ./threadtest3$(TEXE) - -threadtest5: sqlite3.c $(TOP)/test/threadtest5.c - $(LTLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS) - -# Standard install and cleanup targets -# -lib_install: libsqlite3.la - $(INSTALL) -d $(DESTDIR)$(libdir) - $(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir) - -# Use $(tcl_install_$(HAVE_TCL)) to resolve to either tcl_install or -# an empty value. -tcl_install_0 = -tcl_install_1 = tcl_install - -install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc $(tcl_install_$(HAVE_TCL)) - $(INSTALL) -d $(DESTDIR)$(bindir) - $(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir) - $(INSTALL) -d $(DESTDIR)$(includedir) - $(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir) - $(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir) - $(INSTALL) -d $(DESTDIR)$(pkgconfigdir) - $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir) - -pkgIndex.tcl: - echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ - -tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl - $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR) - $(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR) - rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a - $(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR) - -# Build the SQLite TCL extension in a way that make it compatible -# with whatever version of TCL is running as $TCLSH_CMD, possibly defined -# by --with-tclsh= -# -tclextension: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc $(CC) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) - -# Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD -# to find it. -# -tclextension-install: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc $(CC) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) - -# Install the SQLite TCL extension that is used by $TCLSH_CMD -# -tclextension-uninstall: - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall - -# List all installed the SQLite TCL extension that is are accessible -# by $TCLSH_CMD, included prior versions. -# -tclextension-list: - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info - - -# Remove build products sufficient so that subsequent makes will recompile -# everything from scratch. Do not remove: -# -# * test results and test logs -# * output from ./configure -# -tidy: - rm -f *.lo *.la *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) - rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h - rm -rf .libs .deps tsrc .target_source - rm -f lemon$(BEXE) sqlite*.tar.gz - rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) - rm -f parse.* fts5parse.* - rm -f tclsqlite3$(TEXE) $(TESTPROGS) - rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) - rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) - rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) - rm -f *.dll *.lib *.exp *.def *.pc *.vsix *.so *.dylib pkgIndex.tcl - rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE) - rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) - rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) - rm -f threadtest5$(TEXE) - rm -f src-verify has_tclsh* - -# Removes build products and test logs. Retains ./configure outputs. -# -clean: tidy - rm -rf omittest* testrunner* testdir* - -# Clean up everything. No exceptions. -# -distclean: clean - rm -f sqlite_cfg.h config.log config.status Makefile $(LIBTOOL) - -# -# Windows section -# -dll: sqlite3.dll - -REAL_LIBOBJ = $(LIBOBJ:%.lo=.libs/%.o) - -$(REAL_LIBOBJ): $(LIBOBJ) - -sqlite3.def: $(REAL_LIBOBJ) - echo 'EXPORTS' >sqlite3.def - nm $(REAL_LIBOBJ) | grep ' T ' | grep ' _sqlite3_' \ - | sed 's/^.* _//' >>sqlite3.def - -sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def - $(TCC) -shared -o $@ sqlite3.def \ - -Wl,"--strip-all" $(REAL_LIBOBJ) - -# -# Fiddle app -# -fiddle: sqlite3.c shell.c - make -C ext/wasm fiddle emcc_opt=-Os - -# -# Spell-checking for source comments -# The sources checked are either C sources or C source templates. -# Their comments are extracted and processed through aspell using -# a custom dictionary that contains scads of odd identifiers that -# find their way into the comments. -# -# Currently, this target is setup to be "made" in-tree only. -# The output is ephemeral. Redirect it to guide spelling fixups, -# either to correct spelling or add words to tool/custom.txt. -# -./custom.rws: ./tool/custom.txt - @echo 'Updating custom dictionary from tool/custom.txt' - aspell --lang=en create master ./custom.rws < $< - -misspell: ./custom.rws has_tclsh84 - $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in - -# -# tool/version-info: a utility for emitting sqlite3 version info -# in various forms. -# -version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h - $(LTLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c +#XX# +#XX#TCC += $(OPT_FEATURE_FLAGS) +#XX# +#XX## Add in any optional parameters specified on the make commane line +#XX## ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". +#XX#TCC += $(OPTS) +#XX# +#XX## Add in compile-time options for some libraries used by extensions +#XX#TCC += @HAVE_ZLIB@ +#XX# +#XX## Version numbers and release number for the SQLite being compiled. +#XX## +#XX#VERSION = @VERSION@ +#XX#VERSION_NUMBER = @VERSION_NUMBER@ +#XX#RELEASE = @RELEASE@ +#XX# +#XX## Filename extensions +#XX## +#XX#BEXE = @BUILD_EXEEXT@ +#XX#TEXE = @TARGET_EXEEXT@ +#XX# +#XX## The following variable is "1" if the configure script was able to locate +#XX## the tclConfig.sh file. It is an empty string otherwise. When this +#XX## variable is "1", the TCL extension library (libtclsqlite3.so) is built +#XX## and installed. +#XX## +#XX#HAVE_TCL = @HAVE_TCL@ +#XX# +#XX## This is the command to use for tclsh - normally just "tclsh", but we may +#XX## know the specific version we want to use +#XX## +#XX#TCLSH_CMD = @TCLSH_CMD@ +#XX# +#XX## Additional options when running tests using testrunner.tcl +#XX## This is usually either blank, or else --status +#XX## +#XX#TSTRNNR_OPTS = @TSTRNNR_OPTS@ +#XX# +#XX## Where do we want to install the tcl plugin +#XX## +#XX#TCLLIBDIR = @TCLLIBDIR@ +#XX# +#XX## If gcov support was enabled by the configure script, add the appropriate +#XX## flags here. It's not always as easy as just having the user add the right +#XX## CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which +#XX## causes build errors with -fprofile-arcs -ftest-coverage with some GCCs. +#XX## Supposedly GCC does the right thing if you use --coverage, but in +#XX## practice it still fails. See: +#XX## +#XX## http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html +#XX## +#XX## for more info. +#XX## +#XX#GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage +#XX#GCOV_LDFLAGS1 = -lgcov +#XX#USE_GCOV = @USE_GCOV@ +#XX#LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) +#XX#LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) +#XX# +#XX# +#XX## The directory into which to store package information for +#XX# +#XX## Some standard variables and programs +#XX## +#XX#prefix = @prefix@ +#XX#exec_prefix = @exec_prefix@ +#XX#libdir = @libdir@ +#XX#pkgconfigdir = $(libdir)/pkgconfig +#XX#bindir = @bindir@ +#XX#includedir = @includedir@ +#XX#INSTALL = @INSTALL@ +#XX#LIBTOOL = ./libtool +#XX#ALLOWRELEASE = @ALLOWRELEASE@ +#XX# +#XX## libtool compile/link/install +#XX#LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS) +#XX#LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS) +#XX#LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) +#XX# +#XX## You should not have to change anything below this line +#XX################################################################################ +#XX# +#XX#USE_AMALGAMATION = @USE_AMALGAMATION@ +#XX#AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@ +#XX# +#XX## Object files for the SQLite library (non-amalgamation). +#XX## +#XX#LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ +#XX# backup.lo bitvec.lo btmutex.lo btree.lo build.lo \ +#XX# callback.lo complete.lo ctime.lo \ +#XX# date.lo dbpage.lo dbstat.lo delete.lo \ +#XX# expr.lo fault.lo fkey.lo \ +#XX# fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \ +#XX# fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \ +#XX# fts3_tokenize_vtab.lo \ +#XX# fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \ +#XX# fts5.lo \ +#XX# func.lo global.lo hash.lo \ +#XX# icu.lo insert.lo json.lo legacy.lo loadext.lo \ +#XX# main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \ +#XX# memdb.lo memjournal.lo \ +#XX# mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \ +#XX# notify.lo opcodes.lo os.lo os_kv.lo os_unix.lo os_win.lo \ +#XX# pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ +#XX# random.lo resolve.lo rowset.lo rtree.lo \ +#XX# sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \ +#XX# table.lo threads.lo tokenize.lo treeview.lo trigger.lo \ +#XX# update.lo userauth.lo upsert.lo util.lo vacuum.lo \ +#XX# vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ +#XX# vdbetrace.lo vdbevtab.lo \ +#XX# wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \ +#XX# window.lo utf.lo vtab.lo +#XX# +#XX## Object files for the amalgamation. +#XX## +#XX#LIBOBJS1 = sqlite3.lo +#XX# +#XX## Determine the real value of LIBOBJ based on the 'configure' script +#XX## +#XX#LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) +#XX# +#XX# +#XX## All of the source code files. +#XX## +#XX#SRC = \ +#XX# $(TOP)/src/alter.c \ +#XX# $(TOP)/src/analyze.c \ +#XX# $(TOP)/src/attach.c \ +#XX# $(TOP)/src/auth.c \ +#XX# $(TOP)/src/backup.c \ +#XX# $(TOP)/src/bitvec.c \ +#XX# $(TOP)/src/btmutex.c \ +#XX# $(TOP)/src/btree.c \ +#XX# $(TOP)/src/btree.h \ +#XX# $(TOP)/src/btreeInt.h \ +#XX# $(TOP)/src/build.c \ +#XX# $(TOP)/src/callback.c \ +#XX# $(TOP)/src/complete.c \ +#XX# $(TOP)/src/ctime.c \ +#XX# $(TOP)/src/date.c \ +#XX# $(TOP)/src/dbpage.c \ +#XX# $(TOP)/src/dbstat.c \ +#XX# $(TOP)/src/delete.c \ +#XX# $(TOP)/src/expr.c \ +#XX# $(TOP)/src/fault.c \ +#XX# $(TOP)/src/fkey.c \ +#XX# $(TOP)/src/func.c \ +#XX# $(TOP)/src/global.c \ +#XX# $(TOP)/src/hash.c \ +#XX# $(TOP)/src/hash.h \ +#XX# $(TOP)/src/hwtime.h \ +#XX# $(TOP)/src/insert.c \ +#XX# $(TOP)/src/json.c \ +#XX# $(TOP)/src/legacy.c \ +#XX# $(TOP)/src/loadext.c \ +#XX# $(TOP)/src/main.c \ +#XX# $(TOP)/src/malloc.c \ +#XX# $(TOP)/src/mem0.c \ +#XX# $(TOP)/src/mem1.c \ +#XX# $(TOP)/src/mem2.c \ +#XX# $(TOP)/src/mem3.c \ +#XX# $(TOP)/src/mem5.c \ +#XX# $(TOP)/src/memdb.c \ +#XX# $(TOP)/src/memjournal.c \ +#XX# $(TOP)/src/msvc.h \ +#XX# $(TOP)/src/mutex.c \ +#XX# $(TOP)/src/mutex.h \ +#XX# $(TOP)/src/mutex_noop.c \ +#XX# $(TOP)/src/mutex_unix.c \ +#XX# $(TOP)/src/mutex_w32.c \ +#XX# $(TOP)/src/notify.c \ +#XX# $(TOP)/src/os.c \ +#XX# $(TOP)/src/os.h \ +#XX# $(TOP)/src/os_common.h \ +#XX# $(TOP)/src/os_setup.h \ +#XX# $(TOP)/src/os_kv.c \ +#XX# $(TOP)/src/os_unix.c \ +#XX# $(TOP)/src/os_win.c \ +#XX# $(TOP)/src/os_win.h \ +#XX# $(TOP)/src/pager.c \ +#XX# $(TOP)/src/pager.h \ +#XX# $(TOP)/src/parse.y \ +#XX# $(TOP)/src/pcache.c \ +#XX# $(TOP)/src/pcache.h \ +#XX# $(TOP)/src/pcache1.c \ +#XX# $(TOP)/src/pragma.c \ +#XX# $(TOP)/src/pragma.h \ +#XX# $(TOP)/src/prepare.c \ +#XX# $(TOP)/src/printf.c \ +#XX# $(TOP)/src/random.c \ +#XX# $(TOP)/src/resolve.c \ +#XX# $(TOP)/src/rowset.c \ +#XX# $(TOP)/src/select.c \ +#XX# $(TOP)/src/status.c \ +#XX# $(TOP)/src/shell.c.in \ +#XX# $(TOP)/src/sqlite.h.in \ +#XX# $(TOP)/src/sqlite3ext.h \ +#XX# $(TOP)/src/sqliteInt.h \ +#XX# $(TOP)/src/sqliteLimit.h \ +#XX# $(TOP)/src/table.c \ +#XX# $(TOP)/src/tclsqlite.c \ +#XX# $(TOP)/src/threads.c \ +#XX# $(TOP)/src/tokenize.c \ +#XX# $(TOP)/src/treeview.c \ +#XX# $(TOP)/src/trigger.c \ +#XX# $(TOP)/src/utf.c \ +#XX# $(TOP)/src/update.c \ +#XX# $(TOP)/src/upsert.c \ +#XX# $(TOP)/src/util.c \ +#XX# $(TOP)/src/vacuum.c \ +#XX# $(TOP)/src/vdbe.c \ +#XX# $(TOP)/src/vdbe.h \ +#XX# $(TOP)/src/vdbeapi.c \ +#XX# $(TOP)/src/vdbeaux.c \ +#XX# $(TOP)/src/vdbeblob.c \ +#XX# $(TOP)/src/vdbemem.c \ +#XX# $(TOP)/src/vdbesort.c \ +#XX# $(TOP)/src/vdbetrace.c \ +#XX# $(TOP)/src/vdbevtab.c \ +#XX# $(TOP)/src/vdbeInt.h \ +#XX# $(TOP)/src/vtab.c \ +#XX# $(TOP)/src/vxworks.h \ +#XX# $(TOP)/src/wal.c \ +#XX# $(TOP)/src/wal.h \ +#XX# $(TOP)/src/walker.c \ +#XX# $(TOP)/src/where.c \ +#XX# $(TOP)/src/wherecode.c \ +#XX# $(TOP)/src/whereexpr.c \ +#XX# $(TOP)/src/whereInt.h \ +#XX# $(TOP)/src/window.c +#XX# +#XX## Source code for extensions +#XX## +#XX#SRC += \ +#XX# $(TOP)/ext/fts3/fts3.c \ +#XX# $(TOP)/ext/fts3/fts3.h \ +#XX# $(TOP)/ext/fts3/fts3Int.h \ +#XX# $(TOP)/ext/fts3/fts3_aux.c \ +#XX# $(TOP)/ext/fts3/fts3_expr.c \ +#XX# $(TOP)/ext/fts3/fts3_hash.c \ +#XX# $(TOP)/ext/fts3/fts3_hash.h \ +#XX# $(TOP)/ext/fts3/fts3_icu.c \ +#XX# $(TOP)/ext/fts3/fts3_porter.c \ +#XX# $(TOP)/ext/fts3/fts3_snippet.c \ +#XX# $(TOP)/ext/fts3/fts3_tokenizer.h \ +#XX# $(TOP)/ext/fts3/fts3_tokenizer.c \ +#XX# $(TOP)/ext/fts3/fts3_tokenizer1.c \ +#XX# $(TOP)/ext/fts3/fts3_tokenize_vtab.c \ +#XX# $(TOP)/ext/fts3/fts3_unicode.c \ +#XX# $(TOP)/ext/fts3/fts3_unicode2.c \ +#XX# $(TOP)/ext/fts3/fts3_write.c +#XX#SRC += \ +#XX# $(TOP)/ext/icu/sqliteicu.h \ +#XX# $(TOP)/ext/icu/icu.c +#XX#SRC += \ +#XX# $(TOP)/ext/rtree/rtree.h \ +#XX# $(TOP)/ext/rtree/rtree.c \ +#XX# $(TOP)/ext/rtree/geopoly.c +#XX#SRC += \ +#XX# $(TOP)/ext/session/sqlite3session.c \ +#XX# $(TOP)/ext/session/sqlite3session.h +#XX#SRC += \ +#XX# $(TOP)/ext/userauth/userauth.c \ +#XX# $(TOP)/ext/userauth/sqlite3userauth.h +#XX#SRC += \ +#XX# $(TOP)/ext/rbu/sqlite3rbu.h \ +#XX# $(TOP)/ext/rbu/sqlite3rbu.c +#XX#SRC += \ +#XX# $(TOP)/ext/misc/stmt.c +#XX# +#XX## Generated source code files +#XX## +#XX#SRC += \ +#XX# keywordhash.h \ +#XX# opcodes.c \ +#XX# opcodes.h \ +#XX# parse.c \ +#XX# parse.h \ +#XX# sqlite_cfg.h \ +#XX# shell.c \ +#XX# sqlite3.h +#XX# +#XX## Source code to the test files. +#XX## +#XX#TESTSRC = \ +#XX# $(TOP)/src/test1.c \ +#XX# $(TOP)/src/test2.c \ +#XX# $(TOP)/src/test3.c \ +#XX# $(TOP)/src/test4.c \ +#XX# $(TOP)/src/test5.c \ +#XX# $(TOP)/src/test6.c \ +#XX# $(TOP)/src/test8.c \ +#XX# $(TOP)/src/test9.c \ +#XX# $(TOP)/src/test_autoext.c \ +#XX# $(TOP)/src/test_async.c \ +#XX# $(TOP)/src/test_backup.c \ +#XX# $(TOP)/src/test_bestindex.c \ +#XX# $(TOP)/src/test_blob.c \ +#XX# $(TOP)/src/test_btree.c \ +#XX# $(TOP)/src/test_config.c \ +#XX# $(TOP)/src/test_delete.c \ +#XX# $(TOP)/src/test_demovfs.c \ +#XX# $(TOP)/src/test_devsym.c \ +#XX# $(TOP)/src/test_fs.c \ +#XX# $(TOP)/src/test_func.c \ +#XX# $(TOP)/src/test_hexio.c \ +#XX# $(TOP)/src/test_init.c \ +#XX# $(TOP)/src/test_intarray.c \ +#XX# $(TOP)/src/test_journal.c \ +#XX# $(TOP)/src/test_malloc.c \ +#XX# $(TOP)/src/test_md5.c \ +#XX# $(TOP)/src/test_multiplex.c \ +#XX# $(TOP)/src/test_mutex.c \ +#XX# $(TOP)/src/test_onefile.c \ +#XX# $(TOP)/src/test_osinst.c \ +#XX# $(TOP)/src/test_pcache.c \ +#XX# $(TOP)/src/test_quota.c \ +#XX# $(TOP)/src/test_rtree.c \ +#XX# $(TOP)/src/test_schema.c \ +#XX# $(TOP)/src/test_superlock.c \ +#XX# $(TOP)/src/test_syscall.c \ +#XX# $(TOP)/src/test_tclsh.c \ +#XX# $(TOP)/src/test_tclvar.c \ +#XX# $(TOP)/src/test_thread.c \ +#XX# $(TOP)/src/test_vdbecov.c \ +#XX# $(TOP)/src/test_vfs.c \ +#XX# $(TOP)/src/test_windirent.c \ +#XX# $(TOP)/src/test_window.c \ +#XX# $(TOP)/src/test_wsd.c \ +#XX# $(TOP)/ext/fts3/fts3_term.c \ +#XX# $(TOP)/ext/fts3/fts3_test.c \ +#XX# $(TOP)/ext/session/test_session.c \ +#XX# $(TOP)/ext/recover/sqlite3recover.c \ +#XX# $(TOP)/ext/recover/dbdata.c \ +#XX# $(TOP)/ext/recover/test_recover.c \ +#XX# $(TOP)/ext/intck/test_intck.c \ +#XX# $(TOP)/ext/intck/sqlite3intck.c \ +#XX# $(TOP)/ext/rbu/test_rbu.c +#XX# +#XX## Statically linked extensions +#XX## +#XX#TESTSRC += \ +#XX# $(TOP)/ext/expert/sqlite3expert.c \ +#XX# $(TOP)/ext/expert/test_expert.c \ +#XX# $(TOP)/ext/misc/amatch.c \ +#XX# $(TOP)/ext/misc/appendvfs.c \ +#XX# $(TOP)/ext/misc/basexx.c \ +#XX# $(TOP)/ext/misc/carray.c \ +#XX# $(TOP)/ext/misc/cksumvfs.c \ +#XX# $(TOP)/ext/misc/closure.c \ +#XX# $(TOP)/ext/misc/csv.c \ +#XX# $(TOP)/ext/misc/decimal.c \ +#XX# $(TOP)/ext/misc/eval.c \ +#XX# $(TOP)/ext/misc/explain.c \ +#XX# $(TOP)/ext/misc/fileio.c \ +#XX# $(TOP)/ext/misc/fuzzer.c \ +#XX# $(TOP)/ext/fts5/fts5_tcl.c \ +#XX# $(TOP)/ext/fts5/fts5_test_mi.c \ +#XX# $(TOP)/ext/fts5/fts5_test_tok.c \ +#XX# $(TOP)/ext/misc/ieee754.c \ +#XX# $(TOP)/ext/misc/mmapwarm.c \ +#XX# $(TOP)/ext/misc/nextchar.c \ +#XX# $(TOP)/ext/misc/normalize.c \ +#XX# $(TOP)/ext/misc/percentile.c \ +#XX# $(TOP)/ext/misc/prefixes.c \ +#XX# $(TOP)/ext/misc/qpvtab.c \ +#XX# $(TOP)/ext/misc/randomjson.c \ +#XX# $(TOP)/ext/misc/regexp.c \ +#XX# $(TOP)/ext/misc/remember.c \ +#XX# $(TOP)/ext/misc/series.c \ +#XX# $(TOP)/ext/misc/spellfix.c \ +#XX# $(TOP)/ext/misc/stmtrand.c \ +#XX# $(TOP)/ext/misc/totype.c \ +#XX# $(TOP)/ext/misc/unionvtab.c \ +#XX# $(TOP)/ext/misc/wholenumber.c \ +#XX# $(TOP)/ext/misc/zipfile.c \ +#XX# $(TOP)/ext/userauth/userauth.c \ +#XX# $(TOP)/ext/rtree/test_rtreedoc.c +#XX# +#XX## Source code to the library files needed by the test fixture +#XX## +#XX#TESTSRC2 = \ +#XX# $(TOP)/src/attach.c \ +#XX# $(TOP)/src/backup.c \ +#XX# $(TOP)/src/bitvec.c \ +#XX# $(TOP)/src/btree.c \ +#XX# $(TOP)/src/build.c \ +#XX# $(TOP)/src/ctime.c \ +#XX# $(TOP)/src/date.c \ +#XX# $(TOP)/src/dbpage.c \ +#XX# $(TOP)/src/dbstat.c \ +#XX# $(TOP)/src/expr.c \ +#XX# $(TOP)/src/func.c \ +#XX# $(TOP)/src/global.c \ +#XX# $(TOP)/src/insert.c \ +#XX# $(TOP)/src/wal.c \ +#XX# $(TOP)/src/main.c \ +#XX# $(TOP)/src/mem5.c \ +#XX# $(TOP)/src/os.c \ +#XX# $(TOP)/src/os_kv.c \ +#XX# $(TOP)/src/os_unix.c \ +#XX# $(TOP)/src/os_win.c \ +#XX# $(TOP)/src/pager.c \ +#XX# $(TOP)/src/pragma.c \ +#XX# $(TOP)/src/prepare.c \ +#XX# $(TOP)/src/printf.c \ +#XX# $(TOP)/src/random.c \ +#XX# $(TOP)/src/pcache.c \ +#XX# $(TOP)/src/pcache1.c \ +#XX# $(TOP)/src/select.c \ +#XX# $(TOP)/src/tokenize.c \ +#XX# $(TOP)/src/treeview.c \ +#XX# $(TOP)/src/utf.c \ +#XX# $(TOP)/src/util.c \ +#XX# $(TOP)/src/vdbeapi.c \ +#XX# $(TOP)/src/vdbeaux.c \ +#XX# $(TOP)/src/vdbe.c \ +#XX# $(TOP)/src/vdbemem.c \ +#XX# $(TOP)/src/vdbetrace.c \ +#XX# $(TOP)/src/vdbevtab.c \ +#XX# $(TOP)/src/where.c \ +#XX# $(TOP)/src/wherecode.c \ +#XX# $(TOP)/src/whereexpr.c \ +#XX# $(TOP)/src/window.c \ +#XX# parse.c \ +#XX# $(TOP)/ext/fts3/fts3.c \ +#XX# $(TOP)/ext/fts3/fts3_aux.c \ +#XX# $(TOP)/ext/fts3/fts3_expr.c \ +#XX# $(TOP)/ext/fts3/fts3_term.c \ +#XX# $(TOP)/ext/fts3/fts3_tokenizer.c \ +#XX# $(TOP)/ext/fts3/fts3_write.c \ +#XX# $(TOP)/ext/async/sqlite3async.c \ +#XX# $(TOP)/ext/session/sqlite3session.c \ +#XX# $(TOP)/ext/misc/stmt.c \ +#XX# fts5.c +#XX# +#XX## Header files used by all library source files. +#XX## +#XX#HDR = \ +#XX# $(TOP)/src/btree.h \ +#XX# $(TOP)/src/btreeInt.h \ +#XX# $(TOP)/src/hash.h \ +#XX# $(TOP)/src/hwtime.h \ +#XX# keywordhash.h \ +#XX# $(TOP)/src/msvc.h \ +#XX# $(TOP)/src/mutex.h \ +#XX# opcodes.h \ +#XX# $(TOP)/src/os.h \ +#XX# $(TOP)/src/os_common.h \ +#XX# $(TOP)/src/os_setup.h \ +#XX# $(TOP)/src/os_win.h \ +#XX# $(TOP)/src/pager.h \ +#XX# $(TOP)/src/pcache.h \ +#XX# parse.h \ +#XX# $(TOP)/src/pragma.h \ +#XX# sqlite3.h \ +#XX# $(TOP)/src/sqlite3ext.h \ +#XX# $(TOP)/src/sqliteInt.h \ +#XX# $(TOP)/src/sqliteLimit.h \ +#XX# $(TOP)/src/vdbe.h \ +#XX# $(TOP)/src/vdbeInt.h \ +#XX# $(TOP)/src/vxworks.h \ +#XX# $(TOP)/src/whereInt.h \ +#XX# sqlite_cfg.h +#XX# +#XX## Header files used by extensions +#XX## +#XX#EXTHDR += \ +#XX# $(TOP)/ext/fts3/fts3.h \ +#XX# $(TOP)/ext/fts3/fts3Int.h \ +#XX# $(TOP)/ext/fts3/fts3_hash.h \ +#XX# $(TOP)/ext/fts3/fts3_tokenizer.h +#XX#EXTHDR += \ +#XX# $(TOP)/ext/rtree/rtree.h \ +#XX# $(TOP)/ext/rtree/geopoly.c +#XX#EXTHDR += \ +#XX# $(TOP)/ext/icu/sqliteicu.h +#XX#EXTHDR += \ +#XX# $(TOP)/ext/rtree/sqlite3rtree.h +#XX#EXTHDR += \ +#XX# $(TOP)/ext/userauth/sqlite3userauth.h +#XX# +#XX## executables needed for testing +#XX## +#XX#TESTPROGS = \ +#XX# testfixture$(TEXE) \ +#XX# sqlite3$(TEXE) \ +#XX# sqlite3_analyzer$(TEXE) \ +#XX# sqldiff$(TEXE) \ +#XX# dbhash$(TEXE) \ +#XX# sqltclsh$(TEXE) +#XX# +#XX## Databases containing fuzzer test cases +#XX## +#XX#FUZZDATA = \ +#XX# $(TOP)/test/fuzzdata1.db \ +#XX# $(TOP)/test/fuzzdata2.db \ +#XX# $(TOP)/test/fuzzdata3.db \ +#XX# $(TOP)/test/fuzzdata4.db \ +#XX# $(TOP)/test/fuzzdata5.db \ +#XX# $(TOP)/test/fuzzdata6.db \ +#XX# $(TOP)/test/fuzzdata7.db \ +#XX# $(TOP)/test/fuzzdata8.db +#XX# +#XX## Standard options to testfixture +#XX## +#XX#TESTOPTS = --verbose=file --output=test-out.txt +#XX# +#XX## Extra compiler options for various shell tools +#XX## +#XX#SHELL_OPT += -DSQLITE_DQS=0 +#XX#SHELL_OPT += -DSQLITE_ENABLE_FTS4 +#XX##SHELL_OPT += -DSQLITE_ENABLE_FTS5 +#XX#SHELL_OPT += -DSQLITE_ENABLE_RTREE +#XX#SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS +#XX#SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +#XX#SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB +#XX#SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB +#XX#SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB +#XX#SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB +#XX#SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC +#XX#SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1 +#XX#FUZZERSHELL_OPT = +#XX#FUZZCHECK_OPT += -I$(TOP)/test +#XX#FUZZCHECK_OPT += -I$(TOP)/ext/recover +#XX#FUZZCHECK_OPT += \ +#XX# -DSQLITE_OSS_FUZZ \ +#XX# -DSQLITE_ENABLE_BYTECODE_VTAB \ +#XX# -DSQLITE_ENABLE_DBPAGE_VTAB \ +#XX# -DSQLITE_ENABLE_DBSTAT_VTAB \ +#XX# -DSQLITE_ENABLE_BYTECODE_VTAB \ +#XX# -DSQLITE_ENABLE_DESERIALIZE \ +#XX# -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ +#XX# -DSQLITE_ENABLE_FTS3_PARENTHESIS \ +#XX# -DSQLITE_ENABLE_FTS4 \ +#XX# -DSQLITE_ENABLE_FTS5 \ +#XX# -DSQLITE_ENABLE_GEOPOLY \ +#XX# -DSQLITE_ENABLE_MATH_FUNCTIONS \ +#XX# -DSQLITE_ENABLE_MEMSYS5 \ +#XX# -DSQLITE_ENABLE_NORMALIZE \ +#XX# -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ +#XX# -DSQLITE_ENABLE_PREUPDATE_HOOK \ +#XX# -DSQLITE_ENABLE_RTREE \ +#XX# -DSQLITE_ENABLE_SESSION \ +#XX# -DSQLITE_ENABLE_STMTVTAB \ +#XX# -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \ +#XX# -DSQLITE_ENABLE_STAT4 \ +#XX# -DSQLITE_ENABLE_STMT_SCANSTATUS \ +#XX# -DSQLITE_MAX_MEMORY=50000000 \ +#XX# -DSQLITE_MAX_MMAP_SIZE=0 \ +#XX# -DSQLITE_OMIT_LOAD_EXTENSION \ +#XX# -DSQLITE_PRINTF_PRECISION_LIMIT=1000 \ +#XX# -DSQLITE_PRIVATE="" \ +#XX# -DSQLITE_STRICT_SUBTYPE=1 \ +#XX# -DSQLITE_STATIC_RANDOMJSON +#XX# +#XX#FUZZCHECK_SRC += $(TOP)/test/fuzzcheck.c +#XX#FUZZCHECK_SRC += $(TOP)/test/ossfuzz.c +#XX#FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c +#XX#FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c +#XX#FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c +#XX#FUZZCHECK_SRC += $(TOP)/test/vt02.c +#XX#FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c +#XX#FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c +#XX#DBFUZZ_OPT = +#XX#ST_OPT = -DSQLITE_OS_KV_OPTIONAL +#XX# +#XX# +#XX## In wasi-sdk builds, disable the CLI shell build in the "all" target. +#XX#SQLITE3_SHELL_TARGET_ = sqlite3$(TEXE) +#XX#SQLITE3_SHELL_TARGET_1 = +#XX#SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@) +#XX# +#XX## Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either +#XX## libtclsqlite3.la or an empty value. +#XX#libtclsqlite3.la_0 = +#XX#libtclsqlite3.la_1 = libtclsqlite3.la +#XX# +#XX## This is the default Makefile target. The objects listed here +#XX## are what get build when you type just "make" with no arguments. +#XX## +#XX#all: sqlite3.h libsqlite3.la $(SQLITE3_SHELL_TARGET) \ +#XX# $(libtclsqlite3.la_$(HAVE_TCL)) +#XX# +#XX#Makefile: $(TOP)/Makefile.in +#XX# ./config.status +#XX# +#XX#sqlite3.pc: $(TOP)/sqlite3.pc.in +#XX# ./config.status +#XX# +#XX#libsqlite3.la: $(LIBOBJ) +#XX# $(LTLINK) -no-undefined -o $@ $(LIBOBJ) $(TLIBS) \ +#XX# ${ALLOWRELEASE} -rpath "$(libdir)" -version-info "8:6:8" +#XX# +#XX#libtclsqlite3.la: tclsqlite.lo libsqlite3.la +#XX# $(LTLINK) -no-undefined -o $@ tclsqlite.lo \ +#XX# libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \ +#XX# -rpath "$(TCLLIBDIR)" \ +#XX# -version-info "8:6:8" \ +#XX# -avoid-version +#XX# +#XX#sqlite3$(TEXE): shell.c sqlite3.c +#XX# $(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ +#XX# shell.c sqlite3.c \ +#XX# $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" +#XX# +#XX#sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h +#XX# $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) +#XX# +#XX#dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h +#XX# $(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS) +#XX# +#XX#RSYNC_SRC = \ +#XX# $(TOP)/tool/sqlite3-rsync.c \ +#XX# sqlite3.c +#XX# +#XX#RSYNC_OPT = \ +#XX# -DSQLITE_ENABLE_DBPAGE_VTAB \ +#XX# -USQLITE_THREADSAFE \ +#XX# -DSQLITE_THREADSAFE=0 \ +#XX# -DSQLITE_OMIT_LOAD_EXTENSION \ +#XX# -DSQLITE_OMIT_DEPRECATED +#XX# +#XX#sqlite3-rsync$(TEXE): $(RSYNC_SRC) +#XX# $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(TLIBS) +#XX# +#XX#scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo +#XX# $(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \ +#XX# $(TOP)/ext/misc/scrub.c sqlite3.lo $(TLIBS) +#XX# +#XX#srcck1$(BEXE): $(TOP)/tool/srcck1.c +#XX# $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c +#XX# +#XX#sourcetest: srcck1$(BEXE) sqlite3.c +#XX# ./srcck1 sqlite3.c +#XX# +#XX#src-verify: $(TOP)/tool/src-verify.c +#XX# $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c +#XX# +#XX#verify-source: ./src-verify +#XX# ./src-verify $(TOP) +#XX# +#XX#fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h +#XX# $(LTLINK) -o $@ $(FUZZERSHELL_OPT) \ +#XX# $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) +#XX# +#XX#fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) +#XX# $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) +#XX# +#XX#fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) +#XX# $(LTLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) +#XX# +#XX#fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) +#XX# $(LTLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) +#XX# +#XX## Usage: FUZZDB=filename make run-fuzzcheck +#XX## +#XX## Where filename is a fuzzcheck database, this target builds and runs +#XX## fuzzcheck, fuzzcheck-asan, and fuzzcheck-ubsan on that database. +#XX## +#XX## FUZZDB can be a glob pattern of two or more databases. Example: +#XX## +#XX## FUZZDB=test/fuzzdata*.db make run-fuzzcheck +#XX## +#XX#run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) +#XX# @if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi +#XX# ./fuzzcheck$(TEXE) --spinner $(FUZZDB) +#XX# ./fuzzcheck-asan$(TEXE) --spinner $(FUZZDB) +#XX# ./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB) +#XX# +#XX#ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h +#XX# $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ +#XX# $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) +#XX# +#XX#sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h +#XX# $(LTLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS) +#XX# +#XX#dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h +#XX# $(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) +#XX# +#XX#DBFUZZ2_OPTS = \ +#XX# -DSQLITE_THREADSAFE=0 \ +#XX# -DSQLITE_OMIT_LOAD_EXTENSION \ +#XX# -DSQLITE_DEBUG \ +#XX# -DSQLITE_ENABLE_DBSTAT_VTAB \ +#XX# -DSQLITE_ENABLE_BYTECODE_VTAB \ +#XX# -DSQLITE_ENABLE_RTREE \ +#XX# -DSQLITE_ENABLE_FTS4 \ +#XX# -DSQLITE_ENABLE_FTS5 +#XX# +#XX#dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h +#XX# $(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ +#XX# -DSTANDALONE -o dbfuzz2 \ +#XX# $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) +#XX# mkdir -p dbfuzz2-dir +#XX# cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir +#XX# +#XX#dbfuzz2-asan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h +#XX# clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ +#XX# -fsanitize=fuzzer,undefined,address -o dbfuzz2-asan \ +#XX# $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) +#XX# mkdir -p dbfuzz2-dir +#XX# cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir +#XX# +#XX#dbfuzz2-msan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h +#XX# clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ +#XX# -fsanitize=fuzzer,undefined,memory -o dbfuzz2-msan \ +#XX# $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) +#XX# mkdir -p dbfuzz2-dir +#XX# cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir +#XX# +#XX#mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c +#XX# $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ +#XX# $(TLIBS) -rpath "$(libdir)" +#XX# +#XX#MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 +#XX#MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 +#XX#mptest: mptester$(TEXE) +#XX# rm -f mptest.db +#XX# $(MPTEST1) --journalmode DELETE +#XX# $(MPTEST2) --journalmode WAL +#XX# $(MPTEST1) --journalmode WAL +#XX# $(MPTEST2) --journalmode PERSIST +#XX# $(MPTEST1) --journalmode PERSIST +#XX# $(MPTEST2) --journalmode TRUNCATE +#XX# $(MPTEST1) --journalmode TRUNCATE +#XX# $(MPTEST2) --journalmode DELETE +#XX# +#XX# +#XX#has_tclsh84: +#XX# sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) +#XX# touch has_tclsh84 +#XX# +#XX#has_tclsh85: +#XX# sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) +#XX# touch has_tclsh85 +#XX# +#XX#has_tclconfig: +#XX# @ if test x"$(HAVE_TCL)" != "x1"; then echo 'ERROR: Requires access to "tclConfig.sh" which "configure" was not able to locate'; exit 1; fi +#XX# touch has_tclconfig +#XX# +#XX# +#XX## This target creates a directory named "tsrc" and fills it with +#XX## copies of all of the C source code and header files needed to +#XX## build on the target system. Some of the C source code and header +#XX## files are automatically generated. This target takes care of +#XX## all that automatic generation. +#XX## +#XX#.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl has_tclsh84 fts5.c +#XX# rm -rf tsrc +#XX# mkdir tsrc +#XX# cp -f $(SRC) tsrc +#XX# rm tsrc/sqlite.h.in tsrc/parse.y +#XX# $(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new +#XX# mv vdbe.new tsrc/vdbe.c +#XX# cp fts5.c fts5.h tsrc +#XX# touch .target_source +#XX# +#XX#sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84 +#XX# $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) +#XX# cp tsrc/sqlite3ext.h . +#XX# cp $(TOP)/ext/session/sqlite3session.h . +#XX# +#XX#sqlite3r.h: sqlite3.h has_tclsh84 +#XX# $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h +#XX# +#XX#sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84 +#XX# cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ +#XX# cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ +#XX# cp $(TOP)/ext/recover/dbdata.c tsrc/ +#XX# $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) +#XX# +#XX#sqlite3ext.h: .target_source +#XX# cp tsrc/sqlite3ext.h . +#XX# +#XX#tclsqlite3.c: sqlite3.c +#XX# echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c +#XX# cat sqlite3.c >>tclsqlite3.c +#XX# echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c +#XX# cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c +#XX# +#XX#sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl has_tclsh84 +#XX# $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl +#XX# +#XX## Rule to build the amalgamation +#XX## +#XX#sqlite3.lo: sqlite3.c +#XX# $(LTCOMPILE) $(TEMP_STORE) -c sqlite3.c +#XX# +#XX## Rules to build the LEMON compiler generator +#XX## +#XX#lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c +#XX# $(BCC) -o $@ $(TOP)/tool/lemon.c +#XX# cp $(TOP)/tool/lempar.c . +#XX# +#XX## Rules to build the program that generates the source-id +#XX## +#XX#mksourceid$(BEXE): $(TOP)/tool/mksourceid.c +#XX# $(BCC) -o $@ $(TOP)/tool/mksourceid.c +#XX# +#XX## Rules to build individual *.o files from generated *.c files. This +#XX## applies to: +#XX## +#XX## parse.o +#XX## opcodes.o +#XX## +#XX#parse.lo: parse.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c parse.c +#XX# +#XX#opcodes.lo: opcodes.c +#XX# $(LTCOMPILE) $(TEMP_STORE) -c opcodes.c +#XX# +#XX## Rules to build individual *.o files from files in the src directory. +#XX## +#XX#alter.lo: $(TOP)/src/alter.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c +#XX# +#XX#analyze.lo: $(TOP)/src/analyze.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c +#XX# +#XX#attach.lo: $(TOP)/src/attach.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c +#XX# +#XX#auth.lo: $(TOP)/src/auth.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c +#XX# +#XX#backup.lo: $(TOP)/src/backup.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c +#XX# +#XX#bitvec.lo: $(TOP)/src/bitvec.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c +#XX# +#XX#btmutex.lo: $(TOP)/src/btmutex.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c +#XX# +#XX#btree.lo: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c +#XX# +#XX#build.lo: $(TOP)/src/build.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c +#XX# +#XX#callback.lo: $(TOP)/src/callback.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c +#XX# +#XX#complete.lo: $(TOP)/src/complete.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c +#XX# +#XX#ctime.lo: $(TOP)/src/ctime.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c +#XX# +#XX#date.lo: $(TOP)/src/date.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c +#XX# +#XX#dbpage.lo: $(TOP)/src/dbpage.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c +#XX# +#XX#dbstat.lo: $(TOP)/src/dbstat.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c +#XX# +#XX#delete.lo: $(TOP)/src/delete.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c +#XX# +#XX#expr.lo: $(TOP)/src/expr.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c +#XX# +#XX#fault.lo: $(TOP)/src/fault.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c +#XX# +#XX#fkey.lo: $(TOP)/src/fkey.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c +#XX# +#XX#func.lo: $(TOP)/src/func.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c +#XX# +#XX#global.lo: $(TOP)/src/global.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c +#XX# +#XX#hash.lo: $(TOP)/src/hash.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c +#XX# +#XX#insert.lo: $(TOP)/src/insert.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c +#XX# +#XX#json.lo: $(TOP)/src/json.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c +#XX# +#XX#legacy.lo: $(TOP)/src/legacy.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c +#XX# +#XX#loadext.lo: $(TOP)/src/loadext.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c +#XX# +#XX#main.lo: $(TOP)/src/main.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c +#XX# +#XX#malloc.lo: $(TOP)/src/malloc.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c +#XX# +#XX#mem0.lo: $(TOP)/src/mem0.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c +#XX# +#XX#mem1.lo: $(TOP)/src/mem1.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c +#XX# +#XX#mem2.lo: $(TOP)/src/mem2.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c +#XX# +#XX#mem3.lo: $(TOP)/src/mem3.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c +#XX# +#XX#mem5.lo: $(TOP)/src/mem5.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c +#XX# +#XX#memdb.lo: $(TOP)/src/memdb.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c +#XX# +#XX#memjournal.lo: $(TOP)/src/memjournal.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c +#XX# +#XX#mutex.lo: $(TOP)/src/mutex.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c +#XX# +#XX#mutex_noop.lo: $(TOP)/src/mutex_noop.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c +#XX# +#XX#mutex_unix.lo: $(TOP)/src/mutex_unix.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c +#XX# +#XX#mutex_w32.lo: $(TOP)/src/mutex_w32.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c +#XX# +#XX#notify.lo: $(TOP)/src/notify.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c +#XX# +#XX#pager.lo: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c +#XX# +#XX#pcache.lo: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c +#XX# +#XX#pcache1.lo: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c +#XX# +#XX#os.lo: $(TOP)/src/os.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c +#XX# +#XX#os_kv.lo: $(TOP)/src/os_kv.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c +#XX# +#XX#os_unix.lo: $(TOP)/src/os_unix.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c +#XX# +#XX#os_win.lo: $(TOP)/src/os_win.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c +#XX# +#XX#pragma.lo: $(TOP)/src/pragma.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c +#XX# +#XX#prepare.lo: $(TOP)/src/prepare.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c +#XX# +#XX#printf.lo: $(TOP)/src/printf.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c +#XX# +#XX#random.lo: $(TOP)/src/random.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c +#XX# +#XX#resolve.lo: $(TOP)/src/resolve.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c +#XX# +#XX#rowset.lo: $(TOP)/src/rowset.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c +#XX# +#XX#select.lo: $(TOP)/src/select.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c +#XX# +#XX#status.lo: $(TOP)/src/status.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c +#XX# +#XX#table.lo: $(TOP)/src/table.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c +#XX# +#XX#threads.lo: $(TOP)/src/threads.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c +#XX# +#XX#tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c +#XX# +#XX#treeview.lo: $(TOP)/src/treeview.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/treeview.c +#XX# +#XX#trigger.lo: $(TOP)/src/trigger.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c +#XX# +#XX#update.lo: $(TOP)/src/update.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c +#XX# +#XX#upsert.lo: $(TOP)/src/upsert.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c +#XX# +#XX#utf.lo: $(TOP)/src/utf.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c +#XX# +#XX#util.lo: $(TOP)/src/util.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c +#XX# +#XX#vacuum.lo: $(TOP)/src/vacuum.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c +#XX# +#XX#vdbe.lo: $(TOP)/src/vdbe.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c +#XX# +#XX#vdbeapi.lo: $(TOP)/src/vdbeapi.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c +#XX# +#XX#vdbeaux.lo: $(TOP)/src/vdbeaux.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c +#XX# +#XX#vdbeblob.lo: $(TOP)/src/vdbeblob.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c +#XX# +#XX#vdbemem.lo: $(TOP)/src/vdbemem.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c +#XX# +#XX#vdbesort.lo: $(TOP)/src/vdbesort.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c +#XX# +#XX#vdbetrace.lo: $(TOP)/src/vdbetrace.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c +#XX# +#XX#vdbevtab.lo: $(TOP)/src/vdbevtab.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c +#XX# +#XX#vtab.lo: $(TOP)/src/vtab.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c +#XX# +#XX#wal.lo: $(TOP)/src/wal.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c +#XX# +#XX#walker.lo: $(TOP)/src/walker.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c +#XX# +#XX#where.lo: $(TOP)/src/where.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c +#XX# +#XX#wherecode.lo: $(TOP)/src/wherecode.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c +#XX# +#XX#whereexpr.lo: $(TOP)/src/whereexpr.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c +#XX# +#XX#window.lo: $(TOP)/src/window.c $(HDR) +#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c +#XX# +#XX#tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) +#XX# $(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c +#XX# +#XX#tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR) +#XX# $(LTCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c +#XX# +#XX#tclsqlite-stubs.lo: $(TOP)/src/tclsqlite.c $(HDR) +#XX# $(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c +#XX# +#XX#tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.lo libsqlite3.la +#XX# $(LTLINK) -o $@ tclsqlite-shell.lo \ +#XX# libsqlite3.la $(LIBTCL) +#XX# +#XX## Rules to build opcodes.c and opcodes.h +#XX## +#XX#opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl has_tclsh84 +#XX# $(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c +#XX# +#XX#opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl has_tclsh84 +#XX# cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h +#XX# +#XX## Rules to build parse.c and parse.h - the outputs of lemon. +#XX## +#XX#parse.h: parse.c +#XX# +#XX#parse.c: $(TOP)/src/parse.y lemon$(BEXE) +#XX# cp $(TOP)/src/parse.y . +#XX# ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y +#XX# +#XX#sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION has_tclsh84 +#XX# $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h +#XX# +#XX#sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 +#XX# echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ +#XX# echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ +#XX# cat $(TOP)/VERSION | $(TCLSH_CMD) $(TOP)/tool/replace.tcl exact . , >>$@ +#XX# echo '#endif' >>sqlite3rc.h +#XX# +#XX#keywordhash.h: $(TOP)/tool/mkkeywordhash.c +#XX# $(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c +#XX# ./mkkeywordhash$(BEXE) >keywordhash.h +#XX# +#XX## Source and header files that shell.c depends on +#XX#SHELL_DEP = \ +#XX# $(TOP)/src/shell.c.in \ +#XX# $(TOP)/ext/consio/console_io.c \ +#XX# $(TOP)/ext/consio/console_io.h \ +#XX# $(TOP)/ext/expert/sqlite3expert.c \ +#XX# $(TOP)/ext/expert/sqlite3expert.h \ +#XX# $(TOP)/ext/intck/sqlite3intck.c \ +#XX# $(TOP)/ext/intck/sqlite3intck.h \ +#XX# $(TOP)/ext/misc/appendvfs.c \ +#XX# $(TOP)/ext/misc/base64.c \ +#XX# $(TOP)/ext/misc/base85.c \ +#XX# $(TOP)/ext/misc/completion.c \ +#XX# $(TOP)/ext/misc/decimal.c \ +#XX# $(TOP)/ext/misc/fileio.c \ +#XX# $(TOP)/ext/misc/ieee754.c \ +#XX# $(TOP)/ext/misc/memtrace.c \ +#XX# $(TOP)/ext/misc/pcachetrace.c \ +#XX# $(TOP)/ext/misc/percentile.c \ +#XX# $(TOP)/ext/misc/regexp.c \ +#XX# $(TOP)/ext/misc/series.c \ +#XX# $(TOP)/ext/misc/sha1.c \ +#XX# $(TOP)/ext/misc/shathree.c \ +#XX# $(TOP)/ext/misc/sqlar.c \ +#XX# $(TOP)/ext/misc/uint.c \ +#XX# $(TOP)/ext/misc/vfstrace.c \ +#XX# $(TOP)/ext/misc/zipfile.c \ +#XX# $(TOP)/ext/recover/dbdata.c \ +#XX# $(TOP)/ext/recover/sqlite3recover.c \ +#XX# $(TOP)/ext/recover/sqlite3recover.h \ +#XX# $(TOP)/src/test_windirent.c \ +#XX# $(TOP)/src/test_windirent.h +#XX# +#XX#shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl has_tclsh84 +#XX# $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c +#XX# +#XX# +#XX# +#XX# +#XX## Rules to build the extension objects. +#XX## +#XX#icu.lo: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c +#XX# +#XX#fts3.lo: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c +#XX# +#XX#fts3_aux.lo: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c +#XX# +#XX#fts3_expr.lo: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c +#XX# +#XX#fts3_hash.lo: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c +#XX# +#XX#fts3_icu.lo: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c +#XX# +#XX#fts3_porter.lo: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c +#XX# +#XX#fts3_snippet.lo: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c +#XX# +#XX#fts3_tokenizer.lo: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c +#XX# +#XX#fts3_tokenizer1.lo: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c +#XX# +#XX#fts3_tokenize_vtab.lo: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c +#XX# +#XX#fts3_unicode.lo: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c +#XX# +#XX#fts3_unicode2.lo: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c +#XX# +#XX#fts3_write.lo: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c +#XX# +#XX#rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c +#XX# +#XX#userauth.lo: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c +#XX# +#XX#sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c +#XX# +#XX#stmt.lo: $(TOP)/ext/misc/stmt.c +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c +#XX# +#XX## FTS5 things +#XX## +#XX#FTS5_SRC = \ +#XX# $(TOP)/ext/fts5/fts5.h \ +#XX# $(TOP)/ext/fts5/fts5Int.h \ +#XX# $(TOP)/ext/fts5/fts5_aux.c \ +#XX# $(TOP)/ext/fts5/fts5_buffer.c \ +#XX# $(TOP)/ext/fts5/fts5_main.c \ +#XX# $(TOP)/ext/fts5/fts5_config.c \ +#XX# $(TOP)/ext/fts5/fts5_expr.c \ +#XX# $(TOP)/ext/fts5/fts5_hash.c \ +#XX# $(TOP)/ext/fts5/fts5_index.c \ +#XX# fts5parse.c fts5parse.h \ +#XX# $(TOP)/ext/fts5/fts5_storage.c \ +#XX# $(TOP)/ext/fts5/fts5_tokenize.c \ +#XX# $(TOP)/ext/fts5/fts5_unicode2.c \ +#XX# $(TOP)/ext/fts5/fts5_varint.c \ +#XX# $(TOP)/ext/fts5/fts5_vocab.c \ +#XX# +#XX#fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) +#XX# cp $(TOP)/ext/fts5/fts5parse.y . +#XX# rm -f fts5parse.h +#XX# ./lemon$(BEXE) $(OPTS) -S fts5parse.y +#XX# +#XX#fts5parse.h: fts5parse.c +#XX# +#XX#fts5.c: $(FTS5_SRC) has_tclsh84 +#XX# $(TCLSH_CMD) $(TOP)/ext/fts5/tool/mkfts5c.tcl +#XX# cp $(TOP)/ext/fts5/fts5.h . +#XX# +#XX#fts5.lo: fts5.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c fts5.c +#XX# +#XX#sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) +#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c +#XX# +#XX# +#XX## Rules to build the 'testfixture' application. +#XX## +#XX## If using the amalgamation, use sqlite3.c directly to build the test +#XX## fixture. Otherwise link against libsqlite3.la. (This distinction is +#XX## necessary because the test fixture requires non-API symbols which are +#XX## hidden when the library is built via the amalgamation). +#XX## +#XX#TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 +#XX#TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit +#XX#TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE +#XX#TESTFIXTURE_FLAGS += -DBUILD_sqlite +#XX#TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 +#XX#TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 +#XX#TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB +#XX#TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB +#XX#TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB +#XX#TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC +#XX#TESTFIXTURE_FLAGS += -DSQLITE_STATIC_RANDOMJSON +#XX#TESTFIXTURE_FLAGS += -DSQLITE_STRICT_SUBTYPE=1 +#XX# +#XX#TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la +#XX#TESTFIXTURE_SRC1 = sqlite3.c +#XX#TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c +#XX#TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) +#XX# +#XX#testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) +#XX# $(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ +#XX# -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS) +#XX# +#XX#coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) +#XX# +#XX#testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) +#XX# +#XX## A very detailed test running most or all test cases +#XX#fulltest: alltest fuzztest +#XX# +#XX## Run most or all tcl test cases +#XX#alltest: $(TESTPROGS) +#XX# ./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS) +#XX# +#XX## Really really long testing +#XX#soaktest: $(TESTPROGS) +#XX# ./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS) +#XX# +#XX## Do extra testing but not everything. +#XX#fulltestonly: $(TESTPROGS) fuzztest +#XX# ./testfixture$(TEXE) $(TOP)/test/full.test +#XX# +#XX## Fuzz testing +#XX## +#XX## WARNING: When the "fuzztest" target is run by the testrunner.tcl script, +#XX## it does not actually run this code. Instead, it schedules equivalent +#XX## commands. Therefore, if this target is updated, then code in +#XX## testrunner_data.tcl (search for "trd_fuzztest_data") must also be updated. +#XX## +#XX#fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) +#XX# ./fuzzcheck$(TEXE) $(FUZZDATA) +#XX# ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db +#XX# +#XX#valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) +#XX# valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) +#XX# valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db +#XX# +#XX## The veryquick.test TCL tests. +#XX## +#XX#tcltest: ./testfixture$(TEXE) +#XX# ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) +#XX# +#XX## Runs all the same tests cases as the "tcltest" target but uses +#XX## the testrunner.tcl script to run them in multiple cores +#XX## concurrently. +#XX#testrunner: testfixture$(TEXE) +#XX# ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl +#XX# +#XX## This is the testing target preferred by the core SQLite developers. +#XX## It runs tests under a standard configuration, regardless of how +#XX## ./configure was run. The devs run "make devtest" prior to each +#XX## check-in, at a minimum. Probably other tests too, but at least this +#XX## one. +#XX## +#XX#devtest: srctree-check sourcetest +#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) +#XX# +#XX#mdevtest: srctree-check has_tclsh85 +#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) +#XX# +#XX#sdevtest: has_tclsh85 +#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS) +#XX# +#XX## Validate that various generated files in the source tree +#XX## are up-to-date. +#XX## +#XX#srctree-check: $(TOP)/tool/srctree-check.tcl +#XX# $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl +#XX# +#XX## Testing for a release +#XX## +#XX#releasetest: srctree-check has_tclsh85 verify-source +#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS) +#XX# +#XX## Minimal testing that runs in less than 3 minutes +#XX## +#XX#quicktest: ./testfixture$(TEXE) +#XX# ./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS) +#XX# +#XX## Try to run tests on whatever options are specified by the +#XX## ./configure. The developers seldom use this target. Instead +#XX## they use "make devtest" which runs tests on a standard set of +#XX## options regardless of how SQLite is configured. This "test" +#XX## target is provided for legacy only. +#XX## +#XX#test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest +#XX# +#XX## Run a test using valgrind. This can take a really long time +#XX## because valgrind is so much slower than a native machine. +#XX## +#XX#valgrindtest: $(TESTPROGS) valgrindfuzz +#XX# OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) +#XX# +#XX## A very fast test that checks basic sanity. The name comes from +#XX## the 60s-era electronics testing: "Turn it on and see if smoke +#XX## comes out." +#XX## +#XX#smoketest: $(TESTPROGS) fuzzcheck$(TEXE) +#XX# ./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS) +#XX# +#XX#shelltest: +#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell +#XX# +#XX#sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 +#XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c +#XX# +#XX#sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c +#XX# $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) +#XX# +#XX#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 has_tclsh85 +#XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c +#XX# +#XX#sqltclsh$(TEXE): has_tclconfig sqltclsh.c +#XX# $(LTLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS) +#XX# +#XX#sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c +#XX# $(LTLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(TLIBS) +#XX# +#XX#CHECKER_DEPS =\ +#XX# $(TOP)/tool/mkccode.tcl \ +#XX# sqlite3.c \ +#XX# $(TOP)/src/tclsqlite.c \ +#XX# $(TOP)/ext/repair/sqlite3_checker.tcl \ +#XX# $(TOP)/ext/repair/checkindex.c \ +#XX# $(TOP)/ext/repair/checkfreelist.c \ +#XX# $(TOP)/ext/misc/btreeinfo.c \ +#XX# $(TOP)/ext/repair/sqlite3_checker.c.in +#XX# +#XX#sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 +#XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ +#XX# +#XX#sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c +#XX# $(LTLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS) +#XX# +#XX#dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo +#XX# $(LTLINK) -DDBDUMP_STANDALONE -o $@ \ +#XX# $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS) +#XX# +#XX#dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c +#XX# $(LTLINK)-o $@ $(TOP)/tool/dbtotxt.c +#XX# +#XX#showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS) +#XX# +#XX#showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(TLIBS) +#XX# +#XX#showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(TLIBS) +#XX# +#XX#showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(TLIBS) +#XX# +#XX#showshm$(TEXE): $(TOP)/tool/showshm.c +#XX# $(LTLINK) -o $@ $(TOP)/tool/showshm.c +#XX# +#XX#index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo +#XX# $(LTLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(TLIBS) +#XX# +#XX#changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) +#XX# +#XX#changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS) +#XX# +#XX#rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) +#XX# +#XX#atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS) +#XX# +#XX#LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h +#XX# $(LTLINK) -I. -o $@ $(TOP)/tool/logest.c +#XX# +#XX#wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo +#XX# $(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS) +#XX# +#XX#speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile +#XX# $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) +#XX# +#XX#startup$(TEXE): $(TOP)/test/startup.c sqlite3.c +#XX# $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) +#XX# +#XX#KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ +#XX# +#XX#kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c +#XX# $(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS) +#XX# +#XX#rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo +#XX# $(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS) +#XX# +#XX#loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la +#XX# $(LTLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(TLIBS) +#XX# +#XX## This target will fail if the SQLite amalgamation contains any exported +#XX## symbols that do not begin with "sqlite3_". It is run as part of the +#XX## releasetest.tcl script. +#XX## +#XX#VALIDIDS=' sqlite3(changeset|changegroup|session)?_' +#XX#checksymbols: sqlite3.o +#XX# nm -g --defined-only sqlite3.o +#XX# nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 +#XX# echo '0 errors out of 1 tests' +#XX# +#XX## Build the amalgamation-autoconf package. The amalamgation-tarball target builds +#XX## a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. +#XX## The snapshot-tarball target builds a tarball named by the SHA1 hash +#XX## +#XX#amalgamation-tarball: sqlite3.c sqlite3rc.h +#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal +#XX# +#XX#snapshot-tarball: sqlite3.c sqlite3rc.h +#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot +#XX# +#XX## Build a ZIP archive containing various command-line tools. +#XX## +#XX#tool-zip: testfixture sqlite3 sqldiff sqlite3_analyzer $(TOP)/tool/mktoolzip.tcl +#XX# ./testfixture $(TOP)/tool/mktoolzip.tcl +#XX# +#XX## The next two rules are used to support the "threadtest" target. Building +#XX## threadtest runs a few thread-safety tests that are implemented in C. This +#XX## target is invoked by the releasetest.tcl script. +#XX## +#XX#THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ +#XX# $(TOP)/test/tt3_checkpoint.c \ +#XX# $(TOP)/test/tt3_index.c \ +#XX# $(TOP)/test/tt3_vacuum.c \ +#XX# $(TOP)/test/tt3_stress.c \ +#XX# $(TOP)/test/tt3_lookaside1.c +#XX# +#XX#threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC) +#XX# $(LTLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(TLIBS) +#XX# +#XX#threadtest: threadtest3$(TEXE) +#XX# ./threadtest3$(TEXE) +#XX# +#XX#threadtest5: sqlite3.c $(TOP)/test/threadtest5.c +#XX# $(LTLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS) +#XX# +#XX## Standard install and cleanup targets +#XX## +#XX#lib_install: libsqlite3.la +#XX# $(INSTALL) -d $(DESTDIR)$(libdir) +#XX# $(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir) +#XX# +#XX## Use $(tcl_install_$(HAVE_TCL)) to resolve to either tcl_install or +#XX## an empty value. +#XX#tcl_install_0 = +#XX#tcl_install_1 = tcl_install +#XX# +#XX#install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc $(tcl_install_$(HAVE_TCL)) +#XX# $(INSTALL) -d $(DESTDIR)$(bindir) +#XX# $(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir) +#XX# $(INSTALL) -d $(DESTDIR)$(includedir) +#XX# $(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir) +#XX# $(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir) +#XX# $(INSTALL) -d $(DESTDIR)$(pkgconfigdir) +#XX# $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir) +#XX# +#XX#pkgIndex.tcl: +#XX# echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ +#XX# +#XX#tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl +#XX# $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR) +#XX# $(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR) +#XX# rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a +#XX# $(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR) +#XX# +#XX## Build the SQLite TCL extension in a way that make it compatible +#XX## with whatever version of TCL is running as $TCLSH_CMD, possibly defined +#XX## by --with-tclsh= +#XX## +#XX#tclextension: tclsqlite3.c +#XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc $(CC) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) +#XX# +#XX## Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD +#XX## to find it. +#XX## +#XX#tclextension-install: tclsqlite3.c +#XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc $(CC) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) +#XX# +#XX## Install the SQLite TCL extension that is used by $TCLSH_CMD +#XX## +#XX#tclextension-uninstall: +#XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall +#XX# +#XX## List all installed the SQLite TCL extension that is are accessible +#XX## by $TCLSH_CMD, included prior versions. +#XX## +#XX#tclextension-list: +#XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info +#XX# +#XX# +#XX## Remove build products sufficient so that subsequent makes will recompile +#XX## everything from scratch. Do not remove: +#XX## +#XX## * test results and test logs +#XX## * output from ./configure +#XX## +#XX#tidy: +#XX# rm -f *.lo *.la *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) +#XX# rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h +#XX# rm -rf .libs .deps tsrc .target_source +#XX# rm -f lemon$(BEXE) sqlite*.tar.gz +#XX# rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) +#XX# rm -f parse.* fts5parse.* +#XX# rm -f tclsqlite3$(TEXE) $(TESTPROGS) +#XX# rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) +#XX# rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) +#XX# rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) +#XX# rm -f *.dll *.lib *.exp *.def *.pc *.vsix *.so *.dylib pkgIndex.tcl +#XX# rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE) +#XX# rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) +#XX# rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) +#XX# rm -f threadtest5$(TEXE) +#XX# rm -f src-verify has_tclsh* +#XX# +#XX## Removes build products and test logs. Retains ./configure outputs. +#XX## +#XX#clean: tidy +#XX# rm -rf omittest* testrunner* testdir* +#XX# +#XX## Clean up everything. No exceptions. +#XX## +#XX#distclean: clean +#XX# rm -f sqlite_cfg.h config.log config.status Makefile $(LIBTOOL) +#XX# +#XX## +#XX## Windows section +#XX## +#XX#dll: sqlite3.dll +#XX# +#XX#REAL_LIBOBJ = $(LIBOBJ:%.lo=.libs/%.o) +#XX# +#XX#$(REAL_LIBOBJ): $(LIBOBJ) +#XX# +#XX#sqlite3.def: $(REAL_LIBOBJ) +#XX# echo 'EXPORTS' >sqlite3.def +#XX# nm $(REAL_LIBOBJ) | grep ' T ' | grep ' _sqlite3_' \ +#XX# | sed 's/^.* _//' >>sqlite3.def +#XX# +#XX#sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def +#XX# $(TCC) -shared -o $@ sqlite3.def \ +#XX# -Wl,"--strip-all" $(REAL_LIBOBJ) +#XX# +#XX## +#XX## Fiddle app +#XX## +#XX#fiddle: sqlite3.c shell.c +#XX# make -C ext/wasm fiddle emcc_opt=-Os +#XX# +#XX## +#XX## Spell-checking for source comments +#XX## The sources checked are either C sources or C source templates. +#XX## Their comments are extracted and processed through aspell using +#XX## a custom dictionary that contains scads of odd identifiers that +#XX## find their way into the comments. +#XX## +#XX## Currently, this target is setup to be "made" in-tree only. +#XX## The output is ephemeral. Redirect it to guide spelling fixups, +#XX## either to correct spelling or add words to tool/custom.txt. +#XX## +#XX#./custom.rws: ./tool/custom.txt +#XX# @echo 'Updating custom dictionary from tool/custom.txt' +#XX# aspell --lang=en create master ./custom.rws < $< +#XX# +#XX#misspell: ./custom.rws has_tclsh84 +#XX# $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in +#XX# +#XX## +#XX## tool/version-info: a utility for emitting sqlite3 version info +#XX## in various forms. +#XX## +#XX#version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h +#XX# $(LTLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c +#XX# diff --git a/auto.def b/auto.def index 8f8a57bb1d..aea689e5d9 100644 --- a/auto.def +++ b/auto.def @@ -60,6 +60,7 @@ set enable_shared 1 # --enable-tempstore to --with-tempstore seems like the better # approach, in that it doesn't lead to a losing fight with autosetup. options { + with-debug:=1 => {Enable debug build flags} with-tclsh:PATHNAME => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} tcl=1 => {Disable building accessory programs that require TCL-dev} @@ -86,10 +87,11 @@ options { geopoly => {Enable the GEOPOLY extension} rtree => {Enable the RTREE extension} session => {Enable the SESSION extension} - gcov => {Enable coverage testing using gcov} + gcov=0 => {Enable coverage testing using gcov} linemacros => {Enable #line macros in the amalgamation.} with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build} + with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} } # debug=0 => {debugging & verbose explain} @@ -98,7 +100,9 @@ set srcdir $autosetup(srcdir) puts "srcdir = $srcdir" set VERSION [readfile $srcdir/VERSION] puts "VERSION = $VERSION" -puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" +define PACKAGE_VERSION $VERSION +#puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" +#puts "with-debug? = [opt-val with-debug]" # # The build process allows for using a cross-compiler. But the default @@ -164,8 +168,11 @@ puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" ######################################################################## # OPT_FEATURE_FLAGS = -DSQLITE_OMIT/ENABLE flags. define OPT_FEATURE_FLAGS {} +# Adds $flag, if not empty, to OPT_FEATURE_FLAGS. proc add-feature-flag {flag} { - define-append OPT_FEATURE_FLAGS $flag + if {"" ne $flag} { + define-append OPT_FEATURE_FLAGS $flag + } } # add-feature-flag -DSQLITE_JUST_TESTING=3 @@ -180,30 +187,6 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS? } -######################################################################## -# Force-set autosetup option $flag to $val. -proc opt-set {flag {val 1}} { - global autosetup - if {$flag ni $::autosetup(options)} { - # We have to add this to autosetup(options) or else future calls - # to [opt-bool $flag] will fail validation of $flag. - lappend ::autosetup(options) $flag - } - dict set ::autosetup(optset) $flag $val -} - -######################################################################## -# If [opt-bool $boolFlag] is true, eval $then, else eval $else. -proc if-enabled {boolFlag then {else {}}} { - if {[opt-bool $boolFlag]} {eval $then} else {eval $else} -} - -######################################################################## -# If [opt-bool $boolFlag] is false, eval $then, else eval $else. -proc if-disabled {boolFlag then {else {}}} { - if {![opt-bool $boolFlag]} {eval $then} else {eval $else} -} - ######### # Programs needed if {"" eq [hwaci-bin-define install]} { @@ -219,15 +202,29 @@ cc-check-lfs cc-check-types int8_t int16_t int32_t int64_t intptr_t \ uint8_t uint16_t uint32_t uint64_t uintptr_t -######### -# Check for needed/wanted headers -cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h - ######### # Figure out whether or not we have these functions cc-check-functions fdatasync gmtime_r isnan localtime_r localtime_s \ malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 +######### +# Check for needed/wanted headers +cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h +if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { + define HAVE_ZLIB 1 + define LDFLAGS_ZLIB -lz +} else { + define HAVE_ZLIB 0 + define LDFLAGS_ZLIB "" +} + +msg-checking "Debug build? " +hwaci-if-opt-truthy with-debug { + msg-result yes +} { + msg-result "no. Use --with-debug to enable." +} + ########## # Handle --with-wasi-sdk=DIR # @@ -249,8 +246,8 @@ if {1} { msg-result "using wasi-sdk clang, disabling: tcl, CLI shell, DLL" define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir - opt-set tcl 0 - opt-set threadsafe 0 + hwaci-opt-set tcl 0 + hwaci-opt-set threadsafe 0 set cross_compiling 1 set enable_shared 0 @@ -267,9 +264,9 @@ if {1} { # XXX LD="${wasiSdkDir}/bin/wasm-ld" # XXX RANLIB="${wasiSdkDir}/bin/llvm-ranlib" # set cross_compiling yes - # opt-set threadsafe 0 + # hwaci-opt-set threadsafe 0 # set use_tcl no - # opt-set tcl 0 + # hwaci-opt-set tcl 0 # libtool is apparently hard-coded to use gcc for linking DLLs, so # we disable the DLL build... # set enable_shared no @@ -437,48 +434,46 @@ if {0} { # XXX fi # XXX AC_SUBST BUILD_CC -if-enabled all { - opt-set fts4 - opt-set fts5 - opt-set geopoly - opt-set rtree - opt-set session -} { - if-enabled geopoly {opt-set rtree} +hwaci-if-opt-truthy all { + hwaci-opt-set fts4 + hwaci-opt-set fts5 + hwaci-opt-set geopoly + hwaci-opt-set rtree + hwaci-opt-set session } +#{ +# hwaci-if-opt-truthy geopoly {} +#} ########## # Do we want to support multithreaded use of sqlite # -if {0} { - if {![opt-bool threadsafe]} { - } - msg-checking "Checking whether to support threadsafe operation..." - # XXX if test "$enable_threadsafe" = "no"; then - # XXX SQLITE_THREADSAFE=0 - msg-result "no" - # XXX else - # XXX SQLITE_THREADSAFE=1 - msg-result "yes" - # XXX fi - # XXX AC_SUBST SQLITE_THREADSAFE - - # XXX if test "$SQLITE_THREADSAFE" = "1"; then +msg-checking "Checking whether to support threadsafe operation... " +hwaci-if-opt-truthy threadsafe { + msg-result yes + add-feature-flag -DSQLITE_THREADSAFE=1 cc-check-function-in-lib pthread_create pthread cc-check-function-in-lib pthread_mutexattr_init pthread - # XXX fi +} { + msg-result no + add-feature-flag -DSQLITE_THREADSAFE=0 } ########## -# Do we want to support release +# Do we want to support release? # -if-enabled releasemode { - msg-result "Release-mode build." - set enable_releasemode 1 -} { - msg-result "Non-release-mode build." - set enable_releasemode 0 +# Maintenance note: this might be irrelevant with an autosetup port, +# as it appears to be related to libtool (part of the autotools). +# +if {0} { + hwaci-if-opt-truthy releasemode { + msg-result "Release-mode build." + set enable_releasemode 1 + } { + msg-result "Non-release-mode build." + set enable_releasemode 0 + } } if {0} { @@ -494,7 +489,8 @@ if {0} { } ########## -# Do we want temporary databases in memory +# Do we want temporary databases in memory? +# if {1} { set ts [opt-val with-tempstore no] set tsn 1 @@ -505,7 +501,7 @@ if {1} { yes { set tsn 2 } always { set tsn 3 } default { - user-error "Invalid with-tempstore value \[$ts]. Use one of: no, yes, always, never" + user-error "Invalid with-tempstore value \[$ts]. Use one of: never, no, yes, always" } } msg-result $ts @@ -513,55 +509,6 @@ if {1} { unset ts tsn } -if {0} { - ########### - # Lots of things are different if we are compiling for Windows using - # the CYGWIN environment. So check for that special case and handle - # things accordingly. - # - msg-checking "Checking if executables have the .exe suffix..." - # XXX if test "$config_BUILD_EXEEXT" = ".exe"; then - # XXX CYGWIN=yes - msg-result "yes" - # XXX else - msg-result "unknown" - # XXX fi - # XXX if test "$CYGWIN" != "yes"; then - # XXX m4_warn([obsolete], - # XXX [AC_CYGWIN is obsolete: use AC_CANONICAL_HOST and check if $host_os - # XXX matches *cygwin*]) - # XXX case $host_os in - # XXX *cygwin* ) CYGWIN=yes;; - # XXX * ) CYGWIN=no;; - # XXX esac - - # XXX fi - # XXX if test "$CYGWIN" = "yes"; then - # XXX BUILD_EXEEXT=.exe - # XXX else - # XXX BUILD_EXEEXT=$EXEEXT - # XXX fi - # XXX if test x"$cross_compiling" = xno; then - # XXX TARGET_EXEEXT=$BUILD_EXEEXT - # XXX else - # XXX TARGET_EXEEXT=$config_TARGET_EXEEXT - # XXX fi - # XXX if test "$TARGET_EXEEXT" = ".exe"; then - # XXX SQLITE_OS_UNIX=0 - # XXX SQLITE_OS_WIN=1 - # XXX CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1" - # XXX else - # XXX SQLITE_OS_UNIX=1 - # XXX SQLITE_OS_WIN=0 - # XXX CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1" - # XXX fi - - # XXX AC_SUBST BUILD_EXEEXT - # XXX AC_SUBST SQLITE_OS_UNIX - # XXX AC_SUBST SQLITE_OS_WIN - # XXX AC_SUBST TARGET_EXEEXT -} - if {0} { ########## # Figure out what C libraries are required to compile programs @@ -731,7 +678,7 @@ if {0} { # XXX AC_SUBST HAVE_ZLIB } -if-enabled load-extension { +hwaci-if-opt-truthy load-extension { if {[cc-check-function-in-lib dlopen dl]} { define LDFLAGS_DLOPEN [get-define lib_dlopen] } else { @@ -743,7 +690,7 @@ if-enabled load-extension { msg-result "Disabling loadable extensions." } -if-enabled math { +hwaci-if-opt-truthy math { if {![cc-check-function-in-lib ceil m]} { user-error "Cannot find libm functions. Use --disable-math to bypass this." } @@ -756,7 +703,7 @@ if-enabled math { msg-result "Disabling math SQL functions" } -if-enabled json { +hwaci-if-opt-truthy json { msg-result "Enabling JSON SQL functions" } { add-feature-flag {-DSQLITE_OMIT_JSON} @@ -816,85 +763,98 @@ if {0} { msg-result "yes" # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" cc-check-function-in-lib log m - # XXX else msg-result "no" - # XXX fi } -######### -# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter -# XXX for option in $CFLAGS $CPPFLAGS -# XXX do -# XXX case $option in -# XXX -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; -# XXX -DSQLITE_ENABLE*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; -# XXX esac -# XXX done -# XXX AC_SUBST OPT_FEATURE_FLAGS - -# attempt to remove any OMITS and ENABLES from the $(CFLAGS) parameter -# XXX ac_temp_CFLAGS="" -# XXX for option in $CFLAGS -# XXX do -# XXX case $option in -# XXX -DSQLITE_OMIT*) ;; -# XXX -DSQLITE_ENABLE*) ;; -# XXX *) ac_temp_CFLAGS="$ac_temp_CFLAGS $option";; -# XXX esac -# XXX done -# XXX CFLAGS=$ac_temp_CFLAGS - -# attempt to remove any OMITS and ENABLES from the $(CPPFLAGS) parameter -# XXX ac_temp_CPPFLAGS="" -# XXX for option in $CPPFLAGS -# XXX do -# XXX case $option in -# XXX -DSQLITE_OMIT*) ;; -# XXX -DSQLITE_ENABLE*) ;; -# XXX *) ac_temp_CPPFLAGS="$ac_temp_CPPFLAGS $option";; -# XXX esac -# XXX done -# XXX CPPFLAGS=$ac_temp_CPPFLAGS - -# attempt to remove any OMITS and ENABLES from the $(BUILD_CFLAGS) parameter -# XXX ac_temp_BUILD_CFLAGS="" -# XXX for option in $BUILD_CFLAGS -# XXX do -# XXX case $option in -# XXX -DSQLITE_OMIT*) ;; -# XXX -DSQLITE_ENABLE*) ;; -# XXX *) ac_temp_BUILD_CFLAGS="$ac_temp_BUILD_CFLAGS $option";; -# XXX esac -# XXX done -# XXX BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS - - -if-enabled gcov { +if {0} { + # is this still relevant? + + ######### + # attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter + # XXX for option in $CFLAGS $CPPFLAGS + # XXX do + # XXX case $option in + # XXX -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; + # XXX -DSQLITE_ENABLE*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; + # XXX esac + # XXX done + # XXX AC_SUBST OPT_FEATURE_FLAGS + + # attempt to remove any OMITS and ENABLES from the $(CFLAGS) parameter + # XXX ac_temp_CFLAGS="" + # XXX for option in $CFLAGS + # XXX do + # XXX case $option in + # XXX -DSQLITE_OMIT*) ;; + # XXX -DSQLITE_ENABLE*) ;; + # XXX *) ac_temp_CFLAGS="$ac_temp_CFLAGS $option";; + # XXX esac + # XXX done + # XXX CFLAGS=$ac_temp_CFLAGS + + # attempt to remove any OMITS and ENABLES from the $(CPPFLAGS) parameter + # XXX ac_temp_CPPFLAGS="" + # XXX for option in $CPPFLAGS + # XXX do + # XXX case $option in + # XXX -DSQLITE_OMIT*) ;; + # XXX -DSQLITE_ENABLE*) ;; + # XXX *) ac_temp_CPPFLAGS="$ac_temp_CPPFLAGS $option";; + # XXX esac + # XXX done + # XXX CPPFLAGS=$ac_temp_CPPFLAGS + + # attempt to remove any OMITS and ENABLES from the $(BUILD_CFLAGS) parameter + # XXX ac_temp_BUILD_CFLAGS="" + # XXX for option in $BUILD_CFLAGS + # XXX do + # XXX case $option in + # XXX -DSQLITE_OMIT*) ;; + # XXX -DSQLITE_ENABLE*) ;; + # XXX *) ac_temp_BUILD_CFLAGS="$ac_temp_BUILD_CFLAGS $option";; + # XXX esac + # XXX done + # XXX BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS +} + +msg-checking "Enable gcov? " +hwaci-if-opt-truthy gcov { define USE_GCOV 1 - msg-result "Enabling gcov" + msg-result yes } { define USE_GCOV 0 + msg-result no } -foreach {boolFlag featureFlag} { - fts4 -DSQLITE_ENABLE_FTS4 - fts5 -DSQLITE_ENABLE_FTS5 - geopoly -DSQLITE_ENABLE_GEOPOLY - rtree -DSQLITE_ENABLE_RTREE - session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} - update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT +######################################################################## +# Handle various SQLITE_ENABLE_... feature flags. +foreach {boolFlag featureFlag ifSetEvalThis} { + fts4 -DSQLITE_ENABLE_FTS4 {cc-check-function-in-lib log m} + fts5 -DSQLITE_ENABLE_FTS5 {cc-check-function-in-lib log m} + geopoly -DSQLITE_ENABLE_GEOPOLY {hwaci-opt-set rtree} + rtree -DSQLITE_ENABLE_RTREE {} + session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {} + update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {} + memsys5 -DSQLITE_ENABLE_MEMSYS5 {} + memsys3 {} { + if {[opt-bool memsys5]} { + msg-result "NOT enabling memsys3 because memsys5 is enabled." + } else { + add-feature-flag -DSQLITE_ENABLE_MEMSYS3 + } + } } { - if {[opt-bool $boolFlag]} { + if {[hwaci-opt-truthy $boolFlag]} { add-feature-flag $featureFlag - msg-checking "Enabling " + msg-result "Enabling $boolFlag" + eval $ifSetEvalThis } else { - msg-checking "Not enabling " + msg-result "Not enabling $boolFlag" } - msg-result "$boolFlag" } msg-checking "Use #line macros in the amalgamation: " -if-enabled linemacros { +hwaci-if-opt-truthy linemacros { define AMALGAMATION_LINE_MACROS {--linemacros=1} msg-result yes } { @@ -902,21 +862,43 @@ if-enabled linemacros { msg-result no } -if {0} { - ######### - # Generate the output files. - # - # XXX AC_SUBST BUILD_CFLAGS - make-template Makefile.in - make-template sqlite3.pc.in - make-config-header sqlite_cfg.h + +########## +# Emscripten SDK +# +if {1} { + # TODO: port this bit and its associated shell script from the + # Fossil source tree's auto.def and tools/emcc.sh.in. +} + +######### +# Generate the output files. +# +if {1} { + # mystery: why are defines (srcdir, top_srcdir) both absolute when emitted + # from make-config-header but relative when emitted via make-template? + + hwaci-make-from-dot-in Makefile + hwaci-make-from-dot-in sqlite3.pc + #hwaci-make-from-dot-in ext/wasm/GNUmakefile + if {0} { + # output from make-config-header is not quite the same as that from the + # autotools. We may need to write a custom replacement. + # hwaci-make-from-dot-in sqlite_cfg.h + # make-config-header sqlite_cfg.h -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * + # make-config-header sqlite_cfg.h -bare {SIZEOF_* HAVE_*} -none * + # make-config-header sqlite_cfg.h + } } -if {"" ne [get-define OPT_FEATURE_FLAGS]} { +set oFF [get-define OPT_FEATURE_FLAGS] +if {"" ne $oFF} { + define OPT_FEATURE_FLAGS [lsort -unique $oFF] msg-result "Final feature flags: [get-define OPT_FEATURE_FLAGS]" } +unset oFF -if-enabled dump-defines { +hwaci-if-opt-truthy dump-defines { global DUMP_DEFINES_FILE msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" make-config-header $DUMP_DEFINES_FILE -bare {OPT_FEATURE_FLAGS SQLITE_OS_*} -auto {*} diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index c95fba218b..930580960b 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -105,10 +105,49 @@ proc hwaci-require-bash {} { return $bash } +######################################################################## +# Force-set autosetup option $flag to $val. The value can be fetched +# later with [opt-val], [opt-bool], and friends. +proc hwaci-opt-set {flag {val 1}} { + global autosetup + if {$flag ni $::autosetup(options)} { + # We have to add this to autosetup(options) or else future calls + # to [opt-bool $flag] will fail validation of $flag. + lappend ::autosetup(options) $flag + } + dict set ::autosetup(optset) $flag $val +} + +######################################################################## +# Returns 1 if $val appears to be a truthy value, else returns +# 0. Truthy values are any of {1 on enabled yes} +proc hwaci-val-truthy {val} { + return [expr {$val in {1 on enabled yes}}] +} + +######################################################################## +# Returns 1 if [opt-val $flag] appears to be a truthy value or +# [opt-bool $flag] is true. See hwaci-val-truthy. +proc hwaci-opt-truthy {flag} { + if {[hwaci-val-truthy [opt-val $flag]]} { return 1 } + set rc 0 + catch { + # opt-bool will throw if $flag is not a known boolean flag + set rc [opt-bool $flag] + } + return $rc +} + +######################################################################## +# If [hwaci-opt-truthy $flag] is true, eval $then, else eval $else. +proc hwaci-if-opt-truthy {flag then {else {}}} { + if {[hwaci-opt-truthy $flag]} {eval $then} else {eval $else} +} + ######################################################################## # Args: [-v] optName defName {descr {}} # -# Checks [opt-bool $optName] and does [define $defName X] where X is 0 +# Checks [hwaci-opt-truthy $optName] and does [define $defName X] where X is 0 # for false and 1 for true. descr is an optional [msg-checking] # argument which defaults to $defName. Returns X. # @@ -129,7 +168,7 @@ proc hwaci-opt-bool-01 {args} { } set rc 0 msg-checking "$descr ... " - if {[opt-bool $optName]} { + if {[hwaci-opt-truthy $optName]} { if {0 eq $invert} { set rc 1 } else { @@ -305,7 +344,8 @@ proc hwaci-make-from-dot-in {filename {touch 0}} { # tokens, and interfering with autosetup's use of these vars, this # routine does not directly modify CFLAGS or LDFLAGS. proc hwaci-check-profile-flag {{flagname profile}} { - if {[opt-bool $flagname]} { + #puts "flagname=$flagname ?[hwaci-opt-truthy $flagname]?" + if {[hwaci-opt-truthy $flagname]} { set CC [get-define CC] regsub {.*ccache *} $CC "" CC # ^^^ if CC="ccache gcc" then [exec] treats "ccache gcc" as a @@ -328,6 +368,8 @@ proc hwaci-check-profile-flag {{flagname profile}} { # an autosetup define which contains platform name info, defaulting to # "host". The other legal value is "target". proc hwaci-looks-like-windows {{key host}} { + global autosetup + if {$::autosetup(iswin)} { return 1 } switch -glob -- [get-define $key] { *-*-ming* - *-*-cygwin - *-*-msys { return 1 diff --git a/manifest b/manifest index 5968de4007..ee16279e00 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Change\s--enable-tempstore\sto\s--with-tempstore\sto\savoid\sthe\suphill\s(and\slosing)\sbattle\swith\sautosetup's\sbuilt-in\shandling\sof\sthe\s--enable/--disable\sprefixes. -D 2024-09-25T12:16:13.024 +C Lots\sof\swork\son\sauto.def\sand\sthe\sutility\stcl\slib.\sStill\slots\smore\sto\sdo. +D 2024-09-25T14:38:46.807 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in fa448c4c0567623fd140efebecb570ab58d955d766a5ea0fd8a94e9b5697007c +F Makefile.in cc79c614f589bda2a0995851ca652f1713490dc9f79867f3ad2c82121d07cbfa F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 46adeff81937896526e074fb26dad88f482f44ab4577468a43da73304158d357 +F auto.def acffcaef405d1a93e5af1a6bfc9ad175e045f0113b896e31812294155aa729e1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl b6f0c57b377898b8837bd031ca9a37c021d4fe859c9d3967dbb36deab6748459 +F autosetup/hwaci-common.tcl c676836141db22751ab9c4e8ff9e66e744546691643f2c2cce459f3af6647f28 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c223dbb4fb8e800089752617c6c986b6c80be0d180e9d1610f28cf95253e5674 -R 780005d9a0ea48859fdd0440470d05eb +P 8bea45fbbf8557760e792cdfcede72afa9e25dd7b90e4ce3297efebe8d0cfb1c +R cd70ad4d06f521a1f30a01bf2a129759 U stephan -Z 67206b818d975312f9c5773e94dde53e +Z 9f732b0583b6db454836916ab8f6e46b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d805c5e16f..f88028e48b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bea45fbbf8557760e792cdfcede72afa9e25dd7b90e4ce3297efebe8d0cfb1c +2141527a38ca8170e79b5b5e664378f0d8464055119f5b986e5d7b1be75e919e From 2615879760010950ea7d6580ecb7647d6f5a0858 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 14:58:09 +0000 Subject: [PATCH 014/522] Improve common feature flag handling a bit. FossilOrigin-Name: 8716c35eaa168677a10de7b4aa55d35c54035f5e685cc1a5890b940a41cc6ff7 --- Makefile.in | 4 +++ auto.def | 69 ++++++++++++++++----------------------------------- manifest | 14 +++++------ manifest.uuid | 2 +- 4 files changed, 33 insertions(+), 56 deletions(-) diff --git a/Makefile.in b/Makefile.in index 264b68db9d..8b17ef5e47 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,6 +15,10 @@ # TOP = @abs_top_srcdir@ +# Just testing expansions... +# LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ +# LDFLAGS_MATH = @LDFLAGS_MATH@ + # C Compiler and options for use in building executables that # will run on the platform that is doing the build. # diff --git a/auto.def b/auto.def index aea689e5d9..2a3aa4be4d 100644 --- a/auto.def +++ b/auto.def @@ -434,22 +434,11 @@ if {0} { # XXX fi # XXX AC_SUBST BUILD_CC -hwaci-if-opt-truthy all { - hwaci-opt-set fts4 - hwaci-opt-set fts5 - hwaci-opt-set geopoly - hwaci-opt-set rtree - hwaci-opt-set session -} -#{ -# hwaci-if-opt-truthy geopoly {} -#} - ########## # Do we want to support multithreaded use of sqlite # -msg-checking "Checking whether to support threadsafe operation... " +msg-checking "Support threadsafe operation? " hwaci-if-opt-truthy threadsafe { msg-result yes add-feature-flag -DSQLITE_THREADSAFE=1 @@ -734,38 +723,6 @@ if {0} { # XXX fi } -if {0} { - ######### - # See whether we should enable Full Text Search extensions - if {[opt-bool fts3]} { - } - msg-checking "Checking whether to support FTS3..." - # XXX if test "${enable_fts3}" = "yes" ; then - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3" - msg-result "yes" - # XXX else - msg-result "no" - # XXX fi - if {[opt-bool fts4]} { - } - msg-checking "Checking whether to support FTS4..." - # XXX if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then - msg-result "yes" - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" - cc-check-function-in-lib log m - # XXX else - msg-result "no" - # XXX fi - if {[opt-bool fts5]} { - } - msg-checking "Checking whether to support FTS5..." - # XXX if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then - msg-result "yes" - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" - cc-check-function-in-lib log m - msg-result "no" -} - if {0} { # is this still relevant? @@ -826,16 +783,29 @@ hwaci-if-opt-truthy gcov { msg-result no } +proc affirm-have-math {} { + if {![cc-check-function-in-lib log m]} { + user-error "Missing required math APIs" + } + define LDFLAGS_MATH [get-define lib_log ""] +} + ######################################################################## # Handle various SQLITE_ENABLE_... feature flags. foreach {boolFlag featureFlag ifSetEvalThis} { - fts4 -DSQLITE_ENABLE_FTS4 {cc-check-function-in-lib log m} - fts5 -DSQLITE_ENABLE_FTS5 {cc-check-function-in-lib log m} + all {} { + hwaci-opt-set fts4 + hwaci-opt-set fts5 + hwaci-opt-set geopoly + hwaci-opt-set rtree + hwaci-opt-set session + } + fts4 -DSQLITE_ENABLE_FTS4 {affirm-have-math} + fts5 -DSQLITE_ENABLE_FTS5 {affirm-have-math} geopoly -DSQLITE_ENABLE_GEOPOLY {hwaci-opt-set rtree} rtree -DSQLITE_ENABLE_RTREE {} session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {} update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {} - memsys5 -DSQLITE_ENABLE_MEMSYS5 {} memsys3 {} { if {[opt-bool memsys5]} { msg-result "NOT enabling memsys3 because memsys5 is enabled." @@ -843,6 +813,7 @@ foreach {boolFlag featureFlag ifSetEvalThis} { add-feature-flag -DSQLITE_ENABLE_MEMSYS3 } } + memsys5 -DSQLITE_ENABLE_MEMSYS5 {} } { if {[hwaci-opt-truthy $boolFlag]} { add-feature-flag $featureFlag @@ -901,7 +872,9 @@ unset oFF hwaci-if-opt-truthy dump-defines { global DUMP_DEFINES_FILE msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" - make-config-header $DUMP_DEFINES_FILE -bare {OPT_FEATURE_FLAGS SQLITE_OS_*} -auto {*} + make-config-header $DUMP_DEFINES_FILE \ + -bare {OPT_FEATURE_FLAGS SQLITE_OS_* LDFLAGS_* USE_*} \ + -auto {*} # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will # get _undefined_ here unless it's part of the -bare set. } diff --git a/manifest b/manifest index ee16279e00..8bdf8719e2 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Lots\sof\swork\son\sauto.def\sand\sthe\sutility\stcl\slib.\sStill\slots\smore\sto\sdo. -D 2024-09-25T14:38:46.807 +C Improve\scommon\sfeature\sflag\shandling\sa\sbit. +D 2024-09-25T14:58:09.490 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in cc79c614f589bda2a0995851ca652f1713490dc9f79867f3ad2c82121d07cbfa +F Makefile.in 7b3bc24530c2a6580d4b3a049a3f45246118fa2098ce5dd10ab76333f02f7246 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def acffcaef405d1a93e5af1a6bfc9ad175e045f0113b896e31812294155aa729e1 +F auto.def e90da95aff732435d819c840799ae95743ef1bad622e8178c79fa509a9d34b28 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8bea45fbbf8557760e792cdfcede72afa9e25dd7b90e4ce3297efebe8d0cfb1c -R cd70ad4d06f521a1f30a01bf2a129759 +P 2141527a38ca8170e79b5b5e664378f0d8464055119f5b986e5d7b1be75e919e +R 6f04bd8bd4e606869da2c4023fe473ea U stephan -Z 9f732b0583b6db454836916ab8f6e46b +Z f4464a4d74c89ea0380cf484c98507f9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f88028e48b..9dce95606d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2141527a38ca8170e79b5b5e664378f0d8464055119f5b986e5d7b1be75e919e +8716c35eaa168677a10de7b4aa55d35c54035f5e685cc1a5890b940a41cc6ff7 From ae49b334c28d3c29f79b290ee6ccaae38bc4c3c2 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 18:03:26 +0000 Subject: [PATCH 015/522] Further streamlining of auto.def. FossilOrigin-Name: 74d12433599e2f189d8d0a44be834651531ac5a215bf42de386053cd00d29162 --- auto.def | 216 ++++++++++--------------------------- autosetup/hwaci-common.tcl | 23 ++++ manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 90 insertions(+), 165 deletions(-) diff --git a/auto.def b/auto.def index 2a3aa4be4d..d4ee5fee6a 100644 --- a/auto.def +++ b/auto.def @@ -70,6 +70,7 @@ options { with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always} editline=0 => {BSD editline support} readline=0 => {readline support} + largefile=1 => {Disable large file support} with-readline-lib => {readline library} with-readline-inc => {readline include paths} with-linenoise:DIR => {} @@ -194,41 +195,27 @@ if {"" eq [hwaci-bin-define install]} { } ######### -# Enable large file support (if special flags are necessary) -cc-check-lfs - -######### -# Check for needed/wanted data types -cc-check-types int8_t int16_t int32_t int64_t intptr_t \ - uint8_t uint16_t uint32_t uint64_t uintptr_t - -######### -# Figure out whether or not we have these functions -cc-check-functions fdatasync gmtime_r isnan localtime_r localtime_s \ - malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 - -######### -# Check for needed/wanted headers -cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h -if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { - define HAVE_ZLIB 1 - define LDFLAGS_ZLIB -lz -} else { - define HAVE_ZLIB 0 - define LDFLAGS_ZLIB "" -} - -msg-checking "Debug build? " -hwaci-if-opt-truthy with-debug { - msg-result yes -} { - msg-result "no. Use --with-debug to enable." -} +# Locate a compiler for the build machine. This compiler should +# generate command-line programs that run on the build machine. +# +# XXX if test x"$cross_compiling" = xno; then +# XXX BUILD_CC=$CC +# XXX BUILD_CFLAGS=$CFLAGS +# XXX else +# XXX if test "${BUILD_CC+set}" != set; then +# XXX AC_CHECK_PROGS BUILD_CC gcc cc cl +# XXX fi +# XXX if test "${BUILD_CFLAGS+set}" != set; then +# XXX BUILD_CFLAGS="-g" +# XXX fi +# XXX fi +# XXX AC_SUBST BUILD_CC ########## # Handle --with-wasi-sdk=DIR # -# This must be early because it changes the toolchain. +# This must be early because it may change the toolchain and several +# config options. # # It's unclear whether we can actually get away with making these # changes to the autosetup environment. @@ -243,7 +230,7 @@ if {1} { if {![file exists $wasiSdkDir/bin/clang]} { user-error "--with-wasi-sdk=${wasiSdkDir} directory does not contain bin/clang" } - msg-result "using wasi-sdk clang, disabling: tcl, CLI shell, DLL" + msg-result "using wasi-sdk clang, disabling: tcl, CLI shell, DLL, threading" define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir hwaci-opt-set tcl 0 @@ -271,13 +258,40 @@ if {1} { # we disable the DLL build... # set enable_shared no } -# unset wasiSdkDir + unset wasiSdkDir }; # --wasi-sdk-dir ######### -# By default, we use the amalgamation (this may be changed below...) -# -# XXX USE_AMALGAMATION=1 +# Enable large file support (if special flags are necessary) +cc-check-lfs + +######### +# Check for needed/wanted data types +cc-check-types int8_t int16_t int32_t int64_t intptr_t \ + uint8_t uint16_t uint32_t uint64_t uintptr_t + +cc-check-functions gmtime_r isnan localtime_r localtime_s \ + malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 + +cc-check-function-in-lib fdatasync rt +define LDFLAGS_FDATASYNC [get-define lib_fdatasync] +undefine lib_fdatasync + +######### +# Check for needed/wanted headers +cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h +if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { + define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" + define LDFLAGS_ZLIB -lz +} else { + define HAVE_ZLIB 0 + define LDFLAGS_ZLIB "" +} + +hwaci-define-if-opt-truthy with-debug SQLITE_DEBUG "Debug build?" +hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION "Use amalgamation for builds?" +hwaci-define-if-opt-truthy gcov USE_GCOV "Use gcov?" +hwaci-define-if-opt-truthy test-status TSTRNNR_OPTS "test-runner flags?" {--status} {} if {0} { ######### @@ -400,53 +414,21 @@ if {0} { # XXX fi } -if {0} { - ######### - # Set up options for running tests. - # - if {[opt-bool test-status]} { - define TSTRNNR_OPTS {--status} - } else { - define TSTRNNR_OPTS {} - } - # XXX if test $use_vt100 != no; then - # XXX TSTRNNR_OPTS=--status - # XXX else - # XXX TSTRNNR_OPTS= - # XXX fi - # XXX AC_SUBST TSTRNNR_OPTS -} -######### -# Locate a compiler for the build machine. This compiler should -# generate command-line programs that run on the build machine. -# -# XXX if test x"$cross_compiling" = xno; then -# XXX BUILD_CC=$CC -# XXX BUILD_CFLAGS=$CFLAGS -# XXX else -# XXX if test "${BUILD_CC+set}" != set; then -# XXX AC_CHECK_PROGS BUILD_CC gcc cc cl -# XXX fi -# XXX if test "${BUILD_CFLAGS+set}" != set; then -# XXX BUILD_CFLAGS="-g" -# XXX fi -# XXX fi -# XXX AC_SUBST BUILD_CC - - -########## -# Do we want to support multithreaded use of sqlite -# msg-checking "Support threadsafe operation? " hwaci-if-opt-truthy threadsafe { msg-result yes add-feature-flag -DSQLITE_THREADSAFE=1 - cc-check-function-in-lib pthread_create pthread - cc-check-function-in-lib pthread_mutexattr_init pthread + if {![cc-check-function-in-lib pthread_create pthread] + || ![cc-check-function-in-lib pthread_mutexattr_init pthread]} { + user-error "Missing required pthread bits" + } + define LDFLAGS_PTHREAD [get-define lib_pthread_create] + undefine lib_pthread_create } { msg-result no add-feature-flag -DSQLITE_THREADSAFE=0 + define LDFLAGS_PTHREAD "" } ########## @@ -619,57 +601,10 @@ if {0} { # XXX AC_SUBST TARGET_HAVE_LINENOISE } -if {0} { - ########## - # Figure out what C libraries are required to compile programs - # that use "fdatasync()" function. - # - cc-check-function-in-lib fdatasync rt -} - -if {0} { - ######### - # check for debug enabled - if {[opt-bool debug]} { - } - msg-checking "Checking build type..." - # XXX if test "${enable_debug}" = "yes" ; then - # XXX TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall" - msg-result "debug" - # XXX else - # XXX TARGET_DEBUG="-DNDEBUG" - msg-result "release" - # XXX fi - # XXX AC_SUBST TARGET_DEBUG -} - -if {0} { - ######### - # See whether we should use the amalgamation to build - - if {![opt-bool amalgamation]} { - } - # XXX if test "${enable_amalgamation}" = "no" ; then - # XXX USE_AMALGAMATION=0 - # XXX fi - # XXX AC_SUBST USE_AMALGAMATION -} - -if {0} { - ######### - # Look for zlib. Only needed by extensions and by the sqlite3.exe shell - cc-check-includes zlib.h - if {[cc-check-function-in-lib deflate z]} { - define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" - } else { - define HAVE_ZLIB 0; # HAVE_ZLIB="" - } - # XXX AC_SUBST HAVE_ZLIB -} - hwaci-if-opt-truthy load-extension { if {[cc-check-function-in-lib dlopen dl]} { define LDFLAGS_DLOPEN [get-define lib_dlopen] + undefine lib_dlopen } else { user-error "dlopen() not found. Use --disable-load-extension to bypass this check." } @@ -699,30 +634,6 @@ hwaci-if-opt-truthy json { msg-result "Disabling JSON SQL functions" } -if {0} { - ########## - # Do we want to support memsys3 and/or memsys5 - # - if {[opt-bool memsys5]} { - } - msg-checking "Checking whether to support MEMSYS5..." - # XXX if test "${enable_memsys5}" = "yes"; then - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5" - msg-result "yes" - # XXX else - msg-result "no" - # XXX fi - if {[opt-bool memsys3]} { - } - msg-checking "Checking whether to support MEMSYS3..." - # XXX if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then - # XXX OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3" - msg-result "yes" - # XXX else - msg-result "no" - # XXX fi -} - if {0} { # is this still relevant? @@ -774,15 +685,6 @@ if {0} { # XXX BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS } -msg-checking "Enable gcov? " -hwaci-if-opt-truthy gcov { - define USE_GCOV 1 - msg-result yes -} { - define USE_GCOV 0 - msg-result no -} - proc affirm-have-math {} { if {![cc-check-function-in-lib log m]} { user-error "Missing required math APIs" @@ -873,7 +775,7 @@ hwaci-if-opt-truthy dump-defines { global DUMP_DEFINES_FILE msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" make-config-header $DUMP_DEFINES_FILE \ - -bare {OPT_FEATURE_FLAGS SQLITE_OS_* LDFLAGS_* USE_*} \ + -bare {OPT_FEATURE_FLAGS SQLITE_OS* SQLITE_DEBUG LDFLAGS_* USE_*} \ -auto {*} # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will # get _undefined_ here unless it's part of the -bare set. diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 930580960b..20bdb4b470 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -144,6 +144,29 @@ proc hwaci-if-opt-truthy {flag then {else {}}} { if {[hwaci-opt-truthy $flag]} {eval $then} else {eval $else} } +######################################################################## +# If [hwaci-opt-truthy $flag] then [define $def $iftrue] else +# [define $def $iffalse]. Output [msg-checking $msg] and a +# [msg-results ...] which corresponds to the result. Returns 1 +# if the opt-truthy check passes, else 0. +proc hwaci-define-if-opt-truthy {flag def msg {iftrue 1} {iffalse 0}} { + msg-checking "$msg " + set rc 0 + if {[hwaci-opt-truthy $flag]} { + define $def $iftrue + set rc 1 + } else { + define $def $iffalse + } + set msg [get-define $def] + switch -- $msg { + 0 { set msg no } + 1 { set msg yes } + } + msg-result $msg + return $rc +} + ######################################################################## # Args: [-v] optName defName {descr {}} # diff --git a/manifest b/manifest index 8bdf8719e2..c124584a49 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\scommon\sfeature\sflag\shandling\sa\sbit. -D 2024-09-25T14:58:09.490 +C Further\sstreamlining\sof\sauto.def. +D 2024-09-25T18:03:26.242 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def e90da95aff732435d819c840799ae95743ef1bad622e8178c79fa509a9d34b28 +F auto.def 334d1bcda82fe05ac65baa1485701e05911ce4304175f716bacc33b5ddb1d61c F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl c676836141db22751ab9c4e8ff9e66e744546691643f2c2cce459f3af6647f28 +F autosetup/hwaci-common.tcl 6c48b16beb9eb8015f207980095f5f65c55e5238159a9d50791b643e5c295205 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2232,8 +2232,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2141527a38ca8170e79b5b5e664378f0d8464055119f5b986e5d7b1be75e919e -R 6f04bd8bd4e606869da2c4023fe473ea +P 8716c35eaa168677a10de7b4aa55d35c54035f5e685cc1a5890b940a41cc6ff7 +R 7ae842c7d3995cad59964f0358f0039c U stephan -Z f4464a4d74c89ea0380cf484c98507f9 +Z fd55233750e1823126fedbcf310025fa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9dce95606d..172f049785 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8716c35eaa168677a10de7b4aa55d35c54035f5e685cc1a5890b940a41cc6ff7 +74d12433599e2f189d8d0a44be834651531ac5a215bf42de386053cd00d29162 From 2eff8f225292c7fd17299910338e01706dba083a Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 25 Sep 2024 18:55:11 +0000 Subject: [PATCH 016/522] Change the way tokendata indexes are collected for prefix queries. FossilOrigin-Name: 204ddf4e726b695dd12ab4a945ec2461655aa0bcc38b74e970f07ed2ac43c6ff --- ext/fts5/fts5Int.h | 9 +- ext/fts5/fts5_expr.c | 3 +- ext/fts5/fts5_index.c | 246 ++++++++++++++++++++++++++++++++++++------ manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 235 insertions(+), 41 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index b15521f163..a71fb13e06 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -502,7 +502,14 @@ int sqlite3Fts5StructureTest(Fts5Index*, void*); /* ** Used by xInstToken(): */ -int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*); +int sqlite3Fts5IterToken( + Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, + i64 iRowid, + int iCol, + int iOff, + const char **ppOut, int *pnOut +); /* ** Insert or remove data to or from the index. Each time a document is diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 0124a1cc93..877c3f79c5 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -3241,7 +3241,8 @@ int sqlite3Fts5ExprInstToken( pTerm = &pPhrase->aTerm[iToken]; if( pExpr->pConfig->bTokendata || pTerm->bPrefix ){ rc = sqlite3Fts5IterToken( - pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut + pTerm->pIter, pTerm->pTerm, pTerm->nQueryTerm, + iRowid, iCol, iOff+iToken, ppOut, pnOut ); }else{ *ppOut = pTerm->pTerm; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index ded1ec59cf..1efbe5a7b4 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6571,13 +6571,12 @@ int sqlite3Fts5IndexWrite( static int fts5IsTokendataPrefix( Fts5Buffer *pBuf, const u8 *pToken, - int nToken, - int bPrefix + int nToken ){ return ( pBuf->n>=nToken && 0==memcmp(pBuf->p, pToken, nToken) - && (bPrefix || pBuf->n==nToken || pBuf->p[nToken]==0x00) + && (pBuf->n==nToken || pBuf->p[nToken]==0x00) ); } @@ -6602,20 +6601,25 @@ static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ struct Fts5TokenDataMap { i64 iRowid; /* Row this token is located in */ i64 iPos; /* Position of token */ + int iIter; /* Iterator token was read from */ + int nByte; /* Length of token in bytes (or 0) */ }; /* ** An object used to supplement Fts5Iter for tokendata=1 iterators. */ struct Fts5TokenDataIter { - int nIter; - int nIterAlloc; - int nMap; int nMapAlloc; Fts5TokenDataMap *aMap; + /* The following are used for prefix-queries only. */ + Fts5Buffer terms; + + /* The following are used for other full-token tokendata queries only. */ + int nIter; + int nIterAlloc; Fts5PoslistReader *aPoslistReader; int *aPoslistToIter; Fts5Iter *apIter[1]; @@ -6666,6 +6670,7 @@ static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ for(ii=0; iinIter; ii++){ fts5MultiIterFree(pSet->apIter[ii]); } + fts5BufferFree(&pSet->terms); sqlite3_free(pSet->aPoslistReader); sqlite3_free(pSet->aMap); sqlite3_free(pSet); @@ -6679,6 +6684,7 @@ static void fts5TokendataIterAppendMap( Fts5Index *p, Fts5TokenDataIter *pT, int iIter, + int nByte, i64 iRowid, i64 iPos ){ @@ -6701,6 +6707,7 @@ static void fts5TokendataIterAppendMap( pT->aMap[pT->nMap].iRowid = iRowid; pT->aMap[pT->nMap].iPos = iPos; pT->aMap[pT->nMap].iIter = iIter; + pT->aMap[pT->nMap].nByte = nByte; pT->nMap++; } } @@ -6745,7 +6752,7 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ pIter->base.iRowid = iRowid; if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){ - fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1); + fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, 0, iRowid, -1); }else if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){ int nReader = 0; @@ -6880,8 +6887,7 @@ static Fts5Iter *fts5SetupTokendataIter( Fts5Index *p, /* FTS index to query */ const u8 *pToken, /* Buffer containing query term */ int nToken, /* Size of buffer pToken in bytes */ - Fts5Colset *pColset, /* Colset to filter on */ - int bPrefix /* True to match any prefix */ + Fts5Colset *pColset /* Colset to filter on */ ){ Fts5Iter *pRet = 0; Fts5TokenDataIter *pSet = 0; @@ -6963,7 +6969,7 @@ static Fts5Iter *fts5SetupTokendataIter( pSmall = 0; for(ii=0; iinSeg; ii++){ Fts5SegIter *pII = &pNew->aSeg[ii]; - if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken, bPrefix) ){ + if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken) ){ fts5SegIterSetEOF(pII); } if( pII->pLeaf && (!pSmall || fts5BufferCompare(pSmall, &pII->term)>0) ){ @@ -6999,6 +7005,7 @@ static Fts5Iter *fts5SetupTokendataIter( pRet = fts5MultiIterAlloc(p, 0); } if( pRet ){ + pRet->nSeg = 0; pRet->pTokenDataIter = pSet; if( pSet ){ fts5IterSetOutputsTokendata(pRet); @@ -7071,9 +7078,9 @@ int sqlite3Fts5IndexQuery( } } - if( (bTokendata && iIdx==0) || iIdx>pConfig->nPrefix ){ + if( bTokendata && iIdx==0 ){ buf.p[0] = FTS5_MAIN_PREFIX; - pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset, iIdx>0); + pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset); }else if( iIdx<=pConfig->nPrefix ){ /* Straight index lookup */ Fts5Structure *pStruct = fts5StructureRead(p); @@ -7121,7 +7128,8 @@ int sqlite3Fts5IndexQuery( int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); - if( pIter->pTokenDataIter ){ + if( pIter->nSeg==0 ){ + assert( pIter->pTokenDataIter ); fts5TokendataIterNext(pIter, 0, 0); }else{ fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); @@ -7158,7 +7166,8 @@ int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ */ int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - if( pIter->pTokenDataIter ){ + if( pIter->nSeg==0 ){ + assert( pIter->pTokenDataIter ); fts5TokendataIterNext(pIter, 1, iMatch); }else{ fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); @@ -7177,14 +7186,161 @@ const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return (z ? &z[1] : 0); } +static void fts5TokendataMerge( + Fts5TokenDataMap *a1, int n1, + Fts5TokenDataMap *a2, int n2, + Fts5TokenDataMap *aOut +){ + int i1 = 0; + int i2 = 0; + + assert( n1>=0 && n2>=0 ); + while( i1=n2 || (i1nMap * sizeof(Fts5TokenDataMap); + + aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( aTmp ){ + Fts5TokenDataMap *a1 = pT->aMap; + Fts5TokenDataMap *a2 = aTmp; + i64 nHalf; + + for(nHalf=1; nHalfnMap; nHalf=nHalf*2){ + int i1; + for(i1=0; i1nMap; i1+=(nHalf*2)){ + int n1 = MIN(nHalf, pT->nMap-i1); + int n2 = MIN(nHalf, pT->nMap-i1-n1); + fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]); + } + SWAPVAL(Fts5TokenDataMap*, a1, a2); + } + + if( a1!=pT->aMap ){ + memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap)); + } + sqlite3_free(aTmp); + +#ifdef SQLITE_DEBUG + { + int ii; + for(ii=1; iinMap; ii++){ + Fts5TokenDataMap *p1 = &pT->aMap[ii-1]; + Fts5TokenDataMap *p2 = &pT->aMap[ii]; + assert( p1->iRowidiRowid + || (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos) + ); + } + } +#endif + } +} + +static int fts5SetupPrefixIterTokendata( + Fts5Iter *pIter, + const char *pToken, + int nToken +){ + Fts5Index *p = pIter->pIndex; + Fts5Buffer token = {0, 0, 0}; + Fts5TokenDataIter *pT = 0; + + fts5BufferGrow(&p->rc, &token, nToken+1); + pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); + + if( p->rc==SQLITE_OK ){ + const int flags = FTS5INDEX_QUERY_SCAN + | FTS5INDEX_QUERY_SKIPEMPTY + | FTS5INDEX_QUERY_NOOUTPUT; + Fts5Structure *pStruct = 0; + Fts5Iter *p1 = 0; /* Iterator used to find tokendata */ + + int bNewTerm = 1; + int iTermOff = 0; + int nTermByte = 0; + + /* Fill in the token prefix to search for */ + token.p[0] = FTS5_MAIN_PREFIX; + memcpy(&token.p[1], pToken, nToken); + token.n = nToken+1; + + /* Grab a reference to the table structure. That will be released before + ** this function returns. */ + pStruct = fts5StructureRead(p); + + fts5MultiIterNew(p, pStruct, flags, 0, token.p, token.n, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for( /* no-op */ ; + fts5MultiIterEof(p, p1)==0; + fts5MultiIterNext2(p, p1, &bNewTerm) + ){ + i64 iPos = 0; + int iPosOff = 0; + + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + p1->xSetOutputs(p1, pSeg); + + if( bNewTerm ){ + int nTerm = pSeg->term.n; + const u8 *pTerm = pSeg->term.p; + assert_nc( memcmp(token.p, pTerm, MIN(token.n, nTerm))<=0 ); + if( nTermterms.n; + fts5BufferAppendBlob(&p->rc, &pT->terms, nTermByte, pTerm+1); + } + + while( 0==sqlite3Fts5PoslistNext64( + p1->base.pData, p1->base.nData, &iPosOff, &iPos + ) ){ + fts5TokendataIterAppendMap( + p, pT, iTermOff, nTermByte, p1->base.iRowid, iPos + ); + } + } + + /* fts5SetupPrefixIter */ + fts5MultiIterFree(p1); + fts5StructureRelease(pStruct); + + fts5TokendataIterSortMap(p, pT); + } + + if( p->rc==SQLITE_OK ){ + pIter->pTokenDataIter = pT; + }else{ + fts5TokendataIterDelete(pT); + } + fts5BufferFree(&token); + + return fts5IndexReturn(p); +} + /* ** This is used by xInstToken() to access the token at offset iOff, column ** iCol of row iRowid. The token is returned via output variables *ppOut ** and *pnOut. The iterator passed as the first argument must be a tokendata=1 ** iterator (pIter->pTokenDataIter!=0). +** +** pToken/nToken: */ int sqlite3Fts5IterToken( Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, i64 iRowid, int iCol, int iOff, @@ -7192,13 +7348,22 @@ int sqlite3Fts5IterToken( ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5TokenDataIter *pT = pIter->pTokenDataIter; - Fts5TokenDataMap *aMap = pT->aMap; i64 iPos = (((i64)iCol)<<32) + iOff; - + Fts5TokenDataMap *aMap = 0; int i1 = 0; - int i2 = pT->nMap; + int i2 = 0; int iTest = 0; + assert( pT || (pToken && pIter->nSeg>0) ); + if( pT==0 ){ + int rc = fts5SetupPrefixIterTokendata(pIter, pToken, nToken); + if( rc!=SQLITE_OK ) return rc; + pT = pIter->pTokenDataIter; + } + + i2 = pT->nMap; + aMap = pT->aMap; + while( i2>i1 ){ iTest = (i1 + i2) / 2; @@ -7221,9 +7386,15 @@ int sqlite3Fts5IterToken( } if( i2>i1 ){ - Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; - *ppOut = (const char*)pMap->aSeg[0].term.p+1; - *pnOut = pMap->aSeg[0].term.n-1; + if( pIter->nSeg==0 ){ + Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; + *ppOut = (const char*)pMap->aSeg[0].term.p+1; + *pnOut = pMap->aSeg[0].term.n-1; + }else{ + Fts5TokenDataMap *p = &aMap[iTest]; + *ppOut = (const char*)&pT->terms.p[p->iIter]; + *pnOut = aMap[iTest].nByte; + } } return SQLITE_OK; @@ -7235,7 +7406,9 @@ int sqlite3Fts5IterToken( */ void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - if( pIter && pIter->pTokenDataIter ){ + if( pIter && pIter->pTokenDataIter + && (pIter->nSeg==0 || pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_FULL) + ){ pIter->pTokenDataIter->nMap = 0; } } @@ -7255,17 +7428,30 @@ int sqlite3Fts5IndexIterWriteTokendata( Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5TokenDataIter *pT = pIter->pTokenDataIter; Fts5Index *p = pIter->pIndex; - int ii; + i64 iPos = (((i64)iCol)<<32) + iOff; assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); - assert( pIter->pTokenDataIter ); - - for(ii=0; iinIter; ii++){ - Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; - if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; - } - if( iinIter ){ - fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff); + assert( pIter->pTokenDataIter || pIter->nSeg>0 ); + if( pIter->nSeg>0 ){ + /* This is a prefix term iterator. */ + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + if( pT==0 ){ + pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); + pIter->pTokenDataIter = pT; + } + if( pT ){ + fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos); + fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken); + } + }else{ + int ii; + for(ii=0; iinIter; ii++){ + Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; + if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; + } + if( iinIter ){ + fts5TokendataIterAppendMap(p, pT, ii, 0, iRowid, iPos); + } } return fts5IndexReturn(p); } diff --git a/manifest b/manifest index 31fbff973a..91a17cd96b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges\sinto\sthis\sbranch. -D 2024-09-24T15:43:52.339 +C Change\sthe\sway\stokendata\sindexes\sare\scollected\sfor\sprefix\squeries. +D 2024-09-25T18:55:11.223 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -93,13 +93,13 @@ F ext/fts3/unicode/mkunicode.tcl 63db9624ccf70d4887836c320eda93ab552f21008f3be7e F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15 F ext/fts5/fts5.h efaaac0df3d3bc740383044c144b582f47921aafa21d7b10eb98f42c24c740b0 -F ext/fts5/fts5Int.h 93aba03ca417f403b07b2ab6f50aa0e0c1b8b031917a9026b81520e7047a168e +F ext/fts5/fts5Int.h 83a7af3fee07d5163bf7bf97db310544fcc143c94acb13dbced7e06ae8025a18 F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 F ext/fts5/fts5_config.c da21548ddbc1a457cb42545f527065221ede8ada6a734891b8c34317a7a9506b -F ext/fts5/fts5_expr.c 1f60d81aa4703435f98f46bbb41fb2a2efa898423fec070a2b3f7a02f177ac64 +F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c aadd271f3c2048418298377908dd09d496753a5c7da84161a9c86ca8c1e78e9a +F ext/fts5/fts5_index.c 8dfb22c5e42cd56d3abbe107a5561fc3b4f731fc4c821ac049482d9dedc50acc F ext/fts5/fts5_main.c 4503498d3453e29a3cd89dacaba029011e89cb8c481a6241611d106e7a369bd4 F ext/fts5/fts5_storage.c 3332497823c3d171cf56379f2bd8c971ce15a19aadacff961106462022c92470 F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe @@ -2214,8 +2214,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 97c2824f471e7e622c4a166947a6e8162cae891345101539829a6fcec83373fe 42bb941584a1ac922ee6b0b6ecadce71c9259555563cf49913a6f820f3f9b887 -R cb71c4478793484afa282b1a3cf11afa +P 9945206e6e26a48a49b9747650d299eb983cc21a3a61c621cd81f0bbc85a74d7 +R d12c6f9d3e41d3b7f32c957f52650189 U dan -Z efd6491e97a3bc8cd929e608bea6d1a9 +Z 0b9676f39cb90827333f01676ed89ac5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dc02877987..92e4aa62cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9945206e6e26a48a49b9747650d299eb983cc21a3a61c621cd81f0bbc85a74d7 +204ddf4e726b695dd12ab4a945ec2461655aa0bcc38b74e970f07ed2ac43c6ff From 220434abdd457596f4026904ea0d149b264551e6 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 22:13:49 +0000 Subject: [PATCH 017/522] Integrate the configure-time Emscripten bits. FossilOrigin-Name: 456125a14454180d608d8f5bc651aa4350958cdd14f4011ef540beb278ca2d51 --- Makefile.in | 7 +- auto.def | 139 ++++++++++++++++++------------------- autosetup/hwaci-common.tcl | 55 +++++++++++++++ manifest | 17 ++--- manifest.uuid | 2 +- tool/emcc.sh.in | 63 +++++++++++++++++ 6 files changed, 201 insertions(+), 82 deletions(-) create mode 100644 tool/emcc.sh.in diff --git a/Makefile.in b/Makefile.in index 8b17ef5e47..687d482915 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,10 +14,15 @@ # that contains this "Makefile.in" and the "configure" script. # TOP = @abs_top_srcdir@ - # Just testing expansions... +# srcdir = @srcdir@ +# top_srcdir = @top_srcdir@ +# abs_top_srcdir = @abs_top_srcdir@ +# abs_top_builddir = @abs_top_builddir@ # LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ # LDFLAGS_MATH = @LDFLAGS_MATH@ +# LD = @LD@ +# AR = @AR@ # C Compiler and options for use in building executables that # will run on the platform that is doing the build. diff --git a/auto.def b/auto.def index d4ee5fee6a..75c8450e69 100644 --- a/auto.def +++ b/auto.def @@ -1,64 +1,46 @@ # Created by migrate-autoconf - fix items marked XXX global autosetup -use cc cc-shared cc-lib hwaci-common +use cc cc-db cc-shared cc-lib hwaci-common set DUMP_DEFINES_FILE defines.list -set cross_compiling 0 set enable_shared 1 +# Are we cross compiling? +set cross_compiling 0 +if {[get-define host] ne [get-define build]} { + set cross_compiling 1 +} +define cross_compiling ${cross_compiling} + +if {0 && $cross_compiling} { + # gcc's cross-compiler is named platform-os-vendor-gcc instead of + # platform-os-vendor-cc. Checking for cc here will find the CC which + # was already found via (use cc). Checking for gcc here would be + # unportable - the client may well have a different cross-compiler. + define-push {GCC LD AR} { + cc-check-tools gcc ld ar + define BIN_host_GCC [get-define GCC] + define BIN_host_LD [get-define LD] + define BIN_host_AR [get-define AR] + } +} + ######################################################################## -# Note that boolean flags... -# -# 1) Are in the form flagname (default=false) or flagname=0 (false) or -# flagname=1 (true). -# -# 2) If they default to false, the actual flag mapped to them is -# --enable-FLAG. -# -# 3) If they default to true, the actual flag mapped to them is -# --disable-FLAG. +# A very long story made short, autosetup's --flag handling has +# some behaviors which make it impossible to implement 100% identical +# flags, compared to the historical autotools build. The differences +# are documented here: # -# 4) For boolean options, configure will accept any of --flag, --enable-flag, -# or --disable-flag. Unfortunately, it reserves --debug for its own use. # -# 5) Mapping with their full name, e.g. enable-foo=1 or disable-bar=0, -# will lead to breakage in calls to either [opt-bool foo] or -# [opt-bool enable-foo]. +# 1) --debug is used by autosetup itself, so we have to rename it to +# --with-debug. We cannot use --enable-debug because that is, for +# autosetup, and alias for --debug=1. # -# (2) and (3) mean that the help text for flag=1 should start with -# "Disable" and flag=0 should start with "Enable". +# 2) In autosetup, all flags starting with (--enable, --disable) are +# forced to be booleans and received special handling in how they're +# resolved. Because of that we have to rename: # -# In trying to helpfully map between --foo/--enable-foo/--disable-foo, -# it ends up creating some degree of confusion. +# 2.1) --enable-tempstore[=no] to --with-tempstore[=no]. # -# Reminders about flag handling quirks.. -# -# 1) autosetup treats prefixes of 'enable' and 'disable' specially, -# leading to some incompatibilities with the historical sqlite3 -# configure script flags. -# -# Defining non-boolean flags named enable-foo requires different -# downstream handling of those flags. e.g. -# -# enable-tempstore:=no => {...} -# -# requires that [opt-val enable-tempstore], rather than [opt-val -# tempstore], be used, which is in constrast to boolean flags, where -# [opt-bool flag] must be used instead of [opt-bool enable-flag]. -# -# Also, passing --enable-tempstore with no value (to presumably get the -# default value) breaks: autosetup tries to find a boolean-type tempstore -# flag and cannot, so it complains that flag --tempstore is not defined. -# i.e. --enable-tempstore requires that it be passed a value. -# -# An awkward workaround for that, discovered only by random trial and -# error, is to define both {tempstore=1} and {enable-tempstore:}. With -# that in place --enable-tempstore, with no value, works as expected -# (why? Nobody knows!) but --tempstore can only ever be legally passed -# a boolean value (0, 1, yes, no, enabled, disabled). It does, -# however, pollute the --help with a synthetic --disable-tempstore -# option. After an hour of fighting with it, a switch from -# --enable-tempstore to --with-tempstore seems like the better -# approach, in that it doesn't lead to a losing fight with autosetup. options { with-debug:=1 => {Enable debug build flags} with-tclsh:PATHNAME => {Full pathname of tclsh to use} @@ -95,16 +77,21 @@ options { with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} } -# debug=0 => {debugging & verbose explain} set srcdir $autosetup(srcdir) -puts "srcdir = $srcdir" -set VERSION [readfile $srcdir/VERSION] +#puts "srcdir = $srcdir" +set VERSION [readfile $autosetup(srcdir)/VERSION] puts "VERSION = $VERSION" define PACKAGE_VERSION $VERSION #puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" #puts "with-debug? = [opt-val with-debug]" +set outOfTreeBuild 0 +if {![file exists sqlite3.pc.in]} { + puts "This appears to be an out-of-tree build." + set outOfTreeBuild 1 +} + # # The build process allows for using a cross-compiler. But the default # action is to target the same platform that we are running on. The @@ -281,6 +268,7 @@ undefine lib_fdatasync # Check for needed/wanted headers cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { + # TODO: port over the more sophisticated zlib search from the fossil auto.def define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" define LDFLAGS_ZLIB -lz } else { @@ -289,9 +277,13 @@ if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { } hwaci-define-if-opt-truthy with-debug SQLITE_DEBUG "Debug build?" -hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION "Use amalgamation for builds?" +hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ + "Use amalgamation for builds?" hwaci-define-if-opt-truthy gcov USE_GCOV "Use gcov?" -hwaci-define-if-opt-truthy test-status TSTRNNR_OPTS "test-runner flags?" {--status} {} +hwaci-define-if-opt-truthy test-status TSTRNNR_OPTS \ + "test-runner flags:" {--status} {} +hwaci-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \ + "Use #line macros in the amalgamation:" {--linemacros=1} {--linemacros=0} if {0} { ######### @@ -685,6 +677,20 @@ if {0} { # XXX BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS } +########## +# Emscripten SDK for building the web-based wasm components. +# +if {[hwaci-check-emsdk]} { + set wrapper $srcdir/tool/emcc.sh + define EMCC_WRAPPER $wrapper + hwaci-make-from-dot-in $wrapper 1 + catch {exec chmod u+x $wrapper} + unset wrapper +} else { + define EMCC_WRAPPER "" + catch {exec rm -f $srcdir/tool/emcc.sh} +} + proc affirm-have-math {} { if {![cc-check-function-in-lib log m]} { user-error "Missing required math APIs" @@ -726,23 +732,6 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } } -msg-checking "Use #line macros in the amalgamation: " -hwaci-if-opt-truthy linemacros { - define AMALGAMATION_LINE_MACROS {--linemacros=1} - msg-result yes -} { - define AMALGAMATION_LINE_MACROS {--linemacros=0} - msg-result no -} - - -########## -# Emscripten SDK -# -if {1} { - # TODO: port this bit and its associated shell script from the - # Fossil source tree's auto.def and tools/emcc.sh.in. -} ######### # Generate the output files. @@ -776,7 +765,13 @@ hwaci-if-opt-truthy dump-defines { msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" make-config-header $DUMP_DEFINES_FILE \ -bare {OPT_FEATURE_FLAGS SQLITE_OS* SQLITE_DEBUG LDFLAGS_* USE_*} \ + -str {BIN_* CC LD AR} \ -auto {*} # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will # get _undefined_ here unless it's part of the -bare set. + if {0} { + foreach x $::define { + puts "\t$x" + } + } } diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 20bdb4b470..8466e0116d 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -428,3 +428,58 @@ proc hwaci-check-exeext {} { msg-result no } } + +######################################################################## +# Emscripten is used for doing in-tree builds of web-based WASM stuff, +# as opposed to WASI-based WASM or WASM binaries we import from other +# places. This is only set up for Unix-style OSes and is untested +# anywhere but Linux. +# +# Defines the following: +# +# - EMSDK_HOME = top dir of the emsdk or "". It looks for +# --with-emsdk=DIR or the $EMSDK environment variable. +# - EMSDK_ENV = path to EMSDK_HOME/emsdk_env.sh or "" +# - BIN_EMCC = $EMSDK_HOME/upstream/emscripten/emcc or "" +# +# Returns 1 if EMSDK_ENV is found, else 0. If EMSDK_HOME is not empty +# but BIN_EMCC is then emcc was not found in the EMSDK_HOME, in which +# case we have to rely on the fact that sourcing $EMSDK_ENV from a +# shell will add emcc to the $PATH. +proc hwaci-check-emsdk {} { + set emsdkHome [opt-val with-emsdk] + define EMSDK_HOME "" + define EMSDK_ENV "" + define BIN_EMCC "" +# define EMCC_OPT "-Oz" + msg-checking "Emscripten SDK? " + if {$emsdkHome eq "" && [info exists ::env(EMSDK)]} { + # Fall back to checking the environment. $EMSDK gets set + # by sourcing emsdk_env.sh. + set emsdkHome $::env(EMSDK) + } + set rc 0 + if {$emsdkHome ne ""} { + define EMSDK_HOME $emsdkHome + set emsdkEnv "$emsdkHome/emsdk_env.sh" + if {[file exists $emsdkEnv]} { + msg-result "$emsdkHome" + define EMSDK_ENV $emsdkEnv +# if {[info exists ::env(EMCC_OPT)]} { +# define EMCC_OPT $::env(EMCC_OPT) +# } + set rc 1 + set emcc "$emsdkHome/upstream/emscripten/emcc" + if {[file exists $emcc]} { + # puts "is emcc == $emcc ???" + define BIN_EMCC $emcc + } + } else { + msg-result "emsdk_env.sh not found in $emsdkHome" + } + } else { + msg-result "not found" + } + define HAVE_EMSDK $rc + return $rc +} diff --git a/manifest b/manifest index c124584a49..27e3304a7c 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Further\sstreamlining\sof\sauto.def. -D 2024-09-25T18:03:26.242 +C Integrate\sthe\sconfigure-time\sEmscripten\sbits. +D 2024-09-25T22:13:49.969 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 7b3bc24530c2a6580d4b3a049a3f45246118fa2098ce5dd10ab76333f02f7246 +F Makefile.in 423f8b90ccb385a96c9f9551d74ab2b678e7a6191bf908c2b44304997804cb63 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 334d1bcda82fe05ac65baa1485701e05911ce4304175f716bacc33b5ddb1d61c +F auto.def 25c1a8645d4845bc2970d183be0ac2c9bdf0f05c348fc6705385c17047802bb4 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 6c48b16beb9eb8015f207980095f5f65c55e5238159a9d50791b643e5c295205 +F autosetup/hwaci-common.tcl c0ff4bb3399f7a55b5dba83ab6f98b68a54952f28ae49c658340b48ea3cd827d F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2130,6 +2130,7 @@ F tool/custom.txt 6cdf298f43e1db4bb91406d14777669b8fb1df790837823fa6754c4308decc F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c +F tool/emcc.sh.in bc3f3a29f5a7272afe605a483d6463617f27d31c74fa9135c7eaa3b844345b74 F tool/enlargedb.c 3e8b2612b985cfa7e3e8800031ee191b43ae80de96abb5abbd5eada62651ee21 F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -2232,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8716c35eaa168677a10de7b4aa55d35c54035f5e685cc1a5890b940a41cc6ff7 -R 7ae842c7d3995cad59964f0358f0039c +P 74d12433599e2f189d8d0a44be834651531ac5a215bf42de386053cd00d29162 +R dd47ba23be16ca7a64fc24efb04f8a5b U stephan -Z fd55233750e1823126fedbcf310025fa +Z 7445a300c3d8549aa733ba93da0d5f2b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 172f049785..adaa3beb74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74d12433599e2f189d8d0a44be834651531ac5a215bf42de386053cd00d29162 +456125a14454180d608d8f5bc651aa4350958cdd14f4011ef540beb278ca2d51 diff --git a/tool/emcc.sh.in b/tool/emcc.sh.in new file mode 100644 index 0000000000..91ed6a2c27 --- /dev/null +++ b/tool/emcc.sh.in @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +######################################################################## +# WARNING: emcc.sh is generated from emcc.sh.in by the configure +# process. Do not edit emcc.sh directly, as it may be deleted or +# overwritten by the configure script. +# +# A wrapper around the emcc compiler which uses configure-time state +# to locate the Emscripten SDK and import the SDK's environment +# script, if needed. +######################################################################## +# EMSDK_HOME comes from the configure --with-emsdk=/dir flag. +# EMSDK_ENV is ${thatDir}/emsdk_env.sh and is also set by the +# configure process. +EMSDK_HOME="@EMSDK_HOME@" +EMSDK_ENV="@EMSDK_ENV@" +emcc="@BIN_EMCC@" + +if [x = "x${emcc}" ]; then + emcc=$(which emcc 2>/dev/null) +fi + +if [ x = "x${emcc}" ]; then + # If emcc is not found in the path, try to find it via an emsdk + # installation. The SDK variant is the official installation + # style supported by the Emscripten folks, but emcc is also + # available via package managers on some OSes. + if [ x = "x${EMSDK_HOME}" ]; then + echo "EMSDK_HOME is not set. Pass --with-emsdk=/path/to/emsdk" \ + "to the configure script." 1>&2 + exit 1 + fi + + if [ x = "x${EMSDK_ENV}" ]; then + if [ -f "${EMSDK_HOME}/emsdk_env.sh" ]; then + EMSDK_ENV="${EMSDK_HOME}/emsdk_env.sh" + else + echo "EMSDK_ENV is not set. Expecting configure script to set it." 1>&2 + exit 2 + fi + fi + + if [ ! -f "${EMSDK_ENV}" ]; then + echo "emsdk_env script not found: $EMSDK_ENV" 1>&2 + exit 3 + fi + + # $EMSDK is part of the state set by emsdk_env.sh. + if [ x = "x${EMSDK}" ]; then + source "${EMSDK_ENV}" >/dev/null 2>&1 || { + # ^^^ unfortunately outputs lots of noise to stderr + rc=$? + echo "Error sourcing ${EMSDK_ENV}" + exit $rc + } + fi + emcc=$(which emcc 2>/dev/null) + if [ x = "x${emcc}" ]; then + echo "emcc not found in PATH. Normally that's set up by EMSDK_ENV." 1>&2 + exit 4 + fi +fi + +exec emcc "$@" From bb12cdc11b5e2c18bb314eb676e8523bfb54c32b Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 25 Sep 2024 23:09:38 +0000 Subject: [PATCH 018/522] Time for a break. FossilOrigin-Name: 1d29cd9095595b7b027b90d644dc4767fde0b6f98316c0eb82014b7aad6770d7 --- Makefile.in | 1108 ++++++++++++++++++------------------ auto.def | 17 +- autosetup/hwaci-common.tcl | 8 +- manifest | 16 +- manifest.uuid | 2 +- 5 files changed, 585 insertions(+), 566 deletions(-) diff --git a/Makefile.in b/Makefile.in index 687d482915..69e0736801 100644 --- a/Makefile.in +++ b/Makefile.in @@ -19,10 +19,10 @@ TOP = @abs_top_srcdir@ # top_srcdir = @top_srcdir@ # abs_top_srcdir = @abs_top_srcdir@ # abs_top_builddir = @abs_top_builddir@ -# LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ -# LDFLAGS_MATH = @LDFLAGS_MATH@ -# LD = @LD@ -# AR = @AR@ +LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ +LDFLAGS_MATH = @LDFLAGS_MATH@ +LD = @LD@ +AR = @AR@ # C Compiler and options for use in building executables that # will run on the platform that is doing the build. @@ -80,12 +80,12 @@ CFLAGS = @CPPFLAGS@ @CFLAGS@ #XX## #XX#TLIBS = @LIBS@ $(LIBS) #XX# -#XX## Flags controlling use of the in memory btree implementation -#XX## -#XX## SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to -#XX## default to file, 2 to default to memory, and 3 to force temporary -#XX## tables to always be in memory. -#XX## +# Flags controlling use of the in memory btree implementation +# +# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to +# default to file, 2 to default to memory, and 3 to force temporary +# tables to always be in memory. +# TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@ # Enable/disable loadable extensions, and other optional features @@ -98,27 +98,29 @@ TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@ # the build is specifically configured to account for them. # OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) -#XX# -#XX#TCC += $(OPT_FEATURE_FLAGS) -#XX# -#XX## Add in any optional parameters specified on the make commane line -#XX## ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". -#XX#TCC += $(OPTS) -#XX# -#XX## Add in compile-time options for some libraries used by extensions -#XX#TCC += @HAVE_ZLIB@ -#XX# -#XX## Version numbers and release number for the SQLite being compiled. -#XX## -#XX#VERSION = @VERSION@ + +TCC += $(OPT_FEATURE_FLAGS) + +# Add in any optional parameters specified on the make commane line +# ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". +TCC += $(OPTS) + +# Add in compile-time options for some libraries used by extensions +TCC += @LDFLAGS_ZLIB@ + +# Version numbers and release number for the SQLite being compiled. +# +VERSION = @VERSION@ #XX#VERSION_NUMBER = @VERSION_NUMBER@ #XX#RELEASE = @RELEASE@ -#XX# -#XX## Filename extensions -#XX## -#XX#BEXE = @BUILD_EXEEXT@ -#XX#TEXE = @TARGET_EXEEXT@ -#XX# + +# Filename extensions for binaries +# +BEXE = @BUILD_EXEEXT@ +TEXE = @TARGET_EXEEXT@ +BOBJ = @BUILD_OBJEXT@ +TOBJ = @TARGET_OBJEXT@ + #XX## The following variable is "1" if the configure script was able to locate #XX## the tclConfig.sh file. It is an empty string otherwise. When this #XX## variable is "1", the TCL extension library (libtclsqlite3.so) is built @@ -134,41 +136,42 @@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) #XX## Additional options when running tests using testrunner.tcl #XX## This is usually either blank, or else --status #XX## -#XX#TSTRNNR_OPTS = @TSTRNNR_OPTS@ -#XX# +TSTRNNR_OPTS = @TSTRNNR_OPTS@ +# #XX## Where do we want to install the tcl plugin #XX## #XX#TCLLIBDIR = @TCLLIBDIR@ -#XX# -#XX## If gcov support was enabled by the configure script, add the appropriate -#XX## flags here. It's not always as easy as just having the user add the right -#XX## CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which -#XX## causes build errors with -fprofile-arcs -ftest-coverage with some GCCs. -#XX## Supposedly GCC does the right thing if you use --coverage, but in -#XX## practice it still fails. See: -#XX## -#XX## http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html -#XX## -#XX## for more info. -#XX## -#XX#GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage -#XX#GCOV_LDFLAGS1 = -lgcov -#XX#USE_GCOV = @USE_GCOV@ + +# +# If gcov support was enabled by the configure script, add the appropriate +# flags here. It's not always as easy as just having the user add the right +# CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which +# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs. +# Supposedly GCC does the right thing if you use --coverage, but in +# practice it still fails. See: +# +# http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html +# +# for more info. +# +GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage +GCOV_LDFLAGS1 = -lgcov +USE_GCOV = @USE_GCOV@ #XX#LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) #XX#LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) -#XX# -#XX# -#XX## The directory into which to store package information for -#XX# -#XX## Some standard variables and programs -#XX## -#XX#prefix = @prefix@ -#XX#exec_prefix = @exec_prefix@ -#XX#libdir = @libdir@ -#XX#pkgconfigdir = $(libdir)/pkgconfig -#XX#bindir = @bindir@ -#XX#includedir = @includedir@ -#XX#INSTALL = @INSTALL@ + + +# The directory into which to store package information for + +# Some standard variables and programs +# +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +pkgconfigdir = $(libdir)/pkgconfig +bindir = @bindir@ +includedir = @includedir@ +INSTALL = @BIN_INSTALL@ #XX#LIBTOOL = ./libtool #XX#ALLOWRELEASE = @ALLOWRELEASE@ #XX# @@ -176,13 +179,14 @@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) #XX#LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS) #XX#LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS) #XX#LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) -#XX# -#XX## You should not have to change anything below this line -#XX################################################################################ -#XX# -#XX#USE_AMALGAMATION = @USE_AMALGAMATION@ -#XX#AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@ -#XX# + +# +# You should not have to change anything below this line +################################################################################ +# +USE_AMALGAMATION = @USE_AMALGAMATION@ +AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@ +# #XX## Object files for the SQLite library (non-amalgamation). #XX## #XX#LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ @@ -222,455 +226,457 @@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) #XX# #XX## All of the source code files. #XX## -#XX#SRC = \ -#XX# $(TOP)/src/alter.c \ -#XX# $(TOP)/src/analyze.c \ -#XX# $(TOP)/src/attach.c \ -#XX# $(TOP)/src/auth.c \ -#XX# $(TOP)/src/backup.c \ -#XX# $(TOP)/src/bitvec.c \ -#XX# $(TOP)/src/btmutex.c \ -#XX# $(TOP)/src/btree.c \ -#XX# $(TOP)/src/btree.h \ -#XX# $(TOP)/src/btreeInt.h \ -#XX# $(TOP)/src/build.c \ -#XX# $(TOP)/src/callback.c \ -#XX# $(TOP)/src/complete.c \ -#XX# $(TOP)/src/ctime.c \ -#XX# $(TOP)/src/date.c \ -#XX# $(TOP)/src/dbpage.c \ -#XX# $(TOP)/src/dbstat.c \ -#XX# $(TOP)/src/delete.c \ -#XX# $(TOP)/src/expr.c \ -#XX# $(TOP)/src/fault.c \ -#XX# $(TOP)/src/fkey.c \ -#XX# $(TOP)/src/func.c \ -#XX# $(TOP)/src/global.c \ -#XX# $(TOP)/src/hash.c \ -#XX# $(TOP)/src/hash.h \ -#XX# $(TOP)/src/hwtime.h \ -#XX# $(TOP)/src/insert.c \ -#XX# $(TOP)/src/json.c \ -#XX# $(TOP)/src/legacy.c \ -#XX# $(TOP)/src/loadext.c \ -#XX# $(TOP)/src/main.c \ -#XX# $(TOP)/src/malloc.c \ -#XX# $(TOP)/src/mem0.c \ -#XX# $(TOP)/src/mem1.c \ -#XX# $(TOP)/src/mem2.c \ -#XX# $(TOP)/src/mem3.c \ -#XX# $(TOP)/src/mem5.c \ -#XX# $(TOP)/src/memdb.c \ -#XX# $(TOP)/src/memjournal.c \ -#XX# $(TOP)/src/msvc.h \ -#XX# $(TOP)/src/mutex.c \ -#XX# $(TOP)/src/mutex.h \ -#XX# $(TOP)/src/mutex_noop.c \ -#XX# $(TOP)/src/mutex_unix.c \ -#XX# $(TOP)/src/mutex_w32.c \ -#XX# $(TOP)/src/notify.c \ -#XX# $(TOP)/src/os.c \ -#XX# $(TOP)/src/os.h \ -#XX# $(TOP)/src/os_common.h \ -#XX# $(TOP)/src/os_setup.h \ -#XX# $(TOP)/src/os_kv.c \ -#XX# $(TOP)/src/os_unix.c \ -#XX# $(TOP)/src/os_win.c \ -#XX# $(TOP)/src/os_win.h \ -#XX# $(TOP)/src/pager.c \ -#XX# $(TOP)/src/pager.h \ -#XX# $(TOP)/src/parse.y \ -#XX# $(TOP)/src/pcache.c \ -#XX# $(TOP)/src/pcache.h \ -#XX# $(TOP)/src/pcache1.c \ -#XX# $(TOP)/src/pragma.c \ -#XX# $(TOP)/src/pragma.h \ -#XX# $(TOP)/src/prepare.c \ -#XX# $(TOP)/src/printf.c \ -#XX# $(TOP)/src/random.c \ -#XX# $(TOP)/src/resolve.c \ -#XX# $(TOP)/src/rowset.c \ -#XX# $(TOP)/src/select.c \ -#XX# $(TOP)/src/status.c \ -#XX# $(TOP)/src/shell.c.in \ -#XX# $(TOP)/src/sqlite.h.in \ -#XX# $(TOP)/src/sqlite3ext.h \ -#XX# $(TOP)/src/sqliteInt.h \ -#XX# $(TOP)/src/sqliteLimit.h \ -#XX# $(TOP)/src/table.c \ -#XX# $(TOP)/src/tclsqlite.c \ -#XX# $(TOP)/src/threads.c \ -#XX# $(TOP)/src/tokenize.c \ -#XX# $(TOP)/src/treeview.c \ -#XX# $(TOP)/src/trigger.c \ -#XX# $(TOP)/src/utf.c \ -#XX# $(TOP)/src/update.c \ -#XX# $(TOP)/src/upsert.c \ -#XX# $(TOP)/src/util.c \ -#XX# $(TOP)/src/vacuum.c \ -#XX# $(TOP)/src/vdbe.c \ -#XX# $(TOP)/src/vdbe.h \ -#XX# $(TOP)/src/vdbeapi.c \ -#XX# $(TOP)/src/vdbeaux.c \ -#XX# $(TOP)/src/vdbeblob.c \ -#XX# $(TOP)/src/vdbemem.c \ -#XX# $(TOP)/src/vdbesort.c \ -#XX# $(TOP)/src/vdbetrace.c \ -#XX# $(TOP)/src/vdbevtab.c \ -#XX# $(TOP)/src/vdbeInt.h \ -#XX# $(TOP)/src/vtab.c \ -#XX# $(TOP)/src/vxworks.h \ -#XX# $(TOP)/src/wal.c \ -#XX# $(TOP)/src/wal.h \ -#XX# $(TOP)/src/walker.c \ -#XX# $(TOP)/src/where.c \ -#XX# $(TOP)/src/wherecode.c \ -#XX# $(TOP)/src/whereexpr.c \ -#XX# $(TOP)/src/whereInt.h \ -#XX# $(TOP)/src/window.c -#XX# -#XX## Source code for extensions -#XX## -#XX#SRC += \ -#XX# $(TOP)/ext/fts3/fts3.c \ -#XX# $(TOP)/ext/fts3/fts3.h \ -#XX# $(TOP)/ext/fts3/fts3Int.h \ -#XX# $(TOP)/ext/fts3/fts3_aux.c \ -#XX# $(TOP)/ext/fts3/fts3_expr.c \ -#XX# $(TOP)/ext/fts3/fts3_hash.c \ -#XX# $(TOP)/ext/fts3/fts3_hash.h \ -#XX# $(TOP)/ext/fts3/fts3_icu.c \ -#XX# $(TOP)/ext/fts3/fts3_porter.c \ -#XX# $(TOP)/ext/fts3/fts3_snippet.c \ -#XX# $(TOP)/ext/fts3/fts3_tokenizer.h \ -#XX# $(TOP)/ext/fts3/fts3_tokenizer.c \ -#XX# $(TOP)/ext/fts3/fts3_tokenizer1.c \ -#XX# $(TOP)/ext/fts3/fts3_tokenize_vtab.c \ -#XX# $(TOP)/ext/fts3/fts3_unicode.c \ -#XX# $(TOP)/ext/fts3/fts3_unicode2.c \ -#XX# $(TOP)/ext/fts3/fts3_write.c -#XX#SRC += \ -#XX# $(TOP)/ext/icu/sqliteicu.h \ -#XX# $(TOP)/ext/icu/icu.c -#XX#SRC += \ -#XX# $(TOP)/ext/rtree/rtree.h \ -#XX# $(TOP)/ext/rtree/rtree.c \ -#XX# $(TOP)/ext/rtree/geopoly.c -#XX#SRC += \ -#XX# $(TOP)/ext/session/sqlite3session.c \ -#XX# $(TOP)/ext/session/sqlite3session.h -#XX#SRC += \ -#XX# $(TOP)/ext/userauth/userauth.c \ -#XX# $(TOP)/ext/userauth/sqlite3userauth.h -#XX#SRC += \ -#XX# $(TOP)/ext/rbu/sqlite3rbu.h \ -#XX# $(TOP)/ext/rbu/sqlite3rbu.c -#XX#SRC += \ -#XX# $(TOP)/ext/misc/stmt.c -#XX# -#XX## Generated source code files -#XX## -#XX#SRC += \ -#XX# keywordhash.h \ -#XX# opcodes.c \ -#XX# opcodes.h \ -#XX# parse.c \ -#XX# parse.h \ -#XX# sqlite_cfg.h \ -#XX# shell.c \ -#XX# sqlite3.h -#XX# -#XX## Source code to the test files. -#XX## -#XX#TESTSRC = \ -#XX# $(TOP)/src/test1.c \ -#XX# $(TOP)/src/test2.c \ -#XX# $(TOP)/src/test3.c \ -#XX# $(TOP)/src/test4.c \ -#XX# $(TOP)/src/test5.c \ -#XX# $(TOP)/src/test6.c \ -#XX# $(TOP)/src/test8.c \ -#XX# $(TOP)/src/test9.c \ -#XX# $(TOP)/src/test_autoext.c \ -#XX# $(TOP)/src/test_async.c \ -#XX# $(TOP)/src/test_backup.c \ -#XX# $(TOP)/src/test_bestindex.c \ -#XX# $(TOP)/src/test_blob.c \ -#XX# $(TOP)/src/test_btree.c \ -#XX# $(TOP)/src/test_config.c \ -#XX# $(TOP)/src/test_delete.c \ -#XX# $(TOP)/src/test_demovfs.c \ -#XX# $(TOP)/src/test_devsym.c \ -#XX# $(TOP)/src/test_fs.c \ -#XX# $(TOP)/src/test_func.c \ -#XX# $(TOP)/src/test_hexio.c \ -#XX# $(TOP)/src/test_init.c \ -#XX# $(TOP)/src/test_intarray.c \ -#XX# $(TOP)/src/test_journal.c \ -#XX# $(TOP)/src/test_malloc.c \ -#XX# $(TOP)/src/test_md5.c \ -#XX# $(TOP)/src/test_multiplex.c \ -#XX# $(TOP)/src/test_mutex.c \ -#XX# $(TOP)/src/test_onefile.c \ -#XX# $(TOP)/src/test_osinst.c \ -#XX# $(TOP)/src/test_pcache.c \ -#XX# $(TOP)/src/test_quota.c \ -#XX# $(TOP)/src/test_rtree.c \ -#XX# $(TOP)/src/test_schema.c \ -#XX# $(TOP)/src/test_superlock.c \ -#XX# $(TOP)/src/test_syscall.c \ -#XX# $(TOP)/src/test_tclsh.c \ -#XX# $(TOP)/src/test_tclvar.c \ -#XX# $(TOP)/src/test_thread.c \ -#XX# $(TOP)/src/test_vdbecov.c \ -#XX# $(TOP)/src/test_vfs.c \ -#XX# $(TOP)/src/test_windirent.c \ -#XX# $(TOP)/src/test_window.c \ -#XX# $(TOP)/src/test_wsd.c \ -#XX# $(TOP)/ext/fts3/fts3_term.c \ -#XX# $(TOP)/ext/fts3/fts3_test.c \ -#XX# $(TOP)/ext/session/test_session.c \ -#XX# $(TOP)/ext/recover/sqlite3recover.c \ -#XX# $(TOP)/ext/recover/dbdata.c \ -#XX# $(TOP)/ext/recover/test_recover.c \ -#XX# $(TOP)/ext/intck/test_intck.c \ -#XX# $(TOP)/ext/intck/sqlite3intck.c \ -#XX# $(TOP)/ext/rbu/test_rbu.c -#XX# -#XX## Statically linked extensions -#XX## -#XX#TESTSRC += \ -#XX# $(TOP)/ext/expert/sqlite3expert.c \ -#XX# $(TOP)/ext/expert/test_expert.c \ -#XX# $(TOP)/ext/misc/amatch.c \ -#XX# $(TOP)/ext/misc/appendvfs.c \ -#XX# $(TOP)/ext/misc/basexx.c \ -#XX# $(TOP)/ext/misc/carray.c \ -#XX# $(TOP)/ext/misc/cksumvfs.c \ -#XX# $(TOP)/ext/misc/closure.c \ -#XX# $(TOP)/ext/misc/csv.c \ -#XX# $(TOP)/ext/misc/decimal.c \ -#XX# $(TOP)/ext/misc/eval.c \ -#XX# $(TOP)/ext/misc/explain.c \ -#XX# $(TOP)/ext/misc/fileio.c \ -#XX# $(TOP)/ext/misc/fuzzer.c \ -#XX# $(TOP)/ext/fts5/fts5_tcl.c \ -#XX# $(TOP)/ext/fts5/fts5_test_mi.c \ -#XX# $(TOP)/ext/fts5/fts5_test_tok.c \ -#XX# $(TOP)/ext/misc/ieee754.c \ -#XX# $(TOP)/ext/misc/mmapwarm.c \ -#XX# $(TOP)/ext/misc/nextchar.c \ -#XX# $(TOP)/ext/misc/normalize.c \ -#XX# $(TOP)/ext/misc/percentile.c \ -#XX# $(TOP)/ext/misc/prefixes.c \ -#XX# $(TOP)/ext/misc/qpvtab.c \ -#XX# $(TOP)/ext/misc/randomjson.c \ -#XX# $(TOP)/ext/misc/regexp.c \ -#XX# $(TOP)/ext/misc/remember.c \ -#XX# $(TOP)/ext/misc/series.c \ -#XX# $(TOP)/ext/misc/spellfix.c \ -#XX# $(TOP)/ext/misc/stmtrand.c \ -#XX# $(TOP)/ext/misc/totype.c \ -#XX# $(TOP)/ext/misc/unionvtab.c \ -#XX# $(TOP)/ext/misc/wholenumber.c \ -#XX# $(TOP)/ext/misc/zipfile.c \ -#XX# $(TOP)/ext/userauth/userauth.c \ -#XX# $(TOP)/ext/rtree/test_rtreedoc.c -#XX# -#XX## Source code to the library files needed by the test fixture -#XX## -#XX#TESTSRC2 = \ -#XX# $(TOP)/src/attach.c \ -#XX# $(TOP)/src/backup.c \ -#XX# $(TOP)/src/bitvec.c \ -#XX# $(TOP)/src/btree.c \ -#XX# $(TOP)/src/build.c \ -#XX# $(TOP)/src/ctime.c \ -#XX# $(TOP)/src/date.c \ -#XX# $(TOP)/src/dbpage.c \ -#XX# $(TOP)/src/dbstat.c \ -#XX# $(TOP)/src/expr.c \ -#XX# $(TOP)/src/func.c \ -#XX# $(TOP)/src/global.c \ -#XX# $(TOP)/src/insert.c \ -#XX# $(TOP)/src/wal.c \ -#XX# $(TOP)/src/main.c \ -#XX# $(TOP)/src/mem5.c \ -#XX# $(TOP)/src/os.c \ -#XX# $(TOP)/src/os_kv.c \ -#XX# $(TOP)/src/os_unix.c \ -#XX# $(TOP)/src/os_win.c \ -#XX# $(TOP)/src/pager.c \ -#XX# $(TOP)/src/pragma.c \ -#XX# $(TOP)/src/prepare.c \ -#XX# $(TOP)/src/printf.c \ -#XX# $(TOP)/src/random.c \ -#XX# $(TOP)/src/pcache.c \ -#XX# $(TOP)/src/pcache1.c \ -#XX# $(TOP)/src/select.c \ -#XX# $(TOP)/src/tokenize.c \ -#XX# $(TOP)/src/treeview.c \ -#XX# $(TOP)/src/utf.c \ -#XX# $(TOP)/src/util.c \ -#XX# $(TOP)/src/vdbeapi.c \ -#XX# $(TOP)/src/vdbeaux.c \ -#XX# $(TOP)/src/vdbe.c \ -#XX# $(TOP)/src/vdbemem.c \ -#XX# $(TOP)/src/vdbetrace.c \ -#XX# $(TOP)/src/vdbevtab.c \ -#XX# $(TOP)/src/where.c \ -#XX# $(TOP)/src/wherecode.c \ -#XX# $(TOP)/src/whereexpr.c \ -#XX# $(TOP)/src/window.c \ -#XX# parse.c \ -#XX# $(TOP)/ext/fts3/fts3.c \ -#XX# $(TOP)/ext/fts3/fts3_aux.c \ -#XX# $(TOP)/ext/fts3/fts3_expr.c \ -#XX# $(TOP)/ext/fts3/fts3_term.c \ -#XX# $(TOP)/ext/fts3/fts3_tokenizer.c \ -#XX# $(TOP)/ext/fts3/fts3_write.c \ -#XX# $(TOP)/ext/async/sqlite3async.c \ -#XX# $(TOP)/ext/session/sqlite3session.c \ -#XX# $(TOP)/ext/misc/stmt.c \ -#XX# fts5.c -#XX# -#XX## Header files used by all library source files. -#XX## -#XX#HDR = \ -#XX# $(TOP)/src/btree.h \ -#XX# $(TOP)/src/btreeInt.h \ -#XX# $(TOP)/src/hash.h \ -#XX# $(TOP)/src/hwtime.h \ -#XX# keywordhash.h \ -#XX# $(TOP)/src/msvc.h \ -#XX# $(TOP)/src/mutex.h \ -#XX# opcodes.h \ -#XX# $(TOP)/src/os.h \ -#XX# $(TOP)/src/os_common.h \ -#XX# $(TOP)/src/os_setup.h \ -#XX# $(TOP)/src/os_win.h \ -#XX# $(TOP)/src/pager.h \ -#XX# $(TOP)/src/pcache.h \ -#XX# parse.h \ -#XX# $(TOP)/src/pragma.h \ -#XX# sqlite3.h \ -#XX# $(TOP)/src/sqlite3ext.h \ -#XX# $(TOP)/src/sqliteInt.h \ -#XX# $(TOP)/src/sqliteLimit.h \ -#XX# $(TOP)/src/vdbe.h \ -#XX# $(TOP)/src/vdbeInt.h \ -#XX# $(TOP)/src/vxworks.h \ -#XX# $(TOP)/src/whereInt.h \ -#XX# sqlite_cfg.h -#XX# -#XX## Header files used by extensions -#XX## -#XX#EXTHDR += \ -#XX# $(TOP)/ext/fts3/fts3.h \ -#XX# $(TOP)/ext/fts3/fts3Int.h \ -#XX# $(TOP)/ext/fts3/fts3_hash.h \ -#XX# $(TOP)/ext/fts3/fts3_tokenizer.h -#XX#EXTHDR += \ -#XX# $(TOP)/ext/rtree/rtree.h \ -#XX# $(TOP)/ext/rtree/geopoly.c -#XX#EXTHDR += \ -#XX# $(TOP)/ext/icu/sqliteicu.h -#XX#EXTHDR += \ -#XX# $(TOP)/ext/rtree/sqlite3rtree.h -#XX#EXTHDR += \ -#XX# $(TOP)/ext/userauth/sqlite3userauth.h -#XX# -#XX## executables needed for testing -#XX## -#XX#TESTPROGS = \ -#XX# testfixture$(TEXE) \ -#XX# sqlite3$(TEXE) \ -#XX# sqlite3_analyzer$(TEXE) \ -#XX# sqldiff$(TEXE) \ -#XX# dbhash$(TEXE) \ -#XX# sqltclsh$(TEXE) -#XX# -#XX## Databases containing fuzzer test cases -#XX## -#XX#FUZZDATA = \ -#XX# $(TOP)/test/fuzzdata1.db \ -#XX# $(TOP)/test/fuzzdata2.db \ -#XX# $(TOP)/test/fuzzdata3.db \ -#XX# $(TOP)/test/fuzzdata4.db \ -#XX# $(TOP)/test/fuzzdata5.db \ -#XX# $(TOP)/test/fuzzdata6.db \ -#XX# $(TOP)/test/fuzzdata7.db \ -#XX# $(TOP)/test/fuzzdata8.db -#XX# -#XX## Standard options to testfixture -#XX## -#XX#TESTOPTS = --verbose=file --output=test-out.txt -#XX# -#XX## Extra compiler options for various shell tools -#XX## -#XX#SHELL_OPT += -DSQLITE_DQS=0 -#XX#SHELL_OPT += -DSQLITE_ENABLE_FTS4 -#XX##SHELL_OPT += -DSQLITE_ENABLE_FTS5 -#XX#SHELL_OPT += -DSQLITE_ENABLE_RTREE -#XX#SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS -#XX#SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -#XX#SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB -#XX#SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB -#XX#SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB -#XX#SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB -#XX#SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC -#XX#SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1 -#XX#FUZZERSHELL_OPT = -#XX#FUZZCHECK_OPT += -I$(TOP)/test -#XX#FUZZCHECK_OPT += -I$(TOP)/ext/recover -#XX#FUZZCHECK_OPT += \ -#XX# -DSQLITE_OSS_FUZZ \ -#XX# -DSQLITE_ENABLE_BYTECODE_VTAB \ -#XX# -DSQLITE_ENABLE_DBPAGE_VTAB \ -#XX# -DSQLITE_ENABLE_DBSTAT_VTAB \ -#XX# -DSQLITE_ENABLE_BYTECODE_VTAB \ -#XX# -DSQLITE_ENABLE_DESERIALIZE \ -#XX# -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ -#XX# -DSQLITE_ENABLE_FTS3_PARENTHESIS \ -#XX# -DSQLITE_ENABLE_FTS4 \ -#XX# -DSQLITE_ENABLE_FTS5 \ -#XX# -DSQLITE_ENABLE_GEOPOLY \ -#XX# -DSQLITE_ENABLE_MATH_FUNCTIONS \ -#XX# -DSQLITE_ENABLE_MEMSYS5 \ -#XX# -DSQLITE_ENABLE_NORMALIZE \ -#XX# -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ -#XX# -DSQLITE_ENABLE_PREUPDATE_HOOK \ -#XX# -DSQLITE_ENABLE_RTREE \ -#XX# -DSQLITE_ENABLE_SESSION \ -#XX# -DSQLITE_ENABLE_STMTVTAB \ -#XX# -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \ -#XX# -DSQLITE_ENABLE_STAT4 \ -#XX# -DSQLITE_ENABLE_STMT_SCANSTATUS \ -#XX# -DSQLITE_MAX_MEMORY=50000000 \ -#XX# -DSQLITE_MAX_MMAP_SIZE=0 \ -#XX# -DSQLITE_OMIT_LOAD_EXTENSION \ -#XX# -DSQLITE_PRINTF_PRECISION_LIMIT=1000 \ -#XX# -DSQLITE_PRIVATE="" \ -#XX# -DSQLITE_STRICT_SUBTYPE=1 \ -#XX# -DSQLITE_STATIC_RANDOMJSON -#XX# -#XX#FUZZCHECK_SRC += $(TOP)/test/fuzzcheck.c -#XX#FUZZCHECK_SRC += $(TOP)/test/ossfuzz.c -#XX#FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c -#XX#FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c -#XX#FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c -#XX#FUZZCHECK_SRC += $(TOP)/test/vt02.c -#XX#FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c -#XX#FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c -#XX#DBFUZZ_OPT = -#XX#ST_OPT = -DSQLITE_OS_KV_OPTIONAL -#XX# -#XX# -#XX## In wasi-sdk builds, disable the CLI shell build in the "all" target. -#XX#SQLITE3_SHELL_TARGET_ = sqlite3$(TEXE) -#XX#SQLITE3_SHELL_TARGET_1 = -#XX#SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@) -#XX# +SRC = \ + $(TOP)/src/alter.c \ + $(TOP)/src/analyze.c \ + $(TOP)/src/attach.c \ + $(TOP)/src/auth.c \ + $(TOP)/src/backup.c \ + $(TOP)/src/bitvec.c \ + $(TOP)/src/btmutex.c \ + $(TOP)/src/btree.c \ + $(TOP)/src/btree.h \ + $(TOP)/src/btreeInt.h \ + $(TOP)/src/build.c \ + $(TOP)/src/callback.c \ + $(TOP)/src/complete.c \ + $(TOP)/src/ctime.c \ + $(TOP)/src/date.c \ + $(TOP)/src/dbpage.c \ + $(TOP)/src/dbstat.c \ + $(TOP)/src/delete.c \ + $(TOP)/src/expr.c \ + $(TOP)/src/fault.c \ + $(TOP)/src/fkey.c \ + $(TOP)/src/func.c \ + $(TOP)/src/global.c \ + $(TOP)/src/hash.c \ + $(TOP)/src/hash.h \ + $(TOP)/src/hwtime.h \ + $(TOP)/src/insert.c \ + $(TOP)/src/json.c \ + $(TOP)/src/legacy.c \ + $(TOP)/src/loadext.c \ + $(TOP)/src/main.c \ + $(TOP)/src/malloc.c \ + $(TOP)/src/mem0.c \ + $(TOP)/src/mem1.c \ + $(TOP)/src/mem2.c \ + $(TOP)/src/mem3.c \ + $(TOP)/src/mem5.c \ + $(TOP)/src/memdb.c \ + $(TOP)/src/memjournal.c \ + $(TOP)/src/msvc.h \ + $(TOP)/src/mutex.c \ + $(TOP)/src/mutex.h \ + $(TOP)/src/mutex_noop.c \ + $(TOP)/src/mutex_unix.c \ + $(TOP)/src/mutex_w32.c \ + $(TOP)/src/notify.c \ + $(TOP)/src/os.c \ + $(TOP)/src/os.h \ + $(TOP)/src/os_common.h \ + $(TOP)/src/os_setup.h \ + $(TOP)/src/os_kv.c \ + $(TOP)/src/os_unix.c \ + $(TOP)/src/os_win.c \ + $(TOP)/src/os_win.h \ + $(TOP)/src/pager.c \ + $(TOP)/src/pager.h \ + $(TOP)/src/parse.y \ + $(TOP)/src/pcache.c \ + $(TOP)/src/pcache.h \ + $(TOP)/src/pcache1.c \ + $(TOP)/src/pragma.c \ + $(TOP)/src/pragma.h \ + $(TOP)/src/prepare.c \ + $(TOP)/src/printf.c \ + $(TOP)/src/random.c \ + $(TOP)/src/resolve.c \ + $(TOP)/src/rowset.c \ + $(TOP)/src/select.c \ + $(TOP)/src/status.c \ + $(TOP)/src/shell.c.in \ + $(TOP)/src/sqlite.h.in \ + $(TOP)/src/sqlite3ext.h \ + $(TOP)/src/sqliteInt.h \ + $(TOP)/src/sqliteLimit.h \ + $(TOP)/src/table.c \ + $(TOP)/src/tclsqlite.c \ + $(TOP)/src/threads.c \ + $(TOP)/src/tokenize.c \ + $(TOP)/src/treeview.c \ + $(TOP)/src/trigger.c \ + $(TOP)/src/utf.c \ + $(TOP)/src/update.c \ + $(TOP)/src/upsert.c \ + $(TOP)/src/util.c \ + $(TOP)/src/vacuum.c \ + $(TOP)/src/vdbe.c \ + $(TOP)/src/vdbe.h \ + $(TOP)/src/vdbeapi.c \ + $(TOP)/src/vdbeaux.c \ + $(TOP)/src/vdbeblob.c \ + $(TOP)/src/vdbemem.c \ + $(TOP)/src/vdbesort.c \ + $(TOP)/src/vdbetrace.c \ + $(TOP)/src/vdbevtab.c \ + $(TOP)/src/vdbeInt.h \ + $(TOP)/src/vtab.c \ + $(TOP)/src/vxworks.h \ + $(TOP)/src/wal.c \ + $(TOP)/src/wal.h \ + $(TOP)/src/walker.c \ + $(TOP)/src/where.c \ + $(TOP)/src/wherecode.c \ + $(TOP)/src/whereexpr.c \ + $(TOP)/src/whereInt.h \ + $(TOP)/src/window.c + +# Source code for extensions +# +SRC += \ + $(TOP)/ext/fts3/fts3.c \ + $(TOP)/ext/fts3/fts3.h \ + $(TOP)/ext/fts3/fts3Int.h \ + $(TOP)/ext/fts3/fts3_aux.c \ + $(TOP)/ext/fts3/fts3_expr.c \ + $(TOP)/ext/fts3/fts3_hash.c \ + $(TOP)/ext/fts3/fts3_hash.h \ + $(TOP)/ext/fts3/fts3_icu.c \ + $(TOP)/ext/fts3/fts3_porter.c \ + $(TOP)/ext/fts3/fts3_snippet.c \ + $(TOP)/ext/fts3/fts3_tokenizer.h \ + $(TOP)/ext/fts3/fts3_tokenizer.c \ + $(TOP)/ext/fts3/fts3_tokenizer1.c \ + $(TOP)/ext/fts3/fts3_tokenize_vtab.c \ + $(TOP)/ext/fts3/fts3_unicode.c \ + $(TOP)/ext/fts3/fts3_unicode2.c \ + $(TOP)/ext/fts3/fts3_write.c +SRC += \ + $(TOP)/ext/icu/sqliteicu.h \ + $(TOP)/ext/icu/icu.c +SRC += \ + $(TOP)/ext/rtree/rtree.h \ + $(TOP)/ext/rtree/rtree.c \ + $(TOP)/ext/rtree/geopoly.c +SRC += \ + $(TOP)/ext/session/sqlite3session.c \ + $(TOP)/ext/session/sqlite3session.h +SRC += \ + $(TOP)/ext/userauth/userauth.c \ + $(TOP)/ext/userauth/sqlite3userauth.h +SRC += \ + $(TOP)/ext/rbu/sqlite3rbu.h \ + $(TOP)/ext/rbu/sqlite3rbu.c +SRC += \ + $(TOP)/ext/misc/stmt.c + +# Generated source code files +# +SRC += \ + keywordhash.h \ + opcodes.c \ + opcodes.h \ + parse.c \ + parse.h \ + sqlite_cfg.h \ + shell.c \ + sqlite3.h + +# Source code to the test files. +# +TESTSRC = \ + $(TOP)/src/test1.c \ + $(TOP)/src/test2.c \ + $(TOP)/src/test3.c \ + $(TOP)/src/test4.c \ + $(TOP)/src/test5.c \ + $(TOP)/src/test6.c \ + $(TOP)/src/test8.c \ + $(TOP)/src/test9.c \ + $(TOP)/src/test_autoext.c \ + $(TOP)/src/test_async.c \ + $(TOP)/src/test_backup.c \ + $(TOP)/src/test_bestindex.c \ + $(TOP)/src/test_blob.c \ + $(TOP)/src/test_btree.c \ + $(TOP)/src/test_config.c \ + $(TOP)/src/test_delete.c \ + $(TOP)/src/test_demovfs.c \ + $(TOP)/src/test_devsym.c \ + $(TOP)/src/test_fs.c \ + $(TOP)/src/test_func.c \ + $(TOP)/src/test_hexio.c \ + $(TOP)/src/test_init.c \ + $(TOP)/src/test_intarray.c \ + $(TOP)/src/test_journal.c \ + $(TOP)/src/test_malloc.c \ + $(TOP)/src/test_md5.c \ + $(TOP)/src/test_multiplex.c \ + $(TOP)/src/test_mutex.c \ + $(TOP)/src/test_onefile.c \ + $(TOP)/src/test_osinst.c \ + $(TOP)/src/test_pcache.c \ + $(TOP)/src/test_quota.c \ + $(TOP)/src/test_rtree.c \ + $(TOP)/src/test_schema.c \ + $(TOP)/src/test_superlock.c \ + $(TOP)/src/test_syscall.c \ + $(TOP)/src/test_tclsh.c \ + $(TOP)/src/test_tclvar.c \ + $(TOP)/src/test_thread.c \ + $(TOP)/src/test_vdbecov.c \ + $(TOP)/src/test_vfs.c \ + $(TOP)/src/test_windirent.c \ + $(TOP)/src/test_window.c \ + $(TOP)/src/test_wsd.c \ + $(TOP)/ext/fts3/fts3_term.c \ + $(TOP)/ext/fts3/fts3_test.c \ + $(TOP)/ext/session/test_session.c \ + $(TOP)/ext/recover/sqlite3recover.c \ + $(TOP)/ext/recover/dbdata.c \ + $(TOP)/ext/recover/test_recover.c \ + $(TOP)/ext/intck/test_intck.c \ + $(TOP)/ext/intck/sqlite3intck.c \ + $(TOP)/ext/rbu/test_rbu.c + +# Statically linked extensions +# +TESTSRC += \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/test_expert.c \ + $(TOP)/ext/misc/amatch.c \ + $(TOP)/ext/misc/appendvfs.c \ + $(TOP)/ext/misc/basexx.c \ + $(TOP)/ext/misc/carray.c \ + $(TOP)/ext/misc/cksumvfs.c \ + $(TOP)/ext/misc/closure.c \ + $(TOP)/ext/misc/csv.c \ + $(TOP)/ext/misc/decimal.c \ + $(TOP)/ext/misc/eval.c \ + $(TOP)/ext/misc/explain.c \ + $(TOP)/ext/misc/fileio.c \ + $(TOP)/ext/misc/fuzzer.c \ + $(TOP)/ext/fts5/fts5_tcl.c \ + $(TOP)/ext/fts5/fts5_test_mi.c \ + $(TOP)/ext/fts5/fts5_test_tok.c \ + $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/mmapwarm.c \ + $(TOP)/ext/misc/nextchar.c \ + $(TOP)/ext/misc/normalize.c \ + $(TOP)/ext/misc/percentile.c \ + $(TOP)/ext/misc/prefixes.c \ + $(TOP)/ext/misc/qpvtab.c \ + $(TOP)/ext/misc/randomjson.c \ + $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/remember.c \ + $(TOP)/ext/misc/series.c \ + $(TOP)/ext/misc/spellfix.c \ + $(TOP)/ext/misc/stmtrand.c \ + $(TOP)/ext/misc/totype.c \ + $(TOP)/ext/misc/unionvtab.c \ + $(TOP)/ext/misc/wholenumber.c \ + $(TOP)/ext/misc/zipfile.c \ + $(TOP)/ext/userauth/userauth.c \ + $(TOP)/ext/rtree/test_rtreedoc.c + +# Source code to the library files needed by the test fixture +# +TESTSRC2 = \ + $(TOP)/src/attach.c \ + $(TOP)/src/backup.c \ + $(TOP)/src/bitvec.c \ + $(TOP)/src/btree.c \ + $(TOP)/src/build.c \ + $(TOP)/src/ctime.c \ + $(TOP)/src/date.c \ + $(TOP)/src/dbpage.c \ + $(TOP)/src/dbstat.c \ + $(TOP)/src/expr.c \ + $(TOP)/src/func.c \ + $(TOP)/src/global.c \ + $(TOP)/src/insert.c \ + $(TOP)/src/wal.c \ + $(TOP)/src/main.c \ + $(TOP)/src/mem5.c \ + $(TOP)/src/os.c \ + $(TOP)/src/os_kv.c \ + $(TOP)/src/os_unix.c \ + $(TOP)/src/os_win.c \ + $(TOP)/src/pager.c \ + $(TOP)/src/pragma.c \ + $(TOP)/src/prepare.c \ + $(TOP)/src/printf.c \ + $(TOP)/src/random.c \ + $(TOP)/src/pcache.c \ + $(TOP)/src/pcache1.c \ + $(TOP)/src/select.c \ + $(TOP)/src/tokenize.c \ + $(TOP)/src/treeview.c \ + $(TOP)/src/utf.c \ + $(TOP)/src/util.c \ + $(TOP)/src/vdbeapi.c \ + $(TOP)/src/vdbeaux.c \ + $(TOP)/src/vdbe.c \ + $(TOP)/src/vdbemem.c \ + $(TOP)/src/vdbetrace.c \ + $(TOP)/src/vdbevtab.c \ + $(TOP)/src/where.c \ + $(TOP)/src/wherecode.c \ + $(TOP)/src/whereexpr.c \ + $(TOP)/src/window.c \ + parse.c \ + $(TOP)/ext/fts3/fts3.c \ + $(TOP)/ext/fts3/fts3_aux.c \ + $(TOP)/ext/fts3/fts3_expr.c \ + $(TOP)/ext/fts3/fts3_term.c \ + $(TOP)/ext/fts3/fts3_tokenizer.c \ + $(TOP)/ext/fts3/fts3_write.c \ + $(TOP)/ext/async/sqlite3async.c \ + $(TOP)/ext/session/sqlite3session.c \ + $(TOP)/ext/misc/stmt.c \ + fts5.c + +# Header files used by all library source files. +# +HDR = \ + $(TOP)/src/btree.h \ + $(TOP)/src/btreeInt.h \ + $(TOP)/src/hash.h \ + $(TOP)/src/hwtime.h \ + keywordhash.h \ + $(TOP)/src/msvc.h \ + $(TOP)/src/mutex.h \ + opcodes.h \ + $(TOP)/src/os.h \ + $(TOP)/src/os_common.h \ + $(TOP)/src/os_setup.h \ + $(TOP)/src/os_win.h \ + $(TOP)/src/pager.h \ + $(TOP)/src/pcache.h \ + parse.h \ + $(TOP)/src/pragma.h \ + sqlite3.h \ + $(TOP)/src/sqlite3ext.h \ + $(TOP)/src/sqliteInt.h \ + $(TOP)/src/sqliteLimit.h \ + $(TOP)/src/vdbe.h \ + $(TOP)/src/vdbeInt.h \ + $(TOP)/src/vxworks.h \ + $(TOP)/src/whereInt.h \ + sqlite_cfg.h + +# Header files used by extensions +# +EXTHDR += \ + $(TOP)/ext/fts3/fts3.h \ + $(TOP)/ext/fts3/fts3Int.h \ + $(TOP)/ext/fts3/fts3_hash.h \ + $(TOP)/ext/fts3/fts3_tokenizer.h +EXTHDR += \ + $(TOP)/ext/rtree/rtree.h \ + $(TOP)/ext/rtree/geopoly.c +EXTHDR += \ + $(TOP)/ext/icu/sqliteicu.h +EXTHDR += \ + $(TOP)/ext/rtree/sqlite3rtree.h +EXTHDR += \ + $(TOP)/ext/userauth/sqlite3userauth.h + +# executables needed for testing +# +TESTPROGS = \ + testfixture$(TEXE) \ + sqlite3$(TEXE) \ + sqlite3_analyzer$(TEXE) \ + sqldiff$(TEXE) \ + dbhash$(TEXE) \ + sqltclsh$(TEXE) + +# Databases containing fuzzer test cases +# +FUZZDATA = \ + $(TOP)/test/fuzzdata1.db \ + $(TOP)/test/fuzzdata2.db \ + $(TOP)/test/fuzzdata3.db \ + $(TOP)/test/fuzzdata4.db \ + $(TOP)/test/fuzzdata5.db \ + $(TOP)/test/fuzzdata6.db \ + $(TOP)/test/fuzzdata7.db \ + $(TOP)/test/fuzzdata8.db + +# Standard options to testfixture +# +TESTOPTS = --verbose=file --output=test-out.txt + +# Extra compiler options for various shell tools +# +SHELL_OPT += -DSQLITE_DQS=0 +SHELL_OPT += -DSQLITE_ENABLE_FTS4 +#SHELL_OPT += -DSQLITE_ENABLE_FTS5 +SHELL_OPT += -DSQLITE_ENABLE_RTREE +SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS +SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB +SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB +SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB +SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB +SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC +SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1 +FUZZERSHELL_OPT = +FUZZCHECK_OPT += -I$(TOP)/test +FUZZCHECK_OPT += -I$(TOP)/ext/recover +FUZZCHECK_OPT += \ + -DSQLITE_OSS_FUZZ \ + -DSQLITE_ENABLE_BYTECODE_VTAB \ + -DSQLITE_ENABLE_DBPAGE_VTAB \ + -DSQLITE_ENABLE_DBSTAT_VTAB \ + -DSQLITE_ENABLE_BYTECODE_VTAB \ + -DSQLITE_ENABLE_DESERIALIZE \ + -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ + -DSQLITE_ENABLE_FTS3_PARENTHESIS \ + -DSQLITE_ENABLE_FTS4 \ + -DSQLITE_ENABLE_FTS5 \ + -DSQLITE_ENABLE_GEOPOLY \ + -DSQLITE_ENABLE_MATH_FUNCTIONS \ + -DSQLITE_ENABLE_MEMSYS5 \ + -DSQLITE_ENABLE_NORMALIZE \ + -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ + -DSQLITE_ENABLE_PREUPDATE_HOOK \ + -DSQLITE_ENABLE_RTREE \ + -DSQLITE_ENABLE_SESSION \ + -DSQLITE_ENABLE_STMTVTAB \ + -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \ + -DSQLITE_ENABLE_STAT4 \ + -DSQLITE_ENABLE_STMT_SCANSTATUS \ + -DSQLITE_MAX_MEMORY=50000000 \ + -DSQLITE_MAX_MMAP_SIZE=0 \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_PRINTF_PRECISION_LIMIT=1000 \ + -DSQLITE_PRIVATE="" \ + -DSQLITE_STRICT_SUBTYPE=1 \ + -DSQLITE_STATIC_RANDOMJSON + +FUZZCHECK_SRC += $(TOP)/test/fuzzcheck.c +FUZZCHECK_SRC += $(TOP)/test/ossfuzz.c +FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c +FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c +FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c +FUZZCHECK_SRC += $(TOP)/test/vt02.c +FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c +FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c +DBFUZZ_OPT = +ST_OPT = -DSQLITE_OS_KV_OPTIONAL + + +# In wasi-sdk builds, disable the CLI shell build in the "all" target. +SQLITE3_SHELL_TARGET_ = sqlite3$(TEXE) +SQLITE3_SHELL_TARGET_1 = +SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@) + +SQLITE3_O = $(TOP)/sqlite3.o + #XX## Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either #XX## libtclsqlite3.la or an empty value. #XX#libtclsqlite3.la_0 = @@ -1643,42 +1649,42 @@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) #XX## #XX#tclextension-list: #XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info -#XX# -#XX# -#XX## Remove build products sufficient so that subsequent makes will recompile -#XX## everything from scratch. Do not remove: -#XX## -#XX## * test results and test logs -#XX## * output from ./configure -#XX## -#XX#tidy: -#XX# rm -f *.lo *.la *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) -#XX# rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h -#XX# rm -rf .libs .deps tsrc .target_source -#XX# rm -f lemon$(BEXE) sqlite*.tar.gz -#XX# rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) -#XX# rm -f parse.* fts5parse.* -#XX# rm -f tclsqlite3$(TEXE) $(TESTPROGS) -#XX# rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) -#XX# rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) -#XX# rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) -#XX# rm -f *.dll *.lib *.exp *.def *.pc *.vsix *.so *.dylib pkgIndex.tcl -#XX# rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE) -#XX# rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) -#XX# rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) -#XX# rm -f threadtest5$(TEXE) -#XX# rm -f src-verify has_tclsh* -#XX# -#XX## Removes build products and test logs. Retains ./configure outputs. -#XX## -#XX#clean: tidy -#XX# rm -rf omittest* testrunner* testdir* -#XX# -#XX## Clean up everything. No exceptions. -#XX## -#XX#distclean: clean -#XX# rm -f sqlite_cfg.h config.log config.status Makefile $(LIBTOOL) -#XX# + + +# Remove build products sufficient so that subsequent makes will recompile +# everything from scratch. Do not remove: +# +# * test results and test logs +# * output from ./configure +# +tidy: + rm -f *.lo *.la *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) + rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h + rm -rf .libs .deps tsrc .target_source + rm -f lemon$(BEXE) sqlite*.tar.gz + rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) + rm -f parse.* fts5parse.* + rm -f tclsqlite3$(TEXE) $(TESTPROGS) + rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) + rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) + rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) + rm -f *.dll *.lib *.exp *.def *.pc *.vsix *.so *.dylib pkgIndex.tcl + rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE) + rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) + rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) + rm -f threadtest5$(TEXE) + rm -f src-verify has_tclsh* + +# Removes build products and test logs. Retains ./configure outputs. +# +clean: tidy + rm -rf omittest* testrunner* testdir* + +# Clean up everything. No exceptions. +# +distclean: clean + rm -f sqlite_cfg.h config.log config.status Makefile $(LIBTOOL) + #XX## #XX## Windows section #XX## diff --git a/auto.def b/auto.def index 75c8450e69..8cde61e038 100644 --- a/auto.def +++ b/auto.def @@ -11,17 +11,24 @@ if {[get-define host] ne [get-define build]} { } define cross_compiling ${cross_compiling} -if {0 && $cross_compiling} { +if {$cross_compiling} { # gcc's cross-compiler is named platform-os-vendor-gcc instead of # platform-os-vendor-cc. Checking for cc here will find the CC which # was already found via (use cc). Checking for gcc here would be # unportable - the client may well have a different cross-compiler. - define-push {GCC LD AR} { - cc-check-tools gcc ld ar - define BIN_host_GCC [get-define GCC] + define-push {LD AR} { + cc-check-tools ld ar + #define BIN_host_GCC [get-define GCC] define BIN_host_LD [get-define LD] define BIN_host_AR [get-define AR] } + #define BIN_host_CC [get-define CC] +} +#define CC [get-define CC_FOR_BUILD] +if {![cc-path-progs ld ar]} { + # ^^^^ not cc-check-tools because that one resolves cross-compile + # binaries when --host=... is set. + user-error "Missing required binary" } ######################################################################## @@ -82,7 +89,7 @@ set srcdir $autosetup(srcdir) #puts "srcdir = $srcdir" set VERSION [readfile $autosetup(srcdir)/VERSION] puts "VERSION = $VERSION" -define PACKAGE_VERSION $VERSION +define VERSION $VERSION #puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" #puts "with-debug? = [opt-val with-debug]" diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 8466e0116d..ca458b7407 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -408,23 +408,29 @@ proc hwaci-looks-like-windows {{key host}} { # host and target are Windows-esque (Cygwin, MinGW, MSys). If the # build host is then BUILD_EXEEXT is [define]'d to ".exe", else "". If # the build target is then TARGET_EXEEXT is [define]'d to ".exe", else -# "". +# "". It also sets BUILD_OBJEXT and TARGET_OBJEXT to the conventional +# file extension for object files: .obj or .o. proc hwaci-check-exeext {} { msg-checking "Build host is Windows-esque? " if {[hwaci-looks-like-windows host]} { define BUILD_EXEEXT ".exe" + define BUILD_OBJEXT ".obj" msg-result yes } else { define BUILD_EXEEXT "" + define BUILD_OBJEXT ".o" msg-result no } msg-checking "Build target is Windows-esque? " if {[hwaci-looks-like-windows target]} { define TARGET_EXEEXT ".exe" + define TARGET_OBJEXT ".obj" msg-result yes } else { define TARGET_EXEEXT "" + define TARGET_OBJEXT ".o" + msg-result no } } diff --git a/manifest b/manifest index 27e3304a7c..b0841a42e5 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Integrate\sthe\sconfigure-time\sEmscripten\sbits. -D 2024-09-25T22:13:49.969 +C Time\sfor\sa\sbreak. +D 2024-09-25T23:09:38.690 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 423f8b90ccb385a96c9f9551d74ab2b678e7a6191bf908c2b44304997804cb63 +F Makefile.in dee85c233bbfcdf21bc843ecec065c650b0a4c677e87af9bdf50cdf3c3179df7 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 25c1a8645d4845bc2970d183be0ac2c9bdf0f05c348fc6705385c17047802bb4 +F auto.def 667c6566a686bab5994d7c52526c33a2ab516199b85766c29e7fc65b128671ea F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl c0ff4bb3399f7a55b5dba83ab6f98b68a54952f28ae49c658340b48ea3cd827d +F autosetup/hwaci-common.tcl 48465634f1fc73ac30ad747e1d1d1ec897f009ce40edf94092575d9851a61846 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 74d12433599e2f189d8d0a44be834651531ac5a215bf42de386053cd00d29162 -R dd47ba23be16ca7a64fc24efb04f8a5b +P 456125a14454180d608d8f5bc651aa4350958cdd14f4011ef540beb278ca2d51 +R 2167a1dbbb24f998e809942a74a24831 U stephan -Z 7445a300c3d8549aa733ba93da0d5f2b +Z 5237a006f29465dc76d28d429ddf3ad3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index adaa3beb74..1c0777dc76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -456125a14454180d608d8f5bc651aa4350958cdd14f4011ef540beb278ca2d51 +1d29cd9095595b7b027b90d644dc4767fde0b6f98316c0eb82014b7aad6770d7 From 1bc8f07f2036f43ceee1b8de99b15d0ec9e4c02f Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 26 Sep 2024 08:25:10 +0000 Subject: [PATCH 019/522] Remove a misled acrobatics related to cross-compilation, based on suggestions from Steve Bennett. Add a quick-n-dirty placeholder check for tclsh to move that part along. FossilOrigin-Name: c419168938b009b2cf8a42a01272971497b5329792ccb8cef235f47ab5f142e2 --- auto.def | 42 ++++++++++++++++++++---------------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/auto.def b/auto.def index 8cde61e038..7d55af78bd 100644 --- a/auto.def +++ b/auto.def @@ -11,26 +11,6 @@ if {[get-define host] ne [get-define build]} { } define cross_compiling ${cross_compiling} -if {$cross_compiling} { - # gcc's cross-compiler is named platform-os-vendor-gcc instead of - # platform-os-vendor-cc. Checking for cc here will find the CC which - # was already found via (use cc). Checking for gcc here would be - # unportable - the client may well have a different cross-compiler. - define-push {LD AR} { - cc-check-tools ld ar - #define BIN_host_GCC [get-define GCC] - define BIN_host_LD [get-define LD] - define BIN_host_AR [get-define AR] - } - #define BIN_host_CC [get-define CC] -} -#define CC [get-define CC_FOR_BUILD] -if {![cc-path-progs ld ar]} { - # ^^^^ not cc-check-tools because that one resolves cross-compile - # binaries when --host=... is set. - user-error "Missing required binary" -} - ######################################################################## # A very long story made short, autosetup's --flag handling has # some behaviors which make it impossible to implement 100% identical @@ -283,7 +263,6 @@ if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { define LDFLAGS_ZLIB "" } -hwaci-define-if-opt-truthy with-debug SQLITE_DEBUG "Debug build?" hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ "Use amalgamation for builds?" hwaci-define-if-opt-truthy gcov USE_GCOV "Use gcov?" @@ -291,8 +270,27 @@ hwaci-define-if-opt-truthy test-status TSTRNNR_OPTS \ "test-runner flags:" {--status} {} hwaci-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \ "Use #line macros in the amalgamation:" {--linemacros=1} {--linemacros=0} +msg-checking "Debug build? " +hwaci-if-opt-truthy with-debug { + define SQLITE_DEBUG 1 + define TARGET_DEBUG {-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} + msg-result yes +} { + define TARGET_DEBUG {-DNDEBUG} + msg-result no +} -if {0} { +if {1} { + # Temporary quick hack for finding "a" tclsh. TODO is port the + # full-featured check which lives in the elseif part of this block. + # + # Also TODO is figure out whether we can use jimtcl for our internal + # build-tool uses (as opposed to testing purposes, which requires + # the tcl SQLite module). + if {![cc-path-progs tclsh]} { + user-error "Cannot find tclsh" + } +} elseif {0} { ######### # Figure out all the name of a working tclsh and parameters needed to compile against Tcl. # The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. diff --git a/manifest b/manifest index b0841a42e5..05ab0fd794 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Time\sfor\sa\sbreak. -D 2024-09-25T23:09:38.690 +C Remove\sa\smisled\sacrobatics\srelated\sto\scross-compilation,\sbased\son\ssuggestions\sfrom\sSteve\sBennett.\sAdd\sa\squick-n-dirty\splaceholder\scheck\sfor\stclsh\sto\smove\sthat\spart\salong. +D 2024-09-26T08:25:10.543 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 667c6566a686bab5994d7c52526c33a2ab516199b85766c29e7fc65b128671ea +F auto.def 7fb946ca447e7139764c8a8c7902f374ea11219fee12dcb236607ada9f49ee2d F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 456125a14454180d608d8f5bc651aa4350958cdd14f4011ef540beb278ca2d51 -R 2167a1dbbb24f998e809942a74a24831 +P 1d29cd9095595b7b027b90d644dc4767fde0b6f98316c0eb82014b7aad6770d7 +R 69eca432a82c8eab4ae5d756a58d2b01 U stephan -Z 5237a006f29465dc76d28d429ddf3ad3 +Z 44573c215dc1833642057c91ccefe177 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1c0777dc76..28cf2f0143 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d29cd9095595b7b027b90d644dc4767fde0b6f98316c0eb82014b7aad6770d7 +c419168938b009b2cf8a42a01272971497b5329792ccb8cef235f47ab5f142e2 From cda0d6fd74be85b7b915cda38d1a92bca34eb50a Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 26 Sep 2024 12:16:46 +0000 Subject: [PATCH 020/522] Cleanups of the --with-wasi-sdk bits. Straighten out VERSION vs RELEASE. FossilOrigin-Name: 7638f3ad1588ff16c2980763c6c4c1386a711acd64adb21c465f186a47bc975d --- Makefile.in | 37 +++++++++++++++++------------------ auto.def | 40 +++++++++++++++++++++++--------------- autosetup/hwaci-common.tcl | 25 +++++++++++++++++++++++- manifest | 16 +++++++-------- manifest.uuid | 2 +- 5 files changed, 75 insertions(+), 45 deletions(-) diff --git a/Makefile.in b/Makefile.in index 69e0736801..a230b991df 100644 --- a/Makefile.in +++ b/Makefile.in @@ -27,7 +27,7 @@ AR = @AR@ # C Compiler and options for use in building executables that # will run on the platform that is doing the build. # -BCC = @CC_FOR_BUILD@ +BCC = @BUILD_CC@ @BUILD_CFLAGS@ # TODO: @BUILD_CFLAGS@ # #XX## TCC is the C Compile and options for use in building executables that @@ -37,22 +37,22 @@ BCC = @CC_FOR_BUILD@ #XX## on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" #XX## CC = @CC@ -CFLAGS = @CPPFLAGS@ @CFLAGS@ -#TODO: figure out how to get autosetup to do CC_FOR_TARGET. -#XX#TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu -#XX#TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session -#XX#TCC += -I${TOP}/ext/userauth -#XX# -#XX## Define this for the autoconf-based build, so that the code knows it can -#XX## include the generated sqlite_cfg.h -#XX## -#XX#TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite -#XX# -#XX## Define -DNDEBUG to compile without debugging (i.e., for production usage) -#XX## Omitting the define will cause extra debugging code to be inserted and -#XX## includes extra comments when "EXPLAIN stmt" is used. -#XX## -#XX#TCC += @TARGET_DEBUG@ +CFLAGS ?= @CFLAGS@ +CPPFLAGS ?= @CPPFLAGS@ +TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu +TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session +TCC += -I${TOP}/ext/userauth + +# Define this for the autoconf-based build, so that the code knows it can +# include the generated sqlite_cfg.h +# +TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite + +# Define -DNDEBUG to compile without debugging (i.e., for production usage) +# Omitting the define will cause extra debugging code to be inserted and +# includes extra comments when "EXPLAIN stmt" is used. +# +TCC += @TARGET_DEBUG@ #XX# #XX## Compiler options needed for programs that use the TCL library. #XX## @@ -111,8 +111,7 @@ TCC += @LDFLAGS_ZLIB@ # Version numbers and release number for the SQLite being compiled. # VERSION = @VERSION@ -#XX#VERSION_NUMBER = @VERSION_NUMBER@ -#XX#RELEASE = @RELEASE@ +RELEASE = @RELEASE@ # Filename extensions for binaries # diff --git a/auto.def b/auto.def index 6cac92c5c7..641cfa7807 100644 --- a/auto.def +++ b/auto.def @@ -67,9 +67,12 @@ options { set srcdir $autosetup(srcdir) #puts "srcdir = $srcdir" -set VERSION [readfile $autosetup(srcdir)/VERSION] -puts "VERSION = $VERSION" +set RELEASE [readfile $autosetup(srcdir)/VERSION] +regsub {([0-9]*\.*[0-9]*).*} $RELEASE {\1} VERSION define VERSION $VERSION +define RELEASE $RELEASE +puts "RELEASE = $RELEASE" +puts "VERSION = $VERSION" #puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" #puts "with-debug? = [opt-val with-debug]" @@ -79,6 +82,8 @@ if {![file exists sqlite3.pc.in]} { set outOfTreeBuild 1 } +cc-check-tools ld ar + # # The build process allows for using a cross-compiler. But the default # action is to target the same platform that we are running on. The @@ -185,6 +190,9 @@ if {"" eq [hwaci-bin-define install]} { # XXX fi # XXX AC_SUBST BUILD_CC +define BUILD_CC [get-define CC_FOR_BUILD] +define BUILD_CFLAGS [get-env CFLAGS {-g}] + ########## # Handle --with-wasi-sdk=DIR # @@ -201,15 +209,18 @@ if {1} { define WASI_SDK_DIR "" } else { msg-checking "Checking WASI SDK directory \[$wasiSdkDir]... " - if {![file exists $wasiSdkDir/bin/clang]} { - user-error "--with-wasi-sdk=${wasiSdkDir} directory does not contain bin/clang" - } - msg-result "using wasi-sdk clang, disabling: tcl, CLI shell, DLL, threading" + puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" + hwaci-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] + msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading" define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir - hwaci-opt-set tcl 0 - hwaci-opt-set threadsafe 0 + hwaci-opt-set load-extension 0; # ==> --disable-load-extension + hwaci-opt-set threadsafe 0; # ==> --threadsafe + hwaci-opt-set tcl 0; # ==> --disable-tcl + define HAVE_TCL 0 set cross_compiling 1 + # libtool is apparently hard-coded to use gcc for linking DLLs, so + # we disable the DLL build. set enable_shared 0 # Changing --host and --target have no effect here except to possibly @@ -224,13 +235,9 @@ if {1} { # XXX CC="${wasiSdkDir}/bin/clang" # XXX LD="${wasiSdkDir}/bin/wasm-ld" # XXX RANLIB="${wasiSdkDir}/bin/llvm-ranlib" - # set cross_compiling yes - # hwaci-opt-set threadsafe 0 - # set use_tcl no - # hwaci-opt-set tcl 0 - # libtool is apparently hard-coded to use gcc for linking DLLs, so - # we disable the DLL build... - # set enable_shared no + define CC "${wasiSdkDir}/bin/clang" + define LD "${wasiSdkDir}/bin/wasm-ld" + #define STRIP "${wasiSdkDir}/bin/strip" } unset wasiSdkDir }; # --wasi-sdk-dir @@ -737,6 +744,7 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } } +define ENABLE_SHARED $enable_shared ######### # Generate the output files. @@ -775,7 +783,7 @@ hwaci-if-opt-truthy dump-defines { # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will # get _undefined_ here unless it's part of the -bare set. if {0} { - foreach x $::define { + foreach x [all-defines] { puts "\t$x" } } diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index ca458b7407..166ea18db2 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -122,7 +122,7 @@ proc hwaci-opt-set {flag {val 1}} { # Returns 1 if $val appears to be a truthy value, else returns # 0. Truthy values are any of {1 on enabled yes} proc hwaci-val-truthy {val} { - return [expr {$val in {1 on enabled yes}}] + expr {$val in {1 on enabled yes}} } ######################################################################## @@ -435,6 +435,29 @@ proc hwaci-check-exeext {} { } } +######################################################################## +# Expects a list of file names. If any one of them does not exist in +# the filesystem, it fails fatally with an informative message. +# Returns the last file name it checks. If the first argument is -v +# then it emits msg-checking/msg-result messages for each file. +proc hwaci-affirm-files-exist {args} { + set rc "" + set verbose 1 + if {[lindex $args 0] eq "-v"} { + set verbose 1 + set args [lrange $args 1 end] + } + foreach f $args { + if {$verbose} { msg-checking "looking for file... " } + if {![file exists $f]} { + user-error "not found: $f" + } + if {$verbose} { msg-result "$f" } + set rc $f + } + return rc +} + ######################################################################## # Emscripten is used for doing in-tree builds of web-based WASM stuff, # as opposed to WASI-based WASM or WASM binaries we import from other diff --git a/manifest b/manifest index 0561850002..84305538bd 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Merge\scurrent\strunk\sinto\sthis\sbranch. -D 2024-09-26T08:53:37.393 +C Cleanups\sof\sthe\s--with-wasi-sdk\sbits.\sStraighten\sout\sVERSION\svs\sRELEASE. +D 2024-09-26T12:16:46.672 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in dee85c233bbfcdf21bc843ecec065c650b0a4c677e87af9bdf50cdf3c3179df7 +F Makefile.in c9d2e625e2f79127e28e1691e4514ae3c2c426af650cb3e1d59737e89f66f7dc F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def caf598afa0fb40cb86bbfa24be170984a16095b36e317c99f3d2521858e89d9c +F auto.def d2d9c2d473a81551ddd29a155c375fa31a068e05b2227862a24a2e84c00a0bdf F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 48465634f1fc73ac30ad747e1d1d1ec897f009ce40edf94092575d9851a61846 +F autosetup/hwaci-common.tcl b2b8b94915baaa68f5355c3753835095da6290e0fccb22b6f5fa024a452400bc F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c419168938b009b2cf8a42a01272971497b5329792ccb8cef235f47ab5f142e2 9592b9ba3ad7a842cdd4c4010da278485a6fdec7e811bda01ebe640162a8c3b6 -R af319e126fc6fc33c648f8f6f76c92f2 +P 683a9e1e2f68a5c34fe524867576a4405fa2460880ad0bf4c07799744fea4192 +R ad6080b33e617c2bb00e20e12e921109 U stephan -Z b233c57887cfbb961cc652ff444473d0 +Z 6dde9c36df32e2200ff90b427b0efc9c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 15e6e68ed7..72d66ab700 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -683a9e1e2f68a5c34fe524867576a4405fa2460880ad0bf4c07799744fea4192 +7638f3ad1588ff16c2980763c6c4c1386a711acd64adb21c465f186a47bc975d From 76bfcd13be9de94d08e4b6f8510501c1780639ca Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 26 Sep 2024 14:09:23 +0000 Subject: [PATCH 021/522] Do not remove *.def in the cleanup rules because auto.def is a required part of autosetup. Remove the .o vs .obj detection/distinction because the Unix-like Windows environments use .o. FossilOrigin-Name: 65eb1072e297f01ba4ce21fe644f709e75ebaec5307764b549efceafb88f6ebf --- Makefile.in | 9 ++++----- autosetup/hwaci-common.tcl | 8 +------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Makefile.in b/Makefile.in index a230b991df..9c9a132a8c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -7,7 +7,7 @@ # the makefile manually. Just set the parameters below to values that # work well for your system. # - +all: #XX# Lines starting with #XX# are TODOs for the port to autosetup # The toplevel directory of the source tree. This is the directory @@ -117,8 +117,6 @@ RELEASE = @RELEASE@ # BEXE = @BUILD_EXEEXT@ TEXE = @TARGET_EXEEXT@ -BOBJ = @BUILD_OBJEXT@ -TOBJ = @TARGET_OBJEXT@ #XX## The following variable is "1" if the configure script was able to locate #XX## the tclConfig.sh file. It is an empty string otherwise. When this @@ -1667,13 +1665,14 @@ tidy: rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) - rm -f *.dll *.lib *.exp *.def *.pc *.vsix *.so *.dylib pkgIndex.tcl + rm -f *.dll *.lib *.exp *.pc *.vsix *.so *.dylib pkgIndex.tcl rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE) rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) rm -f threadtest5$(TEXE) rm -f src-verify has_tclsh* - +# FIXME? (rm *.def) will remove auto.def (part of autosetup) +# # Removes build products and test logs. Retains ./configure outputs. # clean: tidy diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 166ea18db2..ae56408dfa 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -408,29 +408,23 @@ proc hwaci-looks-like-windows {{key host}} { # host and target are Windows-esque (Cygwin, MinGW, MSys). If the # build host is then BUILD_EXEEXT is [define]'d to ".exe", else "". If # the build target is then TARGET_EXEEXT is [define]'d to ".exe", else -# "". It also sets BUILD_OBJEXT and TARGET_OBJEXT to the conventional -# file extension for object files: .obj or .o. +# "". proc hwaci-check-exeext {} { msg-checking "Build host is Windows-esque? " if {[hwaci-looks-like-windows host]} { define BUILD_EXEEXT ".exe" - define BUILD_OBJEXT ".obj" msg-result yes } else { define BUILD_EXEEXT "" - define BUILD_OBJEXT ".o" msg-result no } msg-checking "Build target is Windows-esque? " if {[hwaci-looks-like-windows target]} { define TARGET_EXEEXT ".exe" - define TARGET_OBJEXT ".obj" msg-result yes } else { define TARGET_EXEEXT "" - define TARGET_OBJEXT ".o" - msg-result no } } diff --git a/manifest b/manifest index 84305538bd..3e9db4ce0d 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Cleanups\sof\sthe\s--with-wasi-sdk\sbits.\sStraighten\sout\sVERSION\svs\sRELEASE. -D 2024-09-26T12:16:46.672 +C Do\snot\sremove\s*.def\sin\sthe\scleanup\srules\sbecause\sauto.def\sis\sa\srequired\spart\sof\sautosetup.\sRemove\sthe\s.o\svs\s.obj\sdetection/distinction\sbecause\sthe\sUnix-like\sWindows\senvironments\suse\s.o. +D 2024-09-26T14:09:23.248 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in c9d2e625e2f79127e28e1691e4514ae3c2c426af650cb3e1d59737e89f66f7dc +F Makefile.in 3806942cc072d2dd09568c530c614dee8274ce2663ba560f7af5271a088d944d F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl b2b8b94915baaa68f5355c3753835095da6290e0fccb22b6f5fa024a452400bc +F autosetup/hwaci-common.tcl a112327a1eb29e3d32670e25a464832abb73f028b679a5433c4630446ca76b56 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 683a9e1e2f68a5c34fe524867576a4405fa2460880ad0bf4c07799744fea4192 -R ad6080b33e617c2bb00e20e12e921109 +P 7638f3ad1588ff16c2980763c6c4c1386a711acd64adb21c465f186a47bc975d +R dd990ac14aacc7aef84cea962548e6de U stephan -Z 6dde9c36df32e2200ff90b427b0efc9c +Z 5264d306ffd6b34f18c75d08cd8d2866 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 72d66ab700..a7a53b3a8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7638f3ad1588ff16c2980763c6c4c1386a711acd64adb21c465f186a47bc975d +65eb1072e297f01ba4ce21fe644f709e75ebaec5307764b549efceafb88f6ebf From c2da952f5d58c59d0e4f7e4546c1449838c56b39 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 26 Sep 2024 18:40:07 +0000 Subject: [PATCH 022/522] Get lemon building. Re-indent hwaci-common.tcl for consistency. FossilOrigin-Name: 53dc33d5e20062e8c4c9856349bbc143c858327ef41f356ffcc574b36d0cc73c --- Makefile.in | 15 +- auto.def | 8 +- autosetup/hwaci-common.tcl | 284 ++++++++++++++++++------------------- manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 163 insertions(+), 162 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9c9a132a8c..0e026097f8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -889,12 +889,15 @@ SQLITE3_O = $(TOP)/sqlite3.o #XX## #XX#sqlite3.lo: sqlite3.c #XX# $(LTCOMPILE) $(TEMP_STORE) -c sqlite3.c -#XX# -#XX## Rules to build the LEMON compiler generator -#XX## -#XX#lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c -#XX# $(BCC) -o $@ $(TOP)/tool/lemon.c -#XX# cp $(TOP)/tool/lempar.c . + +# Rules to build the LEMON compiler generator +# +lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c + $(BCC) -o $@ $(TOP)/tool/lemon.c + cp $(TOP)/tool/lempar.c . +@if BUILD_EXEEXT ne "" +lemon: lemon$(BEXE) +@endif #XX# #XX## Rules to build the program that generates the source-id #XX## diff --git a/auto.def b/auto.def index 641cfa7807..858044eb99 100644 --- a/auto.def +++ b/auto.def @@ -36,7 +36,7 @@ options { test-status => {Enable status of tests} threadsafe=1 => {Disable mutexing} releasemode => {libtool link to release mode} - with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always} + with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always.} editline=0 => {BSD editline support} readline=0 => {readline support} largefile=1 => {Disable large file support} @@ -60,9 +60,9 @@ options { gcov=0 => {Enable coverage testing using gcov} linemacros => {Enable #line macros in the amalgamation.} with-wasi-sdk:=/opt/wasi-sdk - => {Top-most dir of the wasi-sdk for a WASI build} + => {Top-most dir of the wasi-sdk for a WASI build.} with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} - dump-defines=1 => {Dump autosetup defines to $DUMP_DEFINES_FILE} + dump-defines=1 => {Disable dump of autosetup defines to $DUMP_DEFINES_FILE} } set srcdir $autosetup(srcdir) @@ -73,8 +73,6 @@ define VERSION $VERSION define RELEASE $RELEASE puts "RELEASE = $RELEASE" puts "VERSION = $VERSION" -#puts "with-wasi-sdk? = [opt-val with-wasi-sdk]" -#puts "with-debug? = [opt-val with-debug]" set outOfTreeBuild 0 if {![file exists sqlite3.pc.in]} { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index ae56408dfa..77a895e233 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -27,18 +27,18 @@ array set hwaciCache {} ; # used for caching various results. # # On an empty list, returns "". proc hwaci-lshift {listVar {count 1}} { - upvar 1 $listVar l - if {![info exists l]} { - # make the error message show the real variable name - error "can't read \"$listVar\": no such variable" - } - if {![llength $l]} { - # error Empty - return "" - } - set r [lrange $l 0 [incr count -1]] - set l [lreplace $l [set l 0] $count] - return $r + upvar 1 $listVar l + if {![info exists l]} { + # make the error message show the real variable name + error "can't read \"$listVar\": no such variable" + } + if {![llength $l]} { + # error Empty + return "" + } + set r [lrange $l 0 [incr count -1]] + set l [lreplace $l [set l 0] $count] + return $r } ######################################################################## @@ -46,10 +46,10 @@ proc hwaci-lshift {listVar {count 1}} { # routine makes to the LIBS define. Returns the result of # cc-check-function-in-lib. proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { - set _LIBS [get-define LIBS] - set found [cc-check-function-in-lib $function $libs $otherlibs] - define LIBS $_LIBS - return $found + set _LIBS [get-define LIBS] + set found [cc-check-function-in-lib $function $libs $otherlibs] + define LIBS $_LIBS + return $found } ######################################################################## @@ -62,35 +62,35 @@ proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { # If defName is empty then "BIN_X" is used, where X is the upper-case # form of $binName with any '-' characters replaced with '_'. proc hwaci-bin-define {binName {defName {}}} { - global hwaciCache - set cacheName "$binName:$defName" - set check {} - if {[info exists hwaciCache($cacheName)]} { - set check $hwaciCache($cacheName) - } - msg-checking "Looking for $binName ... " - if {"" ne $check} { - set lbl $check - if {" _ 0 _ " eq $check} { - set lbl "not found" - set check "" - } - msg-result "(cached) $lbl" - return $check - } - set check [find-executable-path $binName] - if {"" eq $check} { - msg-result "not found" - set hwaciCache($cacheName) " _ 0 _ " - } else { - msg-result $check - set hwaciCache($cacheName) $check - } - if {"" eq $defName} { - set defName "BIN_[string toupper [string map {- _} $binName]]" + global hwaciCache + set cacheName "$binName:$defName" + set check {} + if {[info exists hwaciCache($cacheName)]} { + set check $hwaciCache($cacheName) + } + msg-checking "Looking for $binName ... " + if {"" ne $check} { + set lbl $check + if {" _ 0 _ " eq $check} { + set lbl "not found" + set check "" } - define $defName $check + msg-result "(cached) $lbl" return $check + } + set check [find-executable-path $binName] + if {"" eq $check} { + msg-result "not found" + set hwaciCache($cacheName) " _ 0 _ " + } else { + msg-result $check + set hwaciCache($cacheName) $check + } + if {"" eq $defName} { + set defName "BIN_[string toupper [string map {- _} $binName]]" + } + define $defName $check + return $check } ######################################################################## @@ -98,11 +98,11 @@ proc hwaci-bin-define {binName {defName {}}} { # BIN_BASH to the full path to bash and returns that value. We # _require_ bash because it's the SHELL value used in our makefiles. proc hwaci-require-bash {} { - set bash [hwaci-bin-define bash] - if {"" eq $bash} { - user-error "Our Makefiles require the bash shell." - } - return $bash + set bash [hwaci-bin-define bash] + if {"" eq $bash} { + user-error "Our Makefiles require the bash shell." + } + return $bash } ######################################################################## @@ -178,31 +178,31 @@ proc hwaci-define-if-opt-truthy {flag def msg {iftrue 1} {iffalse 0}} { # the option is set, it gets define'd to 0, else 1. Returns the # define'd value. proc hwaci-opt-bool-01 {args} { - set invert 0 - if {[lindex $args 0] eq "-v"} { - set invert 1 - set args [lrange $args 1 end] - } - set optName [hwaci-lshift args] - set defName [hwaci-lshift args] - set descr [hwaci-lshift args] - if {"" eq $descr} { - set descr $defName - } - set rc 0 - msg-checking "$descr ... " - if {[hwaci-opt-truthy $optName]} { - if {0 eq $invert} { - set rc 1 - } else { - set rc 0 - } - } elseif {0 ne $invert} { - set rc 1 + set invert 0 + if {[lindex $args 0] eq "-v"} { + set invert 1 + set args [lrange $args 1 end] + } + set optName [hwaci-lshift args] + set defName [hwaci-lshift args] + set descr [hwaci-lshift args] + if {"" eq $descr} { + set descr $defName + } + set rc 0 + msg-checking "$descr ... " + if {[hwaci-opt-truthy $optName]} { + if {0 eq $invert} { + set rc 1 + } else { + set rc 0 } - msg-result $rc - define $defName $rc - return $rc + } elseif {0 ne $invert} { + set rc 1 + } + msg-result $rc + define $defName $rc + return $rc } ######################################################################## @@ -224,48 +224,48 @@ proc hwaci-opt-bool-01 {args} { # Note that if it finds LIBLTDL it does not look for LIBDL, so will # report only that is has LIBLTDL. proc hwaci-check-module-loader {} { - msg-checking "Looking for module-loader APIs... " - if {99 ne [get-define LDFLAGS_MODULE_LOADER]} { - if {1 eq [get-define HAVE_LIBLTDL 0]} { - msg-result "(cached) libltdl" - return 1 - } elseif {1 eq [get-define HAVE_LIBDL 0]} { - msg-result "(cached) libdl" - return 1 - } - # else: wha??? + msg-checking "Looking for module-loader APIs... " + if {99 ne [get-define LDFLAGS_MODULE_LOADER]} { + if {1 eq [get-define HAVE_LIBLTDL 0]} { + msg-result "(cached) libltdl" + return 1 + } elseif {1 eq [get-define HAVE_LIBDL 0]} { + msg-result "(cached) libdl" + return 1 } - set HAVE_LIBLTDL 0 - set HAVE_LIBDL 0 + # else: wha??? + } + set HAVE_LIBLTDL 0 + set HAVE_LIBDL 0 + set LDFLAGS_MODULE_LOADER "" + set rc 0 + puts "" ;# cosmetic kludge for cc-check-XXX + if {[cc-check-includes ltdl.h] && [cc-check-function-in-lib lt_dlopen ltdl]} { + set HAVE_LIBLTDL 1 + set LDFLAGS_MODULE_LOADER "-lltdl -rdynamic" + puts " - Got libltdl." + set rc 1 + } elseif {[cc-with {-includes dlfcn.h} { + cctest -link 1 -declare "extern char* dlerror(void);" -code "dlerror();"}]} { + puts " - This system can use dlopen() without -ldl." + set HAVE_LIBDL 1 set LDFLAGS_MODULE_LOADER "" - set rc 0 - puts "" ;# cosmetic kludge for cc-check-XXX - if {[cc-check-includes ltdl.h] && [cc-check-function-in-lib lt_dlopen ltdl]} { - set HAVE_LIBLTDL 1 - set LDFLAGS_MODULE_LOADER "-lltdl -rdynamic" - puts " - Got libltdl." - set rc 1 - } elseif {[cc-with {-includes dlfcn.h} { - cctest -link 1 -declare "extern char* dlerror(void);" -code "dlerror();"}]} { - puts " - This system can use dlopen() without -ldl." - set HAVE_LIBDL 1 - set LDFLAGS_MODULE_LOADER "" - set rc 1 - } elseif {[cc-check-includes dlfcn.h]} { - set HAVE_LIBDL 1 - set rc 1 - if {[cc-check-function-in-lib dlopen dl]} { - puts " - dlopen() needs libdl." - set LDFLAGS_MODULE_LOADER "-ldl -rdynamic" - } else { - puts " - dlopen() not found in libdl. Assuming dlopen() is built-in." - set LDFLAGS_MODULE_LOADER "-rdynamic" - } + set rc 1 + } elseif {[cc-check-includes dlfcn.h]} { + set HAVE_LIBDL 1 + set rc 1 + if {[cc-check-function-in-lib dlopen dl]} { + puts " - dlopen() needs libdl." + set LDFLAGS_MODULE_LOADER "-ldl -rdynamic" + } else { + puts " - dlopen() not found in libdl. Assuming dlopen() is built-in." + set LDFLAGS_MODULE_LOADER "-rdynamic" } - define HAVE_LIBLTDL $HAVE_LIBLTDL - define HAVE_LIBDL $HAVE_LIBDL - define LDFLAGS_MODULE_LOADER $LDFLAGS_MODULE_LOADER - return $rc + } + define HAVE_LIBLTDL $HAVE_LIBLTDL + define HAVE_LIBDL $HAVE_LIBDL + define LDFLAGS_MODULE_LOADER $LDFLAGS_MODULE_LOADER + return $rc } ######################################################################## @@ -274,30 +274,30 @@ proc hwaci-check-module-loader {} { # loader. Intended to be called in place of that function when # a module loader is explicitly not desired. proc hwaci-no-check-module-loader {} { - define HAVE_LIBDL 0 - define HAVE_LIBLTDL 0 - define LDFLAGS_MODULE_LOADER "" + define HAVE_LIBDL 0 + define HAVE_LIBLTDL 0 + define LDFLAGS_MODULE_LOADER "" } ######################################################################## # Opens the given file, reads all of its content, and returns it. proc hwaci-file-content {fname} { - set fp [open $fname r] - set rc [read $fp] - close $fp - return $rc + set fp [open $fname r] + set rc [read $fp] + close $fp + return $rc } ######################################################################## # Returns the contents of the given file as an array of lines, with # the EOL stripped from each input line. proc hwaci-file-content-list {fname} { - set fp [open $fname r] - set rc {} - while { [gets $fp line] >= 0 } { - lappend rc $line - } - return $rc + set fp [open $fname r] + set rc {} + while { [gets $fp line] >= 0 } { + lappend rc $line + } + return $rc } ######################################################################## @@ -308,25 +308,25 @@ proc hwaci-file-content-list {fname} { # Returns 1 if supported, else 0. Defines MAKE_COMPILATION_DB to "yes" # if supported, "no" if not. proc hwaci-check-compile-commands {{configOpt {}}} { - msg-checking "compile_commands.json support... " - if {"" ne $configOpt && [opt-bool $configOpt]} { - msg-result "explicitly disabled" - define MAKE_COMPILATION_DB no - return 0 + msg-checking "compile_commands.json support... " + if {"" ne $configOpt && [opt-bool $configOpt]} { + msg-result "explicitly disabled" + define MAKE_COMPILATION_DB no + return 0 + } else { + if {[cctest -lang c -cflags {/dev/null -MJ} -source {}]} { + # This test reportedly incorrectly succeeds on one of + # Martin G.'s older systems. drh also reports a false + # positive on an unspecified older Mac system. + msg-result "compiler supports compile_commands.json" + define MAKE_COMPILATION_DB yes + return 1 } else { - if {[cctest -lang c -cflags {/dev/null -MJ} -source {}]} { - # This test reportedly incorrectly succeeds on one of - # Martin G.'s older systems. drh also reports a false - # positive on an unspecified older Mac system. - msg-result "compiler supports compile_commands.json" - define MAKE_COMPILATION_DB yes - return 1 - } else { - msg-result "compiler does not support compile_commands.json" - define MAKE_COMPILATION_DB no - return 0 - } + msg-result "compiler does not support compile_commands.json" + define MAKE_COMPILATION_DB no + return 0 } + } } ######################################################################## @@ -474,7 +474,7 @@ proc hwaci-check-emsdk {} { define EMSDK_HOME "" define EMSDK_ENV "" define BIN_EMCC "" -# define EMCC_OPT "-Oz" + # define EMCC_OPT "-Oz" msg-checking "Emscripten SDK? " if {$emsdkHome eq "" && [info exists ::env(EMSDK)]} { # Fall back to checking the environment. $EMSDK gets set diff --git a/manifest b/manifest index 3e9db4ce0d..43a326a1c9 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Do\snot\sremove\s*.def\sin\sthe\scleanup\srules\sbecause\sauto.def\sis\sa\srequired\spart\sof\sautosetup.\sRemove\sthe\s.o\svs\s.obj\sdetection/distinction\sbecause\sthe\sUnix-like\sWindows\senvironments\suse\s.o. -D 2024-09-26T14:09:23.248 +C Get\slemon\sbuilding.\sRe-indent\shwaci-common.tcl\sfor\sconsistency. +D 2024-09-26T18:40:07.537 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 3806942cc072d2dd09568c530c614dee8274ce2663ba560f7af5271a088d944d +F Makefile.in 9f2eb42f8ace9c686b602f2142325a38417711e3f6aa4355dd904ab21ec77478 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d2d9c2d473a81551ddd29a155c375fa31a068e05b2227862a24a2e84c00a0bdf +F auto.def 32b757ecdb2e2b83190dd160dcff9e508fc97c70f9a59a0fd789cfbf614542f5 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl a112327a1eb29e3d32670e25a464832abb73f028b679a5433c4630446ca76b56 +F autosetup/hwaci-common.tcl 087bcd8ec711da2d3e1c3ede32903e45062ffd148b71f28d59e0c5fda0060ef6 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7638f3ad1588ff16c2980763c6c4c1386a711acd64adb21c465f186a47bc975d -R dd990ac14aacc7aef84cea962548e6de +P 65eb1072e297f01ba4ce21fe644f709e75ebaec5307764b549efceafb88f6ebf +R ad341b1fb26f2538d3ce63a52f00cd0b U stephan -Z 5264d306ffd6b34f18c75d08cd8d2866 +Z 949a6a7cca5b4eb8a6b3e740c1f5b1b4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a7a53b3a8d..ee21b8a0f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65eb1072e297f01ba4ce21fe644f709e75ebaec5307764b549efceafb88f6ebf +53dc33d5e20062e8c4c9856349bbc143c858327ef41f356ffcc574b36d0cc73c From 9a1b212f50495cfbe0425e9c447c6daab62e0242 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 26 Sep 2024 21:08:00 +0000 Subject: [PATCH 023/522] Latest hwaci-common.tcl after refactoring to facilitate including a copy in the libfossil tree. FossilOrigin-Name: feea65bcd54f9266445bc4d65ea5e3cfadee8e3abff5b682e31cdc0034354fbf --- autosetup/hwaci-common.tcl | 81 ++++++++++++++++++++++++-------------- manifest | 12 +++--- manifest.uuid | 2 +- 3 files changed, 58 insertions(+), 37 deletions(-) diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 77a895e233..223785f262 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -10,14 +10,15 @@ # ######################################################################## # Routines for Steve Bennett's autosetup which are common to trees -# managed under the umbrella of the SQLite project. +# managed in and around the umbrella of the SQLite project. # # This file was initially derived from one used in the libfossil # project, authored by the same person who ported it here (so there's -# no licensing issue despite this code having a twin running around). +# no licensing issue despite this code having at least two near-twins +# running around). ######################################################################## -array set hwaciCache {} ; # used for caching various results. +array set _hwaciCache {} ; # used for caching various results. ######################################################################## # hwaci-lshift shifts $count elements from the list named $listVar and @@ -46,6 +47,7 @@ proc hwaci-lshift {listVar {count 1}} { # routine makes to the LIBS define. Returns the result of # cc-check-function-in-lib. proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { + # TODO: this can now be implemented using autosetup's define-push set _LIBS [get-define LIBS] set found [cc-check-function-in-lib $function $libs $otherlibs] define LIBS $_LIBS @@ -62,11 +64,11 @@ proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { # If defName is empty then "BIN_X" is used, where X is the upper-case # form of $binName with any '-' characters replaced with '_'. proc hwaci-bin-define {binName {defName {}}} { - global hwaciCache + global _hwaciCache set cacheName "$binName:$defName" set check {} - if {[info exists hwaciCache($cacheName)]} { - set check $hwaciCache($cacheName) + if {[info exists _hwaciCache($cacheName)]} { + set check $_hwaciCache($cacheName) } msg-checking "Looking for $binName ... " if {"" ne $check} { @@ -81,10 +83,10 @@ proc hwaci-bin-define {binName {defName {}}} { set check [find-executable-path $binName] if {"" eq $check} { msg-result "not found" - set hwaciCache($cacheName) " _ 0 _ " + set _hwaciCache($cacheName) " _ 0 _ " } else { msg-result $check - set hwaciCache($cacheName) $check + set _hwaciCache($cacheName) $check } if {"" eq $defName} { set defName "BIN_[string toupper [string map {- _} $binName]]" @@ -140,6 +142,15 @@ proc hwaci-opt-truthy {flag} { ######################################################################## # If [hwaci-opt-truthy $flag] is true, eval $then, else eval $else. +# +# Note that this may or may not, depending on the content of $then and +# $else, be functionally equivalent to: +# +# if {[hwaci-if-opt-truthy flag]} {...} else {...} +# +# When referencing $vars in $then and $else, the latter can resolve +# (without further assistance) the vars from its current scope, +# whereas $then and $else will not. proc hwaci-if-opt-truthy {flag then {else {}}} { if {[hwaci-opt-truthy $flag]} {eval $then} else {eval $else} } @@ -303,30 +314,33 @@ proc hwaci-file-content-list {fname} { ######################################################################## # Checks the compiler for compile_commands.json support. If passed an # argument it is assumed to be the name of an autosetup boolean config -# option to explicitly DISABLE the compile_commands.json support. +# which controls whether to run/skip this check. # # Returns 1 if supported, else 0. Defines MAKE_COMPILATION_DB to "yes" # if supported, "no" if not. +# +# This test has a long history of false positive results because of +# compilers reacting differently to the -MJ flag. proc hwaci-check-compile-commands {{configOpt {}}} { - msg-checking "compile_commands.json support... " - if {"" ne $configOpt && [opt-bool $configOpt]} { - msg-result "explicitly disabled" - define MAKE_COMPILATION_DB no - return 0 - } else { - if {[cctest -lang c -cflags {/dev/null -MJ} -source {}]} { - # This test reportedly incorrectly succeeds on one of - # Martin G.'s older systems. drh also reports a false - # positive on an unspecified older Mac system. - msg-result "compiler supports compile_commands.json" - define MAKE_COMPILATION_DB yes - return 1 + msg-checking "compile_commands.json support... " + if {"" ne $configOpt && ![hwaci-opt-truthy $configOpt]} { + msg-result "explicitly disabled" + define MAKE_COMPILATION_DB no + return 0 } else { - msg-result "compiler does not support compile_commands.json" - define MAKE_COMPILATION_DB no - return 0 + if {[cctest -lang c -cflags {/dev/null -MJ} -source {}]} { + # This test reportedly incorrectly succeeds on one of + # Martin G.'s older systems. drh also reports a false + # positive on an unspecified older Mac system. + msg-result "compiler supports compile_commands.json" + define MAKE_COMPILATION_DB yes + return 1 + } else { + msg-result "compiler does not support compile_commands.json" + define MAKE_COMPILATION_DB no + return 0 + } } - } } ######################################################################## @@ -389,18 +403,25 @@ proc hwaci-check-profile-flag {{flagname profile}} { # Returns 1 if this appears to be a Windows environment (MinGw, # Cygwin, MSys), else returns 0. The optional argument is the name of # an autosetup define which contains platform name info, defaulting to -# "host". The other legal value is "target". +# "host". The other legal value is "build" (the build machine). If +# $key == "build" then some additional checks may be performed which +# are not applicable when $key == "host". proc hwaci-looks-like-windows {{key host}} { global autosetup - if {$::autosetup(iswin)} { return 1 } switch -glob -- [get-define $key] { *-*-ming* - *-*-cygwin - *-*-msys { return 1 } - default { - return 0 + } + if {$key eq "build"} { + # These apply only to the local OS, not a cross-compilation target, + # as the above check can potentially. + if {$::autosetup(iswin)} { return 1 } + if {[find-an-executable cygpath] ne "" || $::tcl_platform(os)=="Windows NT"} { + return 1 } } + return 0 } ######################################################################## diff --git a/manifest b/manifest index 43a326a1c9..bc95dc98e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\slemon\sbuilding.\sRe-indent\shwaci-common.tcl\sfor\sconsistency. -D 2024-09-26T18:40:07.537 +C Latest\shwaci-common.tcl\safter\srefactoring\sto\sfacilitate\sincluding\sa\scopy\sin\sthe\slibfossil\stree. +D 2024-09-26T21:08:00.671 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 087bcd8ec711da2d3e1c3ede32903e45062ffd148b71f28d59e0c5fda0060ef6 +F autosetup/hwaci-common.tcl d5c192839c2a233380e880df90ee0a3427eef623b3ddf258b466f67ada8f4639 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 65eb1072e297f01ba4ce21fe644f709e75ebaec5307764b549efceafb88f6ebf -R ad341b1fb26f2538d3ce63a52f00cd0b +P 53dc33d5e20062e8c4c9856349bbc143c858327ef41f356ffcc574b36d0cc73c +R 6b7f18b95913add9b8d87d074deb4cfd U stephan -Z 949a6a7cca5b4eb8a6b3e740c1f5b1b4 +Z 0ed9ac144e699edbea90d5afd0259dab # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ee21b8a0f0..7d22fb8208 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53dc33d5e20062e8c4c9856349bbc143c858327ef41f356ffcc574b36d0cc73c +feea65bcd54f9266445bc4d65ea5e3cfadee8e3abff5b682e31cdc0034354fbf From 66cb9d0ec7ffd6c8098e95606a016d9d7b2e9db0 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 26 Sep 2024 21:09:22 +0000 Subject: [PATCH 024/522] Re-indent some tcl code. FossilOrigin-Name: 34ea629a07bfb00c86df7c62462bf2d699347c34dcb7656c86f5f76b52d33b30 --- autosetup/hwaci-common.tcl | 34 +++++++++++++++++----------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 223785f262..570fbf4a84 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -322,25 +322,25 @@ proc hwaci-file-content-list {fname} { # This test has a long history of false positive results because of # compilers reacting differently to the -MJ flag. proc hwaci-check-compile-commands {{configOpt {}}} { - msg-checking "compile_commands.json support... " - if {"" ne $configOpt && ![hwaci-opt-truthy $configOpt]} { - msg-result "explicitly disabled" - define MAKE_COMPILATION_DB no - return 0 + msg-checking "compile_commands.json support... " + if {"" ne $configOpt && ![hwaci-opt-truthy $configOpt]} { + msg-result "explicitly disabled" + define MAKE_COMPILATION_DB no + return 0 + } else { + if {[cctest -lang c -cflags {/dev/null -MJ} -source {}]} { + # This test reportedly incorrectly succeeds on one of + # Martin G.'s older systems. drh also reports a false + # positive on an unspecified older Mac system. + msg-result "compiler supports compile_commands.json" + define MAKE_COMPILATION_DB yes + return 1 } else { - if {[cctest -lang c -cflags {/dev/null -MJ} -source {}]} { - # This test reportedly incorrectly succeeds on one of - # Martin G.'s older systems. drh also reports a false - # positive on an unspecified older Mac system. - msg-result "compiler supports compile_commands.json" - define MAKE_COMPILATION_DB yes - return 1 - } else { - msg-result "compiler does not support compile_commands.json" - define MAKE_COMPILATION_DB no - return 0 - } + msg-result "compiler does not support compile_commands.json" + define MAKE_COMPILATION_DB no + return 0 } + } } ######################################################################## diff --git a/manifest b/manifest index bc95dc98e2..76a18386e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Latest\shwaci-common.tcl\safter\srefactoring\sto\sfacilitate\sincluding\sa\scopy\sin\sthe\slibfossil\stree. -D 2024-09-26T21:08:00.671 +C Re-indent\ssome\stcl\scode. +D 2024-09-26T21:09:22.501 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl d5c192839c2a233380e880df90ee0a3427eef623b3ddf258b466f67ada8f4639 +F autosetup/hwaci-common.tcl ed4b9197d06dce03938e9f0b59a0d605a37761f23098b8c63fc581c5c0eda1ef F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 53dc33d5e20062e8c4c9856349bbc143c858327ef41f356ffcc574b36d0cc73c -R 6b7f18b95913add9b8d87d074deb4cfd +P feea65bcd54f9266445bc4d65ea5e3cfadee8e3abff5b682e31cdc0034354fbf +R 43bb192919b9c029a6389c0f03cc26a7 U stephan -Z 0ed9ac144e699edbea90d5afd0259dab +Z d85ef6beb4955ef9438b7cb0c396c13b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7d22fb8208..adfff17c71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -feea65bcd54f9266445bc4d65ea5e3cfadee8e3abff5b682e31cdc0034354fbf +34ea629a07bfb00c86df7c62462bf2d699347c34dcb7656c86f5f76b52d33b30 From 02616ccf296ba81f82ca7c8f65b823bb57d88fa7 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 01:00:32 +0000 Subject: [PATCH 025/522] Get the generated .c/.h files generating. FossilOrigin-Name: e890c8508da4e126f43c61f809f750d6cb2d7d01600fe2173fbcd7dabbfce0fd --- Makefile.in | 380 ++++++++++++++++++++----------------- auto.def | 114 +++++++---- autosetup/hwaci-common.tcl | 13 ++ manifest | 18 +- manifest.uuid | 2 +- sqlite_cfg.h.in | 144 +++++++++----- 6 files changed, 396 insertions(+), 275 deletions(-) diff --git a/Makefile.in b/Makefile.in index 0e026097f8..60dfbd13a1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -118,23 +118,23 @@ RELEASE = @RELEASE@ BEXE = @BUILD_EXEEXT@ TEXE = @TARGET_EXEEXT@ -#XX## The following variable is "1" if the configure script was able to locate -#XX## the tclConfig.sh file. It is an empty string otherwise. When this -#XX## variable is "1", the TCL extension library (libtclsqlite3.so) is built -#XX## and installed. -#XX## -#XX#HAVE_TCL = @HAVE_TCL@ -#XX# -#XX## This is the command to use for tclsh - normally just "tclsh", but we may -#XX## know the specific version we want to use -#XX## -#XX#TCLSH_CMD = @TCLSH_CMD@ -#XX# -#XX## Additional options when running tests using testrunner.tcl -#XX## This is usually either blank, or else --status -#XX## -TSTRNNR_OPTS = @TSTRNNR_OPTS@ +# The following variable is "1" if the configure script was able to locate +# the tclConfig.sh file. It is an empty string otherwise. When this +# variable is "1", the TCL extension library (libtclsqlite3.so) is built +# and installed. # +HAVE_TCL = @HAVE_TCL@ + +# This is the command to use for tclsh - normally just "tclsh", but we may +# know the specific version we want to use +# +TCLSH_CMD = @TCLSH_CMD@ + +# Additional options when running tests using testrunner.tcl +# This is usually either blank, or else --status +# +TSTRNNR_OPTS = @TSTRNNR_OPTS@ + #XX## Where do we want to install the tcl plugin #XX## #XX#TCLLIBDIR = @TCLLIBDIR@ @@ -181,8 +181,16 @@ INSTALL = @BIN_INSTALL@ # You should not have to change anything below this line ################################################################################ # + +# Vars with the AS_ prefix are specifically related to AutoSetup. +# +# AS_AUTO_DEF is the main configure script. +# +AS_AUTO_DEF = $(TOP)/auto.def + USE_AMALGAMATION = @USE_AMALGAMATION@ AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@ + # #XX## Object files for the SQLite library (non-amalgamation). #XX## @@ -674,23 +682,36 @@ SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@) SQLITE3_O = $(TOP)/sqlite3.o -#XX## Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either -#XX## libtclsqlite3.la or an empty value. -#XX#libtclsqlite3.la_0 = -#XX#libtclsqlite3.la_1 = libtclsqlite3.la -#XX# -#XX## This is the default Makefile target. The objects listed here -#XX## are what get build when you type just "make" with no arguments. -#XX## -#XX#all: sqlite3.h libsqlite3.la $(SQLITE3_SHELL_TARGET) \ +# Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either +# libtclsqlite3.la or an empty value. +libtclsqlite3.la_0 = +libtclsqlite3.la_1 = libtclsqlite3.la +# +# This is the default Makefile target. The objects listed here +# are what get build when you type just "make" with no arguments. +# + +all: sqlite3.h +#all: libsqlite3.la $(SQLITE3_SHELL_TARGET) \ #XX# $(libtclsqlite3.la_$(HAVE_TCL)) -#XX# -#XX#Makefile: $(TOP)/Makefile.in -#XX# ./config.status -#XX# -#XX#sqlite3.pc: $(TOP)/sqlite3.pc.in -#XX# ./config.status -#XX# + +# Re-run $(TOP)/configure with the same args invoked to produce this +# makefile. +# +AUTOREMAKE = @SQLITE_AUTOREMAKE@ + +Makefile: $(TOP)/Makefile.in + $(AUTOREMAKE) + @touch $@ + +sqlite3.pc: $(TOP)/sqlite3.pc.in + $(AUTOREMAKE) + @touch $@ + +sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) + $(AUTOREMAKE) + @touch $@ + #XX#libsqlite3.la: $(LIBOBJ) #XX# $(LTLINK) -no-undefined -o $@ $(LIBOBJ) $(TLIBS) \ #XX# ${ALLOWRELEASE} -rpath "$(libdir)" -version-info "8:6:8" @@ -731,14 +752,14 @@ SQLITE3_O = $(TOP)/sqlite3.o #XX# $(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \ #XX# $(TOP)/ext/misc/scrub.c sqlite3.lo $(TLIBS) #XX# -#XX#srcck1$(BEXE): $(TOP)/tool/srcck1.c -#XX# $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c -#XX# -#XX#sourcetest: srcck1$(BEXE) sqlite3.c -#XX# ./srcck1 sqlite3.c -#XX# -#XX#src-verify: $(TOP)/tool/src-verify.c -#XX# $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c +srcck1$(BEXE): $(TOP)/tool/srcck1.c + $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c + +sourcetest: srcck1$(BEXE) sqlite3.c + ./srcck1 sqlite3.c + +src-verify: $(TOP)/tool/src-verify.c + $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c #XX# #XX#verify-source: ./src-verify #XX# ./src-verify $(TOP) @@ -830,52 +851,52 @@ SQLITE3_O = $(TOP)/sqlite3.o #XX# $(MPTEST2) --journalmode DELETE #XX# #XX# -#XX#has_tclsh84: -#XX# sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) -#XX# touch has_tclsh84 -#XX# -#XX#has_tclsh85: -#XX# sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) -#XX# touch has_tclsh85 -#XX# +has_tclsh84: + sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) + touch has_tclsh84 + +has_tclsh85: + sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) + touch has_tclsh85 + #XX#has_tclconfig: #XX# @ if test x"$(HAVE_TCL)" != "x1"; then echo 'ERROR: Requires access to "tclConfig.sh" which "configure" was not able to locate'; exit 1; fi #XX# touch has_tclconfig #XX# #XX# -#XX## This target creates a directory named "tsrc" and fills it with -#XX## copies of all of the C source code and header files needed to -#XX## build on the target system. Some of the C source code and header -#XX## files are automatically generated. This target takes care of -#XX## all that automatic generation. -#XX## -#XX#.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl has_tclsh84 fts5.c -#XX# rm -rf tsrc -#XX# mkdir tsrc -#XX# cp -f $(SRC) tsrc -#XX# rm tsrc/sqlite.h.in tsrc/parse.y -#XX# $(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new -#XX# mv vdbe.new tsrc/vdbe.c -#XX# cp fts5.c fts5.h tsrc -#XX# touch .target_source -#XX# -#XX#sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84 -#XX# $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) -#XX# cp tsrc/sqlite3ext.h . -#XX# cp $(TOP)/ext/session/sqlite3session.h . -#XX# -#XX#sqlite3r.h: sqlite3.h has_tclsh84 -#XX# $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -#XX# -#XX#sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84 -#XX# cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ -#XX# cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ -#XX# cp $(TOP)/ext/recover/dbdata.c tsrc/ -#XX# $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) -#XX# -#XX#sqlite3ext.h: .target_source -#XX# cp tsrc/sqlite3ext.h . -#XX# +# This target creates a directory named "tsrc" and fills it with +# copies of all of the C source code and header files needed to +# build on the target system. Some of the C source code and header +# files are automatically generated. This target takes care of +# all that automatic generation. +# +.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl has_tclsh84 fts5.c + rm -rf tsrc + mkdir tsrc + cp -f $(SRC) tsrc + rm tsrc/sqlite.h.in tsrc/parse.y + $(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new + mv vdbe.new tsrc/vdbe.c + cp fts5.c fts5.h tsrc + touch .target_source + +sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84 + $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + cp tsrc/sqlite3ext.h . + cp $(TOP)/ext/session/sqlite3session.h . + +sqlite3r.h: sqlite3.h has_tclsh84 + $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h + +sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84 + cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ + cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ + cp $(TOP)/ext/recover/dbdata.c tsrc/ + $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + +sqlite3ext.h: .target_source + cp tsrc/sqlite3ext.h . + #XX#tclsqlite3.c: sqlite3.c #XX# echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c #XX# cat sqlite3.c >>tclsqlite3.c @@ -898,12 +919,15 @@ lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c @if BUILD_EXEEXT ne "" lemon: lemon$(BEXE) @endif -#XX# -#XX## Rules to build the program that generates the source-id -#XX## -#XX#mksourceid$(BEXE): $(TOP)/tool/mksourceid.c -#XX# $(BCC) -o $@ $(TOP)/tool/mksourceid.c -#XX# + +# Rules to build the program that generates the source-id +# +mksourceid$(BEXE): $(TOP)/tool/mksourceid.c + $(BCC) -o $@ $(TOP)/tool/mksourceid.c +@if BUILD_EXEEXT ne "" +mksourceid: mksourceid$(BEXE) +@endif + #XX## Rules to build individual *.o files from generated *.c files. This #XX## applies to: #XX## @@ -1170,71 +1194,71 @@ lemon: lemon$(BEXE) #XX#tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.lo libsqlite3.la #XX# $(LTLINK) -o $@ tclsqlite-shell.lo \ #XX# libsqlite3.la $(LIBTCL) -#XX# -#XX## Rules to build opcodes.c and opcodes.h -#XX## -#XX#opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl has_tclsh84 -#XX# $(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c -#XX# -#XX#opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl has_tclsh84 -#XX# cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h -#XX# -#XX## Rules to build parse.c and parse.h - the outputs of lemon. -#XX## -#XX#parse.h: parse.c -#XX# -#XX#parse.c: $(TOP)/src/parse.y lemon$(BEXE) -#XX# cp $(TOP)/src/parse.y . -#XX# ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y -#XX# -#XX#sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION has_tclsh84 -#XX# $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h -#XX# + +# Rules to build opcodes.c and opcodes.h +# +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl has_tclsh84 + $(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c + +opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl has_tclsh84 + cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h + +# Rules to build parse.c and parse.h - the outputs of lemon. +# +parse.h: parse.c + +parse.c: $(TOP)/src/parse.y lemon$(BEXE) + cp $(TOP)/src/parse.y . + ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y + +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION has_tclsh84 + $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h + #XX#sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 #XX# echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ #XX# echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ #XX# cat $(TOP)/VERSION | $(TCLSH_CMD) $(TOP)/tool/replace.tcl exact . , >>$@ #XX# echo '#endif' >>sqlite3rc.h -#XX# -#XX#keywordhash.h: $(TOP)/tool/mkkeywordhash.c -#XX# $(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c -#XX# ./mkkeywordhash$(BEXE) >keywordhash.h -#XX# -#XX## Source and header files that shell.c depends on -#XX#SHELL_DEP = \ -#XX# $(TOP)/src/shell.c.in \ -#XX# $(TOP)/ext/consio/console_io.c \ -#XX# $(TOP)/ext/consio/console_io.h \ -#XX# $(TOP)/ext/expert/sqlite3expert.c \ -#XX# $(TOP)/ext/expert/sqlite3expert.h \ -#XX# $(TOP)/ext/intck/sqlite3intck.c \ -#XX# $(TOP)/ext/intck/sqlite3intck.h \ -#XX# $(TOP)/ext/misc/appendvfs.c \ -#XX# $(TOP)/ext/misc/base64.c \ -#XX# $(TOP)/ext/misc/base85.c \ -#XX# $(TOP)/ext/misc/completion.c \ -#XX# $(TOP)/ext/misc/decimal.c \ -#XX# $(TOP)/ext/misc/fileio.c \ -#XX# $(TOP)/ext/misc/ieee754.c \ -#XX# $(TOP)/ext/misc/memtrace.c \ -#XX# $(TOP)/ext/misc/pcachetrace.c \ -#XX# $(TOP)/ext/misc/percentile.c \ -#XX# $(TOP)/ext/misc/regexp.c \ -#XX# $(TOP)/ext/misc/series.c \ -#XX# $(TOP)/ext/misc/sha1.c \ -#XX# $(TOP)/ext/misc/shathree.c \ -#XX# $(TOP)/ext/misc/sqlar.c \ -#XX# $(TOP)/ext/misc/uint.c \ -#XX# $(TOP)/ext/misc/vfstrace.c \ -#XX# $(TOP)/ext/misc/zipfile.c \ -#XX# $(TOP)/ext/recover/dbdata.c \ -#XX# $(TOP)/ext/recover/sqlite3recover.c \ -#XX# $(TOP)/ext/recover/sqlite3recover.h \ -#XX# $(TOP)/src/test_windirent.c \ -#XX# $(TOP)/src/test_windirent.h -#XX# -#XX#shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl has_tclsh84 -#XX# $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c + +keywordhash.h: $(TOP)/tool/mkkeywordhash.c + $(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c + ./mkkeywordhash$(BEXE) >keywordhash.h + +# Source and header files that shell.c depends on +SHELL_DEP = \ + $(TOP)/src/shell.c.in \ + $(TOP)/ext/consio/console_io.c \ + $(TOP)/ext/consio/console_io.h \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/sqlite3expert.h \ + $(TOP)/ext/intck/sqlite3intck.c \ + $(TOP)/ext/intck/sqlite3intck.h \ + $(TOP)/ext/misc/appendvfs.c \ + $(TOP)/ext/misc/base64.c \ + $(TOP)/ext/misc/base85.c \ + $(TOP)/ext/misc/completion.c \ + $(TOP)/ext/misc/decimal.c \ + $(TOP)/ext/misc/fileio.c \ + $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/memtrace.c \ + $(TOP)/ext/misc/pcachetrace.c \ + $(TOP)/ext/misc/percentile.c \ + $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/series.c \ + $(TOP)/ext/misc/sha1.c \ + $(TOP)/ext/misc/shathree.c \ + $(TOP)/ext/misc/sqlar.c \ + $(TOP)/ext/misc/uint.c \ + $(TOP)/ext/misc/vfstrace.c \ + $(TOP)/ext/misc/zipfile.c \ + $(TOP)/ext/recover/dbdata.c \ + $(TOP)/ext/recover/sqlite3recover.c \ + $(TOP)/ext/recover/sqlite3recover.h \ + $(TOP)/src/test_windirent.c \ + $(TOP)/src/test_windirent.h + +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl has_tclsh84 + $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c #XX# #XX# #XX# @@ -1294,37 +1318,37 @@ lemon: lemon$(BEXE) #XX# #XX#stmt.lo: $(TOP)/ext/misc/stmt.c #XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c -#XX# -#XX## FTS5 things -#XX## -#XX#FTS5_SRC = \ -#XX# $(TOP)/ext/fts5/fts5.h \ -#XX# $(TOP)/ext/fts5/fts5Int.h \ -#XX# $(TOP)/ext/fts5/fts5_aux.c \ -#XX# $(TOP)/ext/fts5/fts5_buffer.c \ -#XX# $(TOP)/ext/fts5/fts5_main.c \ -#XX# $(TOP)/ext/fts5/fts5_config.c \ -#XX# $(TOP)/ext/fts5/fts5_expr.c \ -#XX# $(TOP)/ext/fts5/fts5_hash.c \ -#XX# $(TOP)/ext/fts5/fts5_index.c \ -#XX# fts5parse.c fts5parse.h \ -#XX# $(TOP)/ext/fts5/fts5_storage.c \ -#XX# $(TOP)/ext/fts5/fts5_tokenize.c \ -#XX# $(TOP)/ext/fts5/fts5_unicode2.c \ -#XX# $(TOP)/ext/fts5/fts5_varint.c \ -#XX# $(TOP)/ext/fts5/fts5_vocab.c \ -#XX# -#XX#fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) -#XX# cp $(TOP)/ext/fts5/fts5parse.y . -#XX# rm -f fts5parse.h -#XX# ./lemon$(BEXE) $(OPTS) -S fts5parse.y -#XX# -#XX#fts5parse.h: fts5parse.c -#XX# -#XX#fts5.c: $(FTS5_SRC) has_tclsh84 -#XX# $(TCLSH_CMD) $(TOP)/ext/fts5/tool/mkfts5c.tcl -#XX# cp $(TOP)/ext/fts5/fts5.h . -#XX# + +# FTS5 things +# +FTS5_SRC = \ + $(TOP)/ext/fts5/fts5.h \ + $(TOP)/ext/fts5/fts5Int.h \ + $(TOP)/ext/fts5/fts5_aux.c \ + $(TOP)/ext/fts5/fts5_buffer.c \ + $(TOP)/ext/fts5/fts5_main.c \ + $(TOP)/ext/fts5/fts5_config.c \ + $(TOP)/ext/fts5/fts5_expr.c \ + $(TOP)/ext/fts5/fts5_hash.c \ + $(TOP)/ext/fts5/fts5_index.c \ + fts5parse.c fts5parse.h \ + $(TOP)/ext/fts5/fts5_storage.c \ + $(TOP)/ext/fts5/fts5_tokenize.c \ + $(TOP)/ext/fts5/fts5_unicode2.c \ + $(TOP)/ext/fts5/fts5_varint.c \ + $(TOP)/ext/fts5/fts5_vocab.c \ + +fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) + cp $(TOP)/ext/fts5/fts5parse.y . + rm -f fts5parse.h + ./lemon$(BEXE) $(OPTS) -S fts5parse.y + +fts5parse.h: fts5parse.c + +fts5.c: $(FTS5_SRC) has_tclsh84 + $(TCLSH_CMD) $(TOP)/ext/fts5/tool/mkfts5c.tcl + cp $(TOP)/ext/fts5/fts5.h . + #XX#fts5.lo: fts5.c $(HDR) $(EXTHDR) #XX# $(LTCOMPILE) -DSQLITE_CORE -c fts5.c #XX# diff --git a/auto.def b/auto.def index 858044eb99..4b81ce9f16 100644 --- a/auto.def +++ b/auto.def @@ -30,8 +30,8 @@ define cross_compiling ${cross_compiling} # options { with-debug:=1 => {Enable debug build flags} - with-tclsh:PATHNAME => {Full pathname of tclsh to use} - with-tcl:DIR => {Directory containing tclConfig.sh} + with-tclsh: => {Full pathname of tclsh to use} + with-tcl: => {Directory containing tclConfig.sh} tcl=1 => {Disable building accessory programs that require TCL-dev} test-status => {Enable status of tests} threadsafe=1 => {Disable mutexing} @@ -66,7 +66,9 @@ options { } set srcdir $autosetup(srcdir) -#puts "srcdir = $srcdir" +set top_srcdir [get-define abs_top_srcdir] +puts "srcdir = $srcdir" +puts "top_srcdir = $top_srcdir" set RELEASE [readfile $autosetup(srcdir)/VERSION] regsub {([0-9]*\.*[0-9]*).*} $RELEASE {\1} VERSION define VERSION $VERSION @@ -74,6 +76,9 @@ define RELEASE $RELEASE puts "RELEASE = $RELEASE" puts "VERSION = $VERSION" +define SQLITE_AUTOREMAKE cd +define-append SQLITE_AUTOREMAKE $autosetup(srcdir) && $top_srcdir/configure {*}$autosetup(argv) + set outOfTreeBuild 0 if {![file exists sqlite3.pc.in]} { puts "This appears to be an out-of-tree build." @@ -258,7 +263,12 @@ undefine lib_fdatasync ######### # Check for needed/wanted headers -cc-check-includes sys/types.h stdlib.h stdint.h inttypes.h malloc.h +cc-check-includes \ + sys/types.h sys/stat.h dlfcn.h unistd.h \ + stdlib.h malloc.h memory.h \ + string.h strings.h \ + stdint.h inttypes.h + if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { # TODO: port over the more sophisticated zlib search from the fossil auto.def define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" @@ -292,39 +302,55 @@ if {1} { # Also TODO is figure out whether we can use jimtcl for our internal # build-tool uses (as opposed to testing purposes, which requires # the tcl SQLite module). - if {![cc-path-progs tclsh]} { - user-error "Cannot find tclsh" + set tclsh [hwaci-first-bin-of tclsh8.6 tclsh tclsh9.0] + if {"" eq $tclsh} { + user-error "Cannot find tclsh, which is required to build certain files." } + define TCLSH_CMD $tclsh + define HAVE_TCL 0 ; # until the following elseif block is ported } elseif {0} { + # Porting this section of configure.ac is going to be a bit of a slog... + set tEnable [hwaci-opt-truthy tcl] + set use_tcl $tEnable + set tclsh "" + #set original_use_tcl ${use_tcl} ######### # Figure out all the name of a working tclsh and parameters needed to compile against Tcl. # The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. # # XXX AC_ARG_WITH tclsh AS_HELP_STRING([--with-tclsh=PATHNAME],[full pathname of a tclsh to use]) # XXX AC_ARG_WITH tcl AS_HELP_STRING([--with-tcl=DIR],[directory containing (tclConfig.sh)]) - # if {![opt-bool tcl]} { - # set use_tcl $enableval - # } else { - # set use_tcl yes - # } - #set original_use_tcl ${use_tcl} - # XXX if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then - # XXX AC_CHECK_PROGS TCLSH_CMD tclsh8.6 tclsh tclsh9.0 none - #set with_tclsh ${TCLSH_CMD} - # XXX fi - # XXX if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then - # XXX TCLSH_CMD=${with_tclsh} - #msg-result "using tclsh at \"$TCLSH_CMD\"" - # XXX if test x"${use_tcl}" = "xyes"; then - #set with_tcl `${with_tclsh} <${srcdir}/tool/find_tclconfig.tcl` - # XXX if test x"${with_tcl}" != x; then - #msg-result "$TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}" - # XXX else - #msg-result Warning: "$TCLSH_CMD is unable to recommend a tclConfig.sh" - #set use_tcl no - # XXX fi - # XXX fi - # XXX fi + set with_tclsh [opt-val with-tclsh] + set with_tcl [opt-val with-tcl] + + if {"" eq $with_tclsh && "" eq $with_tcl} { + # XXX if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then + # XXX AC_CHECK_PROGS TCLSH_CMD tclsh8.6 tclsh tclsh9.0 none + #set with_tclsh ${TCLSH_CMD} + # XXX fi + set with_tclsh [hwaci-first-bin-of tclsh8.6 tclsh tclsh9.0] + } + + if {"" ne $with_tclsh } { + # XXX if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then + # XXX TCLSH_CMD=${with_tclsh} + set tclsh $with_tclsh + puts "using tclsh at \"$tclsh\"" + if {$use_tcl} { + # XXX if test x"${use_tcl}" = "xyes"; then + #set with_tcl `${with_tclsh} <${srcdir}/tool/find_tclconfig.tcl` + # XXX if test x"${with_tcl}" != x; then + #msg-result "$TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}" + # XXX else + #msg-result Warning: "$TCLSH_CMD is unable to recommend a tclConfig.sh" + #set use_tcl no + # XXX fi + # XXX fi + } + # XXX fi + } + + # XXX if test x"${use_tcl}" = "xyes"; then # XXX if test x"${with_tcl}" != x; then # XXX if test -r ${with_tcl}/tclConfig.sh; then @@ -414,7 +440,9 @@ if {1} { # XXX done # XXX TCLLIBDIR="${TCLLIBDIR}/sqlite3" # XXX fi -} + + unset tEnable with_tclsh with_tcl +}; # end of tcl msg-checking "Support threadsafe operation? " @@ -744,24 +772,28 @@ foreach {boolFlag featureFlag ifSetEvalThis} { define ENABLE_SHARED $enable_shared +if {1} { + # for sqlite_cfg.h + define PACKAGE_URL {https://sqlite.org} + define PACKAGE_VERSION [get-define VERSION] +} + ######### # Generate the output files. # if {1} { - # mystery: why are defines (srcdir, top_srcdir) both absolute when emitted - # from make-config-header but relative when emitted via make-template? - hwaci-make-from-dot-in Makefile hwaci-make-from-dot-in sqlite3.pc - #hwaci-make-from-dot-in ext/wasm/GNUmakefile - if {0} { - # output from make-config-header is not quite the same as that from the - # autotools. We may need to write a custom replacement. - # hwaci-make-from-dot-in sqlite_cfg.h - # make-config-header sqlite_cfg.h -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* -none * - # make-config-header sqlite_cfg.h -bare {SIZEOF_* HAVE_*} -none * - # make-config-header sqlite_cfg.h + # hwaci-make-from-dot-in sqlite_cfg.h + if {1} { + hwaci-make-from-dot-in sqlite_cfg.h + } else { + make-config-header -bare {SIZEOF_* HAVE_DECL_*} \ + -auto {HAVE_* PACKAGE_*} -none * } + # make-config-header sqlite_cfg.h -bare {SIZEOF_* HAVE_*} -none * + # make-config-header sqlite_cfg.h + #hwaci-make-from-dot-in ext/wasm/GNUmakefile } set oFF [get-define OPT_FEATURE_FLAGS] diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 570fbf4a84..29c7c3da81 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -95,6 +95,19 @@ proc hwaci-bin-define {binName {defName {}}} { return $check } +######################################################################## +# Each argument is passed to cc-path-progs. If that function returns +# true, the full path to that binary is returned. If no matches are +# found, "" is returned. +proc hwaci-first-bin-of {args} { + foreach b $args { + if {[cc-path-progs $b]} { + return [get-define [string toupper $b]] + } + } + return "" +} + ######################################################################## # Looks for `bash` binary and dies if not found. On success, defines # BIN_BASH to the full path to bash and returns that value. We diff --git a/manifest b/manifest index 76a18386e7..4f7bc2d529 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Re-indent\ssome\stcl\scode. -D 2024-09-26T21:09:22.501 +C Get\sthe\sgenerated\s.c/.h\sfiles\sgenerating. +D 2024-09-27T01:00:32.301 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 9f2eb42f8ace9c686b602f2142325a38417711e3f6aa4355dd904ab21ec77478 +F Makefile.in baef1f3e06a77386d0ec33ad3f220656b8987e876fb821c03332e4888f43bf07 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 32b757ecdb2e2b83190dd160dcff9e508fc97c70f9a59a0fd789cfbf614542f5 +F auto.def dfd9fca19386af90ef9a32b3e6428e9c868fe5b98bec2a5d46bf397617d86b5d F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl ed4b9197d06dce03938e9f0b59a0d605a37761f23098b8c63fc581c5c0eda1ef +F autosetup/hwaci-common.tcl e47d127a33de5729ebcc0fd83a6e09c332b1867b43abdb90a0da76bdc536cfee F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -717,7 +717,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 +F sqlite_cfg.h.in e820a04b0ea3da638858927513f5ac8a5e8b9a822b531ebfeeac32a2fa396dcd F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 30bf40ec4208ead9e977bec017bccc8a9681820936e38ca5a4a7443100a6d5c5 F src/attach.c 08235ab62ed5ccc93c22bf36e640d19effcd632319615851bccf724ec9341333 @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P feea65bcd54f9266445bc4d65ea5e3cfadee8e3abff5b682e31cdc0034354fbf -R 43bb192919b9c029a6389c0f03cc26a7 +P 34ea629a07bfb00c86df7c62462bf2d699347c34dcb7656c86f5f76b52d33b30 +R 8ff7b530b7faebb0e1dc044ed295782f U stephan -Z d85ef6beb4955ef9438b7cb0c396c13b +Z bb9da4d7a0fa389697e835ecfc66d9c6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index adfff17c71..b1a12a15ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34ea629a07bfb00c86df7c62462bf2d699347c34dcb7656c86f5f76b52d33b30 +e890c8508da4e126f43c61f809f750d6cb2d7d01600fe2173fbcd7dabbfce0fd diff --git a/sqlite_cfg.h.in b/sqlite_cfg.h.in index 3adea09936..8a6b5cc7a3 100644 --- a/sqlite_cfg.h.in +++ b/sqlite_cfg.h.in @@ -1,134 +1,179 @@ -/* sqlite_cfg.h.in. Generated from configure.ac by autoheader. */ +/* sqlite_cfg.h.in - autosetup input template for sqlite_cfg.h. */ /* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H +/*#undef HAVE_DLFCN_H*/ +@if HAVE_DLFCN_H +#define HAVE_DLFCN_H @HAVE_DLFCN_H@ +@endif /* Define to 1 if you have the `fdatasync' function. */ -#undef HAVE_FDATASYNC +/*#undef HAVE_FDATASYNC*/ +#define HAVE_FDATASYNC @HAVE_FDATASYNC@ /* Define to 1 if you have the `gmtime_r' function. */ -#undef HAVE_GMTIME_R +/*#undef HAVE_GMTIME_R*/ +#define HAVE_GMTIME_R @HAVE_GMTIME_R@ /* Define to 1 if the system has the type `int16_t'. */ -#undef HAVE_INT16_T +/*#undef HAVE_INT16_T*/ +#define HAVE_INT16_T @HAVE_INT16_T@ /* Define to 1 if the system has the type `int32_t'. */ -#undef HAVE_INT32_T +/*#undef HAVE_INT32_T*/ +#define HAVE_INT32_T @HAVE_INT32_T@ /* Define to 1 if the system has the type `int64_t'. */ -#undef HAVE_INT64_T +/*#undef HAVE_INT64_T*/ +#define HAVE_INT64_T @HAVE_INT64_T@ /* Define to 1 if the system has the type `int8_t'. */ -#undef HAVE_INT8_T +/*#undef HAVE_INT8_T*/ +#define HAVE_INT8_T @HAVE_INT8_T@ /* Define to 1 if the system has the type `intptr_t'. */ -#undef HAVE_INTPTR_T +/*#undef HAVE_INTPTR_T*/ +#define HAVE_INTPTR_T @HAVE_INTPTR_T@ /* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H +/*#undef HAVE_INTTYPES_H*/ +#define HAVE_INTTYPES_H @HAVE_INTTYPES_H@ /* Define to 1 if you have the `isnan' function. */ -#undef HAVE_ISNAN +/*#undef HAVE_ISNAN*/ +#define HAVE_ISNAN @HAVE_ISNAN@ /* Define to 1 if you have the `localtime_r' function. */ -#undef HAVE_LOCALTIME_R +/*#undef HAVE_LOCALTIME_R*/ +#define HAVE_LOCALTIME_R @HAVE_LOCALTIME_R@ /* Define to 1 if you have the `localtime_s' function. */ -#undef HAVE_LOCALTIME_S +/*#undef HAVE_LOCALTIME_S*/ +#define HAVE_LOCALTIME_S @HAVE_LOCALTIME_S@ /* Define to 1 if you have the header file. */ -#undef HAVE_MALLOC_H +/*#undef HAVE_MALLOC_H*/ +#define HAVE_MALLOC_H @HAVE_MALLOC_H@ /* Define to 1 if you have the `malloc_usable_size' function. */ -#undef HAVE_MALLOC_USABLE_SIZE +/*#undef HAVE_MALLOC_USABLE_SIZE*/ +#define HAVE_MALLOC_USABLE_SIZE @HAVE_MALLOC_USABLE_SIZE@ /* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H +/*#undef HAVE_MEMORY_H*/ +#define HAVE_MEMORY_H @HAVE_MEMORY_H@ /* Define to 1 if you have the `pread' function. */ -#undef HAVE_PREAD +/*#undef HAVE_PREAD*/ +#define HAVE_PREAD @HAVE_PREAD@ /* Define to 1 if you have the `pread64' function. */ -#undef HAVE_PREAD64 +/*#undef HAVE_PREAD64*/ +#define HAVE_PREAD64 @HAVE_PREAD64@ /* Define to 1 if you have the `pwrite' function. */ -#undef HAVE_PWRITE +/*#undef HAVE_PWRITE*/ +#define HAVE_PWRITE @HAVE_PWRITE@ /* Define to 1 if you have the `pwrite64' function. */ -#undef HAVE_PWRITE64 +/*#undef HAVE_PWRITE64*/ +#define HAVE_PWRITE64 @HAVE_PWRITE64@ /* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H +/*#undef HAVE_STDINT_H*/ +#define HAVE_STDINT_H @HAVE_STDINT_H@ /* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H +/*#undef HAVE_STDLIB_H*/ +#define HAVE_STDLIB_H @HAVE_STDLIB_H@ /* Define to 1 if you have the `strchrnul' function. */ -#undef HAVE_STRCHRNUL +/*#undef HAVE_STRCHRNUL*/ +#define HAVE_STRCHRNUL @HAVE_STRCHRNUL@ /* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H +/*#undef HAVE_STRINGS_H*/ +#define HAVE_STRINGS_H @HAVE_STRINGS_H@ /* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H +/*#undef HAVE_STRING_H*/ +#define HAVE_STRING_H @HAVE_STRING_H@ /* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H +/*#undef HAVE_SYS_STAT_H*/ +#define HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ /* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H +/*#undef HAVE_SYS_TYPES_H*/ +#define HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ /* Define to 1 if the system has the type `uint16_t'. */ -#undef HAVE_UINT16_T +/*#undef HAVE_UINT16_T*/ +#define HAVE_UINT16_T @HAVE_UINT16_T@ /* Define to 1 if the system has the type `uint32_t'. */ -#undef HAVE_UINT32_T +/*#undef HAVE_UINT32_T*/ +#define HAVE_UINT32_T @HAVE_UINT32_T@ /* Define to 1 if the system has the type `uint64_t'. */ -#undef HAVE_UINT64_T +/*#undef HAVE_UINT64_T*/ +#define HAVE_UINT64_T @HAVE_UINT64_T@ /* Define to 1 if the system has the type `uint8_t'. */ -#undef HAVE_UINT8_T +/*#undef HAVE_UINT8_T*/ +#define HAVE_UINT8_T @HAVE_UINT8_T@ /* Define to 1 if the system has the type `uintptr_t'. */ -#undef HAVE_UINTPTR_T +/*#undef HAVE_UINTPTR_T*/ +#define HAVE_UINTPTR_T @HAVE_UINTPTR_T@ /* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H +/*#undef HAVE_UNISTD_H*/ +#define HAVE_UNISTD_H @HAVE_UNISTD_H@ /* Define to 1 if you have the `usleep' function. */ -#undef HAVE_USLEEP +/*#undef HAVE_USLEEP*/ +#define HAVE_USLEEP @HAVE_USLEEP@ /* Define to 1 if you have the `utime' function. */ -#undef HAVE_UTIME +/*#undef HAVE_UTIME*/ +#define HAVE_UTIME @HAVE_UTIME@ /* Define to 1 if you have the header file. */ -#undef HAVE_ZLIB_H +/*#undef HAVE_ZLIB_H*/ +#define HAVE_ZLIB_H @HAVE_ZLIB_H@ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ -#undef LT_OBJDIR +/*#undef LT_OBJDIR*/ +/*#define LT_OBJDIR @LT_OBJDIR@*/ /* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT +/*#undef PACKAGE_BUGREPORT*/ +#define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ -#undef PACKAGE_NAME +/*#undef PACKAGE_NAME*/ +#define PACKAGE_NAME "sqlite" /* Define to the full name and version of this package. */ -#undef PACKAGE_STRING +/*#undef PACKAGE_STRING*/ +#define PACKAGE_STRING "sqlite @RELEASE@" /* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME +/*#undef PACKAGE_TARNAME*/ +#define PACKAGE_TARNAME "sqlite" /* Define to the home page for this package. */ -#undef PACKAGE_URL +/*#undef PACKAGE_URL*/ +#define PACKAGE_URL "" /* Define to the version of this package. */ -#undef PACKAGE_VERSION +/*#undef PACKAGE_VERSION*/ +#define PACKAGE_VERSION @VERSION@ /* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS +/*#undef STDC_HEADERS*/ +#define STDC_HEADERS 1 /* @STDC_HEADERS@ */ /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE @@ -136,7 +181,14 @@ #endif /* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS +/*#undef _FILE_OFFSET_BITS*/ +/*#define _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@*/ +/*@if _FILE_OFFSET_BITS != ""*/ +/*#define _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@*/ +/*@endif*/ /* Define for large files, on AIX-style hosts. */ -#undef _LARGE_FILES +/*#undef _LARGE_FILES*/ +/*@if _LARGE_FILES*/ +/*#define _LARGE_FILES @_LARGE_FILES@*/ +/*@endif*/ From 42aa26a6073d9e25592dab30f13d82a61e52af8f Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 01:04:09 +0000 Subject: [PATCH 026/522] Remove some gratuitous overengineering before it can spread. FossilOrigin-Name: 94340011ed903434cd12ca982f226c548f7ec43019d449b4ee12e18ec886fb27 --- Makefile.in | 6 ------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 60dfbd13a1..2b74498e62 100644 --- a/Makefile.in +++ b/Makefile.in @@ -916,17 +916,11 @@ sqlite3ext.h: .target_source lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o $@ $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . -@if BUILD_EXEEXT ne "" -lemon: lemon$(BEXE) -@endif # Rules to build the program that generates the source-id # mksourceid$(BEXE): $(TOP)/tool/mksourceid.c $(BCC) -o $@ $(TOP)/tool/mksourceid.c -@if BUILD_EXEEXT ne "" -mksourceid: mksourceid$(BEXE) -@endif #XX## Rules to build individual *.o files from generated *.c files. This #XX## applies to: diff --git a/manifest b/manifest index 4f7bc2d529..ac1cf1f641 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Get\sthe\sgenerated\s.c/.h\sfiles\sgenerating. -D 2024-09-27T01:00:32.301 +C Remove\ssome\sgratuitous\soverengineering\sbefore\sit\scan\sspread. +D 2024-09-27T01:04:09.944 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in baef1f3e06a77386d0ec33ad3f220656b8987e876fb821c03332e4888f43bf07 +F Makefile.in 32bcabed9be12d736ceada701df2976089dc3d072a2e4747ea7ef52a589092db F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 34ea629a07bfb00c86df7c62462bf2d699347c34dcb7656c86f5f76b52d33b30 -R 8ff7b530b7faebb0e1dc044ed295782f +P e890c8508da4e126f43c61f809f750d6cb2d7d01600fe2173fbcd7dabbfce0fd +R 4412cd3ef719ad30399056a948ff39f5 U stephan -Z bb9da4d7a0fa389697e835ecfc66d9c6 +Z 4be646b67bd21ccf89d6b050e9348ec1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b1a12a15ba..18a1b6424a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e890c8508da4e126f43c61f809f750d6cb2d7d01600fe2173fbcd7dabbfce0fd +94340011ed903434cd12ca982f226c548f7ec43019d449b4ee12e18ec886fb27 From 69f2da0eed4d231e58836113efd304335b7d01ee Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 01:25:49 +0000 Subject: [PATCH 027/522] Experimentally build shell.c using the autosetup-provided JimTCL. FossilOrigin-Name: 5bd62cdbc4b188a59c83fb04685f9967d6a5270772eb48f950a5d86409eb8a1b --- Makefile.in | 17 +++++++++++++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2b74498e62..2fe451b2b8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -760,6 +760,16 @@ sourcetest: srcck1$(BEXE) sqlite3.c src-verify: $(TOP)/tool/src-verify.c $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c + + +# JimTCL is part of the autosetup suite and is suitable for certain +# in-tree TCL jobs, but it requires that we build it with non-default +# flags. +# +JIMSH = @srcdir@/jimsh +$(JIMSH): $(TOP)/autosetup/jimsh0.c Makefile + $(BCC) -o $(JIMSH) -DHAVE_REALPATH $< + #XX# #XX#verify-source: ./src-verify #XX# ./src-verify $(TOP) @@ -1251,8 +1261,8 @@ SHELL_DEP = \ $(TOP)/src/test_windirent.c \ $(TOP)/src/test_windirent.h -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(JIMSH) # has_tclsh84 + $(JIMSH) $(TOP)/tool/mkshellc.tcl >shell.c #XX# #XX# #XX# @@ -1668,7 +1678,6 @@ fts5.c: $(FTS5_SRC) has_tclsh84 #XX#tclextension-list: #XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info - # Remove build products sufficient so that subsequent makes will recompile # everything from scratch. Do not remove: # @@ -1702,7 +1711,7 @@ clean: tidy # Clean up everything. No exceptions. # distclean: clean - rm -f sqlite_cfg.h config.log config.status Makefile $(LIBTOOL) + rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile $(LIBTOOL) #XX## #XX## Windows section diff --git a/manifest b/manifest index ac1cf1f641..9968255db6 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Remove\ssome\sgratuitous\soverengineering\sbefore\sit\scan\sspread. -D 2024-09-27T01:04:09.944 +C Experimentally\sbuild\sshell.c\susing\sthe\sautosetup-provided\sJimTCL. +D 2024-09-27T01:25:49.563 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 32bcabed9be12d736ceada701df2976089dc3d072a2e4747ea7ef52a589092db +F Makefile.in bcd7cdc63f4c1564ee0c6fdb7ff197abd566ce4f668f0d198fbbe592de3852df F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e890c8508da4e126f43c61f809f750d6cb2d7d01600fe2173fbcd7dabbfce0fd -R 4412cd3ef719ad30399056a948ff39f5 +P 94340011ed903434cd12ca982f226c548f7ec43019d449b4ee12e18ec886fb27 +R 1e4458ab0745592e456364479f74d688 U stephan -Z 4be646b67bd21ccf89d6b050e9348ec1 +Z 14336e6ef7079fcb9bc0bec73aa50ed7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 18a1b6424a..4d49c5ea35 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94340011ed903434cd12ca982f226c548f7ec43019d449b4ee12e18ec886fb27 +5bd62cdbc4b188a59c83fb04685f9967d6a5270772eb48f950a5d86409eb8a1b From 9ce9ee68190348134aee087dfa8e8be861d16639 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 01:30:34 +0000 Subject: [PATCH 028/522] Generate sqlite3.h/.c with jimsh, somewhat to my surprise. FossilOrigin-Name: c365d8e1f7aa19e424f60f976db683c3ccb489900124811541e02d47f9a1cbe3 --- Makefile.in | 10 ++++++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2fe451b2b8..80ae609016 100644 --- a/Makefile.in +++ b/Makefile.in @@ -890,8 +890,9 @@ has_tclsh85: cp fts5.c fts5.h tsrc touch .target_source -sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) +sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify \ + $(JIMSH) # has_tclsh84 + $(JIMSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . @@ -1215,8 +1216,9 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) cp $(TOP)/src/parse.y . ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ + $(TOP)/VERSION $(JIMSH) # has_tclsh84 + $(JIMSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h #XX#sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 #XX# echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ diff --git a/manifest b/manifest index 9968255db6..92f082e4d1 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Experimentally\sbuild\sshell.c\susing\sthe\sautosetup-provided\sJimTCL. -D 2024-09-27T01:25:49.563 +C Generate\ssqlite3.h/.c\swith\sjimsh,\ssomewhat\sto\smy\ssurprise. +D 2024-09-27T01:30:34.027 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in bcd7cdc63f4c1564ee0c6fdb7ff197abd566ce4f668f0d198fbbe592de3852df +F Makefile.in f4756fd992cd7b87c70c5cdbe8c9b1465c00b2b815f9421057968187477a03b9 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 94340011ed903434cd12ca982f226c548f7ec43019d449b4ee12e18ec886fb27 -R 1e4458ab0745592e456364479f74d688 +P 5bd62cdbc4b188a59c83fb04685f9967d6a5270772eb48f950a5d86409eb8a1b +R ef803379c968170516afffb5463c2345 U stephan -Z 14336e6ef7079fcb9bc0bec73aa50ed7 +Z 9899a937a86e0eff95554dd8ceadaf0f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4d49c5ea35..cb275555ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bd62cdbc4b188a59c83fb04685f9967d6a5270772eb48f950a5d86409eb8a1b +c365d8e1f7aa19e424f60f976db683c3ccb489900124811541e02d47f9a1cbe3 From 474cdc54ef4978816b337c9991201b1225b0cac4 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 01:42:52 +0000 Subject: [PATCH 029/522] Run all of the TCL-based code generators using JimTCL. FossilOrigin-Name: 3193b86a91d8096be68cb83133c7665129694521d7da81bf725e285c229271f7 --- Makefile.in | 28 +++++++++++++++------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Makefile.in b/Makefile.in index 80ae609016..abe06b63cc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -128,7 +128,8 @@ HAVE_TCL = @HAVE_TCL@ # This is the command to use for tclsh - normally just "tclsh", but we may # know the specific version we want to use # -TCLSH_CMD = @TCLSH_CMD@ +# TCLSH_CMD = @TCLSH_CMD@ +TCLSH_CMD = exit 1 # Additional options when running tests using testrunner.tcl # This is usually either blank, or else --status @@ -880,12 +881,12 @@ has_tclsh85: # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl has_tclsh84 fts5.c +.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(JIMSH) # has_tclsh84 rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - $(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new + $(JIMSH) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new mv vdbe.new tsrc/vdbe.c cp fts5.c fts5.h tsrc touch .target_source @@ -896,14 +897,14 @@ sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify \ cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . -sqlite3r.h: sqlite3.h has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h +sqlite3r.h: sqlite3.h $(JIMSH) # has_tclsh84 + $(JIMSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84 +sqlite3r.c: sqlite3.c sqlite3r.h $(JIMSH) # has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(JIMSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . @@ -1202,11 +1203,12 @@ mksourceid$(BEXE): $(TOP)/tool/mksourceid.c # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl has_tclsh84 - $(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(JIMSH) # has_tclsh84 + $(JIMSH) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c -opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl has_tclsh84 - cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h +opcodes.h: parse.h $(TOP)/src/vdbe.c \ + $(TOP)/tool/mkopcodeh.tcl $(JIMSH) # has_tclsh84 + cat parse.h $(TOP)/src/vdbe.c | $(JIMSH) $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. # @@ -1351,8 +1353,8 @@ fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) has_tclsh84 - $(TCLSH_CMD) $(TOP)/ext/fts5/tool/mkfts5c.tcl +fts5.c: $(FTS5_SRC) $(JIMSH) # has_tclsh84 + $(JIMSH) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . #XX#fts5.lo: fts5.c $(HDR) $(EXTHDR) diff --git a/manifest b/manifest index 92f082e4d1..4641f3848d 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Generate\ssqlite3.h/.c\swith\sjimsh,\ssomewhat\sto\smy\ssurprise. -D 2024-09-27T01:30:34.027 +C Run\sall\sof\sthe\sTCL-based\scode\sgenerators\susing\sJimTCL. +D 2024-09-27T01:42:52.890 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in f4756fd992cd7b87c70c5cdbe8c9b1465c00b2b815f9421057968187477a03b9 +F Makefile.in ab329ecf862e1fca897c944c638ab7e4501ce963e68bc36189409f2da0fa805d F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5bd62cdbc4b188a59c83fb04685f9967d6a5270772eb48f950a5d86409eb8a1b -R ef803379c968170516afffb5463c2345 +P c365d8e1f7aa19e424f60f976db683c3ccb489900124811541e02d47f9a1cbe3 +R 6deba968ac63d8a58c958b1d9fa280a1 U stephan -Z 9899a937a86e0eff95554dd8ceadaf0f +Z 4c81e3416eed085f7fee6ec13899f0d9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cb275555ed..3bb145c9c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c365d8e1f7aa19e424f60f976db683c3ccb489900124811541e02d47f9a1cbe3 +3193b86a91d8096be68cb83133c7665129694521d7da81bf725e285c229271f7 From 587256a634ffdd0efa70bfc7deca73f315537a48 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 02:35:41 +0000 Subject: [PATCH 030/522] Tweak build to fall back to system-side tclsh if we cannot find realpath() or _fullpath() for JimTCL (needed for some of the code generator scripts to work). FossilOrigin-Name: b31dbb9945d0ac5e22d146565443bcdc0dd1a1c83034cfb5867b2303ada2bdea --- Makefile.in | 50 +++++++++++++++++++++++++++----------------------- auto.def | 28 +++++++++++++++++++++------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 56 insertions(+), 38 deletions(-) diff --git a/Makefile.in b/Makefile.in index abe06b63cc..0b76e01e3f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -128,8 +128,7 @@ HAVE_TCL = @HAVE_TCL@ # This is the command to use for tclsh - normally just "tclsh", but we may # know the specific version we want to use # -# TCLSH_CMD = @TCLSH_CMD@ -TCLSH_CMD = exit 1 +TCLSH_CMD = @TCLSH_CMD@ # Additional options when running tests using testrunner.tcl # This is usually either blank, or else --status @@ -692,7 +691,7 @@ libtclsqlite3.la_1 = libtclsqlite3.la # are what get build when you type just "make" with no arguments. # -all: sqlite3.h +all: sqlite3.h sqlite3.c shell.c #all: libsqlite3.la $(SQLITE3_SHELL_TARGET) \ #XX# $(libtclsqlite3.la_$(HAVE_TCL)) @@ -768,8 +767,13 @@ src-verify: $(TOP)/tool/src-verify.c # flags. # JIMSH = @srcdir@/jimsh +@if CFLAGS_JIMSH $(JIMSH): $(TOP)/autosetup/jimsh0.c Makefile - $(BCC) -o $(JIMSH) -DHAVE_REALPATH $< + $(BCC) -o $(JIMSH) @CFLAGS_JIMSH@ $< +@endif + +TCL_GENERATOR = @TCL_GENERATOR@ +$(TCL_GENERATOR): #XX# #XX#verify-source: ./src-verify @@ -881,30 +885,30 @@ has_tclsh85: # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(JIMSH) # has_tclsh84 +.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(TCL_GENERATOR) # has_tclsh84 rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - $(JIMSH) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new + $(TCL_GENERATOR) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new mv vdbe.new tsrc/vdbe.c cp fts5.c fts5.h tsrc touch .target_source sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify \ - $(JIMSH) # has_tclsh84 - $(JIMSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(TCL_GENERATOR) # has_tclsh84 + $(TCL_GENERATOR) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . -sqlite3r.h: sqlite3.h $(JIMSH) # has_tclsh84 - $(JIMSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h +sqlite3r.h: sqlite3.h $(TCL_GENERATOR) # has_tclsh84 + $(TCL_GENERATOR) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -sqlite3r.c: sqlite3.c sqlite3r.h $(JIMSH) # has_tclsh84 +sqlite3r.c: sqlite3.c sqlite3r.h $(TCL_GENERATOR) # has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(JIMSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(TCL_GENERATOR) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . @@ -1203,12 +1207,12 @@ mksourceid$(BEXE): $(TOP)/tool/mksourceid.c # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(JIMSH) # has_tclsh84 - $(JIMSH) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(TCL_GENERATOR) # has_tclsh84 + $(TCL_GENERATOR) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c opcodes.h: parse.h $(TOP)/src/vdbe.c \ - $(TOP)/tool/mkopcodeh.tcl $(JIMSH) # has_tclsh84 - cat parse.h $(TOP)/src/vdbe.c | $(JIMSH) $(TOP)/tool/mkopcodeh.tcl >opcodes.h + $(TOP)/tool/mkopcodeh.tcl $(TCL_GENERATOR) # has_tclsh84 + cat parse.h $(TOP)/src/vdbe.c | $(TCL_GENERATOR) $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. # @@ -1219,8 +1223,8 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ - $(TOP)/VERSION $(JIMSH) # has_tclsh84 - $(JIMSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h + $(TOP)/VERSION $(TCL_GENERATOR) # has_tclsh84 + $(TCL_GENERATOR) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h #XX#sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 #XX# echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ @@ -1265,8 +1269,8 @@ SHELL_DEP = \ $(TOP)/src/test_windirent.c \ $(TOP)/src/test_windirent.h -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(JIMSH) # has_tclsh84 - $(JIMSH) $(TOP)/tool/mkshellc.tcl >shell.c +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(TCL_GENERATOR) # has_tclsh84 + $(TCL_GENERATOR) $(TOP)/tool/mkshellc.tcl >shell.c #XX# #XX# #XX# @@ -1353,8 +1357,8 @@ fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) $(JIMSH) # has_tclsh84 - $(JIMSH) $(TOP)/ext/fts5/tool/mkfts5c.tcl +fts5.c: $(FTS5_SRC) $(TCL_GENERATOR) # has_tclsh84 + $(TCL_GENERATOR) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . #XX#fts5.lo: fts5.c $(HDR) $(EXTHDR) @@ -1715,7 +1719,7 @@ clean: tidy # Clean up everything. No exceptions. # distclean: clean - rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile $(LIBTOOL) + rm -f sqlite_cfg.h config.log config.status $(TCL_GENERATOR) Makefile $(LIBTOOL) #XX## #XX## Windows section diff --git a/auto.def b/auto.def index 4b81ce9f16..4d96682408 100644 --- a/auto.def +++ b/auto.def @@ -87,7 +87,6 @@ if {![file exists sqlite3.pc.in]} { cc-check-tools ld ar -# # The build process allows for using a cross-compiler. But the default # action is to target the same platform that we are running on. The # configure script needs to discover the following properties of the @@ -245,6 +244,20 @@ if {1} { unset wasiSdkDir }; # --wasi-sdk-dir +######## +# Check which TCL to use as a code generator +define CFLAGS_JIMSH {} +puts "Looking for path-resolution function for JimTCL... " +define TCL_GENERATOR "\$(JIMSH)" +if {[cc-check-functions realpath]} { + define-append CFLAGS_JIMSH -DHAVE_REALPATH +} elseif {[cc-check-functions _fullpath]} { + # _fullpath() is a Windows API + define-append CFLAGS_JIMSH -DHAVE__FULLPATH +} else { + puts "Cannot find realpath() or _fullpath(). Falling back to system's TCL for code generation." +} + ######### # Enable large file support (if special flags are necessary) cc-check-lfs @@ -295,18 +308,19 @@ hwaci-if-opt-truthy with-debug { msg-result no } -if {1} { - # Temporary quick hack for finding "a" tclsh. TODO is port the - # full-featured check which lives in the elseif part of this block. +define HAVE_TCL 0 +define TCLSH_CMD {exit 1} +if {"" eq [get-define CFLAGS_JIMSH]} { + # We can't use JimTCL for in-tree generation on this system, so... # - # Also TODO is figure out whether we can use jimtcl for our internal - # build-tool uses (as opposed to testing purposes, which requires - # the tcl SQLite module). + # Temporary solution for finding "a" tclsh. TODO is port the + # full-featured check which lives in the elseif part of this block. set tclsh [hwaci-first-bin-of tclsh8.6 tclsh tclsh9.0] if {"" eq $tclsh} { user-error "Cannot find tclsh, which is required to build certain files." } define TCLSH_CMD $tclsh + define TCL_GENERATOR $tclsh define HAVE_TCL 0 ; # until the following elseif block is ported } elseif {0} { # Porting this section of configure.ac is going to be a bit of a slog... diff --git a/manifest b/manifest index 4641f3848d..a38775c4c1 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Run\sall\sof\sthe\sTCL-based\scode\sgenerators\susing\sJimTCL. -D 2024-09-27T01:42:52.890 +C Tweak\sbuild\sto\sfall\sback\sto\ssystem-side\stclsh\sif\swe\scannot\sfind\srealpath()\sor\s_fullpath()\sfor\sJimTCL\s(needed\sfor\ssome\sof\sthe\scode\sgenerator\sscripts\sto\swork). +D 2024-09-27T02:35:41.157 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in ab329ecf862e1fca897c944c638ab7e4501ce963e68bc36189409f2da0fa805d +F Makefile.in 9bdbffc3a2c1b609d855b6b6daa7769b8a12cd56d156f99420a2a9243831bd0c F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def dfd9fca19386af90ef9a32b3e6428e9c868fe5b98bec2a5d46bf397617d86b5d +F auto.def 73d6e09e94dbe2a11c26524d2448c81a7bc5fdb52c2378396138d57ddbf058bb F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c365d8e1f7aa19e424f60f976db683c3ccb489900124811541e02d47f9a1cbe3 -R 6deba968ac63d8a58c958b1d9fa280a1 +P 3193b86a91d8096be68cb83133c7665129694521d7da81bf725e285c229271f7 +R c9ebfe69a4af214d35d57aa4421c3f6e U stephan -Z 4c81e3416eed085f7fee6ec13899f0d9 +Z 2d082ca6d901dc26c8447cb73e030ab8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3bb145c9c5..67187e8b40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3193b86a91d8096be68cb83133c7665129694521d7da81bf725e285c229271f7 +b31dbb9945d0ac5e22d146565443bcdc0dd1a1c83034cfb5867b2303ada2bdea From 3c6db6831dd071ea457fef748548c58d7d22a453 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 03:04:16 +0000 Subject: [PATCH 031/522] General auto.def cleanups, mostly around JimTCL. Swap out impl for the sqlite_cfg.h generator - this approach is lower-maintenance (requires no hand-maintained template) but may not be compatible with expectations. FossilOrigin-Name: da197946dbaacedb6e74827db9b5dd195d4aaf78ad9411a14aca732ab77917c6 --- auto.def | 62 ++++++++++++++++++++++++++++++++++++--------------- manifest | 12 +++++----- manifest.uuid | 2 +- 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/auto.def b/auto.def index 4d96682408..d0c7be78b7 100644 --- a/auto.def +++ b/auto.def @@ -175,7 +175,7 @@ if {"" eq [hwaci-bin-define install]} { msg-result "Cannot find install binary, so 'make install' will not work." } -######### +######################################################################## # Locate a compiler for the build machine. This compiler should # generate command-line programs that run on the build machine. # @@ -195,7 +195,7 @@ if {"" eq [hwaci-bin-define install]} { define BUILD_CC [get-define CC_FOR_BUILD] define BUILD_CFLAGS [get-env CFLAGS {-g}] -########## +######################################################################## # Handle --with-wasi-sdk=DIR # # This must be early because it may change the toolchain and several @@ -244,7 +244,7 @@ if {1} { unset wasiSdkDir }; # --wasi-sdk-dir -######## +######################################################################## # Check which TCL to use as a code generator define CFLAGS_JIMSH {} puts "Looking for path-resolution function for JimTCL... " @@ -258,11 +258,11 @@ if {[cc-check-functions realpath]} { puts "Cannot find realpath() or _fullpath(). Falling back to system's TCL for code generation." } -######### +######################################################################## # Enable large file support (if special flags are necessary) cc-check-lfs -######### +######################################################################## # Check for needed/wanted data types cc-check-types int8_t int16_t int32_t int64_t intptr_t \ uint8_t uint16_t uint32_t uint64_t uintptr_t @@ -274,7 +274,7 @@ cc-check-function-in-lib fdatasync rt define LDFLAGS_FDATASYNC [get-define lib_fdatasync] undefine lib_fdatasync -######### +######################################################################## # Check for needed/wanted headers cc-check-includes \ sys/types.h sys/stat.h dlfcn.h unistd.h \ @@ -282,6 +282,9 @@ cc-check-includes \ string.h strings.h \ stdint.h inttypes.h +# These are optional for JimTCL: +cc-check-includes dirent.h sys/time.h + if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { # TODO: port over the more sophisticated zlib search from the fossil auto.def define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" @@ -308,6 +311,8 @@ hwaci-if-opt-truthy with-debug { msg-result no } +######################################################################## +# TCL... define HAVE_TCL 0 define TCLSH_CMD {exit 1} if {"" eq [get-define CFLAGS_JIMSH]} { @@ -364,7 +369,6 @@ if {"" eq [get-define CFLAGS_JIMSH]} { # XXX fi } - # XXX if test x"${use_tcl}" = "xyes"; then # XXX if test x"${with_tcl}" != x; then # XXX if test -r ${with_tcl}/tclConfig.sh; then @@ -459,6 +463,8 @@ if {"" eq [get-define CFLAGS_JIMSH]} { }; # end of tcl +######################################################################## +# Thread safety? msg-checking "Support threadsafe operation? " hwaci-if-opt-truthy threadsafe { msg-result yes @@ -475,7 +481,7 @@ hwaci-if-opt-truthy threadsafe { define LDFLAGS_PTHREAD "" } -########## +######################################################################## # Do we want to support release? # # Maintenance note: this might be irrelevant with an autosetup port, @@ -503,7 +509,7 @@ if {0} { # XXX AC_SUBST ALLOWRELEASE } -########## +######################################################################## # Do we want temporary databases in memory? # if {1} { @@ -729,7 +735,7 @@ if {0} { # XXX BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS } -########## +######################################################################## # Emscripten SDK for building the web-based wasm components. # if {[hwaci-check-emsdk]} { @@ -784,25 +790,45 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } } -define ENABLE_SHARED $enable_shared +######################################################################## +# Extend JimTCL a bit... +if {"" ne [get-define CFLAGS_JIMSH]} { + foreach jimFunc {opendir fsync isascii} { + if {[cc-check-functions $jimFunc]} { + define-append CFLAGS_JIMSH -DHAVE_[string toupper $jimFunc] + } + } + #foreach jimDef {HAVE_UNISTD_H HAVE_DIRENT_H} { + # if {[is-defined $jimDef]} { + # define-append CFLAGS_JIMSH -D$jimDef + # } + #} + define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available +}; # JimTCL -if {1} { - # for sqlite_cfg.h - define PACKAGE_URL {https://sqlite.org} - define PACKAGE_VERSION [get-define VERSION] -} +define ENABLE_SHARED $enable_shared -######### +######################################################################## # Generate the output files. # if {1} { hwaci-make-from-dot-in Makefile hwaci-make-from-dot-in sqlite3.pc # hwaci-make-from-dot-in sqlite_cfg.h + if {1} { + # for sqlite_cfg.h + define PACKAGE_URL {https://sqlite.org} + define PACKAGE_VERSION [get-define VERSION] + } + if {0} { + # Requires a hand-written sqlite_cfg.h.in... hwaci-make-from-dot-in sqlite_cfg.h + # vs... } else { - make-config-header -bare {SIZEOF_* HAVE_DECL_*} \ + # Requires no input template... + make-config-header sqlite_cfg.h \ + -bare {SIZEOF_* HAVE_DECL_*} \ -auto {HAVE_* PACKAGE_*} -none * } # make-config-header sqlite_cfg.h -bare {SIZEOF_* HAVE_*} -none * diff --git a/manifest b/manifest index a38775c4c1..5efe4184b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tweak\sbuild\sto\sfall\sback\sto\ssystem-side\stclsh\sif\swe\scannot\sfind\srealpath()\sor\s_fullpath()\sfor\sJimTCL\s(needed\sfor\ssome\sof\sthe\scode\sgenerator\sscripts\sto\swork). -D 2024-09-27T02:35:41.157 +C General\sauto.def\scleanups,\smostly\saround\sJimTCL.\sSwap\sout\simpl\sfor\sthe\ssqlite_cfg.h\sgenerator\s-\sthis\sapproach\sis\slower-maintenance\s(requires\sno\shand-maintained\stemplate)\sbut\smay\snot\sbe\scompatible\swith\sexpectations. +D 2024-09-27T03:04:16.754 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 73d6e09e94dbe2a11c26524d2448c81a7bc5fdb52c2378396138d57ddbf058bb +F auto.def 16cabd934d00c8c69fa28f628b5236686c5bfb9f925ce3a8a50fd1caa8c4eedd F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3193b86a91d8096be68cb83133c7665129694521d7da81bf725e285c229271f7 -R c9ebfe69a4af214d35d57aa4421c3f6e +P b31dbb9945d0ac5e22d146565443bcdc0dd1a1c83034cfb5867b2303ada2bdea +R 559826a6b99ae3d6f2212d863a4322c6 U stephan -Z 2d082ca6d901dc26c8447cb73e030ab8 +Z 5d3d66ed442efd8056a05e7c3e59ac1d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 67187e8b40..006e487e4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b31dbb9945d0ac5e22d146565443bcdc0dd1a1c83034cfb5867b2303ada2bdea +da197946dbaacedb6e74827db9b5dd195d4aaf78ad9411a14aca732ab77917c6 From 8d2f6c13e32fbbac98a5608babbafdab1b28e9c7 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 03:16:01 +0000 Subject: [PATCH 032/522] Disable the optional extending of JimTCL on the grounds of YAGNI. FossilOrigin-Name: f395c269d55c2b5ceb074f26d0b63f65b1f04ec513fe203c7e73e3a876b1f055 --- auto.def | 7 +++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index d0c7be78b7..ba434d5d62 100644 --- a/auto.def +++ b/auto.def @@ -791,8 +791,11 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } ######################################################################## -# Extend JimTCL a bit... -if {"" ne [get-define CFLAGS_JIMSH]} { +# Maybe extend JimTCL a bit. As of this writing (2024-09-27) it only +# needs -DHAVE_REALPATH or -DHAVE__FULLPATH to be compatible with our +# code generators. It can, however, be slightly extended via +# easy-to-detect features, should we need them. +if {0 && "" ne [get-define CFLAGS_JIMSH]} { foreach jimFunc {opendir fsync isascii} { if {[cc-check-functions $jimFunc]} { define-append CFLAGS_JIMSH -DHAVE_[string toupper $jimFunc] diff --git a/manifest b/manifest index 5efe4184b7..37b726c7c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C General\sauto.def\scleanups,\smostly\saround\sJimTCL.\sSwap\sout\simpl\sfor\sthe\ssqlite_cfg.h\sgenerator\s-\sthis\sapproach\sis\slower-maintenance\s(requires\sno\shand-maintained\stemplate)\sbut\smay\snot\sbe\scompatible\swith\sexpectations. -D 2024-09-27T03:04:16.754 +C Disable\sthe\soptional\sextending\sof\sJimTCL\son\sthe\sgrounds\sof\sYAGNI. +D 2024-09-27T03:16:01.551 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 16cabd934d00c8c69fa28f628b5236686c5bfb9f925ce3a8a50fd1caa8c4eedd +F auto.def 30290b22601486ec60f45fc43262fa0dadaf77b93f5cd69e272718913df45d94 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b31dbb9945d0ac5e22d146565443bcdc0dd1a1c83034cfb5867b2303ada2bdea -R 559826a6b99ae3d6f2212d863a4322c6 +P da197946dbaacedb6e74827db9b5dd195d4aaf78ad9411a14aca732ab77917c6 +R ab854d117274fb20de9c561e9133e97f U stephan -Z 5d3d66ed442efd8056a05e7c3e59ac1d +Z 4cbb4cf43f8c57e15bc8dd370627f837 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 006e487e4a..f7586c2e1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da197946dbaacedb6e74827db9b5dd195d4aaf78ad9411a14aca732ab77917c6 +f395c269d55c2b5ceb074f26d0b63f65b1f04ec513fe203c7e73e3a876b1f055 From c139ad34debcccb989c47d545a4cbc23d820a6fe Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 09:40:55 +0000 Subject: [PATCH 033/522] Rename TCL_GENERATOR to BTCL for consistency with BCC/TCC. FossilOrigin-Name: a7ff8f3c2c86f435a08d568a07f019a59dcca8f66a719d242289fa0c7097c2af --- Makefile.in | 46 +++++++++++++++++++++++++--------------------- auto.def | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/Makefile.in b/Makefile.in index 0b76e01e3f..bcae830f58 100644 --- a/Makefile.in +++ b/Makefile.in @@ -772,8 +772,12 @@ $(JIMSH): $(TOP)/autosetup/jimsh0.c Makefile $(BCC) -o $(JIMSH) @CFLAGS_JIMSH@ $< @endif -TCL_GENERATOR = @TCL_GENERATOR@ -$(TCL_GENERATOR): +# BTCL is the tclsh-compatible app used for running various code +# generators and other in-tree tools, as opposed to the TCL-based +# tests, which must be built and run using the canonical TCL +# distribution. +BTCL = @BTCL@ +$(BTCL): #XX# #XX#verify-source: ./src-verify @@ -885,30 +889,30 @@ has_tclsh85: # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(TCL_GENERATOR) # has_tclsh84 +.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(BTCL) # has_tclsh84 rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - $(TCL_GENERATOR) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new + $(BTCL) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new mv vdbe.new tsrc/vdbe.c cp fts5.c fts5.h tsrc touch .target_source sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify \ - $(TCL_GENERATOR) # has_tclsh84 - $(TCL_GENERATOR) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(BTCL) # has_tclsh84 + $(BTCL) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . -sqlite3r.h: sqlite3.h $(TCL_GENERATOR) # has_tclsh84 - $(TCL_GENERATOR) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h +sqlite3r.h: sqlite3.h $(BTCL) # has_tclsh84 + $(BTCL) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -sqlite3r.c: sqlite3.c sqlite3r.h $(TCL_GENERATOR) # has_tclsh84 +sqlite3r.c: sqlite3.c sqlite3r.h $(BTCL) # has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(TCL_GENERATOR) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(BTCL) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . @@ -1207,12 +1211,12 @@ mksourceid$(BEXE): $(TOP)/tool/mksourceid.c # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(TCL_GENERATOR) # has_tclsh84 - $(TCL_GENERATOR) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(BTCL) # has_tclsh84 + $(BTCL) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c opcodes.h: parse.h $(TOP)/src/vdbe.c \ - $(TOP)/tool/mkopcodeh.tcl $(TCL_GENERATOR) # has_tclsh84 - cat parse.h $(TOP)/src/vdbe.c | $(TCL_GENERATOR) $(TOP)/tool/mkopcodeh.tcl >opcodes.h + $(TOP)/tool/mkopcodeh.tcl $(BTCL) # has_tclsh84 + cat parse.h $(TOP)/src/vdbe.c | $(BTCL) $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. # @@ -1223,8 +1227,8 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ - $(TOP)/VERSION $(TCL_GENERATOR) # has_tclsh84 - $(TCL_GENERATOR) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h + $(TOP)/VERSION $(BTCL) # has_tclsh84 + $(BTCL) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h #XX#sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 #XX# echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ @@ -1269,8 +1273,8 @@ SHELL_DEP = \ $(TOP)/src/test_windirent.c \ $(TOP)/src/test_windirent.h -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(TCL_GENERATOR) # has_tclsh84 - $(TCL_GENERATOR) $(TOP)/tool/mkshellc.tcl >shell.c +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCL) # has_tclsh84 + $(BTCL) $(TOP)/tool/mkshellc.tcl >shell.c #XX# #XX# #XX# @@ -1357,8 +1361,8 @@ fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) $(TCL_GENERATOR) # has_tclsh84 - $(TCL_GENERATOR) $(TOP)/ext/fts5/tool/mkfts5c.tcl +fts5.c: $(FTS5_SRC) $(BTCL) # has_tclsh84 + $(BTCL) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . #XX#fts5.lo: fts5.c $(HDR) $(EXTHDR) @@ -1719,7 +1723,7 @@ clean: tidy # Clean up everything. No exceptions. # distclean: clean - rm -f sqlite_cfg.h config.log config.status $(TCL_GENERATOR) Makefile $(LIBTOOL) + rm -f sqlite_cfg.h config.log config.status $(BTCL) Makefile $(LIBTOOL) #XX## #XX## Windows section diff --git a/auto.def b/auto.def index ba434d5d62..33a9cdfa5f 100644 --- a/auto.def +++ b/auto.def @@ -248,7 +248,7 @@ if {1} { # Check which TCL to use as a code generator define CFLAGS_JIMSH {} puts "Looking for path-resolution function for JimTCL... " -define TCL_GENERATOR "\$(JIMSH)" +define BTCL "\$(JIMSH)" if {[cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE_REALPATH } elseif {[cc-check-functions _fullpath]} { @@ -325,7 +325,7 @@ if {"" eq [get-define CFLAGS_JIMSH]} { user-error "Cannot find tclsh, which is required to build certain files." } define TCLSH_CMD $tclsh - define TCL_GENERATOR $tclsh + define BTCL $tclsh define HAVE_TCL 0 ; # until the following elseif block is ported } elseif {0} { # Porting this section of configure.ac is going to be a bit of a slog... diff --git a/manifest b/manifest index 37b726c7c3..222245855f 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Disable\sthe\soptional\sextending\sof\sJimTCL\son\sthe\sgrounds\sof\sYAGNI. -D 2024-09-27T03:16:01.551 +C Rename\sTCL_GENERATOR\sto\sBTCL\sfor\sconsistency\swith\sBCC/TCC. +D 2024-09-27T09:40:55.075 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 9bdbffc3a2c1b609d855b6b6daa7769b8a12cd56d156f99420a2a9243831bd0c +F Makefile.in fe90969736fa820a80433efe1c7eab7edc7a3f3784150268baa370a6e279f192 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 30290b22601486ec60f45fc43262fa0dadaf77b93f5cd69e272718913df45d94 +F auto.def fa4c056d8225c195213bdacdb1aa40b4a4bdee598d7076e9bafd9899327efae5 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P da197946dbaacedb6e74827db9b5dd195d4aaf78ad9411a14aca732ab77917c6 -R ab854d117274fb20de9c561e9133e97f +P f395c269d55c2b5ceb074f26d0b63f65b1f04ec513fe203c7e73e3a876b1f055 +R 29a5fb72187eaa096ca16d979b700320 U stephan -Z 4cbb4cf43f8c57e15bc8dd370627f837 +Z c604f90d680170e4b76ef7797c6d4f74 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f7586c2e1c..1a05538def 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f395c269d55c2b5ceb074f26d0b63f65b1f04ec513fe203c7e73e3a876b1f055 +a7ff8f3c2c86f435a08d568a07f019a59dcca8f66a719d242289fa0c7097c2af From 1865e85e0b7920ee0a4046ba26495996513bd624 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 12:15:14 +0000 Subject: [PATCH 034/522] General tinkering and cleanups in the autosetup bits. FossilOrigin-Name: a290e3b15de75f6a0a4975b5747449525fb2b58b3947b8ca0ab64a4d3cca228e --- Makefile.in | 5 ++- auto.def | 8 ++--- autosetup/hwaci-common.tcl | 69 +++++++++++++++++++++----------------- manifest | 16 ++++----- manifest.uuid | 2 +- 5 files changed, 54 insertions(+), 46 deletions(-) diff --git a/Makefile.in b/Makefile.in index bcae830f58..77f96a948c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -764,7 +764,10 @@ src-verify: $(TOP)/tool/src-verify.c # JimTCL is part of the autosetup suite and is suitable for certain # in-tree TCL jobs, but it requires that we build it with non-default -# flags. +# flags. Note that the build tree will, if no system-level tclsh is +# found, also have a ./jimsh0. That one is a bare-bones build for the +# configure process, whereas we need to build it with another option +# enabled for use with the various code generators. # JIMSH = @srcdir@/jimsh @if CFLAGS_JIMSH diff --git a/auto.def b/auto.def index 33a9cdfa5f..10009d060e 100644 --- a/auto.def +++ b/auto.def @@ -781,11 +781,11 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } memsys5 -DSQLITE_ENABLE_MEMSYS5 {} } { - if {[hwaci-opt-truthy $boolFlag]} { + hwaci-if-opt-truthy $boolFlag { add-feature-flag $featureFlag msg-result "Enabling $boolFlag" eval $ifSetEvalThis - } else { + } { msg-result "Not enabling $boolFlag" } } @@ -817,8 +817,6 @@ define ENABLE_SHARED $enable_shared if {1} { hwaci-make-from-dot-in Makefile hwaci-make-from-dot-in sqlite3.pc - # hwaci-make-from-dot-in sqlite_cfg.h - if {1} { # for sqlite_cfg.h define PACKAGE_URL {https://sqlite.org} @@ -834,8 +832,6 @@ if {1} { -bare {SIZEOF_* HAVE_DECL_*} \ -auto {HAVE_* PACKAGE_*} -none * } - # make-config-header sqlite_cfg.h -bare {SIZEOF_* HAVE_*} -none * - # make-config-header sqlite_cfg.h #hwaci-make-from-dot-in ext/wasm/GNUmakefile } diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 29c7c3da81..72219f3851 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -12,22 +12,36 @@ # Routines for Steve Bennett's autosetup which are common to trees # managed in and around the umbrella of the SQLite project. # +# Routines with a suffix of - are intended for internal use, +# within this file, and are not part of the API which auto.def files +# should rely on. +# # This file was initially derived from one used in the libfossil -# project, authored by the same person who ported it here (so there's -# no licensing issue despite this code having at least two near-twins -# running around). +# project, authored by the same person who ported it here, noted here +# only as an indication that there are no licensing issue despite this +# code having at least two near-twins running around in other trees. ######################################################################## -array set _hwaciCache {} ; # used for caching various results. +array set hwaci-cache- {} ; # used for caching various results. + +proc hwaci-warn {msg} { + puts "WARNING: $msg" +} +proc hwaci-notice {msg} { + puts "NOTICE: $msg" +} +proc hwaci-error {msg} { + user-error "ERROR: $msg" +} ######################################################################## -# hwaci-lshift shifts $count elements from the list named $listVar and +# hwaci-lshift- shifts $count elements from the list named $listVar and # returns them. # # Modified slightly from: https://wiki.tcl-lang.org/page/lshift # # On an empty list, returns "". -proc hwaci-lshift {listVar {count 1}} { +proc hwaci-lshift- {listVar {count 1}} { upvar 1 $listVar l if {![info exists l]} { # make the error message show the real variable name @@ -47,10 +61,10 @@ proc hwaci-lshift {listVar {count 1}} { # routine makes to the LIBS define. Returns the result of # cc-check-function-in-lib. proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { - # TODO: this can now be implemented using autosetup's define-push - set _LIBS [get-define LIBS] - set found [cc-check-function-in-lib $function $libs $otherlibs] - define LIBS $_LIBS + set found "" + define-push {LIBS} { + set found [cc-check-function-in-lib $function $libs $otherlibs] + } return $found } @@ -64,11 +78,11 @@ proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { # If defName is empty then "BIN_X" is used, where X is the upper-case # form of $binName with any '-' characters replaced with '_'. proc hwaci-bin-define {binName {defName {}}} { - global _hwaciCache + global hwaci-cache- set cacheName "$binName:$defName" set check {} - if {[info exists _hwaciCache($cacheName)]} { - set check $_hwaciCache($cacheName) + if {[info exists hwaci-cache-($cacheName)]} { + set check $hwaci-cache-($cacheName) } msg-checking "Looking for $binName ... " if {"" ne $check} { @@ -83,10 +97,10 @@ proc hwaci-bin-define {binName {defName {}}} { set check [find-executable-path $binName] if {"" eq $check} { msg-result "not found" - set _hwaciCache($cacheName) " _ 0 _ " + set hwaci-cache-($cacheName) " _ 0 _ " } else { msg-result $check - set _hwaciCache($cacheName) $check + set hwaci-cache-($cacheName) $check } if {"" eq $defName} { set defName "BIN_[string toupper [string map {- _} $binName]]" @@ -155,17 +169,12 @@ proc hwaci-opt-truthy {flag} { ######################################################################## # If [hwaci-opt-truthy $flag] is true, eval $then, else eval $else. -# -# Note that this may or may not, depending on the content of $then and -# $else, be functionally equivalent to: -# -# if {[hwaci-if-opt-truthy flag]} {...} else {...} -# -# When referencing $vars in $then and $else, the latter can resolve -# (without further assistance) the vars from its current scope, -# whereas $then and $else will not. -proc hwaci-if-opt-truthy {flag then {else {}}} { - if {[hwaci-opt-truthy $flag]} {eval $then} else {eval $else} +proc hwaci-if-opt-truthy {boolFlag thenScript {elseScript {}}} { + if {[hwaci-opt-truthy $boolFlag]} { + uplevel 1 $thenScript + } else { + uplevel 1 $elseScript + } } ######################################################################## @@ -201,15 +210,15 @@ proc hwaci-define-if-opt-truthy {flag def msg {iftrue 1} {iffalse 0}} { # If args[0] is -v then the boolean semantics are inverted: if # the option is set, it gets define'd to 0, else 1. Returns the # define'd value. -proc hwaci-opt-bool-01 {args} { +proc hwaci-set-bool-01 {args} { set invert 0 if {[lindex $args 0] eq "-v"} { set invert 1 set args [lrange $args 1 end] } - set optName [hwaci-lshift args] - set defName [hwaci-lshift args] - set descr [hwaci-lshift args] + set optName [hwaci-lshift- args] + set defName [hwaci-lshift- args] + set descr [hwaci-lshift- args] if {"" eq $descr} { set descr $defName } diff --git a/manifest b/manifest index 222245855f..ee7e3844a2 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Rename\sTCL_GENERATOR\sto\sBTCL\sfor\sconsistency\swith\sBCC/TCC. -D 2024-09-27T09:40:55.075 +C General\stinkering\sand\scleanups\sin\sthe\sautosetup\sbits. +D 2024-09-27T12:15:14.956 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in fe90969736fa820a80433efe1c7eab7edc7a3f3784150268baa370a6e279f192 +F Makefile.in 5ac6defaba5f19e487a02c920bdffd42033e2be31172fefaff40cbf997d42947 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def fa4c056d8225c195213bdacdb1aa40b4a4bdee598d7076e9bafd9899327efae5 +F auto.def 63a9d902a3326370aed3698c961161b6f1d975c047fa110e7ea9bcb83c8cd006 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl e47d127a33de5729ebcc0fd83a6e09c332b1867b43abdb90a0da76bdc536cfee +F autosetup/hwaci-common.tcl c6638a9ffb180ed2b240357c443ca60cc16d48d15c6e492b2965d2197ef0fb37 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f395c269d55c2b5ceb074f26d0b63f65b1f04ec513fe203c7e73e3a876b1f055 -R 29a5fb72187eaa096ca16d979b700320 +P a7ff8f3c2c86f435a08d568a07f019a59dcca8f66a719d242289fa0c7097c2af +R 35d30a680586fc0d89ef4699e74bef45 U stephan -Z c604f90d680170e4b76ef7797c6d4f74 +Z b93d9def15ae319c294048d66bd247b2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1a05538def..dbf92f2b43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7ff8f3c2c86f435a08d568a07f019a59dcca8f66a719d242289fa0c7097c2af +a290e3b15de75f6a0a4975b5747449525fb2b58b3947b8ca0ab64a4d3cca228e From 05c5e76c9412eaf771e959c8744acd663c931257 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 27 Sep 2024 13:29:50 +0000 Subject: [PATCH 035/522] Add basic libreadline detection and build CLI shell. FossilOrigin-Name: 2ba7ab562580667bc9249f2d1f2402c605553d5583eec497398abe6d196c83d4 --- Makefile.in | 38 ++++++++++---------- auto.def | 37 ++++++++++++++----- autosetup/hwaci-common.tcl | 73 ++++++++++++++++++++++++++++++++------ manifest | 16 ++++----- manifest.uuid | 2 +- 5 files changed, 120 insertions(+), 46 deletions(-) diff --git a/Makefile.in b/Makefile.in index 77f96a948c..1e60d411b8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -62,9 +62,9 @@ TCC += @TARGET_DEBUG@ #XX## #XX#LIBTCL = @TCL_LIB_SPEC@ #XX# -#XX## Compiler options needed for programs that use the readline() library. -#XX## -#XX#READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@ +# Compiler options needed for programs that use the readline() library. +# +READLINE_FLAGS = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ #XX#READLINE_FLAGS += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ #XX#READLINE_FLAGS += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ #XX# @@ -76,9 +76,9 @@ TCC += @TARGET_DEBUG@ #XX## #XX#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ #XX# -#XX## Any target libraries which libsqlite must be linked against -#XX## -#XX#TLIBS = @LIBS@ $(LIBS) +# Any target libraries which libsqlite must be linked against +# +TLIBS = @LIBS@ $(LIBS) #XX# # Flags controlling use of the in memory btree implementation # @@ -617,6 +617,7 @@ TESTOPTS = --verbose=file --output=test-out.txt # Extra compiler options for various shell tools # +SHELL_OPT = @OPT_SHELL@ SHELL_OPT += -DSQLITE_DQS=0 SHELL_OPT += -DSQLITE_ENABLE_FTS4 #SHELL_OPT += -DSQLITE_ENABLE_FTS5 @@ -675,12 +676,13 @@ DBFUZZ_OPT = ST_OPT = -DSQLITE_OS_KV_OPTIONAL -# In wasi-sdk builds, disable the CLI shell build in the "all" target. -SQLITE3_SHELL_TARGET_ = sqlite3$(TEXE) -SQLITE3_SHELL_TARGET_1 = -SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@) - -SQLITE3_O = $(TOP)/sqlite3.o +# In wasi-sdk builds, disable the CLI shell build. +@if HAVE_WASI_SDK + SQLITE3_SHELL_TARGET = +@else + SQLITE3_SHELL_TARGET = sqlite3$(TEXE) +@endif +#XXX#??? SQLITE3_O = $(TOP)/sqlite3.o # Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either # libtclsqlite3.la or an empty value. @@ -691,8 +693,8 @@ libtclsqlite3.la_1 = libtclsqlite3.la # are what get build when you type just "make" with no arguments. # -all: sqlite3.h sqlite3.c shell.c -#all: libsqlite3.la $(SQLITE3_SHELL_TARGET) \ +all: sqlite3.h sqlite3.c shell.c $(SQLITE3_SHELL_TARGET) +#all: libsqlite3.la \ #XX# $(libtclsqlite3.la_$(HAVE_TCL)) # Re-run $(TOP)/configure with the same args invoked to produce this @@ -723,10 +725,10 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) #XX# -version-info "8:6:8" \ #XX# -avoid-version #XX# -#XX#sqlite3$(TEXE): shell.c sqlite3.c -#XX# $(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ -#XX# shell.c sqlite3.c \ -#XX# $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" +sqlite3$(TEXE): shell.c sqlite3.c + $(TCC) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ + shell.c sqlite3.c \ + @LDFLAGS_RPATH@ @LDFLAGS_READLINE@ $(TLIBS) #XX# #XX#sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h #XX# $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) diff --git a/auto.def b/auto.def index 10009d060e..c5c972d450 100644 --- a/auto.def +++ b/auto.def @@ -38,7 +38,7 @@ options { releasemode => {libtool link to release mode} with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always.} editline=0 => {BSD editline support} - readline=0 => {readline support} + readline=1 => {Disable readline support} largefile=1 => {Disable large file support} with-readline-lib => {readline library} with-readline-inc => {readline include paths} @@ -150,13 +150,19 @@ cc-check-tools ld ar ######################################################################## # OPT_FEATURE_FLAGS = -DSQLITE_OMIT/ENABLE flags. define OPT_FEATURE_FLAGS {} +define OPT_SHELL {}; # CFLAGS for the sqlite3 CLI app # Adds $flag, if not empty, to OPT_FEATURE_FLAGS. -proc add-feature-flag {flag} { - if {"" ne $flag} { - define-append OPT_FEATURE_FLAGS $flag +proc add-feature-flag {args} { + if {"" ne $args} { + define-append OPT_FEATURE_FLAGS {*}$args } } # add-feature-flag -DSQLITE_JUST_TESTING=3 +proc add-shell-opt {args} { + if {"" ne $args} { + define-append OPT_SHELL {*}$args + } +} hwaci-check-exeext if {".exe" eq [get-define TARGET_EXEEXT]} { @@ -206,10 +212,7 @@ define BUILD_CFLAGS [get-env CFLAGS {-g}] if {1} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" - if {$wasiSdkDir eq ""} { - define HAVE_WASI_SDK 0 - define WASI_SDK_DIR "" - } else { + if {$wasiSdkDir ne ""} { msg-checking "Checking WASI SDK directory \[$wasiSdkDir]... " puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" hwaci-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] @@ -267,6 +270,8 @@ cc-check-lfs cc-check-types int8_t int16_t int32_t int64_t intptr_t \ uint8_t uint16_t uint32_t uint64_t uintptr_t +######################################################################## +# Check for needed/wanted functions cc-check-functions gmtime_r isnan localtime_r localtime_s \ malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 @@ -296,12 +301,17 @@ if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ "Use amalgamation for builds?" + hwaci-define-if-opt-truthy gcov USE_GCOV "Use gcov?" + hwaci-define-if-opt-truthy test-status TSTRNNR_OPTS \ "test-runner flags:" {--status} {} + hwaci-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \ "Use #line macros in the amalgamation:" {--linemacros=1} {--linemacros=0} + msg-checking "Debug build? " + hwaci-if-opt-truthy with-debug { define SQLITE_DEBUG 1 define TARGET_DEBUG {-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} @@ -311,6 +321,8 @@ hwaci-if-opt-truthy with-debug { msg-result no } +hwaci-check-rpath + ######################################################################## # TCL... define HAVE_TCL 0 @@ -530,10 +542,13 @@ if {1} { unset ts tsn } -if {0} { +if {1} { ########## # Figure out what C libraries are required to compile programs # that use "readline()" library. + hwaci-check-readline +} else { + # Older impl solely for reference while porting... # # XXX TARGET_READLINE_LIBS="" # XXX TARGET_READLINE_INC="" @@ -840,6 +855,10 @@ if {"" ne $oFF} { define OPT_FEATURE_FLAGS [lsort -unique $oFF] msg-result "Final feature flags: [get-define OPT_FEATURE_FLAGS]" } +set oFF [get-define SHELL_OPT] +if {"" ne $oFF} { + msg-result "Final shell opts: [get-define OPT_SHELL]" +} unset oFF hwaci-if-opt-truthy dump-defines { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 72219f3851..3da0961c54 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -61,7 +61,7 @@ proc hwaci-lshift- {listVar {count 1}} { # routine makes to the LIBS define. Returns the result of # cc-check-function-in-lib. proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { - set found "" + set found 0 define-push {LIBS} { set found [cc-check-function-in-lib $function $libs $otherlibs] } @@ -425,9 +425,11 @@ proc hwaci-check-profile-flag {{flagname profile}} { # Returns 1 if this appears to be a Windows environment (MinGw, # Cygwin, MSys), else returns 0. The optional argument is the name of # an autosetup define which contains platform name info, defaulting to -# "host". The other legal value is "build" (the build machine). If -# $key == "build" then some additional checks may be performed which -# are not applicable when $key == "host". +# "host" (meaning, somewhat counterintuitively, the target system, not +# the current host). The other legal value is "build" (the build +# machine, i.e. the local host). If $key == "build" then some +# additional checks may be performed which are not applicable when +# $key == "host". proc hwaci-looks-like-windows {{key host}} { global autosetup switch -glob -- [get-define $key] { @@ -447,14 +449,14 @@ proc hwaci-looks-like-windows {{key host}} { } ######################################################################## -# Checks autosetup's "host" and "target" defines to see if the build +# Checks autosetup's "host" and "build" defines to see if the build # host and target are Windows-esque (Cygwin, MinGW, MSys). If the -# build host is then BUILD_EXEEXT is [define]'d to ".exe", else "". If -# the build target is then TARGET_EXEEXT is [define]'d to ".exe", else -# "". +# build environment is then BUILD_EXEEXT is [define]'d to ".exe", else +# "". If the target, a.k.a. "host", is then TARGET_EXEEXT is +# [define]'d to ".exe", else "". proc hwaci-check-exeext {} { msg-checking "Build host is Windows-esque? " - if {[hwaci-looks-like-windows host]} { + if {[hwaci-looks-like-windows build]} { define BUILD_EXEEXT ".exe" msg-result yes } else { @@ -463,7 +465,7 @@ proc hwaci-check-exeext {} { } msg-checking "Build target is Windows-esque? " - if {[hwaci-looks-like-windows target]} { + if {[hwaci-looks-like-windows host]} { define TARGET_EXEEXT ".exe" msg-result yes } else { @@ -549,3 +551,54 @@ proc hwaci-check-emsdk {} { define HAVE_EMSDK $rc return $rc } + +######################################################################## +# Tries various approaches to handling the -rpath link-time +# flag. Defines LDFLAGS_RPATH to that/those flag(s) or an empty +# string. Returns 1 if it finds an option, else 0. +proc hwaci-check-rpath {} { + if {[cc-check-flags -Wl,-R/tmp]} { + define LDFLAGS_RPATH "-Wl,-R[get-define libdir]" + return 1 + } elseif {[cc-check-flags -Wl,-rpath -Wl,/tmp]} { + define LDFLAGS_RPATH "-Wl,-rpath -Wl,[get-define libdir]" + return 1 + } else { + define LDFLAGS_RPATH "" + return 0 + } +} + +######################################################################## +# Under construction - check for libreadline functionality +proc hwaci-check-readline {} { + define HAVE_READLINE 0 + define LDFLAGS_READLINE "" + define CFLAGS_READLINE "" + define READLINE_H "" + if {![opt-bool readline]} { + msg-result "libreadline disabled via --disable-readline." + return 0 + } + set h "readline/readline.h" + if {[cc-check-includes $h]} { + define READLINE_H $h + if {[hwaci-check-function-in-lib readline readline]} { + msg-result "Enabling libreadline." + define HAVE_READLINE 1 + define LDFLAGS_READLINE [get-define lib_readline] + undefine lib_readline + return 1 + } + # else TODO: look in various places and [define CFLAGS_READLINE + # -I...] + } + # Numerous TODOs: + # - Requires linking with ncurses or similar on some platforms. + # - Headers are in a weird place on some BSD systems. + # - Add --with-readline=DIR + # - Add --with-readline-lib=lib file + # - Add --with-readline-inc=dir -Idir + msg-result "libreadline not found." + return 0 +} diff --git a/manifest b/manifest index ee7e3844a2..bf80bfb4cb 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C General\stinkering\sand\scleanups\sin\sthe\sautosetup\sbits. -D 2024-09-27T12:15:14.956 +C Add\sbasic\slibreadline\sdetection\sand\sbuild\sCLI\sshell. +D 2024-09-27T13:29:50.775 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 5ac6defaba5f19e487a02c920bdffd42033e2be31172fefaff40cbf997d42947 +F Makefile.in 5253a425c9167286a21b2393d4293c197914c135e35ef3fdea7b1334df98c9cc F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc e3c4723c27464acc31da4420b808c8d2690180ba2b915897bece0a9d5d2cecf6 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 63a9d902a3326370aed3698c961161b6f1d975c047fa110e7ea9bcb83c8cd006 +F auto.def 6e46e578f319e20c2469c90c0e54f4c08c246d136b2b20962ba8281c715c3b4b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl c6638a9ffb180ed2b240357c443ca60cc16d48d15c6e492b2965d2197ef0fb37 +F autosetup/hwaci-common.tcl bd3321e80b92eb0644be4f05df44d5c98ab415b2c7dc10866303dfe5ba77592a F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a7ff8f3c2c86f435a08d568a07f019a59dcca8f66a719d242289fa0c7097c2af -R 35d30a680586fc0d89ef4699e74bef45 +P a290e3b15de75f6a0a4975b5747449525fb2b58b3947b8ca0ab64a4d3cca228e +R 00136067f886dfec24f53eea1a13e92a U stephan -Z b93d9def15ae319c294048d66bd247b2 +Z 89712eb4fe24753b96ac2cf6bb7cec31 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dbf92f2b43..a944e85909 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a290e3b15de75f6a0a4975b5747449525fb2b58b3947b8ca0ab64a4d3cca228e +2ba7ab562580667bc9249f2d1f2402c605553d5583eec497398abe6d196c83d4 From 5ff68db4f113423b9473f70125436a504d6ca278 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 28 Sep 2024 00:41:34 +0000 Subject: [PATCH 036/522] Latest upstream autosetup for a --help fix on QNX. FossilOrigin-Name: b9faebbb543fb3a03f46dd4defe28ffa0c32a9a46ed73912f93b86e41f3db04a --- autosetup/autosetup | 8 +++++--- autosetup/cc.tcl | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/autosetup/autosetup b/autosetup/autosetup index e041e77a3a..90f5454b5f 100755 --- a/autosetup/autosetup +++ b/autosetup/autosetup @@ -566,7 +566,10 @@ proc options-show {what} { set indent [string repeat " " [expr {$max+4}]] set cols [getenv COLUMNS 80] catch { - lassign [exec stty size] rows cols + lassign [exec stty size] _ sttycols + if {[string is integer -strict $sttycols]} { + set cols $sttycols + } } incr cols -1 # Now output @@ -910,8 +913,7 @@ proc list-non-empty {list} { # Searches the path for an executable with the given name. # Note that the name may include some parameters, e.g. 'cc -mbig-endian', # in which case the parameters are ignored. -# The full path to the executable if found, or "" if not found. -# Returns 1 if found, or 0 if not. +# Returns the full path to the executable if found, or "" if not found. # proc find-executable-path {name} { # Ignore any parameters diff --git a/autosetup/cc.tcl b/autosetup/cc.tcl index f45cc2ecdc..5e724d9b78 100644 --- a/autosetup/cc.tcl +++ b/autosetup/cc.tcl @@ -5,7 +5,7 @@ # # The 'cc' module supports checking various 'features' of the C or C++ # compiler/linker environment. Common commands are 'cc-check-includes', -# 'cc-check-types', 'cc-check-functions', 'cc-with', 'make-config-header' and 'make-template'. +# 'cc-check-types', 'cc-check-functions', 'cc-with' and 'make-config-header' # # The following environment variables are used if set: # diff --git a/manifest b/manifest index df35a34bbf..5dd40c0b4e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\sinto\sautosetup\sbranch\sfor\slatest\swasm\spieces. -D 2024-09-28T00:37:23.852 +C Latest\supstream\sautosetup\sfor\sa\s--help\sfix\son\sQNX. +D 2024-09-28T00:41:34.737 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -36,7 +36,7 @@ F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea0034 F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5 F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/autosetup 7d7fe206980a6d04113f85e570229953f7e0cd5ef31bb40868653b976f8698af x +F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x F autosetup/autosetup-find-tclsh c5053419348cdd1aba824c3701bd97392d987b948c1bd748b32f11bbca2c0d8a x @@ -44,7 +44,7 @@ F autosetup/autosetup-test-tclsh 749d20defee533a3842139df47d700fc7a334a5da7bdbd4 F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034b10a7b F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360 F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 -F autosetup/cc.tcl 1b52de228642c1db5a714d54ca974d723ec8b4092e8c3765d348b625850f7311 +F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/hwaci-common.tcl bd3321e80b92eb0644be4f05df44d5c98ab415b2c7dc10866303dfe5ba77592a F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d @@ -631,7 +631,7 @@ F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ce F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core 2bcbbfe3b95c043ed6037e2708a2ee078d212dd1612c364f93588d8dc97300fe -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras fe40d6d758646e38f8b15f709044951e10884214f5453d35502100179c388c13 w ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-session +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras fe40d6d758646e38f8b15f709044951e10884214f5453d35502100179c388c13 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 34fe11466f9c1d81b10a0469e1114e5f1c5a6365c73d80a1a6ca639a1a358b73 @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9586ea204c705430d63e3757f80009a152b89573a75c6862e407062be8ef346c 208c27714646c9bc26eef11266086a71da04bc24e87078de0955e7beb68a821e -R 1ef986af17c4e886df6e4f496b132523 +P c3877d1241f946b470a7a4868f13e1106e8aac4851d4bc5a64c90e0569444b81 +R c95c554af644d55a7c83b59eb1349814 U stephan -Z f102d1cc9aacb9d174c9700a0adefb05 +Z d6501046de47ed3c7029a05bf2997e84 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eb97aee2c0..eccaa51081 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3877d1241f946b470a7a4868f13e1106e8aac4851d4bc5a64c90e0569444b81 +b9faebbb543fb3a03f46dd4defe28ffa0c32a9a46ed73912f93b86e41f3db04a From 595a2532f398331b0efcf923b7dfb15cb21df6e6 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 28 Sep 2024 14:51:10 +0000 Subject: [PATCH 037/522] Get libsqlite3.so building. FossilOrigin-Name: c65e3679e0d28e980bb555b47f31690b27915d9ff0850f598e3bed528b18ca1d --- Makefile.in | 112 +++++++++++++++++++++---------------- auto.def | 4 +- autosetup/hwaci-common.tcl | 21 +++++++ manifest | 16 +++--- manifest.uuid | 2 +- 5 files changed, 96 insertions(+), 59 deletions(-) diff --git a/Makefile.in b/Makefile.in index 1e60d411b8..aa984a53d5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -39,7 +39,11 @@ BCC = @BUILD_CC@ @BUILD_CFLAGS@ CC = @CC@ CFLAGS ?= @CFLAGS@ CPPFLAGS ?= @CPPFLAGS@ -TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu +@if SH_CFLAGS +CFLAGS += @SH_CFLAGS@ +@endif +TCC = ${CC} ${CFLAGS} +TCC += -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session TCC += -I${TOP}/ext/userauth @@ -79,6 +83,7 @@ READLINE_FLAGS = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ # Any target libraries which libsqlite must be linked against # TLIBS = @LIBS@ $(LIBS) + #XX# # Flags controlling use of the in memory btree implementation # @@ -113,10 +118,12 @@ TCC += @LDFLAGS_ZLIB@ VERSION = @VERSION@ RELEASE = @RELEASE@ -# Filename extensions for binaries +# Filename extensions for binaries and shared libraries # BEXE = @BUILD_EXEEXT@ TEXE = @TARGET_EXEEXT@ +BDLL = @BDLL@ +TDLL = @TDLL@ # The following variable is "1" if the configure script was able to locate # the tclConfig.sh file. It is an empty string otherwise. When this @@ -154,9 +161,8 @@ TSTRNNR_OPTS = @TSTRNNR_OPTS@ GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage GCOV_LDFLAGS1 = -lgcov USE_GCOV = @USE_GCOV@ -#XX#LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) -#XX#LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) - +LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) +LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) # The directory into which to store package information for @@ -176,6 +182,9 @@ INSTALL = @BIN_INSTALL@ #XX#LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS) #XX#LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS) #XX#LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) +TCOMPILE = $(TCC) $(LTCOMPILE_EXTRAS) +TLINK = $(TCC) $(LTLINK_EXTRAS) +TINSTALL = $(INSTALL) # # You should not have to change anything below this line @@ -192,45 +201,44 @@ USE_AMALGAMATION = @USE_AMALGAMATION@ AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@ # -#XX## Object files for the SQLite library (non-amalgamation). -#XX## -#XX#LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ -#XX# backup.lo bitvec.lo btmutex.lo btree.lo build.lo \ -#XX# callback.lo complete.lo ctime.lo \ -#XX# date.lo dbpage.lo dbstat.lo delete.lo \ -#XX# expr.lo fault.lo fkey.lo \ -#XX# fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \ -#XX# fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \ -#XX# fts3_tokenize_vtab.lo \ -#XX# fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \ -#XX# fts5.lo \ -#XX# func.lo global.lo hash.lo \ -#XX# icu.lo insert.lo json.lo legacy.lo loadext.lo \ -#XX# main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \ -#XX# memdb.lo memjournal.lo \ -#XX# mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \ -#XX# notify.lo opcodes.lo os.lo os_kv.lo os_unix.lo os_win.lo \ -#XX# pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ -#XX# random.lo resolve.lo rowset.lo rtree.lo \ -#XX# sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \ -#XX# table.lo threads.lo tokenize.lo treeview.lo trigger.lo \ -#XX# update.lo userauth.lo upsert.lo util.lo vacuum.lo \ -#XX# vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ -#XX# vdbetrace.lo vdbevtab.lo \ -#XX# wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \ -#XX# window.lo utf.lo vtab.lo -#XX# -#XX## Object files for the amalgamation. -#XX## -#XX#LIBOBJS1 = sqlite3.lo -#XX# -#XX## Determine the real value of LIBOBJ based on the 'configure' script -#XX## -#XX#LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) -#XX# -#XX# -#XX## All of the source code files. -#XX## +# Object files for the SQLite library (non-amalgamation). +# +LIBOBJS0 = alter.o analyze.o attach.o auth.o \ + backup.o bitvec.o btmutex.o btree.o build.o \ + callback.o complete.o ctime.o \ + date.o dbpage.o dbstat.o delete.o \ + expr.o fault.o fkey.o \ + fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o \ + fts3_porter.o fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \ + fts3_tokenize_vtab.o \ + fts3_unicode.o fts3_unicode2.o fts3_write.o \ + fts5.o \ + func.o global.o hash.o \ + icu.o insert.o json.o legacy.o loadext.o \ + main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \ + memdb.o memjournal.o \ + mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \ + notify.o opcodes.o os.o os_kv.o os_unix.o os_win.o \ + pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \ + random.o resolve.o rowset.o rtree.o \ + sqlite3session.o select.o sqlite3rbu.o status.o stmt.o \ + table.o threads.o tokenize.o treeview.o trigger.o \ + update.o userauth.o upsert.o util.o vacuum.o \ + vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ + vdbetrace.o vdbevtab.o \ + wal.o walker.o where.o wherecode.o whereexpr.o \ + window.o utf.o vtab.o + +# Object files for the amalgamation. +# +LIBOBJS1 = sqlite3.o + +# Determine the real value of LIBOBJ based on the 'configure' script +# +LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) + +# All of the source code files. +# SRC = \ $(TOP)/src/alter.c \ $(TOP)/src/analyze.c \ @@ -714,21 +722,27 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) $(AUTOREMAKE) @touch $@ -#XX#libsqlite3.la: $(LIBOBJ) -#XX# $(LTLINK) -no-undefined -o $@ $(LIBOBJ) $(TLIBS) \ -#XX# ${ALLOWRELEASE} -rpath "$(libdir)" -version-info "8:6:8" -#XX# +libsqlite3.DLL = libsqlite3$(TDLL) +$(libsqlite3.DLL): $(LIBOBJ) + $(TLINK) -o $@ \ + @SHOBJ_LDFLAGS@ $(LIBOBJ) $(TLIBS) \ + @LDFLAGS_RPATH@ +dll: $(libsqlite3.DLL) +all: dll + #XX#libtclsqlite3.la: tclsqlite.lo libsqlite3.la #XX# $(LTLINK) -no-undefined -o $@ tclsqlite.lo \ #XX# libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \ #XX# -rpath "$(TCLLIBDIR)" \ #XX# -version-info "8:6:8" \ #XX# -avoid-version -#XX# + sqlite3$(TEXE): shell.c sqlite3.c $(TCC) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ @LDFLAGS_RPATH@ @LDFLAGS_READLINE@ $(TLIBS) +cli: sqlite3$(TEXE) +all: cli #XX# #XX#sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h #XX# $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) diff --git a/auto.def b/auto.def index c5c972d450..2a87e4b711 100644 --- a/auto.def +++ b/auto.def @@ -174,6 +174,8 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_WIN 0 # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS? } +define BDLL [hwaci-dll-extension build] +define TDLL [hwaci-dll-extension host] ######### # Programs needed @@ -855,7 +857,7 @@ if {"" ne $oFF} { define OPT_FEATURE_FLAGS [lsort -unique $oFF] msg-result "Final feature flags: [get-define OPT_FEATURE_FLAGS]" } -set oFF [get-define SHELL_OPT] +set oFF [get-define OPT_SHELL] if {"" ne $oFF} { msg-result "Final shell opts: [get-define OPT_SHELL]" } diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 3da0961c54..b823d57c63 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -448,6 +448,27 @@ proc hwaci-looks-like-windows {{key host}} { return 0 } +######################################################################## +# Looks at either the 'host' (==compilation target platform) or +# 'build' (==the being-built-on platform) define value and returns a +# file extension for DLLs on that platform, including the leading ".". +# +# TODO: have someone verify whether this is correct for the +# non-Linux/BSD platforms. +proc hwaci-dll-extension {{key host}} { + switch -glob -- [get-define $key] { + *apple* { + return ".dylib" + } + *-*-ming* - *-*-cygwin - *-*-msys { + return ".dll" + } + default { + return ".so" + } + } +} + ######################################################################## # Checks autosetup's "host" and "build" defines to see if the build # host and target are Windows-esque (Cygwin, MinGW, MSys). If the diff --git a/manifest b/manifest index 5dd40c0b4e..aeed538d8d 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Latest\supstream\sautosetup\sfor\sa\s--help\sfix\son\sQNX. -D 2024-09-28T00:41:34.737 +C Get\slibsqlite3.so\sbuilding. +D 2024-09-28T14:51:10.851 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 5253a425c9167286a21b2393d4293c197914c135e35ef3fdea7b1334df98c9cc +F Makefile.in 697e01f6bf783c56ccf80c31dcd58165b5a95469e4b5db716ffe70c48fccfbaa F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 6e46e578f319e20c2469c90c0e54f4c08c246d136b2b20962ba8281c715c3b4b +F auto.def 62bfff338c701174786e6613c30c2be7b98563dbdd1eaaaa3b4156165ee46d53 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl bd3321e80b92eb0644be4f05df44d5c98ab415b2c7dc10866303dfe5ba77592a +F autosetup/hwaci-common.tcl bc7611bd7122b0308453bf0353ef81ae4658744f7ef67e5e53f3033551ddcac6 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c3877d1241f946b470a7a4868f13e1106e8aac4851d4bc5a64c90e0569444b81 -R c95c554af644d55a7c83b59eb1349814 +P b9faebbb543fb3a03f46dd4defe28ffa0c32a9a46ed73912f93b86e41f3db04a +R d30efb2f23fa7708ccc4acb26fa1caa0 U stephan -Z d6501046de47ed3c7029a05bf2997e84 +Z 22dfd7e3022119773556b9c0d01ecb08 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eccaa51081..635d73158a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9faebbb543fb3a03f46dd4defe28ffa0c32a9a46ed73912f93b86e41f3db04a +c65e3679e0d28e980bb555b47f31690b27915d9ff0850f598e3bed528b18ca1d From 7d56669bc48ba12c23713219a2e10923758b915f Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 28 Sep 2024 20:45:11 +0000 Subject: [PATCH 038/522] Rationalize some of the new code on this branch. FossilOrigin-Name: 66f209ba40e7de49b304d7931ff38a4994038452aab08e9347286a234c6f7075 --- ext/fts5/fts5_index.c | 309 ++++++++++++++++++++++++------------------ manifest | 12 +- manifest.uuid | 2 +- 3 files changed, 181 insertions(+), 142 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 1efbe5a7b4..ede091650d 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6198,6 +6198,101 @@ static void fts5MergePrefixLists( *p1 = out; } + +static int fts5VisitPrefixRange( + Fts5Index *p, + Fts5Colset *pColset, + u8 *pToken, + int nToken, + void (*xVisit)(Fts5Index*, void *pCtx, Fts5Iter *pIter, const u8*, int), + void *pCtx +){ + const int flags = FTS5INDEX_QUERY_SCAN + | FTS5INDEX_QUERY_SKIPEMPTY + | FTS5INDEX_QUERY_NOOUTPUT; + Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ + int bNewTerm = 1; + Fts5Structure *pStruct = fts5StructureRead(p); + + fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for( /* no-op */ ; + fts5MultiIterEof(p, p1)==0; + fts5MultiIterNext2(p, p1, &bNewTerm) + ){ + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + int nNew = 0; + const u8 *pNew = 0; + + p1->xSetOutputs(p1, pSeg); + + + if( bNewTerm ){ + nNew = pSeg->term.n; + pNew = pSeg->term.p; + if( nNewrc; +} + +typedef struct PrefixSetupCtx PrefixSetupCtx; +struct PrefixSetupCtx { + void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); + void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); + i64 iLastRowid; + int nMerge; + Fts5Buffer *aBuf; + int nBuf; + Fts5Buffer doclist; +}; + +static void prefixIterSetupCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + PrefixSetupCtx *pSetup = (PrefixSetupCtx*)pCtx; + const int nMerge = pSetup->nMerge; + + if( p1->base.nData>0 ){ + if( p1->base.iRowid<=pSetup->iLastRowid && pSetup->doclist.n>0 ){ + int i; + for(i=0; p->rc==SQLITE_OK && pSetup->doclist.n; i++){ + int i1 = i*nMerge; + int iStore; + assert( i1+nMerge<=pSetup->nBuf ); + for(iStore=i1; iStoreaBuf[iStore].n==0 ){ + fts5BufferSwap(&pSetup->doclist, &pSetup->aBuf[iStore]); + fts5BufferZero(&pSetup->doclist); + break; + } + } + if( iStore==i1+nMerge ){ + pSetup->xMerge(p, &pSetup->doclist, nMerge, &pSetup->aBuf[i1]); + for(iStore=i1; iStoreaBuf[iStore]); + } + } + } + pSetup->iLastRowid = 0; + } + + pSetup->xAppend( + p, (u64)p1->base.iRowid-(u64)pSetup->iLastRowid, p1, &pSetup->doclist + ); + pSetup->iLastRowid = p1->base.iRowid; + } +} + static void fts5SetupPrefixIter( Fts5Index *p, /* Index to read from */ int bDesc, /* True for "ORDER BY rowid DESC" */ @@ -6208,38 +6303,30 @@ static void fts5SetupPrefixIter( Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; - Fts5Buffer *aBuf; - int nBuf = 32; - int nMerge = 1; + PrefixSetupCtx s; + + memset(&s, 0, sizeof(s)); + s.nMerge = 1; + s.iLastRowid = 0; + s.nBuf = 32; - void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); - void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ - xMerge = fts5MergeRowidLists; - xAppend = fts5AppendRowid; + s.xMerge = fts5MergeRowidLists; + s.xAppend = fts5AppendRowid; }else{ - nMerge = FTS5_MERGE_NLIST-1; - nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ - xMerge = fts5MergePrefixLists; - xAppend = fts5AppendPoslist; + s.nMerge = FTS5_MERGE_NLIST-1; + s.nBuf = s.nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ + s.xMerge = fts5MergePrefixLists; + s.xAppend = fts5AppendPoslist; } - aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); + s.aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*s.nBuf); pStruct = fts5StructureRead(p); - assert( p->rc!=SQLITE_OK || (aBuf && pStruct) ); + assert( p->rc!=SQLITE_OK || (s.aBuf && pStruct) ); if( p->rc==SQLITE_OK ){ - const int flags = FTS5INDEX_QUERY_SCAN - | FTS5INDEX_QUERY_SKIPEMPTY - | FTS5INDEX_QUERY_NOOUTPUT; int i; - i64 iLastRowid = 0; - Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; - Fts5Buffer doclist; - int bNewTerm = 1; - - memset(&doclist, 0, sizeof(doclist)); /* If iIdx is non-zero, then it is the number of a prefix-index for ** prefixes 1 character longer than the prefix being queried for. That @@ -6247,6 +6334,7 @@ static void fts5SetupPrefixIter( ** corresponding to the prefix itself. That one is extracted from the ** main term index here. */ if( iIdx!=0 ){ + Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ int dummy = 0; const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; pToken[0] = FTS5_MAIN_PREFIX; @@ -6259,82 +6347,41 @@ static void fts5SetupPrefixIter( Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; p1->xSetOutputs(p1, pSeg); if( p1->base.nData ){ - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); - iLastRowid = p1->base.iRowid; + s.xAppend(p, (u64)p1->base.iRowid-(u64)s.iLastRowid, p1, &s.doclist); + s.iLastRowid = p1->base.iRowid; } } fts5MultiIterFree(p1); } pToken[0] = FTS5_MAIN_PREFIX + iIdx; - fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); - - for( /* no-op */ ; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &bNewTerm) - ){ - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - int nTerm = pSeg->term.n; - const u8 *pTerm = pSeg->term.p; - p1->xSetOutputs(p1, pSeg); - - assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 ); - if( bNewTerm ){ - if( nTermbase.nData==0 ) continue; - if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ - for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - int i1 = i*nMerge; - int iStore; - assert( i1+nMerge<=nBuf ); - for(iStore=i1; iStorebase.iRowid-(u64)iLastRowid, p1, &doclist); - iLastRowid = p1->base.iRowid; - } + fts5VisitPrefixRange( + p, pColset, pToken, nToken, prefixIterSetupCb, (void*)&s + ); - assert( (nBuf%nMerge)==0 ); - for(i=0; irc==SQLITE_OK ){ - xMerge(p, &doclist, nMerge, &aBuf[i]); + s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]); } - for(iFree=i; iFreep = (u8*)&pData[1]; - pData->nn = pData->szLeaf = doclist.n; - if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n); + pData->nn = pData->szLeaf = s.doclist.n; + if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n); fts5MultiIterNew2(p, pData, bDesc, ppIter); } - fts5BufferFree(&doclist); } + fts5BufferFree(&s.doclist); fts5StructureRelease(pStruct); - sqlite3_free(aBuf); + sqlite3_free(s.aBuf); } @@ -7021,7 +7068,6 @@ static Fts5Iter *fts5SetupTokendataIter( return pRet; } - /* ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. @@ -7046,9 +7092,11 @@ int sqlite3Fts5IndexQuery( int bTokendata = pConfig->bTokendata; if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); - /* The NOTOKENDATA flag is set when it is known that tokendata data will - ** not be required. e.g. for queries performed as part of an - ** integrity-check, or by the fts5vocab module. */ + /* The NOTOKENDATA flag is set when each token in a tokendata=1 table + ** should be treated individually, instead of merging all those with + ** a common prefix into a single entry. This is used, for example, by + ** queries performed as part of an integrity-check, or by the fts5vocab + ** module. */ if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){ bTokendata = 0; } @@ -7092,7 +7140,7 @@ int sqlite3Fts5IndexQuery( fts5StructureRelease(pStruct); } }else{ - /* Scan multiple terms in the main index */ + /* Scan multiple terms in the main index for a prefix query. */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); if( pRet==0 ){ @@ -7250,6 +7298,39 @@ static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ } } +typedef struct TokendataSetupCtx TokendataSetupCtx; +struct TokendataSetupCtx { + Fts5TokenDataIter *pT; + int iTermOff; + int nTermByte; +}; + +static void prefixIterSetupTokendataCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx; + int iPosOff = 0; + i64 iPos = 0; + + if( pNew ){ + pSetup->nTermByte = nNew-1; + pSetup->iTermOff = pSetup->pT->terms.n; + fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1); + } + + while( 0==sqlite3Fts5PoslistNext64( + p1->base.pData, p1->base.nData, &iPosOff, &iPos + ) ){ + fts5TokendataIterAppendMap(p, + pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos + ); + } +} + static int fts5SetupPrefixIterTokendata( Fts5Iter *pIter, const char *pToken, @@ -7257,73 +7338,31 @@ static int fts5SetupPrefixIterTokendata( ){ Fts5Index *p = pIter->pIndex; Fts5Buffer token = {0, 0, 0}; - Fts5TokenDataIter *pT = 0; + TokendataSetupCtx ctx; + + memset(&ctx, 0, sizeof(ctx)); fts5BufferGrow(&p->rc, &token, nToken+1); - pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); + ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT)); if( p->rc==SQLITE_OK ){ - const int flags = FTS5INDEX_QUERY_SCAN - | FTS5INDEX_QUERY_SKIPEMPTY - | FTS5INDEX_QUERY_NOOUTPUT; - Fts5Structure *pStruct = 0; - Fts5Iter *p1 = 0; /* Iterator used to find tokendata */ - - int bNewTerm = 1; - int iTermOff = 0; - int nTermByte = 0; /* Fill in the token prefix to search for */ token.p[0] = FTS5_MAIN_PREFIX; memcpy(&token.p[1], pToken, nToken); token.n = nToken+1; - /* Grab a reference to the table structure. That will be released before - ** this function returns. */ - pStruct = fts5StructureRead(p); - - fts5MultiIterNew(p, pStruct, flags, 0, token.p, token.n, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); - for( /* no-op */ ; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &bNewTerm) - ){ - i64 iPos = 0; - int iPosOff = 0; - - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - p1->xSetOutputs(p1, pSeg); - - if( bNewTerm ){ - int nTerm = pSeg->term.n; - const u8 *pTerm = pSeg->term.p; - assert_nc( memcmp(token.p, pTerm, MIN(token.n, nTerm))<=0 ); - if( nTermterms.n; - fts5BufferAppendBlob(&p->rc, &pT->terms, nTermByte, pTerm+1); - } - - while( 0==sqlite3Fts5PoslistNext64( - p1->base.pData, p1->base.nData, &iPosOff, &iPos - ) ){ - fts5TokendataIterAppendMap( - p, pT, iTermOff, nTermByte, p1->base.iRowid, iPos - ); - } - } - - /* fts5SetupPrefixIter */ - fts5MultiIterFree(p1); - fts5StructureRelease(pStruct); + fts5VisitPrefixRange( + p, 0, token.p, token.n, prefixIterSetupTokendataCb, (void*)&ctx + ); - fts5TokendataIterSortMap(p, pT); + fts5TokendataIterSortMap(p, ctx.pT); } if( p->rc==SQLITE_OK ){ - pIter->pTokenDataIter = pT; + pIter->pTokenDataIter = ctx.pT; }else{ - fts5TokendataIterDelete(pT); + fts5TokendataIterDelete(ctx.pT); } fts5BufferFree(&token); diff --git a/manifest b/manifest index 91a17cd96b..0d2ad1c4fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sway\stokendata\sindexes\sare\scollected\sfor\sprefix\squeries. -D 2024-09-25T18:55:11.223 +C Rationalize\ssome\sof\sthe\snew\scode\son\sthis\sbranch. +D 2024-09-28T20:45:11.387 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -99,7 +99,7 @@ F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70 F ext/fts5/fts5_config.c da21548ddbc1a457cb42545f527065221ede8ada6a734891b8c34317a7a9506b F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c 8dfb22c5e42cd56d3abbe107a5561fc3b4f731fc4c821ac049482d9dedc50acc +F ext/fts5/fts5_index.c c1005920192146452a3545500761ecc8cfab84572d251e8536103a01899f67d5 F ext/fts5/fts5_main.c 4503498d3453e29a3cd89dacaba029011e89cb8c481a6241611d106e7a369bd4 F ext/fts5/fts5_storage.c 3332497823c3d171cf56379f2bd8c971ce15a19aadacff961106462022c92470 F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe @@ -2214,8 +2214,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9945206e6e26a48a49b9747650d299eb983cc21a3a61c621cd81f0bbc85a74d7 -R d12c6f9d3e41d3b7f32c957f52650189 +P 204ddf4e726b695dd12ab4a945ec2461655aa0bcc38b74e970f07ed2ac43c6ff +R da06610bae74973a44f69a92b9b60e12 U dan -Z 0b9676f39cb90827333f01676ed89ac5 +Z ca9c653ea5575a07920ac6ddffa15d1d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 92e4aa62cf..f550314bcd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -204ddf4e726b695dd12ab4a945ec2461655aa0bcc38b74e970f07ed2ac43c6ff +66f209ba40e7de49b304d7931ff38a4994038452aab08e9347286a234c6f7075 From 0831b3a9896d83da9ae7f854ee74bc58d54951a6 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 30 Sep 2024 14:33:36 +0000 Subject: [PATCH 039/522] Generic build tinkering. FossilOrigin-Name: b6c1772ce0278988ecaea485c4feb8b0919fa1530f0c53b8321d9bd2277b5acd --- Makefile.in | 4 +- auto.def | 13 ++-- autosetup/hwaci-common.tcl | 119 +++++++++++++++++++++++-------------- manifest | 16 ++--- manifest.uuid | 2 +- 5 files changed, 90 insertions(+), 64 deletions(-) diff --git a/Makefile.in b/Makefile.in index aa984a53d5..9894a56ab9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -122,8 +122,8 @@ RELEASE = @RELEASE@ # BEXE = @BUILD_EXEEXT@ TEXE = @TARGET_EXEEXT@ -BDLL = @BDLL@ -TDLL = @TDLL@ +BDLL = @BUILD_DLLEXT@ +TDLL = @TARGET_DLLEXT@ # The following variable is "1" if the configure script was able to locate # the tclConfig.sh file. It is an empty string otherwise. When this diff --git a/auto.def b/auto.def index 2a87e4b711..07476f1c71 100644 --- a/auto.def +++ b/auto.def @@ -164,7 +164,7 @@ proc add-shell-opt {args} { } } -hwaci-check-exeext +hwaci-exe-extension if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_UNIX 0 define SQLITE_OS_WIN 1 @@ -174,8 +174,7 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_WIN 0 # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS? } -define BDLL [hwaci-dll-extension build] -define TDLL [hwaci-dll-extension host] +hwaci-dll-extension ######### # Programs needed @@ -323,8 +322,6 @@ hwaci-if-opt-truthy with-debug { msg-result no } -hwaci-check-rpath - ######################################################################## # TCL... define HAVE_TCL 0 @@ -477,6 +474,8 @@ if {"" eq [get-define CFLAGS_JIMSH]} { }; # end of tcl +hwaci-check-rpath + ######################################################################## # Thread safety? msg-checking "Support threadsafe operation? " @@ -867,8 +866,8 @@ hwaci-if-opt-truthy dump-defines { global DUMP_DEFINES_FILE msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" make-config-header $DUMP_DEFINES_FILE \ - -bare {OPT_FEATURE_FLAGS SQLITE_OS* SQLITE_DEBUG LDFLAGS_* USE_*} \ - -str {BIN_* CC LD AR} \ + -bare {SQLITE_OS* SQLITE_DEBUG USE_*} \ + -str {BIN_* CC LD AR LDFLAG* OPT_*} \ -auto {*} # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will # get _undefined_ here unless it's part of the -bare set. diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index b823d57c63..61d2c7d120 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -178,12 +178,15 @@ proc hwaci-if-opt-truthy {boolFlag thenScript {elseScript {}}} { } ######################################################################## -# If [hwaci-opt-truthy $flag] then [define $def $iftrue] else -# [define $def $iffalse]. Output [msg-checking $msg] and a -# [msg-results ...] which corresponds to the result. Returns 1 -# if the opt-truthy check passes, else 0. -proc hwaci-define-if-opt-truthy {flag def msg {iftrue 1} {iffalse 0}} { - msg-checking "$msg " +# If [hwaci-opt-truthy $flag] then [define $def $iftrue] else [define +# $def $iffalse]. If $msg is not empty, output [msg-checking $msg] and +# a [msg-results ...] which corresponds to the result. Returns 1 if +# the opt-truthy check passes, else 0. +proc hwaci-define-if-opt-truthy {flag def {msg ""} {iftrue 1} {iffalse 0}} { + if {"" ne $msg} { + msg-checking "$msg " + } + set rcMsg "" set rc 0 if {[hwaci-opt-truthy $flag]} { define $def $iftrue @@ -191,26 +194,27 @@ proc hwaci-define-if-opt-truthy {flag def msg {iftrue 1} {iffalse 0}} { } else { define $def $iffalse } - set msg [get-define $def] - switch -- $msg { - 0 { set msg no } - 1 { set msg yes } + switch -- [hwaci-val-truthy [get-define $def]] { + 0 { set rcMsg no } + 1 { set rcMsg yes } + } + if {"" ne $msg} { + msg-result $rcMsg } - msg-result $msg return $rc } ######################################################################## # Args: [-v] optName defName {descr {}} # -# Checks [hwaci-opt-truthy $optName] and does [define $defName X] where X is 0 -# for false and 1 for true. descr is an optional [msg-checking] -# argument which defaults to $defName. Returns X. +# Checks [hwaci-opt-truthy $optName] and calls [define $defName X] +# where X is 0 for false and 1 for true. descr is an optional +# [msg-checking] argument which defaults to $defName. Returns X. # # If args[0] is -v then the boolean semantics are inverted: if # the option is set, it gets define'd to 0, else 1. Returns the # define'd value. -proc hwaci-set-bool-01 {args} { +proc hwaci-opt-define-bool {args} { set invert 0 if {[lindex $args 0] eq "-v"} { set invert 1 @@ -450,21 +454,19 @@ proc hwaci-looks-like-windows {{key host}} { ######################################################################## # Looks at either the 'host' (==compilation target platform) or -# 'build' (==the being-built-on platform) define value and returns a -# file extension for DLLs on that platform, including the leading ".". +# 'build' (==the being-built-on platform) define value and returns if +# if that value seems to indicate that it represents a Mac platform, +# else returns 0. # # TODO: have someone verify whether this is correct for the # non-Linux/BSD platforms. -proc hwaci-dll-extension {{key host}} { +proc hwaci-looks-like-mac {{key host}} { switch -glob -- [get-define $key] { *apple* { - return ".dylib" - } - *-*-ming* - *-*-cygwin - *-*-msys { - return ".dll" + return 1 } default { - return ".so" + return 0 } } } @@ -475,24 +477,41 @@ proc hwaci-dll-extension {{key host}} { # build environment is then BUILD_EXEEXT is [define]'d to ".exe", else # "". If the target, a.k.a. "host", is then TARGET_EXEEXT is # [define]'d to ".exe", else "". -proc hwaci-check-exeext {} { - msg-checking "Build host is Windows-esque? " +proc hwaci-exe-extension {} { + set rH "" + set rB "" + if {[hwaci-looks-like-windows host]} { + set rH ".exe" + } if {[hwaci-looks-like-windows build]} { - define BUILD_EXEEXT ".exe" - msg-result yes - } else { - define BUILD_EXEEXT "" - msg-result no + set rB ".exe" } + define BUILD_EXEEXT $rH + define TARGET_EXEEXT $rB +} - msg-checking "Build target is Windows-esque? " - if {[hwaci-looks-like-windows host]} { - define TARGET_EXEEXT ".exe" - msg-result yes - } else { - define TARGET_EXEEXT "" - msg-result no +######################################################################## +# Works like hwaci-exe-extension except that it defines BUILD_DLLEXT +# and TARGET_DLLEXT to one of (.so, ,dll, .dylib). +# +# TODO: have someone verify whether this is correct for the +# non-Linux/BSD platforms. +proc hwaci-dll-extension {} { + proc inner {key} { + switch -glob -- [get-define $key] { + *apple* { + return ".dylib" + } + *-*-ming* - *-*-cygwin - *-*-msys { + return ".dll" + } + default { + return ".so" + } + } } + define BUILD_DLLEXT [inner host] + define TARGET_DLLEXT [inner build] } ######################################################################## @@ -577,17 +596,25 @@ proc hwaci-check-emsdk {} { # Tries various approaches to handling the -rpath link-time # flag. Defines LDFLAGS_RPATH to that/those flag(s) or an empty # string. Returns 1 if it finds an option, else 0. +# +# Achtung: we have seen platforms which report that a given option +# checked here will work but then fails at build-time, and the current +# order of checks reflects that. proc hwaci-check-rpath {} { - if {[cc-check-flags -Wl,-R/tmp]} { - define LDFLAGS_RPATH "-Wl,-R[get-define libdir]" - return 1 - } elseif {[cc-check-flags -Wl,-rpath -Wl,/tmp]} { - define LDFLAGS_RPATH "-Wl,-rpath -Wl,[get-define libdir]" - return 1 - } else { - define LDFLAGS_RPATH "" - return 0 + set rc 1 + cc-with {} { + if {[cc-check-flags {-rpath /tmp}]} { + define LDFLAGS_RPATH "-rpath [get-define prefix]/lib" + } elseif {[cc-check-flags {-Wl,-rpath -Wl,/tmp}]} { + define LDFLAGS_RPATH "-Wl,-rpath -Wl,[get-define prefix]/lib" + } elseif {[cc-check-flags -Wl,-R/tmp]} { + define LDFLAGS_RPATH "-Wl,-R[get-define prefix]/lib" + } else { + define LDFLAGS_RPATH "" + set rc 0 + } } + return $rc } ######################################################################## diff --git a/manifest b/manifest index aeed538d8d..9fdc001756 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Get\slibsqlite3.so\sbuilding. -D 2024-09-28T14:51:10.851 +C Generic\sbuild\stinkering. +D 2024-09-30T14:33:36.764 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 697e01f6bf783c56ccf80c31dcd58165b5a95469e4b5db716ffe70c48fccfbaa +F Makefile.in ce7b7897eddee0804eedae6daf7b5cd1e47d85cf9c01d9d74afc21fe6b2f8f5a F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 62bfff338c701174786e6613c30c2be7b98563dbdd1eaaaa3b4156165ee46d53 +F auto.def 1ea8aca38be00ded65793227d845c1766d2255c03eacb6a20ae6a14e304d5f64 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl bc7611bd7122b0308453bf0353ef81ae4658744f7ef67e5e53f3033551ddcac6 +F autosetup/hwaci-common.tcl 0d8454627c9e8352d9483cbe065a5a42cd885f3c8db3ddcadf4aaae1b5ac81c3 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b9faebbb543fb3a03f46dd4defe28ffa0c32a9a46ed73912f93b86e41f3db04a -R d30efb2f23fa7708ccc4acb26fa1caa0 +P c65e3679e0d28e980bb555b47f31690b27915d9ff0850f598e3bed528b18ca1d +R bebdd95eae12b76bf27e689681ef2876 U stephan -Z 22dfd7e3022119773556b9c0d01ecb08 +Z ea887720f1ab42cb508d0a1d2d23ebe1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 635d73158a..dc0f6a5d8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c65e3679e0d28e980bb555b47f31690b27915d9ff0850f598e3bed528b18ca1d +b6c1772ce0278988ecaea485c4feb8b0919fa1530f0c53b8321d9bd2277b5acd From c4c951adbe24d9cd28e79020e7b9cbcc69625806 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 30 Sep 2024 17:44:41 +0000 Subject: [PATCH 040/522] More generic build tinkering. FossilOrigin-Name: 433bfc790258e1d2e7c9ea4839a9edb25dde0b99d1e888d1e2a4cf669825fb79 --- Makefile.in | 7 ++++-- auto.def | 49 ++++++++++++++++++++++++-------------- autosetup/hwaci-common.tcl | 46 +++++++++++++++++++++++++++++------ manifest | 16 ++++++------- manifest.uuid | 2 +- 5 files changed, 84 insertions(+), 36 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9894a56ab9..ed161fe9e0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -21,6 +21,8 @@ TOP = @abs_top_srcdir@ # abs_top_builddir = @abs_top_builddir@ LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ LDFLAGS_MATH = @LDFLAGS_MATH@ +LDFLAGS_RPATH = @LDFLAGS_RPATH@ +LDFLAGS_READLINE = @LDFLAGS_READLINE@ LD = @LD@ AR = @AR@ @@ -723,10 +725,11 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) @touch $@ libsqlite3.DLL = libsqlite3$(TDLL) +LDFLAGS_libsqlite = $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_MATH) $(libsqlite3.DLL): $(LIBOBJ) $(TLINK) -o $@ \ @SHOBJ_LDFLAGS@ $(LIBOBJ) $(TLIBS) \ - @LDFLAGS_RPATH@ + $(LDFLAGS_libsqlite) dll: $(libsqlite3.DLL) all: dll @@ -740,7 +743,7 @@ all: dll sqlite3$(TEXE): shell.c sqlite3.c $(TCC) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ - @LDFLAGS_RPATH@ @LDFLAGS_READLINE@ $(TLIBS) + $(LDFLAGS_libsqlite) $(LDFLAGS_READLINE) cli: sqlite3$(TEXE) all: cli #XX# diff --git a/auto.def b/auto.def index 07476f1c71..a351f8f63a 100644 --- a/auto.def +++ b/auto.def @@ -276,7 +276,7 @@ cc-check-types int8_t int16_t int32_t int64_t intptr_t \ cc-check-functions gmtime_r isnan localtime_r localtime_s \ malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 -cc-check-function-in-lib fdatasync rt +hwaci-check-function-in-lib fdatasync rt define LDFLAGS_FDATASYNC [get-define lib_fdatasync] undefine lib_fdatasync @@ -291,7 +291,7 @@ cc-check-includes \ # These are optional for JimTCL: cc-check-includes dirent.h sys/time.h -if {[cc-check-includes zlib.h] && [cc-check-function-in-lib deflate z]} { +if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { # TODO: port over the more sophisticated zlib search from the fossil auto.def define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" define LDFLAGS_ZLIB -lz @@ -482,8 +482,8 @@ msg-checking "Support threadsafe operation? " hwaci-if-opt-truthy threadsafe { msg-result yes add-feature-flag -DSQLITE_THREADSAFE=1 - if {![cc-check-function-in-lib pthread_create pthread] - || ![cc-check-function-in-lib pthread_mutexattr_init pthread]} { + if {![hwaci-check-function-in-lib pthread_create pthread] + || ![hwaci-check-function-in-lib pthread_mutexattr_init pthread]} { user-error "Missing required pthread bits" } define LDFLAGS_PTHREAD [get-define lib_pthread_create] @@ -570,7 +570,7 @@ if {1} { # XXX sLIBS=$LIBS # XXX LIBS="" # XXX TARGET_HAVE_EDITLINE=1 - if {[cc-check-function-in-lib readline edit]} { + if {[hwaci-check-function-in-lib readline edit]} { set with_readline no } else { # XXX TARGET_HAVE_EDITLINE=0 @@ -590,12 +590,12 @@ if {1} { # XXX if test "x$with_readline_lib" = xauto; then # XXX save_LIBS="$LIBS" # XXX LIBS="" - if {[cc-check-function-in-lib tgetent readline ncurses curses termcap]} { + if {[hwaci-check-function-in-lib tgetent readline ncurses curses termcap]} { # XXX term_LIBS="$LIBS" } else { # XXX term_LIBS="" } - if {[cc-check-function-in-lib readline readline]} { + if {[hwaci-check-function-in-lib readline readline]} { # XXX TARGET_READLINE_LIBS="-lreadline" } else { set found "no" @@ -668,7 +668,7 @@ if {1} { } hwaci-if-opt-truthy load-extension { - if {[cc-check-function-in-lib dlopen dl]} { + if {[hwaci-check-function-in-lib dlopen dl]} { define LDFLAGS_DLOPEN [get-define lib_dlopen] undefine lib_dlopen } else { @@ -681,25 +681,18 @@ hwaci-if-opt-truthy load-extension { } hwaci-if-opt-truthy math { - if {![cc-check-function-in-lib ceil m]} { + if {![hwaci-check-function-in-lib ceil m]} { user-error "Cannot find libm functions. Use --disable-math to bypass this." } define LDFLAGS_MATH [get-define lib_ceil] undefine lib_ceil add-feature-flag {-DSQLITE_ENABLE_MATH_FUNCTIONS} - msg-result "Enabling math SQL functions" + msg-result "Enabling math SQL functions [get-define LDFLAGS_MATH]" } { define LDFLAGS_MATH "" msg-result "Disabling math SQL functions" } -hwaci-if-opt-truthy json { - msg-result "Enabling JSON SQL functions" -} { - add-feature-flag {-DSQLITE_OMIT_JSON} - msg-result "Disabling JSON SQL functions" -} - if {0} { # is this still relevant? @@ -766,7 +759,7 @@ if {[hwaci-check-emsdk]} { } proc affirm-have-math {} { - if {![cc-check-function-in-lib log m]} { + if {![hwaci-check-function-in-lib log m]} { user-error "Missing required math APIs" } define LDFLAGS_MATH [get-define lib_log ""] @@ -806,6 +799,22 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } } +######################################################################## +# Invert the above loop's logic for some explicit +# SQLITE_OMIT_... cases. If config option $boolFlag is set, +# [add-feature-flag $featureFlag], where $featureFlag is intended to +# be -DSQLITE_OMIT_... +foreach {boolFlag featureFlag} { + json -DSQLITE_OMIT_JSON +} { + if {[hwaci-opt-truthy $boolFlag]} { + msg-result "Enabling $boolFlag" + } else { + add-feature-flag $featureFlag + msg-result "Disabling $boolFlag" + } +} + ######################################################################## # Maybe extend JimTCL a bit. As of this writing (2024-09-27) it only # needs -DHAVE_REALPATH or -DHAVE__FULLPATH to be compatible with our @@ -877,3 +886,7 @@ hwaci-if-opt-truthy dump-defines { } } } + +puts { +Done! Now run "make". +} diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 61d2c7d120..2239525b4c 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -20,6 +20,25 @@ # project, authored by the same person who ported it here, noted here # only as an indication that there are no licensing issue despite this # code having at least two near-twins running around in other trees. +# +######################################################################## +# +# Design notes: by and large, autosetup prefers to update global state +# with the results of feature checks, e.g. whether the compiler +# supports flag --X. In this developer's opinion that (A) causes more +# confusion than it solves[^1] and (B) adds an unnecessary layer of +# "voodoo" between the autosetup user and its internals. This module, +# in contrast, instead injects the results of its own tests into +# well-defined variables and leaves the integration of those values to +# the caller's discretion. +# +# [1]: As an example: testing for the -rpath flag, using +# cc-check-flags, can break later checks which use +# [cc-check-function-in-lib ...] because the resulting -rpath flag +# implicitly becomes part of those tests. In the case of an rpath +# test, downstream tests may not like the $prefix/lib path added by +# the rpath test. To avoid such problems, we avoid (intentionally) +# updating global state via feature tests. ######################################################################## array set hwaci-cache- {} ; # used for caching various results. @@ -602,13 +621,18 @@ proc hwaci-check-emsdk {} { # order of checks reflects that. proc hwaci-check-rpath {} { set rc 1 + set lp "[get-define prefix]/lib" + # If we _don't_ use cc-with {} here (to avoid updating the global + # CFLAGS or LIBS or whatever it is that cc-check-flags updates) then + # downstream tests may fail because the resulting rpath gets + # implicitly injected into them. cc-with {} { - if {[cc-check-flags {-rpath /tmp}]} { - define LDFLAGS_RPATH "-rpath [get-define prefix]/lib" - } elseif {[cc-check-flags {-Wl,-rpath -Wl,/tmp}]} { - define LDFLAGS_RPATH "-Wl,-rpath -Wl,[get-define prefix]/lib" - } elseif {[cc-check-flags -Wl,-R/tmp]} { - define LDFLAGS_RPATH "-Wl,-R[get-define prefix]/lib" + if {[cc-check-flags {-rpath $lp}]} { + define LDFLAGS_RPATH "-rpath $lp" + } elseif {[cc-check-flags {-Wl,-rpath -Wl,$lp}]} { + define LDFLAGS_RPATH "-Wl,-rpath -Wl,$lp" + } elseif {[cc-check-flags -Wl,-R$lp]} { + define LDFLAGS_RPATH "-Wl,-R$lp" } else { define LDFLAGS_RPATH "" set rc 0 @@ -618,7 +642,15 @@ proc hwaci-check-rpath {} { } ######################################################################## -# Under construction - check for libreadline functionality +# Under construction - check for libreadline functionality. +# Defines the following vars: +# +# - HAVE_READLINE: 0 or 1 +# - LDFLAGS_READLINE: "" or linker flags +# - CFLAGS_READLINE: "" or c-flags +# - READLINE_H: "" or "readline/readlin.h" (or similar) +# +# Returns the value of HAVE_READLINE. proc hwaci-check-readline {} { define HAVE_READLINE 0 define LDFLAGS_READLINE "" diff --git a/manifest b/manifest index 9fdc001756..572fb362fe 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Generic\sbuild\stinkering. -D 2024-09-30T14:33:36.764 +C More\sgeneric\sbuild\stinkering. +D 2024-09-30T17:44:41.299 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in ce7b7897eddee0804eedae6daf7b5cd1e47d85cf9c01d9d74afc21fe6b2f8f5a +F Makefile.in b791c6761d7e3b020fe6001cc33f985f99c0d9e3a745e94fe7c25d09dc1d6f45 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 1ea8aca38be00ded65793227d845c1766d2255c03eacb6a20ae6a14e304d5f64 +F auto.def 82046ac0d90df3b6478bf193610d00254b64a4fbaba4e08bdd9964fda6baa532 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 0d8454627c9e8352d9483cbe065a5a42cd885f3c8db3ddcadf4aaae1b5ac81c3 +F autosetup/hwaci-common.tcl c92da569c334b6db38c91f99f4ba26a5a5746b955e7fad1ba585bd1064a82d1c F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c65e3679e0d28e980bb555b47f31690b27915d9ff0850f598e3bed528b18ca1d -R bebdd95eae12b76bf27e689681ef2876 +P b6c1772ce0278988ecaea485c4feb8b0919fa1530f0c53b8321d9bd2277b5acd +R 3f3552467c9f9c5110dce0fc316253de U stephan -Z ea887720f1ab42cb508d0a1d2d23ebe1 +Z 5922ab49dc459c0a84758656bf396042 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dc0f6a5d8c..f8e4e253ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6c1772ce0278988ecaea485c4feb8b0919fa1530f0c53b8321d9bd2277b5acd +433bfc790258e1d2e7c9ea4839a9edb25dde0b99d1e888d1e2a4cf669825fb79 From aca993423fd7ae9c868498006a95c20a69d3b77d Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 30 Sep 2024 19:01:41 +0000 Subject: [PATCH 041/522] Add static library build. Get build working (for a given value of working) with the --disable-amalgamation flag. FossilOrigin-Name: ddfda58004fa3e43c4f2d497c6feecbea3b195d14196bf179f4aafd21ea089ea --- Makefile.in | 769 +++++++++++++++++++------------------ auto.def | 6 + autosetup/hwaci-common.tcl | 22 ++ manifest | 16 +- manifest.uuid | 2 +- 5 files changed, 425 insertions(+), 390 deletions(-) diff --git a/Makefile.in b/Makefile.in index ed161fe9e0..8b59372d31 100644 --- a/Makefile.in +++ b/Makefile.in @@ -113,7 +113,7 @@ TCC += $(OPT_FEATURE_FLAGS) TCC += $(OPTS) # Add in compile-time options for some libraries used by extensions -TCC += @LDFLAGS_ZLIB@ +TCC += @CFLAGS_ZLIB@ # Version numbers and release number for the SQLite being compiled. # @@ -126,6 +126,8 @@ BEXE = @BUILD_EXEEXT@ TEXE = @TARGET_EXEEXT@ BDLL = @BUILD_DLLEXT@ TDLL = @TARGET_DLLEXT@ +BLIB = @BUILD_LIBEXT@ +TLIB = @TARGET_LIBEXT@ # The following variable is "1" if the configure script was able to locate # the tclConfig.sh file. It is an empty string otherwise. When this @@ -163,8 +165,8 @@ TSTRNNR_OPTS = @TSTRNNR_OPTS@ GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage GCOV_LDFLAGS1 = -lgcov USE_GCOV = @USE_GCOV@ -LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) -LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) +TCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) +TLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) # The directory into which to store package information for @@ -181,11 +183,11 @@ INSTALL = @BIN_INSTALL@ #XX#ALLOWRELEASE = @ALLOWRELEASE@ #XX# #XX## libtool compile/link/install -#XX#LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS) -#XX#LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS) +#XX#TCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(TCOMPILE_EXTRAS) +#XX#TLINK = $(LIBTOOL) --mode=link $(TCC) $(TCOMPILE_EXTRAS) @LDFLAGS@ $(TLINK_EXTRAS) #XX#LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) -TCOMPILE = $(TCC) $(LTCOMPILE_EXTRAS) -TLINK = $(TCC) $(LTLINK_EXTRAS) +TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) +TLINK = $(TCC) $(TLINK_EXTRAS) TINSTALL = $(INSTALL) # @@ -712,11 +714,11 @@ all: sqlite3.h sqlite3.c shell.c $(SQLITE3_SHELL_TARGET) # AUTOREMAKE = @SQLITE_AUTOREMAKE@ -Makefile: $(TOP)/Makefile.in +Makefile: $(TOP)/Makefile.in $(AS_AUTO_DEF) $(AUTOREMAKE) @touch $@ -sqlite3.pc: $(TOP)/sqlite3.pc.in +sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF) $(AUTOREMAKE) @touch $@ @@ -725,7 +727,9 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) @touch $@ libsqlite3.DLL = libsqlite3$(TDLL) +libsqlite3.LIB = libsqlite3$(TLIB) LDFLAGS_libsqlite = $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_MATH) + $(libsqlite3.DLL): $(LIBOBJ) $(TLINK) -o $@ \ @SHOBJ_LDFLAGS@ $(LIBOBJ) $(TLIBS) \ @@ -733,8 +737,13 @@ $(libsqlite3.DLL): $(LIBOBJ) dll: $(libsqlite3.DLL) all: dll +$(libsqlite3.LIB): $(LIBOBJ) + $(AR) r $@ $(LIBOBJ) +lib: $(libsqlite3.LIB) +all: lib + #XX#libtclsqlite3.la: tclsqlite.lo libsqlite3.la -#XX# $(LTLINK) -no-undefined -o $@ tclsqlite.lo \ +#XX# $(TLINK) -no-undefined -o $@ tclsqlite.lo \ #XX# libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \ #XX# -rpath "$(TCLLIBDIR)" \ #XX# -version-info "8:6:8" \ @@ -748,10 +757,10 @@ cli: sqlite3$(TEXE) all: cli #XX# #XX#sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h -#XX# $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) #XX# #XX#dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h -#XX# $(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS) #XX# #XX#RSYNC_SRC = \ #XX# $(TOP)/tool/sqlite3-rsync.c \ @@ -768,7 +777,7 @@ all: cli #XX# $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(TLIBS) #XX# #XX#scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo -#XX# $(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \ +#XX# $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ #XX# $(TOP)/ext/misc/scrub.c sqlite3.lo $(TLIBS) #XX# srcck1$(BEXE): $(TOP)/tool/srcck1.c @@ -806,17 +815,17 @@ $(BTCL): #XX# ./src-verify $(TOP) #XX# #XX#fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h -#XX# $(LTLINK) -o $@ $(FUZZERSHELL_OPT) \ +#XX# $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ #XX# $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) #XX# #XX#fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) -#XX# $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) +#XX# $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) #XX# #XX#fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) -#XX# $(LTLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) +#XX# $(TLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) #XX# #XX#fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) -#XX# $(LTLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) +#XX# $(TLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) #XX# #XX## Usage: FUZZDB=filename make run-fuzzcheck #XX## @@ -834,14 +843,14 @@ $(BTCL): #XX# ./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB) #XX# #XX#ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h -#XX# $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ +#XX# $(TLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ #XX# $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) #XX# #XX#sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h -#XX# $(LTLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS) #XX# #XX#dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h -#XX# $(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) +#XX# $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) #XX# #XX#DBFUZZ2_OPTS = \ #XX# -DSQLITE_THREADSAFE=0 \ @@ -875,7 +884,7 @@ $(BTCL): #XX# cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir #XX# #XX#mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c -#XX# $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ +#XX# $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ #XX# $(TLIBS) -rpath "$(libdir)" #XX# #XX#MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 @@ -951,7 +960,7 @@ sqlite3ext.h: .target_source #XX## Rule to build the amalgamation #XX## #XX#sqlite3.lo: sqlite3.c -#XX# $(LTCOMPILE) $(TEMP_STORE) -c sqlite3.c +#XX# $(TCOMPILE) $(TEMP_STORE) -c sqlite3.c # Rules to build the LEMON compiler generator # @@ -964,271 +973,271 @@ lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c mksourceid$(BEXE): $(TOP)/tool/mksourceid.c $(BCC) -o $@ $(TOP)/tool/mksourceid.c -#XX## Rules to build individual *.o files from generated *.c files. This -#XX## applies to: -#XX## -#XX## parse.o -#XX## opcodes.o -#XX## -#XX#parse.lo: parse.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c parse.c -#XX# -#XX#opcodes.lo: opcodes.c -#XX# $(LTCOMPILE) $(TEMP_STORE) -c opcodes.c -#XX# -#XX## Rules to build individual *.o files from files in the src directory. -#XX## -#XX#alter.lo: $(TOP)/src/alter.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c -#XX# -#XX#analyze.lo: $(TOP)/src/analyze.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c -#XX# -#XX#attach.lo: $(TOP)/src/attach.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c -#XX# -#XX#auth.lo: $(TOP)/src/auth.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c -#XX# -#XX#backup.lo: $(TOP)/src/backup.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c -#XX# -#XX#bitvec.lo: $(TOP)/src/bitvec.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c -#XX# -#XX#btmutex.lo: $(TOP)/src/btmutex.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c -#XX# -#XX#btree.lo: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c -#XX# -#XX#build.lo: $(TOP)/src/build.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c -#XX# -#XX#callback.lo: $(TOP)/src/callback.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c -#XX# -#XX#complete.lo: $(TOP)/src/complete.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c -#XX# -#XX#ctime.lo: $(TOP)/src/ctime.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c -#XX# -#XX#date.lo: $(TOP)/src/date.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c -#XX# -#XX#dbpage.lo: $(TOP)/src/dbpage.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c -#XX# -#XX#dbstat.lo: $(TOP)/src/dbstat.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c -#XX# -#XX#delete.lo: $(TOP)/src/delete.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c -#XX# -#XX#expr.lo: $(TOP)/src/expr.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c -#XX# -#XX#fault.lo: $(TOP)/src/fault.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c -#XX# -#XX#fkey.lo: $(TOP)/src/fkey.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c -#XX# -#XX#func.lo: $(TOP)/src/func.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c -#XX# -#XX#global.lo: $(TOP)/src/global.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c -#XX# -#XX#hash.lo: $(TOP)/src/hash.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c -#XX# -#XX#insert.lo: $(TOP)/src/insert.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c -#XX# -#XX#json.lo: $(TOP)/src/json.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c -#XX# -#XX#legacy.lo: $(TOP)/src/legacy.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c -#XX# -#XX#loadext.lo: $(TOP)/src/loadext.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c -#XX# -#XX#main.lo: $(TOP)/src/main.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c -#XX# -#XX#malloc.lo: $(TOP)/src/malloc.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c -#XX# -#XX#mem0.lo: $(TOP)/src/mem0.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c -#XX# -#XX#mem1.lo: $(TOP)/src/mem1.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c -#XX# -#XX#mem2.lo: $(TOP)/src/mem2.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c -#XX# -#XX#mem3.lo: $(TOP)/src/mem3.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c -#XX# -#XX#mem5.lo: $(TOP)/src/mem5.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c -#XX# -#XX#memdb.lo: $(TOP)/src/memdb.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c -#XX# -#XX#memjournal.lo: $(TOP)/src/memjournal.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c -#XX# -#XX#mutex.lo: $(TOP)/src/mutex.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c -#XX# -#XX#mutex_noop.lo: $(TOP)/src/mutex_noop.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c -#XX# -#XX#mutex_unix.lo: $(TOP)/src/mutex_unix.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c -#XX# -#XX#mutex_w32.lo: $(TOP)/src/mutex_w32.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c -#XX# -#XX#notify.lo: $(TOP)/src/notify.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c -#XX# -#XX#pager.lo: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c -#XX# -#XX#pcache.lo: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c -#XX# -#XX#pcache1.lo: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c -#XX# -#XX#os.lo: $(TOP)/src/os.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c -#XX# -#XX#os_kv.lo: $(TOP)/src/os_kv.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c -#XX# -#XX#os_unix.lo: $(TOP)/src/os_unix.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c -#XX# -#XX#os_win.lo: $(TOP)/src/os_win.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c -#XX# -#XX#pragma.lo: $(TOP)/src/pragma.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c -#XX# -#XX#prepare.lo: $(TOP)/src/prepare.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c -#XX# -#XX#printf.lo: $(TOP)/src/printf.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c -#XX# -#XX#random.lo: $(TOP)/src/random.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c -#XX# -#XX#resolve.lo: $(TOP)/src/resolve.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c -#XX# -#XX#rowset.lo: $(TOP)/src/rowset.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c -#XX# -#XX#select.lo: $(TOP)/src/select.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c -#XX# -#XX#status.lo: $(TOP)/src/status.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c -#XX# -#XX#table.lo: $(TOP)/src/table.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c -#XX# -#XX#threads.lo: $(TOP)/src/threads.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c -#XX# -#XX#tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c -#XX# -#XX#treeview.lo: $(TOP)/src/treeview.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/treeview.c -#XX# -#XX#trigger.lo: $(TOP)/src/trigger.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c -#XX# -#XX#update.lo: $(TOP)/src/update.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c -#XX# -#XX#upsert.lo: $(TOP)/src/upsert.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c -#XX# -#XX#utf.lo: $(TOP)/src/utf.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c -#XX# -#XX#util.lo: $(TOP)/src/util.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c -#XX# -#XX#vacuum.lo: $(TOP)/src/vacuum.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c -#XX# -#XX#vdbe.lo: $(TOP)/src/vdbe.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c -#XX# -#XX#vdbeapi.lo: $(TOP)/src/vdbeapi.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c -#XX# -#XX#vdbeaux.lo: $(TOP)/src/vdbeaux.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c -#XX# -#XX#vdbeblob.lo: $(TOP)/src/vdbeblob.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c -#XX# -#XX#vdbemem.lo: $(TOP)/src/vdbemem.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c -#XX# -#XX#vdbesort.lo: $(TOP)/src/vdbesort.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c -#XX# -#XX#vdbetrace.lo: $(TOP)/src/vdbetrace.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c -#XX# -#XX#vdbevtab.lo: $(TOP)/src/vdbevtab.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c -#XX# -#XX#vtab.lo: $(TOP)/src/vtab.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c -#XX# -#XX#wal.lo: $(TOP)/src/wal.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c -#XX# -#XX#walker.lo: $(TOP)/src/walker.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c -#XX# -#XX#where.lo: $(TOP)/src/where.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c -#XX# -#XX#wherecode.lo: $(TOP)/src/wherecode.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c -#XX# -#XX#whereexpr.lo: $(TOP)/src/whereexpr.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c -#XX# -#XX#window.lo: $(TOP)/src/window.c $(HDR) -#XX# $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c -#XX# -#XX#tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) -#XX# $(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c +# Rules to build individual *.o files from generated *.c files. This +# applies to: +# +# parse.o +# opcodes.o +# +parse.o: parse.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c parse.c + +opcodes.o: opcodes.c + $(TCOMPILE) $(TEMP_STORE) -c opcodes.c + +# Rules to build individual *.o files from files in the src directory. +# +alter.o: $(TOP)/src/alter.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c + +analyze.o: $(TOP)/src/analyze.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c + +attach.o: $(TOP)/src/attach.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c + +auth.o: $(TOP)/src/auth.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c + +backup.o: $(TOP)/src/backup.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c + +bitvec.o: $(TOP)/src/bitvec.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c + +btmutex.o: $(TOP)/src/btmutex.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c + +btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c + +build.o: $(TOP)/src/build.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c + +callback.o: $(TOP)/src/callback.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c + +complete.o: $(TOP)/src/complete.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c + +ctime.o: $(TOP)/src/ctime.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c + +date.o: $(TOP)/src/date.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c + +dbpage.o: $(TOP)/src/dbpage.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c + +dbstat.o: $(TOP)/src/dbstat.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c + +delete.o: $(TOP)/src/delete.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c + +expr.o: $(TOP)/src/expr.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c + +fault.o: $(TOP)/src/fault.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c + +fkey.o: $(TOP)/src/fkey.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c + +func.o: $(TOP)/src/func.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c + +global.o: $(TOP)/src/global.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c + +hash.o: $(TOP)/src/hash.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c + +insert.o: $(TOP)/src/insert.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c + +json.o: $(TOP)/src/json.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c + +legacy.o: $(TOP)/src/legacy.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c + +loadext.o: $(TOP)/src/loadext.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c + +main.o: $(TOP)/src/main.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c + +malloc.o: $(TOP)/src/malloc.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c + +mem0.o: $(TOP)/src/mem0.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c + +mem1.o: $(TOP)/src/mem1.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c + +mem2.o: $(TOP)/src/mem2.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c + +mem3.o: $(TOP)/src/mem3.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c + +mem5.o: $(TOP)/src/mem5.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c + +memdb.o: $(TOP)/src/memdb.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c + +memjournal.o: $(TOP)/src/memjournal.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c + +mutex.o: $(TOP)/src/mutex.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c + +mutex_noop.o: $(TOP)/src/mutex_noop.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c + +mutex_unix.o: $(TOP)/src/mutex_unix.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c + +mutex_w32.o: $(TOP)/src/mutex_w32.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c + +notify.o: $(TOP)/src/notify.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c + +pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c + +pcache.o: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c + +pcache1.o: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c + +os.o: $(TOP)/src/os.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c + +os_kv.o: $(TOP)/src/os_kv.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c + +os_unix.o: $(TOP)/src/os_unix.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c + +os_win.o: $(TOP)/src/os_win.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c + +pragma.o: $(TOP)/src/pragma.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c + +prepare.o: $(TOP)/src/prepare.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c + +printf.o: $(TOP)/src/printf.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c + +random.o: $(TOP)/src/random.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c + +resolve.o: $(TOP)/src/resolve.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c + +rowset.o: $(TOP)/src/rowset.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c + +select.o: $(TOP)/src/select.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c + +status.o: $(TOP)/src/status.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c + +table.o: $(TOP)/src/table.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c + +threads.o: $(TOP)/src/threads.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c + +tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c + +treeview.o: $(TOP)/src/treeview.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/treeview.c + +trigger.o: $(TOP)/src/trigger.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c + +update.o: $(TOP)/src/update.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c + +upsert.o: $(TOP)/src/upsert.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c + +utf.o: $(TOP)/src/utf.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c + +util.o: $(TOP)/src/util.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c + +vacuum.o: $(TOP)/src/vacuum.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c + +vdbe.o: $(TOP)/src/vdbe.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c + +vdbeapi.o: $(TOP)/src/vdbeapi.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c + +vdbeaux.o: $(TOP)/src/vdbeaux.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c + +vdbeblob.o: $(TOP)/src/vdbeblob.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c + +vdbemem.o: $(TOP)/src/vdbemem.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c + +vdbesort.o: $(TOP)/src/vdbesort.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c + +vdbetrace.o: $(TOP)/src/vdbetrace.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c + +vdbevtab.o: $(TOP)/src/vdbevtab.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c + +vtab.o: $(TOP)/src/vtab.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c + +wal.o: $(TOP)/src/wal.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c + +walker.o: $(TOP)/src/walker.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c + +where.o: $(TOP)/src/where.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c + +wherecode.o: $(TOP)/src/wherecode.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c + +whereexpr.o: $(TOP)/src/whereexpr.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c + +window.o: $(TOP)/src/window.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c + +#XX#tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) +#XX# $(TCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c #XX# -#XX#tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR) -#XX# $(LTCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c +#XX#tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(HDR) +#XX# $(TCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c #XX# -#XX#tclsqlite-stubs.lo: $(TOP)/src/tclsqlite.c $(HDR) -#XX# $(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c +#XX#tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(HDR) +#XX# $(TCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c #XX# #XX#tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.lo libsqlite3.la -#XX# $(LTLINK) -o $@ tclsqlite-shell.lo \ +#XX# $(TLINK) -o $@ tclsqlite-shell.lo \ #XX# libsqlite3.la $(LIBTCL) # Rules to build opcodes.c and opcodes.h @@ -1297,65 +1306,63 @@ SHELL_DEP = \ shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCL) # has_tclsh84 $(BTCL) $(TOP)/tool/mkshellc.tcl >shell.c -#XX# -#XX# -#XX# -#XX# -#XX## Rules to build the extension objects. -#XX## -#XX#icu.lo: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c -#XX# -#XX#fts3.lo: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c -#XX# -#XX#fts3_aux.lo: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c -#XX# -#XX#fts3_expr.lo: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c -#XX# -#XX#fts3_hash.lo: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c -#XX# -#XX#fts3_icu.lo: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c -#XX# -#XX#fts3_porter.lo: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c -#XX# -#XX#fts3_snippet.lo: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c -#XX# -#XX#fts3_tokenizer.lo: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c -#XX# -#XX#fts3_tokenizer1.lo: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c -#XX# -#XX#fts3_tokenize_vtab.lo: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c -#XX# -#XX#fts3_unicode.lo: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c -#XX# -#XX#fts3_unicode2.lo: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c -#XX# -#XX#fts3_write.lo: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c -#XX# -#XX#rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c -#XX# -#XX#userauth.lo: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c -#XX# -#XX#sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c -#XX# -#XX#stmt.lo: $(TOP)/ext/misc/stmt.c -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c + + +# Rules to build the extension objects. +# +icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c + +fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c + +fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c + +fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c + +fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c + +fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c + +fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c + +fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c + +fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c + +fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c + +fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c + +fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c + +fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c + +fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c + +rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c + +userauth.o: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c + +sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c + +stmt.o: $(TOP)/ext/misc/stmt.c + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c # FTS5 things # @@ -1387,13 +1394,13 @@ fts5.c: $(FTS5_SRC) $(BTCL) # has_tclsh84 $(BTCL) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . -#XX#fts5.lo: fts5.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c fts5.c -#XX# -#XX#sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) -#XX# $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c -#XX# -#XX# +fts5.o: fts5.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c fts5.c + +sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c + + #XX## Rules to build the 'testfixture' application. #XX## #XX## If using the amalgamation, use sqlite3.c directly to build the test @@ -1420,7 +1427,7 @@ fts5.c: $(FTS5_SRC) $(BTCL) # has_tclsh84 #XX#TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) #XX# #XX#testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) -#XX# $(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ +#XX# $(TLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ #XX# -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS) #XX# #XX#coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) @@ -1527,16 +1534,16 @@ fts5.c: $(FTS5_SRC) $(BTCL) # has_tclsh84 #XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c #XX# #XX#sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c -#XX# $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) +#XX# $(TLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) #XX# #XX#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 has_tclsh85 #XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c #XX# #XX#sqltclsh$(TEXE): has_tclconfig sqltclsh.c -#XX# $(LTLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS) +#XX# $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS) #XX# #XX#sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -#XX# $(LTLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(TLIBS) +#XX# $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(TLIBS) #XX# #XX#CHECKER_DEPS =\ #XX# $(TOP)/tool/mkccode.tcl \ @@ -1552,53 +1559,53 @@ fts5.c: $(FTS5_SRC) $(BTCL) # has_tclsh84 #XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ #XX# #XX#sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c -#XX# $(LTLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS) +#XX# $(TLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS) #XX# #XX#dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo -#XX# $(LTLINK) -DDBDUMP_STANDALONE -o $@ \ +#XX# $(TLINK) -DDBDUMP_STANDALONE -o $@ \ #XX# $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS) #XX# #XX#dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c -#XX# $(LTLINK)-o $@ $(TOP)/tool/dbtotxt.c +#XX# $(TLINK)-o $@ $(TOP)/tool/dbtotxt.c #XX# #XX#showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS) #XX# #XX#showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(TLIBS) #XX# #XX#showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(TLIBS) #XX# #XX#showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(TLIBS) #XX# #XX#showshm$(TEXE): $(TOP)/tool/showshm.c -#XX# $(LTLINK) -o $@ $(TOP)/tool/showshm.c +#XX# $(TLINK) -o $@ $(TOP)/tool/showshm.c #XX# #XX#index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo -#XX# $(LTLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(TLIBS) #XX# #XX#changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) #XX# #XX#changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS) #XX# #XX#rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) #XX# #XX#atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS) #XX# #XX#LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h -#XX# $(LTLINK) -I. -o $@ $(TOP)/tool/logest.c +#XX# $(TLINK) -I. -o $@ $(TOP)/tool/logest.c #XX# #XX#wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo -#XX# $(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS) #XX# #XX#speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile -#XX# $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) +#XX# $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) #XX# #XX#startup$(TEXE): $(TOP)/test/startup.c sqlite3.c #XX# $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) @@ -1606,13 +1613,13 @@ fts5.c: $(FTS5_SRC) $(BTCL) # has_tclsh84 #XX#KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ #XX# #XX#kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c -#XX# $(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS) +#XX# $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS) #XX# #XX#rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo -#XX# $(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS) +#XX# $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS) #XX# #XX#loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la -#XX# $(LTLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(TLIBS) +#XX# $(TLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(TLIBS) #XX# #XX## This target will fail if the SQLite amalgamation contains any exported #XX## symbols that do not begin with "sqlite3_". It is run as part of the @@ -1651,13 +1658,13 @@ fts5.c: $(FTS5_SRC) $(BTCL) # has_tclsh84 #XX# $(TOP)/test/tt3_lookaside1.c #XX# #XX#threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC) -#XX# $(LTLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(TLIBS) +#XX# $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(TLIBS) #XX# #XX#threadtest: threadtest3$(TEXE) #XX# ./threadtest3$(TEXE) #XX# #XX#threadtest5: sqlite3.c $(TOP)/test/threadtest5.c -#XX# $(LTLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS) +#XX# $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS) #XX# #XX## Standard install and cleanup targets #XX## @@ -1725,6 +1732,7 @@ tidy: rm -f lemon$(BEXE) sqlite*.tar.gz rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) rm -f parse.* fts5parse.* + rm -f $(libsqlite3.DLL) $(libsqlite3.LIB) rm -f tclsqlite3$(TEXE) $(TESTPROGS) rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) @@ -1789,10 +1797,9 @@ distclean: clean #XX#misspell: ./custom.rws has_tclsh84 #XX# $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in #XX# -#XX## -#XX## tool/version-info: a utility for emitting sqlite3 version info -#XX## in various forms. -#XX## -#XX#version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h -#XX# $(LTLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c -#XX# +# +# tool/version-info: a utility for emitting sqlite3 version info +# in various forms. +# +version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h + $(TLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c diff --git a/auto.def b/auto.def index a351f8f63a..1406dfc736 100644 --- a/auto.def +++ b/auto.def @@ -175,6 +175,7 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS? } hwaci-dll-extension +hwaci-lib-extension ######### # Programs needed @@ -295,9 +296,14 @@ if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { # TODO: port over the more sophisticated zlib search from the fossil auto.def define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" define LDFLAGS_ZLIB -lz +# -DSQLITE_HAVE_ZLIB=1 is handled separately from the other feature +# flags in the autotools build +# add-feature-flag -DSQLITE_HAVE_ZLIB=1 + define CFLAGS_ZLIB -DSQLITE_HAVE_ZLIB=1 } else { define HAVE_ZLIB 0 define LDFLAGS_ZLIB "" + define CFLAGS_ZLIB "" } hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 2239525b4c..a359475449 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -533,6 +533,28 @@ proc hwaci-dll-extension {} { define TARGET_DLLEXT [inner build] } +######################################################################## +# Static-library counterpart of hwaci-dll-extension. Defines +# BUILD_LIBEXT and TARGET_LIBEXT to the conventional static library +# extension for the being-built-on resp. the target platform. +proc hwaci-lib-extension {} { + proc inner {key} { + switch -glob -- [get-define $key] { + *apple* { + return ".lib" + } + *-*-ming* - *-*-cygwin - *-*-msys { + return ".lib" + } + default { + return ".a" + } + } + } + define BUILD_LIBEXT [inner host] + define TARGET_LIBEXT [inner build] +} + ######################################################################## # Expects a list of file names. If any one of them does not exist in # the filesystem, it fails fatally with an informative message. diff --git a/manifest b/manifest index 572fb362fe..509a8f3368 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C More\sgeneric\sbuild\stinkering. -D 2024-09-30T17:44:41.299 +C Add\sstatic\slibrary\sbuild.\sGet\sbuild\sworking\s(for\sa\sgiven\svalue\sof\sworking)\swith\sthe\s--disable-amalgamation\sflag. +D 2024-09-30T19:01:41.209 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in b791c6761d7e3b020fe6001cc33f985f99c0d9e3a745e94fe7c25d09dc1d6f45 +F Makefile.in c766d3b7c308091e94c57836b6f8933b3afe6f29643ec4c95af55a8fbe586617 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 82046ac0d90df3b6478bf193610d00254b64a4fbaba4e08bdd9964fda6baa532 +F auto.def c5e1387cebdfc91f861d3810b90ecc4609dc7c7b6d716219c9abd2f692fda40a F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl c92da569c334b6db38c91f99f4ba26a5a5746b955e7fad1ba585bd1064a82d1c +F autosetup/hwaci-common.tcl 8d8e8f7f4f0387c8683d6a3b2105c9d42ebb7595cceaac6a273b002f7755b3ba F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b6c1772ce0278988ecaea485c4feb8b0919fa1530f0c53b8321d9bd2277b5acd -R 3f3552467c9f9c5110dce0fc316253de +P 433bfc790258e1d2e7c9ea4839a9edb25dde0b99d1e888d1e2a4cf669825fb79 +R 8f22d9dd2b4c58fa46771476eda60898 U stephan -Z 5922ab49dc459c0a84758656bf396042 +Z 1648d4959e73cfe83c15546006463525 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f8e4e253ee..0963459d8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -433bfc790258e1d2e7c9ea4839a9edb25dde0b99d1e888d1e2a4cf669825fb79 +ddfda58004fa3e43c4f2d497c6feecbea3b195d14196bf179f4aafd21ea089ea From 2e7c9ae4736eb135d694c47f36e5ea546b820aa7 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 1 Oct 2024 11:04:02 +0000 Subject: [PATCH 042/522] Fix reversed logic in the build/target/host names in several hwaci-* functions. FossilOrigin-Name: fde7257ad9ce84be6d907be3c6d277b04dd9466ee6828bfded4cfefc86db22db --- autosetup/hwaci-common.tcl | 14 +++++++------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index a359475449..439c4d2de6 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -505,8 +505,8 @@ proc hwaci-exe-extension {} { if {[hwaci-looks-like-windows build]} { set rB ".exe" } - define BUILD_EXEEXT $rH - define TARGET_EXEEXT $rB + define BUILD_EXEEXT $rB + define TARGET_EXEEXT $rH } ######################################################################## @@ -529,8 +529,8 @@ proc hwaci-dll-extension {} { } } } - define BUILD_DLLEXT [inner host] - define TARGET_DLLEXT [inner build] + define BUILD_DLLEXT [inner build] + define TARGET_DLLEXT [inner host] } ######################################################################## @@ -541,7 +541,7 @@ proc hwaci-lib-extension {} { proc inner {key} { switch -glob -- [get-define $key] { *apple* { - return ".lib" + return ".a" } *-*-ming* - *-*-cygwin - *-*-msys { return ".lib" @@ -551,8 +551,8 @@ proc hwaci-lib-extension {} { } } } - define BUILD_LIBEXT [inner host] - define TARGET_LIBEXT [inner build] + define BUILD_LIBEXT [inner build] + define TARGET_LIBEXT [inner host] } ######################################################################## diff --git a/manifest b/manifest index 509a8f3368..489e98e6ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sstatic\slibrary\sbuild.\sGet\sbuild\sworking\s(for\sa\sgiven\svalue\sof\sworking)\swith\sthe\s--disable-amalgamation\sflag. -D 2024-09-30T19:01:41.209 +C Fix\sreversed\slogic\sin\sthe\sbuild/target/host\snames\sin\sseveral\shwaci-*\sfunctions. +D 2024-10-01T11:04:02.571 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 8d8e8f7f4f0387c8683d6a3b2105c9d42ebb7595cceaac6a273b002f7755b3ba +F autosetup/hwaci-common.tcl 4961de5c660cfe3f4616d119c5aef0af9dccf8a54b7a7f98064024735cb2e26d F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 433bfc790258e1d2e7c9ea4839a9edb25dde0b99d1e888d1e2a4cf669825fb79 -R 8f22d9dd2b4c58fa46771476eda60898 +P ddfda58004fa3e43c4f2d497c6feecbea3b195d14196bf179f4aafd21ea089ea +R c63f6b95b69f924ec60d866a54529dc8 U stephan -Z 1648d4959e73cfe83c15546006463525 +Z 38ecc5a009d6d90955debf1069637c2a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0963459d8c..f9db5f1c9f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ddfda58004fa3e43c4f2d497c6feecbea3b195d14196bf179f4aafd21ea089ea +fde7257ad9ce84be6d907be3c6d277b04dd9466ee6828bfded4cfefc86db22db From 51e8287dde18d7bc22f683dbd5f4ed4d20c44fa0 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 1 Oct 2024 11:09:50 +0000 Subject: [PATCH 043/522] Correct missing LDFLAGS_ZLIB for libsqlite3.so. FossilOrigin-Name: 98bbba3a05734e080a0c8c51fac0368436809d4ff3c39959a51970400b4470cb --- Makefile.in | 3 ++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 8b59372d31..8903e93245 100644 --- a/Makefile.in +++ b/Makefile.in @@ -728,7 +728,8 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) libsqlite3.DLL = libsqlite3$(TDLL) libsqlite3.LIB = libsqlite3$(TLIB) -LDFLAGS_libsqlite = $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_MATH) +LDFLAGS_libsqlite = \ + $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) $(libsqlite3.DLL): $(LIBOBJ) $(TLINK) -o $@ \ diff --git a/manifest b/manifest index 489e98e6ef..4d9fabd511 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sreversed\slogic\sin\sthe\sbuild/target/host\snames\sin\sseveral\shwaci-*\sfunctions. -D 2024-10-01T11:04:02.571 +C Correct\smissing\sLDFLAGS_ZLIB\sfor\slibsqlite3.so. +D 2024-10-01T11:09:50.892 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in c766d3b7c308091e94c57836b6f8933b3afe6f29643ec4c95af55a8fbe586617 +F Makefile.in 03b37ca1ca620ae9074bf79c6f3357a54f2fe8f9befee918aa52b107d78b4040 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ddfda58004fa3e43c4f2d497c6feecbea3b195d14196bf179f4aafd21ea089ea -R c63f6b95b69f924ec60d866a54529dc8 +P fde7257ad9ce84be6d907be3c6d277b04dd9466ee6828bfded4cfefc86db22db +R 04bf171d78ee7f138b5f990ba32f5afc U stephan -Z 38ecc5a009d6d90955debf1069637c2a +Z 22b8ec3ae34f09b70dd7dcbd99830d71 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f9db5f1c9f..8922f9e1a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fde7257ad9ce84be6d907be3c6d277b04dd9466ee6828bfded4cfefc86db22db +98bbba3a05734e080a0c8c51fac0368436809d4ff3c39959a51970400b4470cb From ea63f48ec8c0f2262bc7012796c113f12f96a4f0 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 1 Oct 2024 13:40:59 +0000 Subject: [PATCH 044/522] Get more of the CLI utils building. FossilOrigin-Name: 6838b7b5d6130b1e0af9a71ad2c5922b1ef35f082907dffeed03811e1e62406f --- Makefile.in | 63 +++++++++++++++++++++++++++------------------------ manifest | 12 +++++----- manifest.uuid | 2 +- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/Makefile.in b/Makefile.in index 8903e93245..994c14c68f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -44,6 +44,8 @@ CPPFLAGS ?= @CPPFLAGS@ @if SH_CFLAGS CFLAGS += @SH_CFLAGS@ @endif +CFLAGS_stdio3 := -I${TOP}/ext/misc +# CFLAGS_stdio3 ==> for sqlite3_stdio.h TCC = ${CC} ${CFLAGS} TCC += -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session @@ -730,6 +732,9 @@ libsqlite3.DLL = libsqlite3$(TDLL) libsqlite3.LIB = libsqlite3$(TLIB) LDFLAGS_libsqlite = \ $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) +# LDFLAGS_libsqlite should be used with any target which +# either results in building libsqlite3.so, builds sqlite3.c +# directly, links in sqlite3.o, or links in $(LIBOBJS0). $(libsqlite3.DLL): $(LIBOBJ) $(TLINK) -o $@ \ @@ -739,7 +744,7 @@ dll: $(libsqlite3.DLL) all: dll $(libsqlite3.LIB): $(LIBOBJ) - $(AR) r $@ $(LIBOBJ) + $(AR) crs $@ $(LIBOBJ) lib: $(libsqlite3.LIB) all: lib @@ -756,31 +761,31 @@ sqlite3$(TEXE): shell.c sqlite3.c $(LDFLAGS_libsqlite) $(LDFLAGS_READLINE) cli: sqlite3$(TEXE) all: cli -#XX# -#XX#sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h -#XX# $(TLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) -#XX# -#XX#dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h -#XX# $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS) -#XX# -#XX#RSYNC_SRC = \ -#XX# $(TOP)/tool/sqlite3-rsync.c \ -#XX# sqlite3.c -#XX# -#XX#RSYNC_OPT = \ -#XX# -DSQLITE_ENABLE_DBPAGE_VTAB \ -#XX# -USQLITE_THREADSAFE \ -#XX# -DSQLITE_THREADSAFE=0 \ -#XX# -DSQLITE_OMIT_LOAD_EXTENSION \ -#XX# -DSQLITE_OMIT_DEPRECATED -#XX# -#XX#sqlite3-rsync$(TEXE): $(RSYNC_SRC) -#XX# $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(TLIBS) -#XX# -#XX#scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo -#XX# $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ -#XX# $(TOP)/ext/misc/scrub.c sqlite3.lo $(TLIBS) -#XX# + +sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h + $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite) + +dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h + $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite) + +RSYNC_SRC = \ + $(TOP)/tool/sqlite3-rsync.c \ + sqlite3.c + +RSYNC_OPT = \ + -DSQLITE_ENABLE_DBPAGE_VTAB \ + -USQLITE_THREADSAFE \ + -DSQLITE_THREADSAFE=0 \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_OMIT_DEPRECATED + +sqlite3-rsync$(TEXE): $(RSYNC_SRC) + $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite) + +scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo + $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ + $(TOP)/ext/misc/scrub.c sqlite3.lo $(LDFLAGS_libsqlite) + srcck1$(BEXE): $(TOP)/tool/srcck1.c $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c @@ -1543,9 +1548,9 @@ sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) #XX#sqltclsh$(TEXE): has_tclconfig sqltclsh.c #XX# $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS) #XX# -#XX#sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -#XX# $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(TLIBS) -#XX# +sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c + $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite) + #XX#CHECKER_DEPS =\ #XX# $(TOP)/tool/mkccode.tcl \ #XX# sqlite3.c \ diff --git a/manifest b/manifest index 4d9fabd511..b9eed692c0 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Correct\smissing\sLDFLAGS_ZLIB\sfor\slibsqlite3.so. -D 2024-10-01T11:09:50.892 +C Get\smore\sof\sthe\sCLI\sutils\sbuilding. +D 2024-10-01T13:40:59.914 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 03b37ca1ca620ae9074bf79c6f3357a54f2fe8f9befee918aa52b107d78b4040 +F Makefile.in 19afd3c31ea260e22eea118053b97d79f2b8d40b5d388e2c9c8a573554b97d4d F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2233,8 +2233,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fde7257ad9ce84be6d907be3c6d277b04dd9466ee6828bfded4cfefc86db22db -R 04bf171d78ee7f138b5f990ba32f5afc +P 98bbba3a05734e080a0c8c51fac0368436809d4ff3c39959a51970400b4470cb +R d61b1bae6c19264b9c460b550873251d U stephan -Z 22b8ec3ae34f09b70dd7dcbd99830d71 +Z 5f773d8b1897a9c16436ea21d9b0af59 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8922f9e1a1..d1a0280e23 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -98bbba3a05734e080a0c8c51fac0368436809d4ff3c39959a51970400b4470cb +6838b7b5d6130b1e0af9a71ad2c5922b1ef35f082907dffeed03811e1e62406f From d2a88e961a78582050bd56e3676bf54fef01fb3f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 1 Oct 2024 20:38:08 +0000 Subject: [PATCH 045/522] Rationalize code further. And add tests. FossilOrigin-Name: 0ca002a4ab88f3e7ae1e6e518038157eaa20759f57888c2ed7e50cb92bd96348 --- ext/fts5/fts5_index.c | 165 +++++++++++++++++++++-------- ext/fts5/test/fts5origintext3.test | 23 ++++ manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 151 insertions(+), 53 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index ede091650d..f6f51d7343 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6199,15 +6199,45 @@ static void fts5MergePrefixLists( } -static int fts5VisitPrefixRange( - Fts5Index *p, - Fts5Colset *pColset, - u8 *pToken, - int nToken, +/* +** Iterate through a range of entries in the FTS index, invoking the xVisit +** callback for each of them. +** +** Parameter pToken points to an nToken buffer containing an FTS index term +** (i.e. a document term with the preceding 1 byte index identifier - +** FTS5_MAIN_PREFIX or similar). If bPrefix is true, then the call visits +** all entries for terms that have pToken/nToken as a prefix. If bPrefix +** is false, then only entries with pToken/nToken as the entire key are +** visited. +** +** If the current table is a tokendata=1 table, then if bPrefix is true then +** each index term is treated separately. However, if bPrefix is false, then +** all index terms corresponding to pToken/nToken are collapsed into a single +** term before the callback is invoked. +** +** The callback invoked for each entry visited is specified by paramter xVisit. +** Each time it is invoked, it is passed a pointer to the Fts5Index object, +** a copy of the 7th paramter to this function (pCtx) and a pointer to the +** iterator that indicates the current entry. If the current entry is the +** first with a new term (i.e. different from that of the previous entry, +** including the very first term), then the final two parameters are passed +** a pointer to the term and its size in bytes, respectively. If the current +** entry is not the first associated with its term, these two parameters +** are passed 0. +** +** If parameter pColset is not NULL, then it is used to filter entries before +** the callback is invoked. +*/ +static int fts5VisitEntries( + Fts5Index *p, /* Fts5 index object */ + Fts5Colset *pColset, /* Columns filter to apply, or NULL */ + u8 *pToken, /* Buffer containing token */ + int nToken, /* Size of buffer pToken in bytes */ + int bPrefix, /* True for a prefix scan */ void (*xVisit)(Fts5Index*, void *pCtx, Fts5Iter *pIter, const u8*, int), - void *pCtx + void *pCtx /* Passed as second argument to xVisit() */ ){ - const int flags = FTS5INDEX_QUERY_SCAN + const int flags = (bPrefix ? FTS5INDEX_QUERY_SCAN : 0) | FTS5INDEX_QUERY_SKIPEMPTY | FTS5INDEX_QUERY_NOOUTPUT; Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ @@ -6226,7 +6256,6 @@ static int fts5VisitPrefixRange( p1->xSetOutputs(p1, pSeg); - if( bNewTerm ){ nNew = pSeg->term.n; pNew = pSeg->term.p; @@ -6241,6 +6270,9 @@ static int fts5VisitPrefixRange( return p->rc; } +/* +** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries(). +*/ typedef struct PrefixSetupCtx PrefixSetupCtx; struct PrefixSetupCtx { void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); @@ -6252,6 +6284,9 @@ struct PrefixSetupCtx { Fts5Buffer doclist; }; +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIter() +*/ static void prefixIterSetupCb( Fts5Index *p, void *pCtx, @@ -6325,6 +6360,7 @@ static void fts5SetupPrefixIter( assert( p->rc!=SQLITE_OK || (s.aBuf && pStruct) ); if( p->rc==SQLITE_OK ){ + void *pCtx = (void*)&s; int i; Fts5Data *pData; @@ -6334,30 +6370,12 @@ static void fts5SetupPrefixIter( ** corresponding to the prefix itself. That one is extracted from the ** main term index here. */ if( iIdx!=0 ){ - Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ - int dummy = 0; - const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; pToken[0] = FTS5_MAIN_PREFIX; - fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); - for(; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &dummy) - ){ - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - p1->xSetOutputs(p1, pSeg); - if( p1->base.nData ){ - s.xAppend(p, (u64)p1->base.iRowid-(u64)s.iLastRowid, p1, &s.doclist); - s.iLastRowid = p1->base.iRowid; - } - } - fts5MultiIterFree(p1); + fts5VisitEntries(p, pColset, pToken, nToken, 0, prefixIterSetupCb, pCtx); } pToken[0] = FTS5_MAIN_PREFIX + iIdx; - fts5VisitPrefixRange( - p, pColset, pToken, nToken, prefixIterSetupCb, (void*)&s - ); + fts5VisitEntries(p, pColset, pToken, nToken, 1, prefixIterSetupCb, pCtx); assert( (s.nBuf%s.nMerge)==0 ); for(i=0; i0, not just a container for +** Fts5TokenDataMap structures), then this variable is an index into +** the apIter[] array. The corresponding term is that which the iterator +** at apIter[iIter] currently points to. +** +** Or, if the Fts5TokenDataIter iterator is just a container object +** (nIter==0), then iIter is an index into the term.p[] buffer where +** the term is stored. +** +** nByte: +** In the case where iIter is an index into term.p[], this variable +** is the size of the term in bytes. If iIter is an index into apIter[], +** this variable is unused. */ struct Fts5TokenDataMap { i64 iRowid; /* Row this token is located in */ i64 iPos; /* Position of token */ - int iIter; /* Iterator token was read from */ int nByte; /* Length of token in bytes (or 0) */ }; /* ** An object used to supplement Fts5Iter for tokendata=1 iterators. +** +** This object serves two purposes. The first is as a container for an array +** of Fts5TokenDataMap structures, which are used to find the token required +** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and +** aMap[] variables. */ struct Fts5TokenDataIter { - int nMap; - int nMapAlloc; - Fts5TokenDataMap *aMap; + int nMapAlloc; /* Allocated size of aMap[] in entries */ + int nMap; /* Number of valid entries in aMap[] */ + Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */ /* The following are used for prefix-queries only. */ Fts5Buffer terms; @@ -7234,10 +7280,18 @@ const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return (z ? &z[1] : 0); } +/* +** The two input arrays - a1[] and a2[] - are in sorted order. This function +** merges the two arrays together and writes the result to output array +** aOut[]. aOut[] is guaranteed to be large enough to hold the result. +** +** Duplicate entries are copied into the output. So the size of the output +** array is always (n1+n2) entries. +*/ static void fts5TokendataMerge( - Fts5TokenDataMap *a1, int n1, - Fts5TokenDataMap *a2, int n2, - Fts5TokenDataMap *aOut + Fts5TokenDataMap *a1, int n1, /* Input array 1 */ + Fts5TokenDataMap *a2, int n2, /* Input array 2 */ + Fts5TokenDataMap *aOut /* Output array */ ){ int i1 = 0; int i2 = 0; @@ -7258,6 +7312,12 @@ static void fts5TokendataMerge( } } +/* +** Sort the contents of the pT->aMap[] array. +** +** The sorting algorithm requries a malloc(). If this fails, an error code +** is left in Fts5Index.rc before returning. +*/ static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ Fts5TokenDataMap *aTmp = 0; int nByte = pT->nMap * sizeof(Fts5TokenDataMap); @@ -7298,13 +7358,23 @@ static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ } } +/* +** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata() +** to pass data to prefixIterSetupTokendataCb(). +*/ typedef struct TokendataSetupCtx TokendataSetupCtx; struct TokendataSetupCtx { - Fts5TokenDataIter *pT; - int iTermOff; - int nTermByte; + Fts5TokenDataIter *pT; /* Object being populated with mappings */ + int iTermOff; /* Offset of current term in terms.p[] */ + int nTermByte; /* Size of current term in bytes */ }; +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This +** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each +** position in the current position-list. It doesn't matter that some of +** these may be out of order - they will be sorted later. +*/ static void prefixIterSetupTokendataCb( Fts5Index *p, void *pCtx, @@ -7331,10 +7401,15 @@ static void prefixIterSetupTokendataCb( } } +/* +** pIter is a prefix query. This function populates pIter->pTokenDataIter +** with an Fts5TokenDataIter object containing mappings for all rows +** matched by the query. +*/ static int fts5SetupPrefixIterTokendata( Fts5Iter *pIter, - const char *pToken, - int nToken + const char *pToken, /* Token prefix to search for */ + int nToken /* Size of pToken in bytes */ ){ Fts5Index *p = pIter->pIndex; Fts5Buffer token = {0, 0, 0}; @@ -7352,8 +7427,8 @@ static int fts5SetupPrefixIterTokendata( memcpy(&token.p[1], pToken, nToken); token.n = nToken+1; - fts5VisitPrefixRange( - p, 0, token.p, token.n, prefixIterSetupTokendataCb, (void*)&ctx + fts5VisitEntries( + p, 0, token.p, token.n, 1, prefixIterSetupTokendataCb, (void*)&ctx ); fts5TokendataIterSortMap(p, ctx.pT); diff --git a/ext/fts5/test/fts5origintext3.test b/ext/fts5/test/fts5origintext3.test index 9dda2a5748..a4bca0de9b 100644 --- a/ext/fts5/test/fts5origintext3.test +++ b/ext/fts5/test/fts5origintext3.test @@ -95,6 +95,29 @@ foreach_detail_mode $testprefix { do_execsql_test 1.8 { SELECT rowid FROM ft2('aaa AND bbb'); } {10 24} do_execsql_test 1.9 { SELECT rowid FROM ft2('bbb AND aaa'); } {10 24} + do_execsql_test 2.0 { + CREATE VIRTUAL TABLE ft3 USING fts5( + x, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%, + prefix=2 + ); + } + do_execsql_test 2.1 { + INSERT INTO ft3(rowid, x) VALUES(1, 'one'); + INSERT INTO ft3(rowid, x) VALUES(2, 'ONE'); + INSERT INTO ft3(rowid, x) VALUES(3, 'ONT'); + INSERT INTO ft3(rowid, x) VALUES(4, 'on'); + INSERT INTO ft3(rowid, x) VALUES(5, 'On'); + } + + do_execsql_test 2.2 { + SELECT rowid FROM ft3('on*'); + } {1 2 3 4 5} + + do_execsql_test 2.3 { + SELECT rowid, insttoken(ft3, 0, 0) FROM ft3('on*'); + } {1 one 2 one.ONE 3 ont.ONT 4 on 5 on.On} + + } finish_test diff --git a/manifest b/manifest index 0d2ad1c4fb..7b755eff5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rationalize\ssome\sof\sthe\snew\scode\son\sthis\sbranch. -D 2024-09-28T20:45:11.387 +C Rationalize\scode\sfurther.\sAnd\sadd\stests. +D 2024-10-01T20:38:08.239 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -99,7 +99,7 @@ F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70 F ext/fts5/fts5_config.c da21548ddbc1a457cb42545f527065221ede8ada6a734891b8c34317a7a9506b F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c c1005920192146452a3545500761ecc8cfab84572d251e8536103a01899f67d5 +F ext/fts5/fts5_index.c 9b2b9636ccefd6140c0ad7a44c51c2ea39f377753a13f06a2e6792215b62cede F ext/fts5/fts5_main.c 4503498d3453e29a3cd89dacaba029011e89cb8c481a6241611d106e7a369bd4 F ext/fts5/fts5_storage.c 3332497823c3d171cf56379f2bd8c971ce15a19aadacff961106462022c92470 F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe @@ -203,7 +203,7 @@ F ext/fts5/test/fts5optimize2.test 795d4ae5f66a7239cf8d5aef4c2ea96aeb8bcd907bd9b F ext/fts5/test/fts5optimize3.test 1653029284e10e0715246819893ba30565c4ead0d0fc470adae92c353ea857d3 F ext/fts5/test/fts5origintext.test 63d5b0dc00f0104add8960da0705a70bffd4d86b6feb6ddbb38bff21141d42f0 F ext/fts5/test/fts5origintext2.test f4505ff79bf7369f2b8b10b9cef7476049d844e20b37f29cad3a8b8d5ac6f9ba -F ext/fts5/test/fts5origintext3.test 45c33cf0c91a9ca0e36d298462db3edc7c8fe45fd185649a9dbfd66bb670058b +F ext/fts5/test/fts5origintext3.test 1f5174a9f4cf42f58f833dbfb314940793ca4723854ec2651e7530ddb35a66a6 F ext/fts5/test/fts5origintext4.test 0d3ef0a8038f471dbc83001c34fe5f7ae39b571bfc209670771eb28bc0fc50e8 F ext/fts5/test/fts5origintext5.test ee12b440ec335e5b422d1668aca0051b52ff28b6ee67073e8bbc29f509fd562b F ext/fts5/test/fts5phrase.test bb2554bb61d15f859678c96dc89a7de415cd5fc3b7b54c29b82a0d0ad138091c @@ -2214,8 +2214,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 204ddf4e726b695dd12ab4a945ec2461655aa0bcc38b74e970f07ed2ac43c6ff -R da06610bae74973a44f69a92b9b60e12 +P 66f209ba40e7de49b304d7931ff38a4994038452aab08e9347286a234c6f7075 +R 364baf490f2f60461704cce12defe7d5 U dan -Z ca9c653ea5575a07920ac6ddffa15d1d +Z 98928b751e601e5ab0ec38779c287b09 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f550314bcd..7b4f75a7f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -66f209ba40e7de49b304d7931ff38a4994038452aab08e9347286a234c6f7075 +0ca002a4ab88f3e7ae1e6e518038157eaa20759f57888c2ed7e50cb92bd96348 From d5503d383bd1ee65269d460ab3ff38926878be6a Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 8 Oct 2024 16:05:54 +0000 Subject: [PATCH 046/522] Make tool/emcc.sh.in Bourne-friendly. FossilOrigin-Name: a69ab88474a7b917679633e366364b05a99c348dabc37f1bbc5010f7005d5500 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/emcc.sh.in | 9 +++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 45d994c0f6..ab28b01f14 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\sinto\sautosetup\sbranch. -D 2024-10-05T12:06:31.859 +C Make\stool/emcc.sh.in\sBourne-friendly. +D 2024-10-08T16:05:54.098 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -2132,7 +2132,7 @@ F tool/custom.txt 6cdf298f43e1db4bb91406d14777669b8fb1df790837823fa6754c4308decc F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c -F tool/emcc.sh.in bc3f3a29f5a7272afe605a483d6463617f27d31c74fa9135c7eaa3b844345b74 +F tool/emcc.sh.in ccd415e9784d8efdb6e29bd2289bff57d37a928122620a244fcb99f445ae276c F tool/enlargedb.c 3e8b2612b985cfa7e3e8800031ee191b43ae80de96abb5abbd5eada62651ee21 F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -2235,8 +2235,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6838b7b5d6130b1e0af9a71ad2c5922b1ef35f082907dffeed03811e1e62406f 2f7eab381e16760952d1c90a9119d2a217933f0136442d8f6eeb6d95e366ca4f -R 718af76a1b8b829ff662e805c69f5727 +P 6cbb05fde1b74ced6d56d6ec7f815c989697381531175daccebc4311bfef61d9 +R 2c8a1ade7d9f0039a6c4438b17ebd26a U stephan -Z d5ebe1dc79c6b40a021966341f66c463 +Z 1d93be3fe611f8efdba1c2ce6cdf2d85 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 13b38ba824..e1bdceaadb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6cbb05fde1b74ced6d56d6ec7f815c989697381531175daccebc4311bfef61d9 +a69ab88474a7b917679633e366364b05a99c348dabc37f1bbc5010f7005d5500 diff --git a/tool/emcc.sh.in b/tool/emcc.sh.in index 91ed6a2c27..3edc65fb42 100644 --- a/tool/emcc.sh.in +++ b/tool/emcc.sh.in @@ -1,4 +1,5 @@ -#!/usr/bin/env bash +#!/bin/sh +# ^^^^^^^ Please try to keep this script Bourne-compatible. ######################################################################## # WARNING: emcc.sh is generated from emcc.sh.in by the configure # process. Do not edit emcc.sh directly, as it may be deleted or @@ -16,7 +17,7 @@ EMSDK_ENV="@EMSDK_ENV@" emcc="@BIN_EMCC@" if [x = "x${emcc}" ]; then - emcc=$(which emcc 2>/dev/null) + emcc=`which emcc 2>/dev/null` fi if [ x = "x${emcc}" ]; then @@ -53,9 +54,9 @@ if [ x = "x${emcc}" ]; then exit $rc } fi - emcc=$(which emcc 2>/dev/null) + emcc=`which emcc 2>/dev/null` if [ x = "x${emcc}" ]; then - echo "emcc not found in PATH. Normally that's set up by EMSDK_ENV." 1>&2 + echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV}." 1>&2 exit 4 fi fi From 59ded3ff1460a8e0c56185d8bf86bd7d0a9fc5ce Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 8 Oct 2024 16:06:11 +0000 Subject: [PATCH 047/522] Get some basic install rules working. FossilOrigin-Name: e9ab211f82f789c89ab52e8d5fe7526c09943b2b8b3002fa7a16fb2b40addc8f --- Makefile.in | 51 +++++++++++++++++++++++++++++++++++--- auto.def | 9 ++++++- autosetup/hwaci-common.tcl | 7 +++--- manifest | 16 ++++++------ manifest.uuid | 2 +- 5 files changed, 68 insertions(+), 17 deletions(-) diff --git a/Makefile.in b/Makefile.in index e64f651b12..3d9c06a2c4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -181,6 +181,7 @@ pkgconfigdir = $(libdir)/pkgconfig bindir = @bindir@ includedir = @includedir@ INSTALL = @BIN_INSTALL@ +INSTALL_noexec = $(INSTALL) --mode=0644 #XX#LIBTOOL = ./libtool #XX#ALLOWRELEASE = @ALLOWRELEASE@ #XX# @@ -190,7 +191,6 @@ INSTALL = @BIN_INSTALL@ #XX#LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) TLINK = $(TCC) $(TLINK_EXTRAS) -TINSTALL = $(INSTALL) # # You should not have to change anything below this line @@ -748,6 +748,36 @@ $(libsqlite3.LIB): $(LIBOBJ) lib: $(libsqlite3.LIB) all: lib +install.bindir = $(DESTDIR)$(bindir) +install.libdir = $(DESTDIR)$(libdir) +install.includedir = $(DESTDIR)$(prefix)/include +$(install.bindir) $(install.libdir) $(install.includedir): + $(INSTALL) -d "$@" + +# Install the $(libsqlite3.DLL) as $(libsqlite3.DLL).@RELEASE@ and +# create symlinks which point to it. Do we really need all of this +# hoop-jumping? Can we not simply install the .so as-is? +# +# The historical SQLite build always used a version number of 0.8.6 +# for reasons lost to history. +install-dll: $(install.libdir) $(libsqlite3.DLL) + $(INSTALL) $(libsqlite3.DLL) "$(install.libdir)" + cd "$(install.libdir)"; \ + rm -f $(libsqlite3.DLL).3 $(libsqlite3.DLL).@RELEASE@; \ + mv $(libsqlite3.DLL) $(libsqlite3.DLL).@RELEASE@; \ + ln -s $(libsqlite3.DLL).@RELEASE@ $(libsqlite3.DLL).3; \ + ln -s $(libsqlite3.DLL).3 $(libsqlite3.DLL) + +# Install $(libsqlite3.LIB) +install-lib: $(install.libdir) $(libsqlite3.LIB) + $(INSTALL_noexec) $(libsqlite3.LIB) "$(install.libdir)" + +install-includes: sqlite3.h $(install.includedir) + $(INSTALL_noexec) sqlite3.h "$(install.includedir)" + +install-libs: install-lib install-dll +install: install-libs install-includes + #XX#libtclsqlite3.la: tclsqlite.lo libsqlite3.la #XX# $(TLINK) -no-undefined -o $@ tclsqlite.lo \ #XX# libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \ @@ -762,9 +792,19 @@ sqlite3$(TEXE): shell.c sqlite3.c cli: sqlite3$(TEXE) all: cli +install-cli: sqlite3$(TEXT) $(install.bindir) + $(INSTALL) -s sqlite3$(TEXT) "$(install.bindir)" + +install: install-cli + sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite) +install-diff: sqldiff$(TEXE) $(install.bindir) + $(INSTALL) -s sqldiff$(TEXT) "$(install.bindir)" + +#install: install-diff + dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite) @@ -782,6 +822,11 @@ RSYNC_OPT = \ sqlite3-rsync$(TEXE): $(RSYNC_SRC) $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite) +install-rsync: sqlite3-rsync$(TEXE) $(install.bindir) + $(INSTALL) sqlite3-rsync$(TEXT) "$(install.bindir)" + +#install: install-rsync + scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ $(TOP)/ext/misc/scrub.c sqlite3.lo $(LDFLAGS_libsqlite) @@ -1755,12 +1800,12 @@ tidy: # clean: tidy rm -rf omittest* testrunner* testdir* - -gmake -C ext/wasm distclean + -gmake -C ext/wasm distclean 2>/dev/null; true # Clean up everything. No exceptions. distclean: clean rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile - -gmake -C ext/wasm distclean + -gmake -C ext/wasm distclean 2>/dev/null; true #XX## #XX## Windows section diff --git a/auto.def b/auto.def index 1406dfc736..36ff88a1e9 100644 --- a/auto.def +++ b/auto.def @@ -35,7 +35,6 @@ options { tcl=1 => {Disable building accessory programs that require TCL-dev} test-status => {Enable status of tests} threadsafe=1 => {Disable mutexing} - releasemode => {libtool link to release mode} with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always.} editline=0 => {BSD editline support} readline=1 => {Disable readline support} @@ -65,6 +64,14 @@ options { dump-defines=1 => {Disable dump of autosetup defines to $DUMP_DEFINES_FILE} } +######################################################################## +# Notes about certain historical flags: +# +# --releasemode: libtool-specific (which we don't have now) +# +######################################################################## + + set srcdir $autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] puts "srcdir = $srcdir" diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 439c4d2de6..b0d6fec99c 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -106,7 +106,7 @@ proc hwaci-bin-define {binName {defName {}}} { msg-checking "Looking for $binName ... " if {"" ne $check} { set lbl $check - if {" _ 0 _ " eq $check} { + if {"" eq $check} { set lbl "not found" set check "" } @@ -116,7 +116,7 @@ proc hwaci-bin-define {binName {defName {}}} { set check [find-executable-path $binName] if {"" eq $check} { msg-result "not found" - set hwaci-cache-($cacheName) " _ 0 _ " + set hwaci-cache-($cacheName) "" } else { msg-result $check set hwaci-cache-($cacheName) $check @@ -143,8 +143,7 @@ proc hwaci-first-bin-of {args} { ######################################################################## # Looks for `bash` binary and dies if not found. On success, defines -# BIN_BASH to the full path to bash and returns that value. We -# _require_ bash because it's the SHELL value used in our makefiles. +# BIN_BASH to the full path to bash and returns that value. proc hwaci-require-bash {} { set bash [hwaci-bin-define bash] if {"" eq $bash} { diff --git a/manifest b/manifest index ab28b01f14..3d1501b7d4 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Make\stool/emcc.sh.in\sBourne-friendly. -D 2024-10-08T16:05:54.098 +C Get\ssome\sbasic\sinstall\srules\sworking. +D 2024-10-08T16:06:11.707 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in fc3b3656ee35ba81f492a5db71f3eef8f3fd789f04416cfa1fd51533933c5d9a +F Makefile.in fc2ef4e2955bf2f773ccefdadb5d8c27b66f04556178f3112d56f0a95c92255b F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def c5e1387cebdfc91f861d3810b90ecc4609dc7c7b6d716219c9abd2f692fda40a +F auto.def afec3012da348dd0214047f575131d0a69e1aa67588e212daf604d4393453a3b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 4961de5c660cfe3f4616d119c5aef0af9dccf8a54b7a7f98064024735cb2e26d +F autosetup/hwaci-common.tcl fcb479deea42c54d5486d20b811a00b3880f8dc597afac41145463cc5d58cdae F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2235,8 +2235,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6cbb05fde1b74ced6d56d6ec7f815c989697381531175daccebc4311bfef61d9 -R 2c8a1ade7d9f0039a6c4438b17ebd26a +P a69ab88474a7b917679633e366364b05a99c348dabc37f1bbc5010f7005d5500 +R ba28a71964131b9ba3350911d33dc11d U stephan -Z 1d93be3fe611f8efdba1c2ce6cdf2d85 +Z 03e49a16b7d4bc0546430cb7f164dfa8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e1bdceaadb..5c11fae8e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a69ab88474a7b917679633e366364b05a99c348dabc37f1bbc5010f7005d5500 +e9ab211f82f789c89ab52e8d5fe7526c09943b2b8b3002fa7a16fb2b40addc8f From 10d1b0c5db1ce12a128585c303b0b899106192cc Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 8 Oct 2024 16:33:42 +0000 Subject: [PATCH 048/522] Fix build portability problems discovered on an ARM OpenBSD system. FossilOrigin-Name: ef5348dc3f5b9fbe19753ff85e4da461ee962f0790e5f9cfda6eba522576451b --- Makefile.in | 8 ++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3d9c06a2c4..2e4bfec762 100644 --- a/Makefile.in +++ b/Makefile.in @@ -23,6 +23,7 @@ LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ LDFLAGS_MATH = @LDFLAGS_MATH@ LDFLAGS_RPATH = @LDFLAGS_RPATH@ LDFLAGS_READLINE = @LDFLAGS_READLINE@ +LDFLAGS_PTHREAD = @LDFLAGS_PTHREAD@ LD = @LD@ AR = @AR@ @@ -181,7 +182,9 @@ pkgconfigdir = $(libdir)/pkgconfig bindir = @bindir@ includedir = @includedir@ INSTALL = @BIN_INSTALL@ -INSTALL_noexec = $(INSTALL) --mode=0644 +INSTALL_noexec = $(INSTALL) -m 0644 +# ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... + #XX#LIBTOOL = ./libtool #XX#ALLOWRELEASE = @ALLOWRELEASE@ #XX# @@ -731,7 +734,8 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) libsqlite3.DLL = libsqlite3$(TDLL) libsqlite3.LIB = libsqlite3$(TLIB) LDFLAGS_libsqlite = \ - $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) + $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_PTHREAD) \ + $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) # LDFLAGS_libsqlite should be used with any target which # either results in building libsqlite3.so, builds sqlite3.c # directly, links in either of $(LIBOBJSO) or $(LIBOBJS1). diff --git a/manifest b/manifest index 3d1501b7d4..c0dca8ca8e 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Get\ssome\sbasic\sinstall\srules\sworking. -D 2024-10-08T16:06:11.707 +C Fix\sbuild\sportability\sproblems\sdiscovered\son\san\sARM\sOpenBSD\ssystem. +D 2024-10-08T16:33:42.863 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in fc2ef4e2955bf2f773ccefdadb5d8c27b66f04556178f3112d56f0a95c92255b +F Makefile.in 4cb6e44af5d0ed2a1ad347f008c00d3ddeae8f1dd2089a1348e7c6aa6be8e63d F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2235,8 +2235,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a69ab88474a7b917679633e366364b05a99c348dabc37f1bbc5010f7005d5500 -R ba28a71964131b9ba3350911d33dc11d +P e9ab211f82f789c89ab52e8d5fe7526c09943b2b8b3002fa7a16fb2b40addc8f +R 83d7d512ee4d92805faea47e6da138cb U stephan -Z 03e49a16b7d4bc0546430cb7f164dfa8 +Z 65540e91f90dac7f75bdfc0fac8976f3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5c11fae8e0..24c3e11ae9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9ab211f82f789c89ab52e8d5fe7526c09943b2b8b3002fa7a16fb2b40addc8f +ef5348dc3f5b9fbe19753ff85e4da461ee962f0790e5f9cfda6eba522576451b From f400f41fde557816c60e0933e22866b44d4ba8d2 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Oct 2024 04:01:14 +0000 Subject: [PATCH 049/522] Get much of the --with-tcl-related bits working. FossilOrigin-Name: 4e4a740369d3edc58d35c660b1ea73ee381503f82a98a4b770fd07cef1704e8b --- Makefile.in | 23 ++- auto.def | 384 ++++++++++++++------------------------- manifest | 15 +- manifest.uuid | 2 +- tool/tclConfigShToTcl.sh | 27 +++ 5 files changed, 192 insertions(+), 259 deletions(-) create mode 100755 tool/tclConfigShToTcl.sh diff --git a/Makefile.in b/Makefile.in index 2e4bfec762..86aaa6cba4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -143,6 +143,14 @@ HAVE_TCL = @HAVE_TCL@ # know the specific version we want to use # TCLSH_CMD = @TCLSH_CMD@ +TCL_CONFIG_SH = @TCL_CONFIG_SH@ + +# TCL config info from tclConfig.sh +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@ + # Additional options when running tests using testrunner.tcl # This is usually either blank, or else --status @@ -844,13 +852,14 @@ sourcetest: srcck1$(BEXE) sqlite3.c src-verify: $(TOP)/tool/src-verify.c $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c - -# JimTCL is part of the autosetup suite and is suitable for certain -# in-tree TCL jobs, but it requires that we build it with non-default -# flags. Note that the build tree will, if no system-level tclsh is -# found, also have a ./jimsh0. That one is a bare-bones build for the -# configure process, whereas we need to build it with another option -# enabled for use with the various code generators. +# +# JimTCL is part of the autosetup suite and is suitable for all +# current in-tree code-generation TCL jobs, but it requires that we +# build it with non-default flags. Note that the build tree will, if +# no system-level tclsh is found, also have a ./jimsh0. That one is a +# bare-bones build for the configure process, whereas we need to build +# it with another option enabled for use with the various code +# generators. # JIMSH = @srcdir@/jimsh @if CFLAGS_JIMSH diff --git a/auto.def b/auto.def index 36ff88a1e9..455d71d36c 100644 --- a/auto.def +++ b/auto.def @@ -30,8 +30,8 @@ define cross_compiling ${cross_compiling} # options { with-debug:=1 => {Enable debug build flags} - with-tclsh: => {Full pathname of tclsh to use} - with-tcl: => {Directory containing tclConfig.sh} + with-tclsh:PATH => {Full pathname of tclsh to use} + with-tcl:DIR => {Directory containing tclConfig.sh} tcl=1 => {Disable building accessory programs that require TCL-dev} test-status => {Enable status of tests} threadsafe=1 => {Disable mutexing} @@ -69,7 +69,7 @@ options { # # --releasemode: libtool-specific (which we don't have now) # -######################################################################## +# set srcdir $autosetup(srcdir) @@ -94,6 +94,7 @@ if {![file exists sqlite3.pc.in]} { cc-check-tools ld ar +######################################################################## # The build process allows for using a cross-compiler. But the default # action is to target the same platform that we are running on. The # configure script needs to discover the following properties of the @@ -154,7 +155,7 @@ cc-check-tools ld ar # files for the readline library. If the compiler is able # to find on its own, then this can be blank. -######################################################################## +# # OPT_FEATURE_FLAGS = -DSQLITE_OMIT/ENABLE flags. define OPT_FEATURE_FLAGS {} define OPT_SHELL {}; # CFLAGS for the sqlite3 CLI app @@ -218,6 +219,7 @@ define BUILD_CFLAGS [get-env CFLAGS {-g}] # # It's unclear whether we can actually get away with making these # changes to the autosetup environment. +# if {1} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" @@ -256,30 +258,16 @@ if {1} { unset wasiSdkDir }; # --wasi-sdk-dir -######################################################################## -# Check which TCL to use as a code generator -define CFLAGS_JIMSH {} -puts "Looking for path-resolution function for JimTCL... " -define BTCL "\$(JIMSH)" -if {[cc-check-functions realpath]} { - define-append CFLAGS_JIMSH -DHAVE_REALPATH -} elseif {[cc-check-functions _fullpath]} { - # _fullpath() is a Windows API - define-append CFLAGS_JIMSH -DHAVE__FULLPATH -} else { - puts "Cannot find realpath() or _fullpath(). Falling back to system's TCL for code generation." -} - -######################################################################## +# # Enable large file support (if special flags are necessary) cc-check-lfs -######################################################################## +# # Check for needed/wanted data types cc-check-types int8_t int16_t int32_t int64_t intptr_t \ uint8_t uint16_t uint32_t uint64_t uintptr_t -######################################################################## +# # Check for needed/wanted functions cc-check-functions gmtime_r isnan localtime_r localtime_s \ malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 @@ -288,7 +276,7 @@ hwaci-check-function-in-lib fdatasync rt define LDFLAGS_FDATASYNC [get-define lib_fdatasync] undefine lib_fdatasync -######################################################################## +# # Check for needed/wanted headers cc-check-includes \ sys/types.h sys/stat.h dlfcn.h unistd.h \ @@ -296,7 +284,8 @@ cc-check-includes \ string.h strings.h \ stdint.h inttypes.h -# These are optional for JimTCL: +# These are optional for JimTCL but necessary if we want to use it for +# code generation: cc-check-includes dirent.h sys/time.h if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { @@ -337,157 +326,135 @@ hwaci-if-opt-truthy with-debug { ######################################################################## # TCL... +# +# Under construction. An attempt to port most of the +# --with-tcl/--with-tclsh logic from configure.ac to autosetup. This +# part would actually be easier in the shell, and some of it will +# seemingly be impossible without shell code. define HAVE_TCL 0 define TCLSH_CMD {exit 1} -if {"" eq [get-define CFLAGS_JIMSH]} { - # We can't use JimTCL for in-tree generation on this system, so... - # - # Temporary solution for finding "a" tclsh. TODO is port the - # full-featured check which lives in the elseif part of this block. - set tclsh [hwaci-first-bin-of tclsh8.6 tclsh tclsh9.0] - if {"" eq $tclsh} { - user-error "Cannot find tclsh, which is required to build certain files." - } - define TCLSH_CMD $tclsh - define BTCL $tclsh - define HAVE_TCL 0 ; # until the following elseif block is ported -} elseif {0} { - # Porting this section of configure.ac is going to be a bit of a slog... - set tEnable [hwaci-opt-truthy tcl] - set use_tcl $tEnable +proc hwaci-check-tcl {} { + global top_srcdir + puts "Checking for a suitable tcl... " + set optTcl [hwaci-opt-truthy tcl] + set use_tcl $optTcl set tclsh "" - #set original_use_tcl ${use_tcl} - ######### - # Figure out all the name of a working tclsh and parameters needed to compile against Tcl. - # The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. - # - # XXX AC_ARG_WITH tclsh AS_HELP_STRING([--with-tclsh=PATHNAME],[full pathname of a tclsh to use]) - # XXX AC_ARG_WITH tcl AS_HELP_STRING([--with-tcl=DIR],[directory containing (tclConfig.sh)]) set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] - +# puts "hwaci-check-tcl: use_tcl ${use_tcl}" +# puts "hwaci-check-tcl: with_tclsh=${with_tclsh}" +# puts "hwaci-check-tcl: with_tcl=$with_tcl" if {"" eq $with_tclsh && "" eq $with_tcl} { - # XXX if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then - # XXX AC_CHECK_PROGS TCLSH_CMD tclsh8.6 tclsh tclsh9.0 none - #set with_tclsh ${TCLSH_CMD} - # XXX fi set with_tclsh [hwaci-first-bin-of tclsh8.6 tclsh tclsh9.0] } - if {"" ne $with_tclsh } { - # XXX if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then - # XXX TCLSH_CMD=${with_tclsh} - set tclsh $with_tclsh - puts "using tclsh at \"$tclsh\"" + if {"" ne $with_tclsh} { + if {![file isfile $with_tclsh]} { + hwaci-error "TCL shell $with_tclsh is not a file" + } elseif {![file executable $with_tclsh]} { + hwaci-error "TCL shell $with_tclsh is not executable" + } else { + define TCLSH_CMD $with_tclsh + puts "Using tclsh at \"$with_tclsh\"" + } if {$use_tcl} { - # XXX if test x"${use_tcl}" = "xyes"; then - #set with_tcl `${with_tclsh} <${srcdir}/tool/find_tclconfig.tcl` - # XXX if test x"${with_tcl}" != x; then - #msg-result "$TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}" - # XXX else - #msg-result Warning: "$TCLSH_CMD is unable to recommend a tclConfig.sh" - #set use_tcl no - # XXX fi - # XXX fi + #set with_tcl [exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl] + if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { + set with_tcl $result + } + if {"" ne $with_tcl && [file isdir $with_tcl]} { + puts "$with_tclsh recommends the tclConfig.sh from $with_tcl" + } else { + puts "$with_tclsh is unable to recommand a tclConfig.sh" + set use_tcl 0 + } } - # XXX fi } - # XXX if test x"${use_tcl}" = "xyes"; then - # XXX if test x"${with_tcl}" != x; then - # XXX if test -r ${with_tcl}/tclConfig.sh; then - # set tclconfig "${with_tcl}/tclConfig.sh" - # XXX else - # XXX for i in tcl8.6 tcl9.0 lib; do - # XXX if test -r ${with_tcl}/$i/tclConfig.sh; then - #set tclconfig ${with_tcl}/$i/tclConfig.sh - # XXX break - # XXX fi - # XXX done - # XXX fi - # XXX if test ! -r "${tclconfig}"; then - #user-error "no tclConfig.sh file found under ${with_tcl}" - # XXX fi - # XXX else - # If we have not yet found a tclConfig.sh file, look in $libdir whic is - # set automatically by autoconf or by the --prefix command-line option. - # See https://sqlite.org/forum/forumpost/e04e693439a22457 - #set libdir ${prefix}/lib - # XXX if test -r ${libdir}/tclConfig.sh; then - #set tclconfig ${libdir}/tclConfig.sh - # XXX else - # XXX for i in tcl8.6 tcl9.0 lib; do - # XXX if test -r ${libdir}/$i/tclConfig.sh; then - #set tclconfig ${libdir}/$i/tclConfig.sh - # XXX break - # XXX fi - # XXX done - # XXX fi - # XXX if test ! -r "${tclconfig}"; then - #user-error "cannot find a usable tclConfig.sh file. - # Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. - # SQLite does not use TCL internally, but TCL is required to build SQLite - # from canonical sources and TCL is required for testing." - # XXX fi - # XXX fi - # msg-result "loading TCL configuration from ${tclconfig}" - # XXX . ${tclconfig} - # XXX autosetup automatically substitutes all define'd values - # In general, simply 'define' the value rather than using a shell - # variable and AC_SUBST. - # - # XXX AC_SUBST TCL_INCLUDE_SPEC - # XXX AC_SUBST TCL_LIB_SPEC - # XXX AC_SUBST TCL_STUB_LIB_SPEC - # There are lots of other configuration variables that are provided by the - # tclConfig.sh file and that could be included here. But as of right now, - # TCL_LIB_SPEC is the only what that the Makefile uses. - # XXX HAVE_TCL=1 - # XXX elif test x"${original_use_tcl}" = "xno"; then - # msg-result "unable to run tests because of --disable-tcl" - # XXX HAVE_TCL=0 - # XXX else - # msg-result "unable to run tests because no tclConfig.sh file could be located" - # XXX HAVE_TCL=0 - # XXX fi - # XXX AC_SUBST HAVE_TCL - # XXX if test x"$TCLSH_CMD" == x; then - # XXX TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION} - # XXX if test ! -x ${TCLSH_CMD}; then - # set _2 ${TCL_EXEC_PREFIX}/bin/tclsh - # XXX if test ! -x ${TCLSH_CMD_2}; then - # msg-result Warning: "cannot find a usable tclsh at either ${TCLSH_CMD} or ${TCLSH_CMD_2}" - # XXX TCLSH_CMD=none - # XXX else - # XXX TCLSH_CMD=${TCLSH_CMD_2} - # XXX fi - # XXX fi - # XXX fi - # XXX if test "$TCLSH_CMD" = "none"; then - # If we can't find a local tclsh, then building the amalgamation will fail. - # We act as though --disable-amalgamation has been used. - # msg-result Warning: "Warning: can't find tclsh - defaulting to non-amalgamation build." - # XXX USE_AMALGAMATION=0 - # XXX TCLSH_CMD="tclsh" - # XXX fi - # XXX AC_SUBST TCLSH_CMD - - # XXX AC_ARG_VAR TCLLIBDIR Where to install tcl plugin - # XXX if test "x${TCLLIBDIR+set}" != "xset" ; then - # XXX for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do - # XXX if test -d $i ; then - # XXX TCLLIBDIR=$i - # XXX break - # XXX fi - # XXX done - # XXX TCLLIBDIR="${TCLLIBDIR}/sqlite3" - # XXX fi + set cfg "" + set tclSubdirs {tcl8.6 tcl9.0 lib} + if {$use_tcl} { + if {"" ne $with_tcl} { + if {[file readable "${with_tcl}/tclConfig.sh"]} { + set cfg "${with_tcl}/tclConfig.sh" + } else { + foreach i $tclSubdirs { + if {[file readable "${with_tcl}/$i/tclConfig.sh"]} { + set cfg "${with_tcl}/$i/tclConfig.sh" + break + } + } + } + if {"" eq $cfg} { + hwaci-error "No tclConfig.sh found under ${with_tcl}" + } + } else { + # If we have not yet found a tclConfig.sh file, look in $libdir which is + # set automatically by autosetup or by the --prefix command-line option. + # See https://sqlite.org/forum/forumpost/e04e693439a22457 + set libdir [get-define libdir] + if {[file readable "${libdir}/tclConfig.sh"]} { + set cfg "${libdir}/tclConfig.sh" + } else { + foreach i $tclSubdirs { + if {[file readable "${libdir}/$i/tclConfig.sh"]} { + set cfg "${libdir}/$i/tclConfig.sh" + break + } + } + } + if {![file readable $cfg]} { + hwaci-error { + Cannot find a usable tclConfig.sh file. + Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. + SQLite does not use TCL internally, but TCL is required to build SQLite + from canonical sources and TCL is required for testing. + } + } + } + } elseif {!$optTcl} { + puts "Unable to run tests because of --disable-tcl" + } else { + puts "Unable to run tests because no tclConfig.sh file could be located" + } - unset tEnable with_tclsh with_tcl -}; # end of tcl + define HAVE_TCL $use_tcl + define TCL_CONFIG_SH $cfg +# puts "hwaci-check-tcl: with_tclsh=$with_tclsh" +# puts "hwaci-check-tcl: with_tcl=$with_tcl" +# puts "hwaci-check-tcl: cfg=$cfg" +# puts "hwaci-check-tcl: use_tcl ${use_tcl}" +} +hwaci-check-tcl -hwaci-check-rpath +# The historical configure.ac sources tclConfig.sh so that it can use +# the several TCL_... env vars. We obviously cannot do that from TCL, +# so we apply a level of indirection. Note that if the config is not +# available, this generates empty-string entries for the various +# options we're interested in. +eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]"] + +######################################################################## +# Check which TCL to use as a code generator. Prefer jimsh simply +# because we have it in-tree (it's part of autosetup). +define CFLAGS_JIMSH {} +puts "Looking for path-resolution function for JimTCL... " +if {[cc-check-functions realpath]} { + define-append CFLAGS_JIMSH -DHAVE_REALPATH + define BTCL "\$(JIMSH)" +} elseif {[cc-check-functions _fullpath]} { + # _fullpath() is a Windows API + define-append CFLAGS_JIMSH -DHAVE__FULLPATH + define BTCL "\$(JIMSH)" +} elseif {"" ne [get-define TCLSH_CMD]} { + define BTCL "\$(TCLSH_CMD)" +} else { + hwaci-error "Cannot find a tclsh to use for code generation." +} + +# /TCL +######################################################################## ######################################################################## # Thread safety? @@ -507,34 +474,6 @@ hwaci-if-opt-truthy threadsafe { define LDFLAGS_PTHREAD "" } -######################################################################## -# Do we want to support release? -# -# Maintenance note: this might be irrelevant with an autosetup port, -# as it appears to be related to libtool (part of the autotools). -# -if {0} { - hwaci-if-opt-truthy releasemode { - msg-result "Release-mode build." - set enable_releasemode 1 - } { - msg-result "Non-release-mode build." - set enable_releasemode 0 - } -} - -if {0} { - msg-checking "Checking whether to support shared library linked as release mode or not..." - # XXX if test "$enable_releasemode" = "no"; then - # XXX ALLOWRELEASE="" - msg-result "no" - # XXX else - # XXX ALLOWRELEASE="-release `cat $srcdir/VERSION`" - msg-result "yes" - # XXX fi - # XXX AC_SUBST ALLOWRELEASE -} - ######################################################################## # Do we want temporary databases in memory? # @@ -706,57 +645,6 @@ hwaci-if-opt-truthy math { msg-result "Disabling math SQL functions" } -if {0} { - # is this still relevant? - - ######### - # attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter - # XXX for option in $CFLAGS $CPPFLAGS - # XXX do - # XXX case $option in - # XXX -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; - # XXX -DSQLITE_ENABLE*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; - # XXX esac - # XXX done - # XXX AC_SUBST OPT_FEATURE_FLAGS - - # attempt to remove any OMITS and ENABLES from the $(CFLAGS) parameter - # XXX ac_temp_CFLAGS="" - # XXX for option in $CFLAGS - # XXX do - # XXX case $option in - # XXX -DSQLITE_OMIT*) ;; - # XXX -DSQLITE_ENABLE*) ;; - # XXX *) ac_temp_CFLAGS="$ac_temp_CFLAGS $option";; - # XXX esac - # XXX done - # XXX CFLAGS=$ac_temp_CFLAGS - - # attempt to remove any OMITS and ENABLES from the $(CPPFLAGS) parameter - # XXX ac_temp_CPPFLAGS="" - # XXX for option in $CPPFLAGS - # XXX do - # XXX case $option in - # XXX -DSQLITE_OMIT*) ;; - # XXX -DSQLITE_ENABLE*) ;; - # XXX *) ac_temp_CPPFLAGS="$ac_temp_CPPFLAGS $option";; - # XXX esac - # XXX done - # XXX CPPFLAGS=$ac_temp_CPPFLAGS - - # attempt to remove any OMITS and ENABLES from the $(BUILD_CFLAGS) parameter - # XXX ac_temp_BUILD_CFLAGS="" - # XXX for option in $BUILD_CFLAGS - # XXX do - # XXX case $option in - # XXX -DSQLITE_OMIT*) ;; - # XXX -DSQLITE_ENABLE*) ;; - # XXX *) ac_temp_BUILD_CFLAGS="$ac_temp_BUILD_CFLAGS $option";; - # XXX esac - # XXX done - # XXX BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS -} - ######################################################################## # Emscripten SDK for building the web-based wasm components. # @@ -813,10 +701,10 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } ######################################################################## -# Invert the above loop's logic for some explicit -# SQLITE_OMIT_... cases. If config option $boolFlag is set, -# [add-feature-flag $featureFlag], where $featureFlag is intended to -# be -DSQLITE_OMIT_... +# Invert the above loop's logic for some explicit SQLITE_OMIT_... +# cases. If config option $boolFlag is set, [add-feature-flag +# $featureFlag], where $featureFlag is intended to be +# -DSQLITE_OMIT_... foreach {boolFlag featureFlag} { json -DSQLITE_OMIT_JSON } { @@ -830,15 +718,16 @@ foreach {boolFlag featureFlag} { ######################################################################## # Maybe extend JimTCL a bit. As of this writing (2024-09-27) it only -# needs -DHAVE_REALPATH or -DHAVE__FULLPATH to be compatible with our -# code generators. It can, however, be slightly extended via -# easy-to-detect features, should we need them. +# needs (-DHAVE_REALPATH or -DHAVE__FULLPATH) and -DHAVE_DIRENT_H to +# be compatible with our code generators. It can, however, be slightly +# extended via easy-to-detect features, should we need them. if {0 && "" ne [get-define CFLAGS_JIMSH]} { foreach jimFunc {opendir fsync isascii} { if {[cc-check-functions $jimFunc]} { define-append CFLAGS_JIMSH -DHAVE_[string toupper $jimFunc] } } + #These are hard-coded into jimsh0.c, so we must not -D them: #foreach jimDef {HAVE_UNISTD_H HAVE_DIRENT_H} { # if {[is-defined $jimDef]} { # define-append CFLAGS_JIMSH -D$jimDef @@ -849,6 +738,11 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { define ENABLE_SHARED $enable_shared + +######################################################################## +# Determine proper rpath-handling flags +hwaci-check-rpath + ######################################################################## # Generate the output files. # @@ -884,6 +778,8 @@ if {"" ne $oFF} { } unset oFF +######################################################################## +# Some build-dev/debug-only output hwaci-if-opt-truthy dump-defines { global DUMP_DEFINES_FILE msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" diff --git a/manifest b/manifest index c0dca8ca8e..60c7f85e38 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sbuild\sportability\sproblems\sdiscovered\son\san\sARM\sOpenBSD\ssystem. -D 2024-10-08T16:33:42.863 +C Get\smuch\sof\sthe\s--with-tcl-related\sbits\sworking. +D 2024-10-09T04:01:14.131 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 4cb6e44af5d0ed2a1ad347f008c00d3ddeae8f1dd2089a1348e7c6aa6be8e63d +F Makefile.in 3d237163c5cf5817eb63f2ce20119372e36f5cf48609dd22292160a26b599de4 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def afec3012da348dd0214047f575131d0a69e1aa67588e212daf604d4393453a3b +F auto.def 6c4f3b9d88ae343f0634a1534d3918cb3f7a215c65c85d1c3d0cce2f5dd47686 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2207,6 +2207,7 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9 +F tool/tclConfigShToTcl.sh e385583402655b1626f7ff737a607687f84aa4660d2125c2bd7daeb91ba424ba x F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl 1dcb7632e57cf57105248029e6e162fddaf6c0fccb3bb9e6215603752c5a2d4a F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e @@ -2235,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e9ab211f82f789c89ab52e8d5fe7526c09943b2b8b3002fa7a16fb2b40addc8f -R 83d7d512ee4d92805faea47e6da138cb +P ef5348dc3f5b9fbe19753ff85e4da461ee962f0790e5f9cfda6eba522576451b +R 53257972217ca0415948a8eb62c6c23b U stephan -Z 65540e91f90dac7f75bdfc0fac8976f3 +Z f49c2f1fcffe6fc0ebe3c9d93e81fc78 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 24c3e11ae9..594a612658 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef5348dc3f5b9fbe19753ff85e4da461ee962f0790e5f9cfda6eba522576451b +4e4a740369d3edc58d35c660b1ea73ee381503f82a98a4b770fd07cef1704e8b diff --git a/tool/tclConfigShToTcl.sh b/tool/tclConfigShToTcl.sh new file mode 100755 index 0000000000..e4eefc1d10 --- /dev/null +++ b/tool/tclConfigShToTcl.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# A level of indirection for use soley by the configure script +# (auto.def). +# +# Expects to be passed a full path to a tclConfig.sh. It sources it +# and emits TCL code which sets some vars which are exported by +# tclConfig.sh. +# +# This script expects that the caller has already validated that the +# file exists, is not a directory, and is readable. +# +# If passed no filename, or an empty one, then it emits config code +# suitable for the "config not found" case. +if test x = "x$1"; then + TCL_INCLUDE_SPEC= + TCL_LIB_SPEC= + TCL_STUB_LIB_SPEC= + TCL_EXEC_PREFIX= +else + . "$1" +fi + +echo "define TCL_INCLUDE_SPEC {$TCL_INCLUDE_SPEC} ;" +echo "define TCL_LIB_SPEC {$TCL_LIB_SPEC} ;" +echo "define TCL_STUB_LIB_SPEC {$TCL_STUB_LIB_SPEC} ;" +echo "define TCL_EXEC_PREFIX {$TCL_EXEC_PREFIX} ;" From 114e0543af6b65faf74f2f9b7f8f1e654b78ca5e Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Oct 2024 04:27:03 +0000 Subject: [PATCH 050/522] More work on the --with-tcl bits. FossilOrigin-Name: 4d4cc49b6a886fef9a7b3af78a7b752c199045904a1bf74912adae2e8fd360ad --- Makefile.in | 3 ++- auto.def | 28 +++++++++++++++++++++++++--- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/tclConfigShToTcl.sh | 2 ++ 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 86aaa6cba4..17f4853bbb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -150,6 +150,7 @@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@ +TCL_VERSION = @TCL_VERSION@ # Additional options when running tests using testrunner.tcl @@ -863,7 +864,7 @@ src-verify: $(TOP)/tool/src-verify.c # JIMSH = @srcdir@/jimsh @if CFLAGS_JIMSH -$(JIMSH): $(TOP)/autosetup/jimsh0.c Makefile +$(JIMSH): $(TOP)/autosetup/jimsh0.c $(BCC) -o $(JIMSH) @CFLAGS_JIMSH@ $< @endif diff --git a/auto.def b/auto.def index 455d71d36c..42de230636 100644 --- a/auto.def +++ b/auto.def @@ -439,7 +439,8 @@ eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]" # Check which TCL to use as a code generator. Prefer jimsh simply # because we have it in-tree (it's part of autosetup). define CFLAGS_JIMSH {} -puts "Looking for path-resolution function for JimTCL... " +puts "Which TCL to use for code generation... " +set cgtcl jimtcl if {[cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE_REALPATH define BTCL "\$(JIMSH)" @@ -448,11 +449,32 @@ if {[cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE__FULLPATH define BTCL "\$(JIMSH)" } elseif {"" ne [get-define TCLSH_CMD]} { + set cgtcl [get-define TCLSH_CMD] define BTCL "\$(TCLSH_CMD)" } else { - hwaci-error "Cannot find a tclsh to use for code generation." + # One last-ditch effort to find TCLSH_CMD: use info from + # tclConfig.sh to try to find a tclsh + if {"" eq [get-define TCLSH_CMD]} { + set tpre [get-define TCL_EXEC_PREFIX] + if {"" ne $tpre} { + set tv [get-define TCL_VERSION] + if {[file executable "${tpre}/bin/tclsh${tv}"]} { + define TCLSH_CMD "${tpre}/bin/tclsh${tv}" + } elseif {[file executable "${tpre}/bin/tclsh"]} { + define TCLSH_CMD "${tpre}/bin/tclsh" + } + unset tv + } + unset tpre + if {"" eq [get-define TCLSH_CMD]} { + hwaci-error "Cannot find a tclsh to use for code generation." + } + } + set cgtcl [get-define TCLSH_CMD] + define BTCL "\$(TCLSH_CMD)" } - +puts "TCL for code generation: $cgtcl" +unset cgtcl # /TCL ######################################################################## diff --git a/manifest b/manifest index 60c7f85e38..bd34874480 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Get\smuch\sof\sthe\s--with-tcl-related\sbits\sworking. -D 2024-10-09T04:01:14.131 +C More\swork\son\sthe\s--with-tcl\sbits. +D 2024-10-09T04:27:03.784 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 3d237163c5cf5817eb63f2ce20119372e36f5cf48609dd22292160a26b599de4 +F Makefile.in 660f7cdb7efa0ca81955eeaa923cf2ca4224394b26ad48c6e3827812473d7f35 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 6c4f3b9d88ae343f0634a1534d3918cb3f7a215c65c85d1c3d0cce2f5dd47686 +F auto.def dbe13ac57def26db322a1f757d56a058b7bdf291a7446d6cbb5ba8a07427e592 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2207,7 +2207,7 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9 -F tool/tclConfigShToTcl.sh e385583402655b1626f7ff737a607687f84aa4660d2125c2bd7daeb91ba424ba x +F tool/tclConfigShToTcl.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl 1dcb7632e57cf57105248029e6e162fddaf6c0fccb3bb9e6215603752c5a2d4a F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ef5348dc3f5b9fbe19753ff85e4da461ee962f0790e5f9cfda6eba522576451b -R 53257972217ca0415948a8eb62c6c23b +P 4e4a740369d3edc58d35c660b1ea73ee381503f82a98a4b770fd07cef1704e8b +R 5a4df385433704c071e534c0acd78587 U stephan -Z f49c2f1fcffe6fc0ebe3c9d93e81fc78 +Z f2c20cd58d6329de3edbd05f7dbd96d4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 594a612658..d0ea55ab84 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e4a740369d3edc58d35c660b1ea73ee381503f82a98a4b770fd07cef1704e8b +4d4cc49b6a886fef9a7b3af78a7b752c199045904a1bf74912adae2e8fd360ad diff --git a/tool/tclConfigShToTcl.sh b/tool/tclConfigShToTcl.sh index e4eefc1d10..d12657063e 100755 --- a/tool/tclConfigShToTcl.sh +++ b/tool/tclConfigShToTcl.sh @@ -17,6 +17,7 @@ if test x = "x$1"; then TCL_LIB_SPEC= TCL_STUB_LIB_SPEC= TCL_EXEC_PREFIX= + TCL_VERSION= else . "$1" fi @@ -25,3 +26,4 @@ echo "define TCL_INCLUDE_SPEC {$TCL_INCLUDE_SPEC} ;" echo "define TCL_LIB_SPEC {$TCL_LIB_SPEC} ;" echo "define TCL_STUB_LIB_SPEC {$TCL_STUB_LIB_SPEC} ;" echo "define TCL_EXEC_PREFIX {$TCL_EXEC_PREFIX} ;" +echo "define TCL_VERSION {$TCL_VERSION} ;" From 49bb81844c883b9442cbd3d1092dce84a9edee70 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Oct 2024 05:28:29 +0000 Subject: [PATCH 051/522] Generic build cleanups. FossilOrigin-Name: 2cd213b38748d93134dc88b25aada4741838eaed683e44d5cc7837a6586fa4cf --- Makefile.in | 35 ++++++++++++++++++--------- auto.def | 48 +++++++++++++++++++++----------------- autosetup/hwaci-common.tcl | 21 ++++++++++++----- manifest | 16 ++++++------- manifest.uuid | 2 +- 5 files changed, 74 insertions(+), 48 deletions(-) diff --git a/Makefile.in b/Makefile.in index 17f4853bbb..3fd42f3ebe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -749,12 +749,17 @@ LDFLAGS_libsqlite = \ # either results in building libsqlite3.so, builds sqlite3.c # directly, links in either of $(LIBOBJSO) or $(LIBOBJS1). +@if ENABLE_SHARED $(libsqlite3.DLL): $(LIBOBJ) $(TLINK) -o $@ \ @SHOBJ_LDFLAGS@ $(LIBOBJ) $(TLIBS) \ $(LDFLAGS_libsqlite) dll: $(libsqlite3.DLL) all: dll +@else +$(libsqlite3.DLL): + @echo "Build of $@ was explicitly disabled."; exit 1 +@endif $(libsqlite3.LIB): $(LIBOBJ) $(AR) crs $@ $(LIBOBJ) @@ -803,7 +808,9 @@ sqlite3$(TEXE): shell.c sqlite3.c shell.c sqlite3.c \ $(LDFLAGS_libsqlite) $(LDFLAGS_READLINE) cli: sqlite3$(TEXE) +@if !HAVE_WASI_SDK all: cli +@endif install-cli: sqlite3$(TEXT) $(install.bindir) $(INSTALL) -s sqlite3$(TEXT) "$(install.bindir)" @@ -848,11 +855,14 @@ srcck1$(BEXE): $(TOP)/tool/srcck1.c $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c sourcetest: srcck1$(BEXE) sqlite3.c - ./srcck1 sqlite3.c + ./srcck1$(BEXE) sqlite3.c -src-verify: $(TOP)/tool/src-verify.c +src-verify$(BEXE): $(TOP)/tool/src-verify.c $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c +verify-source: ./src-verify$(BEXE) + ./src-verify$(BEXE) $(TOP) + # # JimTCL is part of the autosetup suite and is suitable for all # current in-tree code-generation TCL jobs, but it requires that we @@ -875,9 +885,6 @@ $(JIMSH): $(TOP)/autosetup/jimsh0.c BTCL = @BTCL@ $(BTCL): -#XX# -#XX#verify-source: ./src-verify -#XX# ./src-verify $(TOP) #XX# #XX#fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h #XX# $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ @@ -1839,12 +1846,18 @@ distclean: clean #XX# $(TCC) -shared -o $@ sqlite3.def \ #XX# -Wl,"--strip-all" $(REAL_LIBOBJ) #XX# -#XX## -#XX## Fiddle app -#XX## -#XX#fiddle: sqlite3.c shell.c -#XX# make -C ext/wasm fiddle emcc_opt=-Os -#XX# + +# +# Fiddle app +# +@if EMCC_WRAPPER +fiddle: sqlite3.c shell.c + make -C ext/wasm fiddle emcc_opt=-Os +@else +fiddle: + @echo "Configure script did not find emcc, so fiddle build is not available."; exit 1 +@endif + #XX## #XX## Spell-checking for source comments #XX## The sources checked are either C sources or C source templates. diff --git a/auto.def b/auto.def index 42de230636..ae9499781f 100644 --- a/auto.def +++ b/auto.def @@ -2,14 +2,13 @@ global autosetup use cc cc-db cc-shared cc-lib hwaci-common set DUMP_DEFINES_FILE defines.list -set enable_shared 1 +define ENABLE_SHARED 1 # Are we cross compiling? set cross_compiling 0 if {[get-define host] ne [get-define build]} { set cross_compiling 1 } -define cross_compiling ${cross_compiling} ######################################################################## # A very long story made short, autosetup's --flag handling has @@ -172,7 +171,7 @@ proc add-shell-opt {args} { } } -hwaci-exe-extension +hwaci-file-extensions if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_UNIX 0 define SQLITE_OS_WIN 1 @@ -182,8 +181,6 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_WIN 0 # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS? } -hwaci-dll-extension -hwaci-lib-extension ######### # Programs needed @@ -219,7 +216,6 @@ define BUILD_CFLAGS [get-env CFLAGS {-g}] # # It's unclear whether we can actually get away with making these # changes to the autosetup environment. -# if {1} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" @@ -231,13 +227,13 @@ if {1} { define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir hwaci-opt-set load-extension 0; # ==> --disable-load-extension - hwaci-opt-set threadsafe 0; # ==> --threadsafe + hwaci-opt-set threadsafe 0; # ==> --threadsafe=0 hwaci-opt-set tcl 0; # ==> --disable-tcl define HAVE_TCL 0 set cross_compiling 1 # libtool is apparently hard-coded to use gcc for linking DLLs, so # we disable the DLL build. - set enable_shared 0 + define ENABLE_SHARED 0 # Changing --host and --target have no effect here except to possibly # cause confusion. autoconf has finished processing them by this @@ -420,6 +416,12 @@ proc hwaci-check-tcl {} { define HAVE_TCL $use_tcl define TCL_CONFIG_SH $cfg + # The historical configure.ac sources tclConfig.sh so that it can + # use the several TCL_... env vars. We obviously cannot do that from + # TCL, so we apply a level of indirection. If the config is not + # available, this generates empty-string entries for the various + # options we're interested in. + eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]"] # puts "hwaci-check-tcl: with_tclsh=$with_tclsh" # puts "hwaci-check-tcl: with_tcl=$with_tcl" # puts "hwaci-check-tcl: cfg=$cfg" @@ -428,13 +430,6 @@ proc hwaci-check-tcl {} { hwaci-check-tcl -# The historical configure.ac sources tclConfig.sh so that it can use -# the several TCL_... env vars. We obviously cannot do that from TCL, -# so we apply a level of indirection. Note that if the config is not -# available, this generates empty-string entries for the various -# options we're interested in. -eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]"] - ######################################################################## # Check which TCL to use as a code generator. Prefer jimsh simply # because we have it in-tree (it's part of autosetup). @@ -667,6 +662,8 @@ hwaci-if-opt-truthy math { msg-result "Disabling math SQL functions" } +define cross_compiling ${cross_compiling} + ######################################################################## # Emscripten SDK for building the web-based wasm components. # @@ -681,11 +678,18 @@ if {[hwaci-check-emsdk]} { catch {exec rm -f $srcdir/tool/emcc.sh} } -proc affirm-have-math {} { +######################################################################## +# Check for log(3) in libm and die with an error if it is not +# found. $why should be the feature name which requires that function +# (it's used only in error messages). defines LDFLAGS_MATH to the +# required linker flags (which may be empty even if the math APIs are +# found, depending on the OS). +proc affirm-have-math {why} { if {![hwaci-check-function-in-lib log m]} { - user-error "Missing required math APIs" + user-error "Missing math APIs for $why" } define LDFLAGS_MATH [get-define lib_log ""] + undefine lib_log } ######################################################################## @@ -698,8 +702,8 @@ foreach {boolFlag featureFlag ifSetEvalThis} { hwaci-opt-set rtree hwaci-opt-set session } - fts4 -DSQLITE_ENABLE_FTS4 {affirm-have-math} - fts5 -DSQLITE_ENABLE_FTS5 {affirm-have-math} + fts4 -DSQLITE_ENABLE_FTS4 {affirm-have-math fts4} + fts5 -DSQLITE_ENABLE_FTS5 {affirm-have-math fts5} geopoly -DSQLITE_ENABLE_GEOPOLY {hwaci-opt-set rtree} rtree -DSQLITE_ENABLE_RTREE {} session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {} @@ -715,8 +719,10 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } { hwaci-if-opt-truthy $boolFlag { add-feature-flag $featureFlag - msg-result "Enabling $boolFlag" eval $ifSetEvalThis + if {"all" ne $boolFlag} { + msg-result "Enabling $boolFlag" + } } { msg-result "Not enabling $boolFlag" } @@ -758,8 +764,6 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available }; # JimTCL -define ENABLE_SHARED $enable_shared - ######################################################################## # Determine proper rpath-handling flags diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index b0d6fec99c..35ba1b3819 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -512,6 +512,9 @@ proc hwaci-exe-extension {} { # Works like hwaci-exe-extension except that it defines BUILD_DLLEXT # and TARGET_DLLEXT to one of (.so, ,dll, .dylib). # +# Trivia: for .dylib files, the linker needs the -dynamiclib flag +# instead of -shared. +# # TODO: have someone verify whether this is correct for the # non-Linux/BSD platforms. proc hwaci-dll-extension {} { @@ -539,9 +542,6 @@ proc hwaci-dll-extension {} { proc hwaci-lib-extension {} { proc inner {key} { switch -glob -- [get-define $key] { - *apple* { - return ".a" - } *-*-ming* - *-*-cygwin - *-*-msys { return ".lib" } @@ -554,6 +554,14 @@ proc hwaci-lib-extension {} { define TARGET_LIBEXT [inner host] } +######################################################################## +# Calls all of the hwaci-*-extension functions. +proc hwaci-file-extensions {} { + hwaci-exe-extension + hwaci-dll-extension + hwaci-lib-extension +} + ######################################################################## # Expects a list of file names. If any one of them does not exist in # the filesystem, it fails fatally with an informative message. @@ -561,7 +569,7 @@ proc hwaci-lib-extension {} { # then it emits msg-checking/msg-result messages for each file. proc hwaci-affirm-files-exist {args} { set rc "" - set verbose 1 + set verbose 0 if {[lindex $args 0] eq "-v"} { set verbose 1 set args [lrange $args 1 end] @@ -589,6 +597,7 @@ proc hwaci-affirm-files-exist {args} { # --with-emsdk=DIR or the $EMSDK environment variable. # - EMSDK_ENV = path to EMSDK_HOME/emsdk_env.sh or "" # - BIN_EMCC = $EMSDK_HOME/upstream/emscripten/emcc or "" +# - HAVE_EMSDK = 0 or 1 (this function's return value) # # Returns 1 if EMSDK_ENV is found, else 0. If EMSDK_HOME is not empty # but BIN_EMCC is then emcc was not found in the EMSDK_HOME, in which @@ -648,9 +657,9 @@ proc hwaci-check-rpath {} { # downstream tests may fail because the resulting rpath gets # implicitly injected into them. cc-with {} { - if {[cc-check-flags {-rpath $lp}]} { + if {[cc-check-flags "-rpath $lp"]} { define LDFLAGS_RPATH "-rpath $lp" - } elseif {[cc-check-flags {-Wl,-rpath -Wl,$lp}]} { + } elseif {[cc-check-flags "-Wl,-rpath -Wl,$lp"]} { define LDFLAGS_RPATH "-Wl,-rpath -Wl,$lp" } elseif {[cc-check-flags -Wl,-R$lp]} { define LDFLAGS_RPATH "-Wl,-R$lp" diff --git a/manifest b/manifest index bd34874480..a632b291e5 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C More\swork\son\sthe\s--with-tcl\sbits. -D 2024-10-09T04:27:03.784 +C Generic\sbuild\scleanups. +D 2024-10-09T05:28:29.735 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 660f7cdb7efa0ca81955eeaa923cf2ca4224394b26ad48c6e3827812473d7f35 +F Makefile.in 3d059a8dba41c3134fbf9a9501aee8e70b4ebfaa9e0f258004bf2885e774ba27 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def dbe13ac57def26db322a1f757d56a058b7bdf291a7446d6cbb5ba8a07427e592 +F auto.def 606f65a487c5ef875859a0a8cccbb87c41e6725a8552ec3b0a8b9d9d1519d3d1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -46,7 +46,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl fcb479deea42c54d5486d20b811a00b3880f8dc597afac41145463cc5d58cdae +F autosetup/hwaci-common.tcl 8bb16ac39af463ad58a499a12ab3c813e003d6d7dd8ed90f94375b05ae4cdbd4 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4e4a740369d3edc58d35c660b1ea73ee381503f82a98a4b770fd07cef1704e8b -R 5a4df385433704c071e534c0acd78587 +P 4d4cc49b6a886fef9a7b3af78a7b752c199045904a1bf74912adae2e8fd360ad +R 03792e2dee1fc3db74b33e1210d2352d U stephan -Z f2c20cd58d6329de3edbd05f7dbd96d4 +Z 17a57a3c16f20db47faf261d6adb40b0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d0ea55ab84..aae4532baa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d4cc49b6a886fef9a7b3af78a7b752c199045904a1bf74912adae2e8fd360ad +2cd213b38748d93134dc88b25aada4741838eaed683e44d5cc7837a6586fa4cf From c7b822082e04d0fab3de137486b5b5f65e546a2a Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Oct 2024 07:12:32 +0000 Subject: [PATCH 052/522] More work on the tcl build bits. FossilOrigin-Name: f00988a909dd4338083a6e09231932c6fa57a40e35968c51483615121d20d25f --- Makefile.in | 174 +++++++++++++++++++++++++++----------------------- auto.def | 56 ++++++++++++++-- manifest | 14 ++-- manifest.uuid | 2 +- 4 files changed, 151 insertions(+), 95 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3fd42f3ebe..53a3969e78 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,11 +1,11 @@ -#!/usr/make +#!/usr/bin/make # # Makefile for SQLITE # -# This makefile is suppose to be configured automatically using the -# configure script. But if that does not work for you, you can configure -# the makefile manually. Just set the parameters below to values that -# work well for your system. +# This makefile is intended to be configured automatically using the +# configure script. Hand editing may not work as expected because +# certain blocks are added or removed depending on configure-time +# information. # all: #XX# Lines starting with #XX# are TODOs for the port to autosetup @@ -31,22 +31,21 @@ AR = @AR@ # will run on the platform that is doing the build. # BCC = @BUILD_CC@ @BUILD_CFLAGS@ -# TODO: @BUILD_CFLAGS@ # -#XX## TCC is the C Compile and options for use in building executables that -#XX## will run on the target platform. (BCC and TCC are usually the -#XX## same unless your are cross-compiling.) Separate CC and CFLAGS macros -#XX## are provide so that these aspects of the build process can be changed -#XX## on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" -#XX## +# TCC is the C Compile and options for use in building executables that +# will run on the target platform. (BCC and TCC are usually the +# same unless your are cross-compiling.) Separate CC and CFLAGS macros +# are provide so that these aspects of the build process can be changed +# on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" +# CC = @CC@ CFLAGS ?= @CFLAGS@ CPPFLAGS ?= @CPPFLAGS@ @if SH_CFLAGS CFLAGS += @SH_CFLAGS@ @endif -CFLAGS_stdio3 := -I${TOP}/ext/misc # CFLAGS_stdio3 ==> for sqlite3_stdio.h +CFLAGS_stdio3 := -I${TOP}/ext/misc TCC = ${CC} ${CFLAGS} TCC += -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session @@ -194,15 +193,24 @@ INSTALL = @BIN_INSTALL@ INSTALL_noexec = $(INSTALL) -m 0644 # ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... -#XX#LIBTOOL = ./libtool -#XX#ALLOWRELEASE = @ALLOWRELEASE@ -#XX# +install.bindir = "$(DESTDIR)$(bindir)" +install.libdir = "$(DESTDIR)$(libdir)" +install.includedir = "$(DESTDIR)$(prefix)/include" +install.pkgconfigdir = "$(DESTDIR)$(pkgconfigdir)" +$(install.bindir) $(install.libdir) $(install.includedir) $(install.pkgconfigdir): + $(INSTALL) -d "$@" + #XX## libtool compile/link/install #XX#TCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(TCOMPILE_EXTRAS) #XX#TLINK = $(LIBTOOL) --mode=link $(TCC) $(TCOMPILE_EXTRAS) @LDFLAGS@ $(TLINK_EXTRAS) #XX#LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) + +# TCOMPILE = generic target platform compiler invocation TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) +# TLINK = compiler invocation for when the target will be an executable TLINK = $(TCC) $(TLINK_EXTRAS) +# TLINK_shared = $(TLINK) invocation specifically for shared libraries +TLINK_shared = $(TLINK) @SHOBJ_LDFLAGS@ # # You should not have to change anything below this line @@ -702,26 +710,25 @@ DBFUZZ_OPT = ST_OPT = -DSQLITE_OS_KV_OPTIONAL -# In wasi-sdk builds, disable the CLI shell build. +# In wasi-sdk builds, remove the CLI shell build from 'all'. @if HAVE_WASI_SDK SQLITE3_SHELL_TARGET = @else SQLITE3_SHELL_TARGET = sqlite3$(TEXE) @endif -#XXX#??? SQLITE3_O = $(TOP)/sqlite3.o -# Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either -# libtclsqlite3.la or an empty value. -libtclsqlite3.la_0 = -libtclsqlite3.la_1 = libtclsqlite3.la +@if HAVE_TCL +libtclsqlite3.DLL = libtclsqlite3$(TDLL) +@else +libtclsqlite3.DLL = +@endif + # # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. # all: sqlite3.h sqlite3.c shell.c $(SQLITE3_SHELL_TARGET) -#all: libsqlite3.la \ -#XX# $(libtclsqlite3.la_$(HAVE_TCL)) # Re-run $(TOP)/configure with the same args invoked to produce this # makefile. @@ -735,6 +742,9 @@ Makefile: $(TOP)/Makefile.in $(AS_AUTO_DEF) sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF) $(AUTOREMAKE) @touch $@ +install-pc: sqlite3.pc $(install.pkgconfigdir) + $(INSTALL_noexec) sqlite3.pc $(install.pkgconfigdir) +install: install-pc sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) $(AUTOREMAKE) @@ -751,57 +761,64 @@ LDFLAGS_libsqlite = \ @if ENABLE_SHARED $(libsqlite3.DLL): $(LIBOBJ) - $(TLINK) -o $@ \ - @SHOBJ_LDFLAGS@ $(LIBOBJ) $(TLIBS) \ - $(LDFLAGS_libsqlite) -dll: $(libsqlite3.DLL) + $(TLINK_shared) -o $@ \ + $(LIBOBJ) $(TLIBS) $(LDFLAGS_libsqlite) all: dll @else $(libsqlite3.DLL): @echo "Build of $@ was explicitly disabled."; exit 1 @endif +dll: $(libsqlite3.DLL) $(libsqlite3.LIB): $(LIBOBJ) $(AR) crs $@ $(LIBOBJ) lib: $(libsqlite3.LIB) all: lib -install.bindir = $(DESTDIR)$(bindir) -install.libdir = $(DESTDIR)$(libdir) -install.includedir = $(DESTDIR)$(prefix)/include -$(install.bindir) $(install.libdir) $(install.includedir): - $(INSTALL) -d "$@" - +# # Install the $(libsqlite3.DLL) as $(libsqlite3.DLL).@RELEASE@ and # create symlinks which point to it. Do we really need all of this -# hoop-jumping? Can we not simply install the .so as-is? +# hoop-jumping? Can we not simply install the .so as-is to +# libsqlite3.so (without the versioned bits)? # # The historical SQLite build always used a version number of 0.8.6 # for reasons lost to history. install-dll: $(install.libdir) $(libsqlite3.DLL) - $(INSTALL) $(libsqlite3.DLL) "$(install.libdir)" - cd "$(install.libdir)"; \ + $(INSTALL) $(libsqlite3.DLL) $(install.libdir) + cd $(install.libdir); \ rm -f $(libsqlite3.DLL).3 $(libsqlite3.DLL).@RELEASE@; \ mv $(libsqlite3.DLL) $(libsqlite3.DLL).@RELEASE@; \ ln -s $(libsqlite3.DLL).@RELEASE@ $(libsqlite3.DLL).3; \ ln -s $(libsqlite3.DLL).3 $(libsqlite3.DLL) +install: install-dll +# # Install $(libsqlite3.LIB) install-lib: $(install.libdir) $(libsqlite3.LIB) - $(INSTALL_noexec) $(libsqlite3.LIB) "$(install.libdir)" + $(INSTALL_noexec) $(libsqlite3.LIB) $(install.libdir) +install: install-lib +# +# Install C header files install-includes: sqlite3.h $(install.includedir) - $(INSTALL_noexec) sqlite3.h "$(install.includedir)" - -install-libs: install-lib install-dll -install: install-libs install-includes - -#XX#libtclsqlite3.la: tclsqlite.lo libsqlite3.la -#XX# $(TLINK) -no-undefined -o $@ tclsqlite.lo \ -#XX# libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \ -#XX# -rpath "$(TCLLIBDIR)" \ -#XX# -version-info "8:6:8" \ -#XX# -avoid-version + $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install.includedir) +install: install-includes + +@if HAVE_TCL +$(libtclsqlite3.DLL): tclsqlite.o $(libsqlite3.LIB) + $(TLINK_shared) -o $@ tclsqlite.o \ + $(libsqlite3.LIB) $(TCL_INCLUDE_SPEC) \ + $(TCL_STUB_LIB_SPEC) $(TLIBS) \ + @TCLLIB_RPATH@ +libtcl: $(libtclsqlite3.DLL) +all: $(libtclsqlite3.DLL) +install.tcldir = "$(DESTDIR)@TCLLIBDIR@" +install-tcl: $(libtclsqlite3.DLL) pkgIndex.tcl + $(INSTALL) -d $(install.tcldir) + $(INSTALL) $(libtclsqlite3.DLL) $(install.tcldir) + $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) +install: install-tcl +@endif sqlite3$(TEXE): shell.c sqlite3.c $(TCC) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ @@ -813,7 +830,7 @@ all: cli @endif install-cli: sqlite3$(TEXT) $(install.bindir) - $(INSTALL) -s sqlite3$(TEXT) "$(install.bindir)" + $(INSTALL) -s sqlite3$(TEXT) $(install.bindir) install: install-cli @@ -821,8 +838,7 @@ sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite) install-diff: sqldiff$(TEXE) $(install.bindir) - $(INSTALL) -s sqldiff$(TEXT) "$(install.bindir)" - + $(INSTALL) -s sqldiff$(TEXT) $(install.bindir) #install: install-diff dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h @@ -843,13 +859,12 @@ sqlite3-rsync$(TEXE): $(RSYNC_SRC) $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite) install-rsync: sqlite3-rsync$(TEXE) $(install.bindir) - $(INSTALL) sqlite3-rsync$(TEXT) "$(install.bindir)" - + $(INSTALL) sqlite3-rsync$(TEXT) $(install.bindir) #install: install-rsync -scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo +scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ - $(TOP)/ext/misc/scrub.c sqlite3.lo $(LDFLAGS_libsqlite) + $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS_libsqlite) srcck1$(BEXE): $(TOP)/tool/srcck1.c $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c @@ -972,7 +987,7 @@ $(BTCL): #XX# $(MPTEST1) --journalmode TRUNCATE #XX# $(MPTEST2) --journalmode DELETE #XX# -#XX# + has_tclsh84: sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) touch has_tclsh84 @@ -981,11 +996,11 @@ has_tclsh85: sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) touch has_tclsh85 -#XX#has_tclconfig: -#XX# @ if test x"$(HAVE_TCL)" != "x1"; then echo 'ERROR: Requires access to "tclConfig.sh" which "configure" was not able to locate'; exit 1; fi -#XX# touch has_tclconfig -#XX# -#XX# +has_tclconfig: + @ if test x"$(HAVE_TCL)" != "x1"; then echo 'ERROR: Requires access to "tclConfig.sh" which "configure" was not able to locate'; exit 1; fi + touch has_tclconfig + +# # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to # build on the target system. Some of the C source code and header @@ -1029,10 +1044,6 @@ sqlite3ext.h: .target_source #XX#sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl has_tclsh84 #XX# $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl #XX# -#XX## Rule to build the amalgamation -#XX## -#XX#sqlite3.lo: sqlite3.c -#XX# $(TCOMPILE) $(TEMP_STORE) -c sqlite3.c # Rules to build the LEMON compiler generator # @@ -1299,18 +1310,19 @@ whereexpr.o: $(TOP)/src/whereexpr.c $(HDR) window.o: $(TOP)/src/window.c $(HDR) $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c -#XX#tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) -#XX# $(TCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c -#XX# -#XX#tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(HDR) -#XX# $(TCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c -#XX# -#XX#tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(HDR) -#XX# $(TCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c -#XX# -#XX#tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.lo libsqlite3.la -#XX# $(TLINK) -o $@ tclsqlite-shell.lo \ -#XX# libsqlite3.la $(LIBTCL) +tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) + $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) \ + -c $(TOP)/src/tclsqlite.c + +tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(HDR) + $(TCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c + +tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(HDR) + $(TCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c + +tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) + $(TLINK) -o $@ tclsqlite-shell.o \ + $(libsqlite3.LIB) $(LIBTCL) # Rules to build opcodes.c and opcodes.h # @@ -1758,8 +1770,8 @@ sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlit #XX# $(INSTALL) -d $(DESTDIR)$(pkgconfigdir) #XX# $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir) #XX# -#XX#pkgIndex.tcl: -#XX# echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ +pkgIndex.tcl: + echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ #XX# #XX#tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl #XX# $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR) @@ -1843,7 +1855,7 @@ distclean: clean #XX# | sed 's/^.* _//' >>sqlite3.def #XX# #XX#sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def -#XX# $(TCC) -shared -o $@ sqlite3.def \ +#XX# $(TCC) @SHOBJ_LDFLAGS@ -o $@ sqlite3.def \ #XX# -Wl,"--strip-all" $(REAL_LIBOBJ) #XX# diff --git a/auto.def b/auto.def index ae9499781f..fbb4e0e3a3 100644 --- a/auto.def +++ b/auto.def @@ -323,10 +323,28 @@ hwaci-if-opt-truthy with-debug { ######################################################################## # TCL... # -# Under construction. An attempt to port most of the -# --with-tcl/--with-tclsh logic from configure.ac to autosetup. This -# part would actually be easier in the shell, and some of it will -# seemingly be impossible without shell code. +# hwaci-check-tcl performs most of the --with-tcl and --with-tclsh +# handling. Some related bits and pieces are performed before and +# after that function is called. +# +# Important [define]'d vars: +# +# - HAVE_TCL indicates whether we have a tclsh suitable for building +# the TCL SQLite extension and, by extension, the testing +# infrastructure. This must only be 1 for environments where +# tclConfig.sh can be found. +# +# - TCLSH_CMD is the path to the canonical tclsh. It never refers to +# jimtcl. +# +# - TCL_CONFIG_SH is the path to tclConfig.sh or "". +# +# - TCLLIBDIR is the dir to which libtclsqlite3 gets installed. +# +# - TCLLIB_RPATH = the -rpath flag specific to libtclsqlite3. +# +# - BTCL = the path to the tcl interpreter used for in-tree code +# generation. It may be jimtcl or the canonical tclsh. define HAVE_TCL 0 define TCLSH_CMD {exit 1} proc hwaci-check-tcl {} { @@ -334,7 +352,6 @@ proc hwaci-check-tcl {} { puts "Checking for a suitable tcl... " set optTcl [hwaci-opt-truthy tcl] set use_tcl $optTcl - set tclsh "" set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] # puts "hwaci-check-tcl: use_tcl ${use_tcl}" @@ -426,7 +443,33 @@ proc hwaci-check-tcl {} { # puts "hwaci-check-tcl: with_tcl=$with_tcl" # puts "hwaci-check-tcl: cfg=$cfg" # puts "hwaci-check-tcl: use_tcl ${use_tcl}" -} + + if {$use_tcl} { + # Set up the TCLLIBDIR and TCLLIB_RPATH + set tcllibdir [getenv TCLLIBDIR ""] + if {"" eq $tcllibdir} { + if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { + foreach i $result { + if {[file isdir $i]} { + set tcllibdir $i + break + } + } + } else { + hwaci-warn "Cannot determine TCLLIBDIR" + } + } + set tclrpath "" + if {"" ne $tcllibdir} { + set tcllibdir "${tcllibdir}/sqlite3" + set rp [get-define SH_LINKRPATH] + set tclrpath [string map [list "%s" $tcllibdir] $rp] + } + define TCLLIBDIR $tcllibdir + define TCLLIB_RPATH $tclrpath + #hwaci-error "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" + } +}; # hwaci-check-tcl hwaci-check-tcl @@ -470,6 +513,7 @@ if {[cc-check-functions realpath]} { } puts "TCL for code generation: $cgtcl" unset cgtcl + # /TCL ######################################################################## diff --git a/manifest b/manifest index a632b291e5..77a4fe8e17 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Generic\sbuild\scleanups. -D 2024-10-09T05:28:29.735 +C More\swork\son\sthe\stcl\sbuild\sbits. +D 2024-10-09T07:12:32.985 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 3d059a8dba41c3134fbf9a9501aee8e70b4ebfaa9e0f258004bf2885e774ba27 +F Makefile.in fb858ccb1965a829f8b1c266cf4b756edde5b50339b95481536e28f32d077b69 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 606f65a487c5ef875859a0a8cccbb87c41e6725a8552ec3b0a8b9d9d1519d3d1 +F auto.def 42b2334f320fafcebb09673453fc9df470839e136d84ddeb74699af16b08b056 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4d4cc49b6a886fef9a7b3af78a7b752c199045904a1bf74912adae2e8fd360ad -R 03792e2dee1fc3db74b33e1210d2352d +P 2cd213b38748d93134dc88b25aada4741838eaed683e44d5cc7837a6586fa4cf +R 98f7d4f5f7af2536964c79c65e8d70ef U stephan -Z 17a57a3c16f20db47faf261d6adb40b0 +Z cbdd1ae5509e6acf440c2deb9730c343 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index aae4532baa..d030b291c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2cd213b38748d93134dc88b25aada4741838eaed683e44d5cc7837a6586fa4cf +f00988a909dd4338083a6e09231932c6fa57a40e35968c51483615121d20d25f From 92860ade7a85cb057fa1f62bc26f03e991676c83 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Oct 2024 08:05:21 +0000 Subject: [PATCH 053/522] Remove extra layer of quotes around install target dirs. FossilOrigin-Name: f2e3cf219e28c369ad6de240f0780eb3b638c47e1bab56ab80713a9bf63e2aa7 --- Makefile.in | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 53a3969e78..59ebc6c8f0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -198,7 +198,7 @@ install.libdir = "$(DESTDIR)$(libdir)" install.includedir = "$(DESTDIR)$(prefix)/include" install.pkgconfigdir = "$(DESTDIR)$(pkgconfigdir)" $(install.bindir) $(install.libdir) $(install.includedir) $(install.pkgconfigdir): - $(INSTALL) -d "$@" + $(INSTALL) -d $@ #XX## libtool compile/link/install #XX#TCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(TCOMPILE_EXTRAS) diff --git a/manifest b/manifest index 77a4fe8e17..bcc00ba203 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C More\swork\son\sthe\stcl\sbuild\sbits. -D 2024-10-09T07:12:32.985 +C Remove\sextra\slayer\sof\squotes\saround\sinstall\starget\sdirs. +D 2024-10-09T08:05:21.230 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in fb858ccb1965a829f8b1c266cf4b756edde5b50339b95481536e28f32d077b69 +F Makefile.in 77e637423518a13f901da15cc2faee0b8bf19bf3a5d6e78f9f5e6fd526318047 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2cd213b38748d93134dc88b25aada4741838eaed683e44d5cc7837a6586fa4cf -R 98f7d4f5f7af2536964c79c65e8d70ef +P f00988a909dd4338083a6e09231932c6fa57a40e35968c51483615121d20d25f +R f1cf57e7d2a38201da3601f8ddb82096 U stephan -Z cbdd1ae5509e6acf440c2deb9730c343 +Z 7c98480696b78887885abe8d02f332ed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d030b291c1..4c2e9e0910 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f00988a909dd4338083a6e09231932c6fa57a40e35968c51483615121d20d25f +f2e3cf219e28c369ad6de240f0780eb3b638c47e1bab56ab80713a9bf63e2aa7 From fa2770fec5d8b1c31f95d8363c35577a4aa5d500 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Oct 2024 13:20:25 +0000 Subject: [PATCH 054/522] More work on the tcl build parts. FossilOrigin-Name: 292ad7d519d39f16f130d082d3f134deadd5409d56ffb5340064a1996f4b4d57 --- Makefile.in | 78 +++++++++++++++++++++++++++------------------------ manifest | 12 ++++---- manifest.uuid | 2 +- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/Makefile.in b/Makefile.in index 59ebc6c8f0..b0526f0d84 100644 --- a/Makefile.in +++ b/Makefile.in @@ -811,13 +811,54 @@ $(libtclsqlite3.DLL): tclsqlite.o $(libsqlite3.LIB) $(TCL_STUB_LIB_SPEC) $(TLIBS) \ @TCLLIB_RPATH@ libtcl: $(libtclsqlite3.DLL) + all: $(libtclsqlite3.DLL) + +pkgIndex.tcl: + echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ + install.tcldir = "$(DESTDIR)@TCLLIBDIR@" install-tcl: $(libtclsqlite3.DLL) pkgIndex.tcl $(INSTALL) -d $(install.tcldir) $(INSTALL) $(libtclsqlite3.DLL) $(install.tcldir) $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) + install: install-tcl + +tclsqlite3.c: sqlite3.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 + +#sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCL) # has_tclsh84 +# $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl + +# Build the SQLite TCL extension in a way that make it compatible +# with whatever version of TCL is running as $TCLSH_CMD, possibly defined +# by --with-tclsh= +# +tclextension: tclsqlite3.c + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) + +# Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD +# to find it. +# +tclextension-install: tclsqlite3.c + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) + +# Install the SQLite TCL extension that is used by $TCLSH_CMD +# +tclextension-uninstall: + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall + +# List all installed the SQLite TCL extension that is are accessible +# by $TCLSH_CMD, included prior versions. +# +tclextension-list: + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info + +# end of @if HAVE_TCL @endif sqlite3$(TEXE): shell.c sqlite3.c @@ -1035,16 +1076,6 @@ sqlite3r.c: sqlite3.c sqlite3r.h $(BTCL) # has_tclsh84 sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . -#XX#tclsqlite3.c: sqlite3.c -#XX# echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c -#XX# cat sqlite3.c >>tclsqlite3.c -#XX# echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c -#XX# cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c -#XX# -#XX#sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl has_tclsh84 -#XX# $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl -#XX# - # Rules to build the LEMON compiler generator # lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c @@ -1770,38 +1801,12 @@ sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlit #XX# $(INSTALL) -d $(DESTDIR)$(pkgconfigdir) #XX# $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir) #XX# -pkgIndex.tcl: - echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ #XX# #XX#tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl #XX# $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR) #XX# $(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR) #XX# rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a #XX# $(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR) -#XX# -#XX## Build the SQLite TCL extension in a way that make it compatible -#XX## with whatever version of TCL is running as $TCLSH_CMD, possibly defined -#XX## by --with-tclsh= -#XX## -#XX#tclextension: tclsqlite3.c -#XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc $(CC) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) -#XX# -#XX## Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD -#XX## to find it. -#XX## -#XX#tclextension-install: tclsqlite3.c -#XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc $(CC) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) -#XX# -#XX## Install the SQLite TCL extension that is used by $TCLSH_CMD -#XX## -#XX#tclextension-uninstall: -#XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall -#XX# -#XX## List all installed the SQLite TCL extension that is are accessible -#XX## by $TCLSH_CMD, included prior versions. -#XX## -#XX#tclextension-list: -#XX# $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info # Remove build products sufficient so that subsequent makes will recompile # everything from scratch. Do not remove: @@ -1827,6 +1832,7 @@ tidy: rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) rm -f threadtest5$(TEXE) rm -f src-verify has_tclsh* + rm -f tclsqlite3.c # FIXME? (rm *.def) will remove auto.def (part of autosetup) # # Removes build products and test logs. Retains ./configure outputs. diff --git a/manifest b/manifest index bcc00ba203..e331c041e6 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Remove\sextra\slayer\sof\squotes\saround\sinstall\starget\sdirs. -D 2024-10-09T08:05:21.230 +C More\swork\son\sthe\stcl\sbuild\sparts. +D 2024-10-09T13:20:25.332 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 77e637423518a13f901da15cc2faee0b8bf19bf3a5d6e78f9f5e6fd526318047 +F Makefile.in 6b2af34fd34078d0e3fa2a96b19c45c676809ffccf35e0045361537a3874e7d7 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f00988a909dd4338083a6e09231932c6fa57a40e35968c51483615121d20d25f -R f1cf57e7d2a38201da3601f8ddb82096 +P f2e3cf219e28c369ad6de240f0780eb3b638c47e1bab56ab80713a9bf63e2aa7 +R 9655f65151ed80683dca7e9653bd7560 U stephan -Z 7c98480696b78887885abe8d02f332ed +Z 9dbf98f5a4875d0b1d5b97e8ccbcb61d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4c2e9e0910..039f40615c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2e3cf219e28c369ad6de240f0780eb3b638c47e1bab56ab80713a9bf63e2aa7 +292ad7d519d39f16f130d082d3f134deadd5409d56ffb5340064a1996f4b4d57 From a60142fef5a314ba3510f95a14025de053e2b1f5 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 9 Oct 2024 13:26:01 +0000 Subject: [PATCH 055/522] Add sqlite3rc.h build. FossilOrigin-Name: 8d5f99f7e3f0ff9eaea1cb550369864e49a0fe0b00a53b1eba6ed099b61d8d24 --- Makefile.in | 11 ++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Makefile.in b/Makefile.in index b0526f0d84..1e50522094 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1376,11 +1376,11 @@ sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ $(TOP)/VERSION $(BTCL) # has_tclsh84 $(BTCL) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h -#XX#sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 -#XX# echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ -#XX# echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ -#XX# cat $(TOP)/VERSION | $(TCLSH_CMD) $(TOP)/tool/replace.tcl exact . , >>$@ -#XX# echo '#endif' >>sqlite3rc.h +sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(BTCL) # has_tclsh84 + echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ + echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ + cat $(TOP)/VERSION | $(BTCL) $(TOP)/tool/replace.tcl exact . , >>$@ + echo '#endif' >>sqlite3rc.h keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c @@ -1833,6 +1833,7 @@ tidy: rm -f threadtest5$(TEXE) rm -f src-verify has_tclsh* rm -f tclsqlite3.c + rm -f sqlite3rc.h # FIXME? (rm *.def) will remove auto.def (part of autosetup) # # Removes build products and test logs. Retains ./configure outputs. diff --git a/manifest b/manifest index e331c041e6..33eeb2bba9 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C More\swork\son\sthe\stcl\sbuild\sparts. -D 2024-10-09T13:20:25.332 +C Add\ssqlite3rc.h\sbuild. +D 2024-10-09T13:26:01.411 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 6b2af34fd34078d0e3fa2a96b19c45c676809ffccf35e0045361537a3874e7d7 +F Makefile.in e09c278841effbb93503fe3846337350bebc215f06c63f2c998e8cce7b109e8b F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 9c6d80d9d103fa42e931f4c464884a5e577fae8563acc7589bff4e43fbe8f864 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f2e3cf219e28c369ad6de240f0780eb3b638c47e1bab56ab80713a9bf63e2aa7 -R 9655f65151ed80683dca7e9653bd7560 +P 292ad7d519d39f16f130d082d3f134deadd5409d56ffb5340064a1996f4b4d57 +R b2998251d1a1c77a7b55806ea3c31919 U stephan -Z 9dbf98f5a4875d0b1d5b97e8ccbcb61d +Z 2c5ae792bbaf5eea557dff2e61da4cd7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 039f40615c..d3ad4492e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -292ad7d519d39f16f130d082d3f134deadd5409d56ffb5340064a1996f4b4d57 +8d5f99f7e3f0ff9eaea1cb550369864e49a0fe0b00a53b1eba6ed099b61d8d24 From 14101a3c28d95680f615a47effad7813a0db353c Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 11 Oct 2024 20:36:26 +0000 Subject: [PATCH 056/522] Experimental change to explain query plan to identify covering indexes on expressions. FossilOrigin-Name: 3bb03a2891e30c58b66e3665a8877a8eab4a8bac57ee153d8d31358caeaf4b7c --- manifest | 25 +++++++++-------- manifest.uuid | 2 +- src/where.c | 24 ++++++++++++---- src/whereInt.h | 8 ++++++ src/wherecode.c | 65 ++++++++++++++++++++++++++++++++++---------- test/indexexpr1.test | 24 ++++++++-------- test/indexexpr3.test | 38 ++++++++++++++++++++++++++ 7 files changed, 142 insertions(+), 44 deletions(-) diff --git a/manifest b/manifest index 9e10c216c6..524fb6f6ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scomments\sin\sext/misc/sqlite3_stdio.c\sto\sreflect\sthe\slatest\senhancements.\nNo\schanges\sto\scode. -D 2024-10-11T19:57:41.456 +C Experimental\schange\sto\sexplain\squery\splan\sto\sidentify\scovering\sindexes\son\sexpressions. +D 2024-10-11T20:36:26.974 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -855,9 +855,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c a0d42bfdef935e1389737152394d08e59e7c48697f40a9fc2e0552cb19dc731f F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c 12fe24880901997372b88fd7ca9a21457404ad35201712c02cc57978578abb10 -F src/whereInt.h a5d079c346a658b7a6e9e47bb943d021e02fa1e6aed3b964ca112112a4892192 -F src/wherecode.c 5172d647798134e7c92536ddffe7e530c393d79b5dedd648b88faf2646c65baf +F src/where.c 55defd94b89d6ef9eb9c9a8627a799d1f9ab6f8046c72f97956cd0171e0caa5c +F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca +F src/wherecode.c 8a260111af36d827d218118e36ccb8c359f9517f2743f5fe758e51dd9ae4acc7 F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f F src/window.c 499d48f315a09242dc68f2fac635ed27dcf6bbb0d9ab9084857898c64489e975 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1323,9 +1323,9 @@ F test/index8.test caa097735c91dbc23d8a402f5e63a2a03c83840ba3928733ed7f9a03f8a91 F test/index9.test 2ac891806a4136ef3e91280477e23114e67575207dc331e6797fa0ed9379f997 F test/indexA.test 11d84f6995e6e5b9d8315953fb1b6d29772ee7c7803ee9112715e7e4dd3e4974 F test/indexedby.test f21eca4f7a6ffe14c8500a7ad6cd53166666c99e5ccd311842a28bc94a195fe0 -F test/indexexpr1.test 24fa85a12da384dd1d56f7b24e593c51a8a54b4c5e2e8bbb9e5fdf1099427faf +F test/indexexpr1.test 928671af9d7374bb56ed4dcfbc157f4eeddb1e86ab5615ceb3ac97a713c2dd8f F test/indexexpr2.test 1c382e81ef996d8ae8b834a74f2a9013dddf59214c32201d7c8a656d739f999a -F test/indexexpr3.test 9d893bf440937ebcc1e59c7c9c1505c40c918346a3ddde76a69078f3c733c45d +F test/indexexpr3.test 47b91bc7999805c9a34d356f672259bc49295ecc797448511cae554a309b47cd F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 4e3f0de67aac3c5be1f4aaedbcea11638f1b5cdc9a3115be14d19aa9db7623c6 @@ -2217,8 +2217,11 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a3e16e478b03ccc12888eb5700c2e480a446957368f4b37ed322af2f4c9cd7c4 -R 1291abc09c87e338ea2cfa1281bb85ca -U drh -Z 347c97452247d4e75e184990772431fa +P 9621c3b527702b47799538e028f96945b5697752dbb56078aa7f114c72fd4e1a +R dd12fabe1565dab7ca455bbaabb2f1b1 +T *branch * eqp-covering-index-on-expr +T *sym-eqp-covering-index-on-expr * +T -sym-trunk * +U dan +Z 46f8403a99a7acbc4dd09a2ad01f75a8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9e0ede130..a0470874d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9621c3b527702b47799538e028f96945b5697752dbb56078aa7f114c72fd4e1a +3bb03a2891e30c58b66e3665a8877a8eab4a8bac57ee153d8d31358caeaf4b7c diff --git a/src/where.c b/src/where.c index c2fc338247..e99cdb355b 100644 --- a/src/where.c +++ b/src/where.c @@ -7441,14 +7441,28 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); - }else{ - /* Unable to translate the table reference into an index - ** reference. Verify that this is harmless - that the - ** table being referenced really is open. - */ + }else if( pLoop->wsFlags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ if( pLoop->wsFlags & WHERE_IDX_ONLY ){ + /* An error. pLoop is supposed to be a covering index loop, + ** and yet the VM code refers to a column of the table that + ** is not part of the index. */ sqlite3ErrorMsg(pParse, "internal query planner error"); pParse->rc = SQLITE_INTERNAL; + }else{ + /* The WHERE_EXPRIDX flag is set by the planner when it is likely + ** that pLoop is a covering index loop, but it is not possible + ** to be 100% sure. In this case, any OP_Explain opcode + ** corresponding to this loop describes the index as a "COVERING + ** INDEX". But, pOp proves that pLoop is not actually a covering + ** index loop. So clear the WHERE_EXPRIDX flag and rewrite the + ** text that accompanies the OP_Explain opcode, if any. */ + pLoop->wsFlags &= ~WHERE_EXPRIDX; + sqlite3WhereAddExplainText(pParse, + pLevel->addrBody-1, + pTabList, + pLevel, + pWInfo->wctrlFlags + ); } } }else if( pOp->opcode==OP_Rowid ){ diff --git a/src/whereInt.h b/src/whereInt.h index 8247528a93..f262b0eebc 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -533,9 +533,17 @@ int sqlite3WhereExplainBloomFilter( const WhereInfo *pWInfo, /* WHERE clause */ const WhereLevel *pLevel /* Bloom filter on this level */ ); +void sqlite3WhereAddExplainText( + Parse *pParse, /* Parse context */ + int addr, + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +); #else # define sqlite3WhereExplainOneScan(u,v,w,x) 0 # define sqlite3WhereExplainBloomFilter(u,v,w) 0 +# define sqlite3WhereAddExplainText(u,v,w,x,y) #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS void sqlite3WhereAddScanStatus( diff --git a/src/wherecode.c b/src/wherecode.c index 0951e5e204..f1c6711af8 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -110,27 +110,24 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ } /* -** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN -** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG -** was defined at compile-time. If it is not a no-op, a single OP_Explain -** opcode is added to the output to describe the table scan strategy in pLevel. -** -** If an OP_Explain opcode is added to the VM, its address is returned. -** Otherwise, if no OP_Explain is coded, zero is returned. +** This function sets the P4 value of an existing OP_Explain opcode to +** text describing the loop in pLevel. If the OP_Explain opcode already has +** a P4 value, it is freed before it is overwritten. */ -int sqlite3WhereExplainOneScan( +void sqlite3WhereAddExplainText( Parse *pParse, /* Parse context */ + int addr, /* Address of OP_Explain opcode */ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ - int ret = 0; #if !defined(SQLITE_DEBUG) if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) #endif { + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr); + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; - Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ WhereLoop *pLoop; /* The controlling WhereLoop object */ @@ -139,9 +136,10 @@ int sqlite3WhereExplainOneScan( StrAccum str; /* EQP output string */ char zBuf[100]; /* Initial space for EQP output string */ + if( db->mallocFailed ) return; + pLoop = pLevel->pWLoop; flags = pLoop->wsFlags; - if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0; isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) @@ -165,7 +163,7 @@ int sqlite3WhereExplainOneScan( zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; }else if( flags & WHERE_AUTO_INDEX ){ zFmt = "AUTOMATIC COVERING INDEX"; - }else if( flags & WHERE_IDX_ONLY ){ + }else if( flags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ zFmt = "COVERING INDEX %s"; }else{ zFmt = "INDEX %s"; @@ -219,9 +217,46 @@ int sqlite3WhereExplainOneScan( #endif zMsg = sqlite3StrAccumFinish(&str); sqlite3ExplainBreakpoint("",zMsg); - ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), - pParse->addrExplain, pLoop->rRun, - zMsg, P4_DYNAMIC); + + assert( pOp->opcode==OP_Explain ); + assert( pOp->p4type==P4_DYNAMIC || pOp->p4.z==0 ); + sqlite3DbFree(db, pOp->p4.z); + pOp->p4type = P4_DYNAMIC; + pOp->p4.z = sqlite3StrAccumFinish(&str); + } +} + + +/* +** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN +** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG +** was defined at compile-time. If it is not a no-op, a single OP_Explain +** opcode is added to the output to describe the table scan strategy in pLevel. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +int sqlite3WhereExplainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ + int ret = 0; +#if !defined(SQLITE_DEBUG) + if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + if( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + ){ + Vdbe *v = pParse->pVdbe; + int addr = sqlite3VdbeCurrentAddr(v); + ret = sqlite3VdbeAddOp3( + v, OP_Explain, addr, pParse->addrExplain, pLevel->pWLoop->rRun + ); + sqlite3WhereAddExplainText(pParse, addr, pTabList, pLevel, wctrlFlags); + } } return ret; } diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 3ba59449d5..d5c47e403e 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -49,7 +49,7 @@ do_execsql_test indexexpr1-130 { do_execsql_test indexexpr1-130eqp { EXPLAIN QUERY PLAN SELECT c FROM t1 WHERE b=1 AND substr(a,2,3)='nd_' ORDER BY c; -} {/USING INDEX t1ba/} +} {/USING COVERING INDEX t1ba/} do_execsql_test indexexpr1-140 { SELECT rowid, substr(a,b,3), '|' FROM t1 ORDER BY 2; @@ -61,7 +61,7 @@ do_execsql_test indexexpr1-141 { do_execsql_test indexexpr1-141eqp { EXPLAIN QUERY PLAN SELECT rowid FROM t1 WHERE substr(a,b,3)<='and' ORDER BY +rowid; -} {/USING INDEX t1abx/} +} {/USING COVERING INDEX t1abx/} do_execsql_test indexexpr1-142 { SELECT rowid FROM t1 WHERE +substr(a,b,3)<='and' ORDER BY +rowid; } {1 2 3} @@ -73,7 +73,7 @@ do_execsql_test indexexpr1-150eqp { EXPLAIN QUERY PLAN SELECT rowid FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz') ORDER BY +rowid; -} {/USING INDEX t1abx/} +} {/USING COVERING INDEX t1abx/} ifcapable altertable { do_execsql_test indexexpr1-160 { @@ -99,14 +99,14 @@ do_execsql_test indexexpr1-170 { do_execsql_test indexexpr1-170eqp { EXPLAIN QUERY PLAN SELECT length(a) FROM t1 ORDER BY length(a); -} {/SCAN t1 USING INDEX t1alen/} +} {/SCAN t1 USING COVERING INDEX t1alen/} do_execsql_test indexexpr1-171 { SELECT length(a) FROM t1 ORDER BY length(a) DESC; } {52 38 29 27 25 20} do_execsql_test indexexpr1-171eqp { EXPLAIN QUERY PLAN SELECT length(a) FROM t1 ORDER BY length(a) DESC; -} {/SCAN t1 USING INDEX t1alen/} +} {/SCAN t1 USING COVERING INDEX t1alen/} do_execsql_test indexexpr1-200 { DROP TABLE t1; @@ -142,7 +142,7 @@ do_execsql_test indexexpr1-230 { do_execsql_test indexexpr1-230eqp { EXPLAIN QUERY PLAN SELECT c FROM t1 WHERE b=1 AND substr(a,2,3)='nd_' ORDER BY c; -} {/USING INDEX t1ba/} +} {/USING COVERING INDEX t1ba/} do_execsql_test indexexpr1-240 { SELECT id, substr(a,b,3), '|' FROM t1 ORDER BY 2; @@ -154,7 +154,7 @@ do_execsql_test indexexpr1-241 { do_execsql_test indexexpr1-241eqp { EXPLAIN QUERY PLAN SELECT id FROM t1 WHERE substr(a,b,3)<='and' ORDER BY +id; -} {/USING INDEX t1abx/} +} {/USING COVERING INDEX t1abx/} do_execsql_test indexexpr1-242 { SELECT id FROM t1 WHERE +substr(a,b,3)<='and' ORDER BY +id; } {1 2 3} @@ -166,7 +166,7 @@ do_execsql_test indexexpr1-250eqp { EXPLAIN QUERY PLAN SELECT id FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz') ORDER BY +id; -} {/USING INDEX t1abx/} +} {/USING COVERING INDEX t1abx/} ifcapable altertable { do_execsql_test indexexpr1-260 { @@ -238,7 +238,7 @@ do_execsql_test indexexpr1-510 { do_execsql_test indexexpr1-510eqp { EXPLAIN QUERY PLAN SELECT substr(a,4,3) AS k FROM cnt, t5 WHERE k=printf('%03d',x); -} {/USING INDEX t5ax/} +} {/USING COVERING INDEX t5ax/} # Skip-scan on an indexed expression # @@ -547,7 +547,7 @@ do_execsql_test indexexpr1-2030 { (3, '{"x":1}', 6, 7); CREATE INDEX t1x ON t1(d, a, b->>'x', c); } -do_execsql_test indexexpr1-2030 { +do_execsql_test indexexpr1-2040 { SELECT a, SUM(1) AS t1, SUM(CASE WHEN b->>'x'=1 THEN 1 END) AS t2, @@ -555,7 +555,7 @@ do_execsql_test indexexpr1-2030 { SUM(CASE WHEN b->>'x'=1 THEN c END) AS t4 FROM t1; } {1 6 4 54 46} -do_execsql_test indexexpr1-2030 { +do_execsql_test indexexpr1-2050 { explain query plan SELECT a, SUM(1) AS t1, @@ -563,7 +563,7 @@ do_execsql_test indexexpr1-2030 { SUM(c) AS t3, SUM(CASE WHEN b->>'x'=1 THEN c END) AS t4 FROM t1; -} {/.*SCAN t1 USING INDEX t1x.*/} +} {/.*SCAN t1 USING COVERING INDEX t1x.*/} reset_db do_execsql_test indexexpr1-2100 { diff --git a/test/indexexpr3.test b/test/indexexpr3.test index 21e1d329ad..76d3331f75 100644 --- a/test/indexexpr3.test +++ b/test/indexexpr3.test @@ -78,6 +78,44 @@ do_hasfunction_test 1.6 { 2 {{"y":"two"}} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a, b, j); + CREATE INDEX i1 ON t1( a, json_extract(j, '$.x') ); +} + +do_eqp_test 2.1 { + SELECT json_extract(j, '$.x') FROM t1 WHERE a=? +} { + t1 USING COVERING INDEX i1 +} + +do_eqp_test 2.2 { + SELECT b, json_extract(j, '$.x') FROM t1 WHERE a=? +} { + t1 USING INDEX i1 +} + +do_eqp_test 2.3 { + SELECT json_insert( '{}', json_extract(j, '$.x') ) FROM t1 WHERE a=? +} { + t1 USING INDEX i1 +} + +do_eqp_test 2.4 { + SELECT sum( json_extract(j, '$.x') ) FROM t1 WHERE a=? +} { + t1 USING COVERING INDEX i1 +} + +do_eqp_test 2.5 { + SELECT json_extract(j, '$.x'), sum( json_extract(j, '$.x') ) FROM t1 WHERE a=? +} { + t1 USING INDEX i1 +} + + finish_test From ead26840b861d56241061bc986a25e0ec132dc39 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 16 Oct 2024 14:04:00 +0000 Subject: [PATCH 057/522] Get testfixture building. FossilOrigin-Name: 9a7e56a01703fdcb4c83481d33d48bd4c8e6a5586c1315bae36fdff34a1b3bd1 --- Makefile.in | 83 ++++++++++++++++++++++++++------------------------- auto.def | 49 +++++++++++++++++++++++------- manifest | 18 +++++------ manifest.uuid | 2 +- 4 files changed, 92 insertions(+), 60 deletions(-) diff --git a/Makefile.in b/Makefile.in index 1e50522094..1f65bcdbc8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -68,7 +68,7 @@ TCC += @TARGET_DEBUG@ #XX# #XX## The library that programs using TCL must link against. #XX## -#XX#LIBTCL = @TCL_LIB_SPEC@ +LIBTCL = @TCL_LIB_SPEC@ #XX# # Compiler options needed for programs that use the readline() library. # @@ -157,9 +157,9 @@ TCL_VERSION = @TCL_VERSION@ # TSTRNNR_OPTS = @TSTRNNR_OPTS@ -#XX## Where do we want to install the tcl plugin -#XX## -#XX#TCLLIBDIR = @TCLLIBDIR@ +# Where do we want to install the tcl plugin +# +TCLLIBDIR = @TCLLIBDIR@ # # If gcov support was enabled by the configure script, add the appropriate @@ -752,12 +752,12 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) libsqlite3.DLL = libsqlite3$(TDLL) libsqlite3.LIB = libsqlite3$(TLIB) -LDFLAGS_libsqlite = \ - $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_PTHREAD) \ - $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) # LDFLAGS_libsqlite should be used with any target which # either results in building libsqlite3.so, builds sqlite3.c # directly, links in either of $(LIBOBJSO) or $(LIBOBJS1). +LDFLAGS_libsqlite = \ + $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_PTHREAD) \ + $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) @if ENABLE_SHARED $(libsqlite3.DLL): $(LIBOBJ) @@ -1038,8 +1038,11 @@ has_tclsh85: touch has_tclsh85 has_tclconfig: - @ if test x"$(HAVE_TCL)" != "x1"; then echo 'ERROR: Requires access to "tclConfig.sh" which "configure" was not able to locate'; exit 1; fi +@if !TCL_CONFIG_SH + @echo 'ERROR: Requires access to "tclConfig.sh" which "configure" was not able to locate'; exit 1; +@else touch has_tclconfig +@endif # # This target creates a directory named "tsrc" and fills it with @@ -1516,37 +1519,37 @@ sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c -#XX## Rules to build the 'testfixture' application. -#XX## -#XX## If using the amalgamation, use sqlite3.c directly to build the test -#XX## fixture. Otherwise link against libsqlite3.la. (This distinction is -#XX## necessary because the test fixture requires non-API symbols which are -#XX## hidden when the library is built via the amalgamation). -#XX## -#XX#TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 -#XX#TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit -#XX#TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE -#XX#TESTFIXTURE_FLAGS += -DBUILD_sqlite -#XX#TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 -#XX#TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 -#XX#TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB -#XX#TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB -#XX#TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB -#XX#TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC -#XX#TESTFIXTURE_FLAGS += -DSQLITE_STATIC_RANDOMJSON -#XX#TESTFIXTURE_FLAGS += -DSQLITE_STRICT_SUBTYPE=1 -#XX# -#XX#TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la -#XX#TESTFIXTURE_SRC1 = sqlite3.c -#XX#TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c -#XX#TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) -#XX# -#XX#testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) -#XX# $(TLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ -#XX# -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS) -#XX# -#XX#coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) -#XX# +# Rules to build the 'testfixture' application. +# +# If using the amalgamation, use sqlite3.c directly to build the test +# fixture. Otherwise link against libsqlite3.a. (This distinction is +# necessary because the test fixture requires non-API symbols which are +# hidden when the library is built via the amalgamation). +# +TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 +TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit +TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE +TESTFIXTURE_FLAGS += -DBUILD_sqlite +TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 +TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB +TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC +TESTFIXTURE_FLAGS += -DSQLITE_STATIC_RANDOMJSON +TESTFIXTURE_FLAGS += -DSQLITE_STRICT_SUBTYPE=1 + +TESTFIXTURE_SRC0 = $(TESTSRC2) $(libsqlite3.LIB) +TESTFIXTURE_SRC1 = sqlite3.c +TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c +TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) + +testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) + $(TLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ + -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(LDFLAGS_libsqlite) @TCL_INCLUDE_SPEC@ + +coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) + #XX#testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) #XX# #XX## A very detailed test running most or all test cases @@ -1831,7 +1834,7 @@ tidy: rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) rm -f threadtest5$(TEXE) - rm -f src-verify has_tclsh* + rm -f src-verify has_tclsh* has_tclconfig rm -f tclsqlite3.c rm -f sqlite3rc.h # FIXME? (rm *.def) will remove auto.def (part of autosetup) diff --git a/auto.def b/auto.def index fbb4e0e3a3..cad31b0e88 100644 --- a/auto.def +++ b/auto.def @@ -354,12 +354,13 @@ proc hwaci-check-tcl {} { set use_tcl $optTcl set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] -# puts "hwaci-check-tcl: use_tcl ${use_tcl}" -# puts "hwaci-check-tcl: with_tclsh=${with_tclsh}" -# puts "hwaci-check-tcl: with_tcl=$with_tcl" + #puts "hwaci-check-tcl: use_tcl ${use_tcl}" + #puts "hwaci-check-tcl: with_tclsh=${with_tclsh}" + #puts "hwaci-check-tcl: with_tcl=$with_tcl" if {"" eq $with_tclsh && "" eq $with_tcl} { - set with_tclsh [hwaci-first-bin-of tclsh8.6 tclsh tclsh9.0] + set with_tclsh [hwaci-first-bin-of tclsh9.0 tclsh8.6 tclsh] } + #puts "hwaci-check-tcl: with_tclsh=${with_tclsh}" if {"" ne $with_tclsh} { if {![file isfile $with_tclsh]} { @@ -371,7 +372,6 @@ proc hwaci-check-tcl {} { puts "Using tclsh at \"$with_tclsh\"" } if {$use_tcl} { - #set with_tcl [exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl] if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { set with_tcl $result } @@ -385,7 +385,7 @@ proc hwaci-check-tcl {} { } set cfg "" - set tclSubdirs {tcl8.6 tcl9.0 lib} + set tclSubdirs {tcl9.0 tcl8.6 lib} if {$use_tcl} { if {"" ne $with_tcl} { if {[file readable "${with_tcl}/tclConfig.sh"]} { @@ -439,10 +439,23 @@ proc hwaci-check-tcl {} { # available, this generates empty-string entries for the various # options we're interested in. eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]"] -# puts "hwaci-check-tcl: with_tclsh=$with_tclsh" -# puts "hwaci-check-tcl: with_tcl=$with_tcl" -# puts "hwaci-check-tcl: cfg=$cfg" -# puts "hwaci-check-tcl: use_tcl ${use_tcl}" + #puts "hwaci-check-tcl: with_tclsh=$with_tclsh" + #puts "hwaci-check-tcl: with_tcl=$with_tcl" + #puts "hwaci-check-tcl: cfg=$cfg" + #puts "hwaci-check-tcl: use_tcl ${use_tcl}" + + if {"" eq $with_tclsh} { + set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] + if {![file executable $with_tclsh]} { + set with_tclsh2 [get-define TCL_EXEC_PREFIX]/bin/tclsh + if {![file executable $with_tclsh2]} { + hwaci-warn "Cannot find a usable tclsh as $with_tclsh or $with_tclsh2" + } else { + set with_tclsh $with_tclsh2 + } + } + } + define TCLSH_CMD $with_tclsh if {$use_tcl} { # Set up the TCLLIBDIR and TCLLIB_RPATH @@ -464,10 +477,26 @@ proc hwaci-check-tcl {} { set tcllibdir "${tcllibdir}/sqlite3" set rp [get-define SH_LINKRPATH] set tclrpath [string map [list "%s" $tcllibdir] $rp] + # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the + # rpath but (A) it includes an unexpand var ref to + # ${LIB_RUNTIME_DIR}, which must tbe set in the makefile and (B) + # that flag is inherently compiler-dependent so it's not as + # portable as tclConfig.sh assumes. We'll instead use the rpath + # flag which autosetup determines for the current compiler. } define TCLLIBDIR $tcllibdir define TCLLIB_RPATH $tclrpath #hwaci-error "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" + } else { + define TCLLIBDIR "" + define TCLLIB_RPATH "" + } + + + if {"" eq $with_tclsh} { + hwaci-warn "Cannot find a usable tclsh." + } else { + puts "Using tclsh: $with_tclsh" } }; # hwaci-check-tcl diff --git a/manifest b/manifest index 9848bfb321..a864854b59 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Merge\strunk\sinto\sthis\sbranch. -D 2024-10-16T13:02:07.918 +C Get\stestfixture\sbuilding. +D 2024-10-16T14:04:00.330 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in e09c278841effbb93503fe3846337350bebc215f06c63f2c998e8cce7b109e8b +F Makefile.in fa354ef30557591ef661274ed2e7e544ffe67946473ec5651bde26742c766686 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 42b2334f320fafcebb09673453fc9df470839e136d84ddeb74699af16b08b056 +F auto.def 9586e698e1cd80f072f3736fd179fd743cf3d85e16b56e1bdc2062b38c9e429e F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -23,7 +23,7 @@ F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56 F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277 F autoconf/tea/Makefile.in 106a96f2f745d41a0f6193f1de98d7355830b65d45032c18cd7c90295ec24196 -F autoconf/tea/README.txt 94fa2472d3ee4139ab24b364d99a70445d0a25531dac3ce03af2055d581f76b4 w autoconf/tea/README +F autoconf/tea/README.txt 94fa2472d3ee4139ab24b364d99a70445d0a25531dac3ce03af2055d581f76b4 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 F autoconf/tea/configure.ac 0deb5d6c49c8119f75f436488219fc043127d72057af5dfba2c9ce096a5734bc F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb @@ -2199,7 +2199,7 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b F tool/sqlite3_analyzer.c.in 348ba349bbdc93c9866439f9f935d7284866a2a4e6898bc906ae1204ade56918 -F tool/sqlite3_rsync.c 2a2b79a0463d400696aa9429be5c0ddec6b1f7ceefa5fed7acfdc859a435221f w tool/sqlite3-rsync.c +F tool/sqlite3_rsync.c 2a2b79a0463d400696aa9429be5c0ddec6b1f7ceefa5fed7acfdc859a435221f F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c d00f93263aa2fa6ba0cba0106d95458e6effb94fdb5fc634f56834f90c05bbb4 @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8d5f99f7e3f0ff9eaea1cb550369864e49a0fe0b00a53b1eba6ed099b61d8d24 86e794cbaa5ae600635c933b46298a39f2465daf4c5cd1570f2a03e19ac08d9d -R 0f51619208545f999beb801583f35ef3 +P 9c3bb3dc4f5b5cd7db6cd50d22dbe8f933cccf5f2fd253467bb50f36b3207a93 +R 45a9e71fe8f588895d4532716f9e4e63 U stephan -Z b40f13e331b5567249a3bbe5622b7fa3 +Z a3d7258d39f45514e566632502958cc2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6dac849c2d..dc3dbcc09b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c3bb3dc4f5b5cd7db6cd50d22dbe8f933cccf5f2fd253467bb50f36b3207a93 +9a7e56a01703fdcb4c83481d33d48bd4c8e6a5586c1315bae36fdff34a1b3bd1 From 2a1a3d6af556dfca485a9806c9dbc2507adc6916 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 17 Oct 2024 22:19:37 +0000 Subject: [PATCH 058/522] General cleanups. Rename BTCL to BTCLSH for some clarity. FossilOrigin-Name: 83eaef7d62677a85a2c42f98d52ff2e8e5356724ad6d12b2907409d96d4757f1 --- Makefile.in | 94 ++++++++++++++++++++++++++------------------------- auto.def | 10 +++--- manifest | 14 ++++---- manifest.uuid | 2 +- 4 files changed, 61 insertions(+), 59 deletions(-) diff --git a/Makefile.in b/Makefile.in index 1f65bcdbc8..9113960709 100644 --- a/Makefile.in +++ b/Makefile.in @@ -88,7 +88,28 @@ READLINE_FLAGS = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ # TLIBS = @LIBS@ $(LIBS) -#XX# +# +# JimTCL is part of the autosetup suite and is suitable for all +# current in-tree code-generation TCL jobs, but it requires that we +# build it with non-default flags. Note that the build tree will, if +# no system-level tclsh is found, also have a ./jimsh0. That one is a +# bare-bones build for the configure process, whereas we need to build +# it with another option enabled for use with the various code +# generators. +# +JIMSH = @srcdir@/jimsh +@if CFLAGS_JIMSH +$(JIMSH): $(TOP)/autosetup/jimsh0.c + $(BCC) -o $(JIMSH) @CFLAGS_JIMSH@ $< +@endif + +# BTCLSH is the tclsh-compatible app used for running various code +# generators and other in-tree tools, as opposed to the TCL-based +# tests, which must be built and run using the canonical TCL +# distribution. +BTCLSH = @BTCLSH@ +$(BTCLSH): + # Flags controlling use of the in memory btree implementation # # SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to @@ -790,7 +811,9 @@ install-dll: $(install.libdir) $(libsqlite3.DLL) mv $(libsqlite3.DLL) $(libsqlite3.DLL).@RELEASE@; \ ln -s $(libsqlite3.DLL).@RELEASE@ $(libsqlite3.DLL).3; \ ln -s $(libsqlite3.DLL).3 $(libsqlite3.DLL) +@if ENABLE_SHARED install: install-dll +@endif # # Install $(libsqlite3.LIB) @@ -817,13 +840,14 @@ all: $(libtclsqlite3.DLL) pkgIndex.tcl: echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ +@if TCLLIBDIR install.tcldir = "$(DESTDIR)@TCLLIBDIR@" install-tcl: $(libtclsqlite3.DLL) pkgIndex.tcl $(INSTALL) -d $(install.tcldir) $(INSTALL) $(libtclsqlite3.DLL) $(install.tcldir) $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) - install: install-tcl +@endif tclsqlite3.c: sqlite3.c echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c @@ -831,8 +855,8 @@ tclsqlite3.c: sqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c -#sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCL) # has_tclsh84 -# $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl +sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/split-sqlite3c.tcl # Build the SQLite TCL extension in a way that make it compatible # with whatever version of TCL is running as $TCLSH_CMD, possibly defined @@ -919,28 +943,6 @@ src-verify$(BEXE): $(TOP)/tool/src-verify.c verify-source: ./src-verify$(BEXE) ./src-verify$(BEXE) $(TOP) -# -# JimTCL is part of the autosetup suite and is suitable for all -# current in-tree code-generation TCL jobs, but it requires that we -# build it with non-default flags. Note that the build tree will, if -# no system-level tclsh is found, also have a ./jimsh0. That one is a -# bare-bones build for the configure process, whereas we need to build -# it with another option enabled for use with the various code -# generators. -# -JIMSH = @srcdir@/jimsh -@if CFLAGS_JIMSH -$(JIMSH): $(TOP)/autosetup/jimsh0.c - $(BCC) -o $(JIMSH) @CFLAGS_JIMSH@ $< -@endif - -# BTCL is the tclsh-compatible app used for running various code -# generators and other in-tree tools, as opposed to the TCL-based -# tests, which must be built and run using the canonical TCL -# distribution. -BTCL = @BTCL@ -$(BTCL): - #XX# #XX#fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h #XX# $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ @@ -1051,30 +1053,30 @@ has_tclconfig: # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(BTCL) # has_tclsh84 +.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(BTCLSH) # has_tclsh84 rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - $(BTCL) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new + $(BTCLSH) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new mv vdbe.new tsrc/vdbe.c cp fts5.c fts5.h tsrc touch .target_source sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify \ - $(BTCL) # has_tclsh84 - $(BTCL) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . -sqlite3r.h: sqlite3.h $(BTCL) # has_tclsh84 - $(BTCL) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h +sqlite3r.h: sqlite3.h $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -sqlite3r.c: sqlite3.c sqlite3r.h $(BTCL) # has_tclsh84 +sqlite3r.c: sqlite3.c sqlite3r.h $(BTCLSH) # has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(BTCL) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . @@ -1360,12 +1362,12 @@ tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(BTCL) # has_tclsh84 - $(BTCL) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c opcodes.h: parse.h $(TOP)/src/vdbe.c \ - $(TOP)/tool/mkopcodeh.tcl $(BTCL) # has_tclsh84 - cat parse.h $(TOP)/src/vdbe.c | $(BTCL) $(TOP)/tool/mkopcodeh.tcl >opcodes.h + $(TOP)/tool/mkopcodeh.tcl $(BTCLSH) # has_tclsh84 + cat parse.h $(TOP)/src/vdbe.c | $(BTCLSH) $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. # @@ -1376,13 +1378,13 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ - $(TOP)/VERSION $(BTCL) # has_tclsh84 - $(BTCL) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h + $(TOP)/VERSION $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h -sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(BTCL) # has_tclsh84 +sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(BTCLSH) # has_tclsh84 echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ - cat $(TOP)/VERSION | $(BTCL) $(TOP)/tool/replace.tcl exact . , >>$@ + cat $(TOP)/VERSION | $(BTCLSH) $(TOP)/tool/replace.tcl exact . , >>$@ echo '#endif' >>sqlite3rc.h keywordhash.h: $(TOP)/tool/mkkeywordhash.c @@ -1422,8 +1424,8 @@ SHELL_DEP = \ $(TOP)/src/test_windirent.c \ $(TOP)/src/test_windirent.h -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCL) # has_tclsh84 - $(BTCL) $(TOP)/tool/mkshellc.tcl >shell.c +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mkshellc.tcl >shell.c # Rules to build the extension objects. @@ -1508,8 +1510,8 @@ fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) $(BTCL) # has_tclsh84 - $(BTCL) $(TOP)/ext/fts5/tool/mkfts5c.tcl +fts5.c: $(FTS5_SRC) $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . fts5.o: fts5.c $(HDR) $(EXTHDR) diff --git a/auto.def b/auto.def index cad31b0e88..6fc77bd7ee 100644 --- a/auto.def +++ b/auto.def @@ -343,7 +343,7 @@ hwaci-if-opt-truthy with-debug { # # - TCLLIB_RPATH = the -rpath flag specific to libtclsqlite3. # -# - BTCL = the path to the tcl interpreter used for in-tree code +# - BTCLSH = the path to the tcl interpreter used for in-tree code # generation. It may be jimtcl or the canonical tclsh. define HAVE_TCL 0 define TCLSH_CMD {exit 1} @@ -510,14 +510,14 @@ puts "Which TCL to use for code generation... " set cgtcl jimtcl if {[cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE_REALPATH - define BTCL "\$(JIMSH)" + define BTCLSH "\$(JIMSH)" } elseif {[cc-check-functions _fullpath]} { # _fullpath() is a Windows API define-append CFLAGS_JIMSH -DHAVE__FULLPATH - define BTCL "\$(JIMSH)" + define BTCLSH "\$(JIMSH)" } elseif {"" ne [get-define TCLSH_CMD]} { set cgtcl [get-define TCLSH_CMD] - define BTCL "\$(TCLSH_CMD)" + define BTCLSH "\$(TCLSH_CMD)" } else { # One last-ditch effort to find TCLSH_CMD: use info from # tclConfig.sh to try to find a tclsh @@ -538,7 +538,7 @@ if {[cc-check-functions realpath]} { } } set cgtcl [get-define TCLSH_CMD] - define BTCL "\$(TCLSH_CMD)" + define BTCLSH "\$(TCLSH_CMD)" } puts "TCL for code generation: $cgtcl" unset cgtcl diff --git a/manifest b/manifest index a864854b59..6550686c37 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Get\stestfixture\sbuilding. -D 2024-10-16T14:04:00.330 +C General\scleanups.\sRename\sBTCL\sto\sBTCLSH\sfor\ssome\sclarity. +D 2024-10-17T22:19:37.426 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in fa354ef30557591ef661274ed2e7e544ffe67946473ec5651bde26742c766686 +F Makefile.in a01307498cd4d2c615be19a0fea96a488ec18924c0c0fa30a9a828aa9f28f0ee F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 9586e698e1cd80f072f3736fd179fd743cf3d85e16b56e1bdc2062b38c9e429e +F auto.def 6b669b781de0eec9ad7dea65079c469ac7013c115487cf3e66c068e40b2a6df3 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9c3bb3dc4f5b5cd7db6cd50d22dbe8f933cccf5f2fd253467bb50f36b3207a93 -R 45a9e71fe8f588895d4532716f9e4e63 +P 9a7e56a01703fdcb4c83481d33d48bd4c8e6a5586c1315bae36fdff34a1b3bd1 +R 30374e42cf396edeeab8be3ba90d92cf U stephan -Z a3d7258d39f45514e566632502958cc2 +Z 533ef536662a14cac9318bc23f02aeac # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dc3dbcc09b..188d01b8e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a7e56a01703fdcb4c83481d33d48bd4c8e6a5586c1315bae36fdff34a1b3bd1 +83eaef7d62677a85a2c42f98d52ff2e8e5356724ad6d12b2907409d96d4757f1 From 20755cef7dc35a2cf52722a8be484d9c5d1a39dc Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 18 Oct 2024 16:39:17 +0000 Subject: [PATCH 059/522] Get most of the fuzzing-related apps building, sans dbuzz2-asan/msan, both of which refuse to link with clang v18 because it's trying to use -lstdc++ despite the app being only C. FossilOrigin-Name: 3e843452927aaea152eab60213337912c34966e2c77d3cfd50d2ee9eb77c6796 --- Makefile.in | 196 +++++++++++++++++++++++++++++--------------------- auto.def | 5 ++ manifest | 14 ++-- manifest.uuid | 2 +- 4 files changed, 126 insertions(+), 91 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9113960709..875ac3571e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -83,9 +83,14 @@ READLINE_FLAGS = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ #XX## Should the database engine be compiled threadsafe #XX## #XX#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ -#XX# + +# # Any target libraries which libsqlite must be linked against # +# With the autosetup build, the intended way to do this is to set +# those in $(LDFLAGS_libsqlite3) and include those flags for both +# $(libsqlite3.DLL) and any apps which directly link in either +# sqlite3.o or its origin sources. TLIBS = @LIBS@ $(LIBS) # @@ -773,17 +778,17 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) libsqlite3.DLL = libsqlite3$(TDLL) libsqlite3.LIB = libsqlite3$(TLIB) -# LDFLAGS_libsqlite should be used with any target which +# LDFLAGS_libsqlite3 should be used with any target which # either results in building libsqlite3.so, builds sqlite3.c # directly, links in either of $(LIBOBJSO) or $(LIBOBJS1). -LDFLAGS_libsqlite = \ - $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_PTHREAD) \ +LDFLAGS_libsqlite3 = \ + $(LDFLAGS_RPATH) @LIBS@ $(LIBS) $(LDFLAGS_PTHREAD) \ $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) @if ENABLE_SHARED $(libsqlite3.DLL): $(LIBOBJ) $(TLINK_shared) -o $@ \ - $(LIBOBJ) $(TLIBS) $(LDFLAGS_libsqlite) + $(LIBOBJ) $(TLIBS) $(LDFLAGS_libsqlite3) all: dll @else $(libsqlite3.DLL): @@ -888,7 +893,7 @@ tclextension-list: sqlite3$(TEXE): shell.c sqlite3.c $(TCC) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ - $(LDFLAGS_libsqlite) $(LDFLAGS_READLINE) + $(LDFLAGS_libsqlite3) $(LDFLAGS_READLINE) cli: sqlite3$(TEXE) @if !HAVE_WASI_SDK all: cli @@ -900,14 +905,14 @@ install-cli: sqlite3$(TEXT) $(install.bindir) install: install-cli sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h - $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite) + $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite3) install-diff: sqldiff$(TEXE) $(install.bindir) $(INSTALL) -s sqldiff$(TEXT) $(install.bindir) #install: install-diff dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h - $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite) + $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite3) RSYNC_SRC = \ $(TOP)/tool/sqlite3-rsync.c \ @@ -921,7 +926,7 @@ RSYNC_OPT = \ -DSQLITE_OMIT_DEPRECATED sqlite3-rsync$(TEXE): $(RSYNC_SRC) - $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite) + $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) install-rsync: sqlite3-rsync$(TEXE) $(install.bindir) $(INSTALL) sqlite3-rsync$(TEXT) $(install.bindir) @@ -929,7 +934,7 @@ install-rsync: sqlite3-rsync$(TEXE) $(install.bindir) scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ - $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS_libsqlite) + $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS_libsqlite3) srcck1$(BEXE): $(TOP)/tool/srcck1.c $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c @@ -943,76 +948,97 @@ src-verify$(BEXE): $(TOP)/tool/src-verify.c verify-source: ./src-verify$(BEXE) ./src-verify$(BEXE) $(TOP) -#XX# -#XX#fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h -#XX# $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ -#XX# $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) -#XX# -#XX#fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) -#XX# $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) -#XX# -#XX#fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) -#XX# $(TLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) -#XX# -#XX#fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) -#XX# $(TLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) -#XX# -#XX## Usage: FUZZDB=filename make run-fuzzcheck -#XX## -#XX## Where filename is a fuzzcheck database, this target builds and runs -#XX## fuzzcheck, fuzzcheck-asan, and fuzzcheck-ubsan on that database. -#XX## -#XX## FUZZDB can be a glob pattern of two or more databases. Example: -#XX## -#XX## FUZZDB=test/fuzzdata*.db make run-fuzzcheck -#XX## -#XX#run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) -#XX# @if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi -#XX# ./fuzzcheck$(TEXE) --spinner $(FUZZDB) -#XX# ./fuzzcheck-asan$(TEXE) --spinner $(FUZZDB) -#XX# ./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB) -#XX# -#XX#ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h -#XX# $(TLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ -#XX# $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) -#XX# -#XX#sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h -#XX# $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS) -#XX# -#XX#dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h -#XX# $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) -#XX# -#XX#DBFUZZ2_OPTS = \ -#XX# -DSQLITE_THREADSAFE=0 \ -#XX# -DSQLITE_OMIT_LOAD_EXTENSION \ -#XX# -DSQLITE_DEBUG \ -#XX# -DSQLITE_ENABLE_DBSTAT_VTAB \ -#XX# -DSQLITE_ENABLE_BYTECODE_VTAB \ -#XX# -DSQLITE_ENABLE_RTREE \ -#XX# -DSQLITE_ENABLE_FTS4 \ -#XX# -DSQLITE_ENABLE_FTS5 -#XX# -#XX#dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h -#XX# $(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ -#XX# -DSTANDALONE -o dbfuzz2 \ -#XX# $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) -#XX# mkdir -p dbfuzz2-dir -#XX# cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir -#XX# -#XX#dbfuzz2-asan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h -#XX# clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ -#XX# -fsanitize=fuzzer,undefined,address -o dbfuzz2-asan \ -#XX# $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) -#XX# mkdir -p dbfuzz2-dir -#XX# cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir -#XX# -#XX#dbfuzz2-msan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h -#XX# clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ -#XX# -fsanitize=fuzzer,undefined,memory -o dbfuzz2-msan \ -#XX# $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) -#XX# mkdir -p dbfuzz2-dir -#XX# cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir -#XX# +fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h + $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ + $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: fuzzershell$(TEXE) + +fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: fuzzcheck$(TEXE) + +fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(TLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ + sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: fuzzcheck-asan$(TEXE) + + +fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(TLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ + sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: fuzzcheck-ubsan$(TEXE) + +# Usage: FUZZDB=filename make run-fuzzcheck +# +# Where filename is a fuzzcheck database, this target builds and runs +# fuzzcheck, fuzzcheck-asan, and fuzzcheck-ubsan on that database. +# +# FUZZDB can be a glob pattern of two or more databases. Example: +# +# FUZZDB=test/fuzzdata*.db make run-fuzzcheck +# +run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) + @if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi + ./fuzzcheck$(TEXE) --spinner $(FUZZDB) + ./fuzzcheck-asan$(TEXE) --spinner $(FUZZDB) + ./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB) + +ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h + $(TLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ + $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: ossshell$(TEXE) + +sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h + $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(LDFLAGS_libsqlite3) +fuzzy: sessionfuzz$(TEXE) + +dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h + $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: dbfuzz$(TEXE) + +DBFUZZ2_OPTS = \ + -USQLITE_THREADSAFE \ + -DSQLITE_THREADSAFE=0 \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_DEBUG \ + -DSQLITE_ENABLE_DBSTAT_VTAB \ + -DSQLITE_ENABLE_BYTECODE_VTAB \ + -DSQLITE_ENABLE_RTREE \ + -DSQLITE_ENABLE_FTS4 \ + -DSQLITE_ENABLE_FTS5 + +dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h + $(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ + -DSTANDALONE -o dbfuzz2 \ + $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS_libsqlite3) + mkdir -p dbfuzz2-dir + cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir +fuzzy: dbfuzz2$(TEXE) + +@if BIN_CLANG +# ^^^ modern clangs are failing to build the dbfuzz2-... apps with the +# error "cannot find -lstdc++", even though we don't use C++ here. +CC_CLANG = @BIN_CLANG@ +dbfuzz2-asan$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h + $(CC_CLANG) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ + -fsanitize=fuzzer,undefined,address -o dbfuzz2-asan$(TEXE) \ + $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS_libsqlite3) + mkdir -p dbfuzz2-dir + cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir +#fuzzy: dbfuzz2-asan$(TEXE) + +dbfuzz2-msan$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h + $(CC_CLANG) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ + -fsanitize=fuzzer,undefined,memory -o dbfuzz2-msan$(TEXE) \ + $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS_libsqlite3) + mkdir -p dbfuzz2-dir + cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir +#fuzzy: dbfuzz2-msan$(TEXE) +@else +dbfuzz2-asan$(TEXE) dbfuzz2-ubsan$(TEXE): + @echo "Missing clang required by for $@"; exit 1 +@endif + #XX#mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c #XX# $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ #XX# $(TLIBS) -rpath "$(libdir)" @@ -1548,7 +1574,7 @@ TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) $(TLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ - -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(LDFLAGS_libsqlite) @TCL_INCLUDE_SPEC@ + -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(LDFLAGS_libsqlite3) @TCL_INCLUDE_SPEC@ coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) @@ -1663,7 +1689,7 @@ coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) #XX# $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS) #XX# sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c - $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite) + $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite3) #XX#CHECKER_DEPS =\ #XX# $(TOP)/tool/mkccode.tcl \ @@ -1835,11 +1861,15 @@ tidy: rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE) sqlite3_expert$(TEXE) rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) + rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) dbfuzz2-asan$(TEXE) dbfuzz2-msan$(TEXE) + rm -f fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE) + rm -f sessionfuzz$(TEXE) rm -f threadtest5$(TEXE) rm -f src-verify has_tclsh* has_tclconfig rm -f tclsqlite3.c rm -f sqlite3rc.h -# FIXME? (rm *.def) will remove auto.def (part of autosetup) +# FIXME? (rm *.def) from the historical build will remove auto.def (part of autosetup) + # # Removes build products and test logs. Retains ./configure outputs. # diff --git a/auto.def b/auto.def index 6fc77bd7ee..3b4befb652 100644 --- a/auto.def +++ b/auto.def @@ -546,6 +546,11 @@ unset cgtcl # /TCL ######################################################################## +######################################################################## +# Some of the fuzzer bits require clang +define BIN_CLANG [hwaci-first-bin-of clang-6.0 clang] + + ######################################################################## # Thread safety? msg-checking "Support threadsafe operation? " diff --git a/manifest b/manifest index 1933defda9..76d4b224c9 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Merge\scurrent\strunk\sinto\sthe\sautosetup\sbranch. -D 2024-10-17T22:20:27.470 +C Get\smost\sof\sthe\sfuzzing-related\sapps\sbuilding,\ssans\sdbuzz2-asan/msan,\sboth\sof\swhich\srefuse\sto\slink\swith\sclang\sv18\sbecause\sit's\strying\sto\suse\s-lstdc++\sdespite\sthe\sapp\sbeing\sonly\sC. +D 2024-10-18T16:39:17.498 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in a01307498cd4d2c615be19a0fea96a488ec18924c0c0fa30a9a828aa9f28f0ee +F Makefile.in 7cfcce78e311c64e04a28bb5695d2ef7c2c4d6e1a165e8e944150cf373bf8a4e F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 6b669b781de0eec9ad7dea65079c469ac7013c115487cf3e66c068e40b2a6df3 +F auto.def 74a6b53f7050ab342e21e96fd67fa7044421e8c700b0ba7a2bfa28253319db6c F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 83eaef7d62677a85a2c42f98d52ff2e8e5356724ad6d12b2907409d96d4757f1 0a32624015f16fd881a4ecbb56b7833391028d327a95f4c899eee864ed7fe00d -R 5bf6ee4a5edead94a59479d61cb4229f +P 352da23b46f13fbb2c38fcdd0b6092bf39a391a0bfed587004c85f7f5b99a58d +R c42c85ba5209b7fc0431438c5c54d35b U stephan -Z 0e34f05747acefc37ecfc30a7ac64e71 +Z b9cb46d76e081b85eda921cc556eb271 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 247ccbec00..4d8ef72d21 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -352da23b46f13fbb2c38fcdd0b6092bf39a391a0bfed587004c85f7f5b99a58d +3e843452927aaea152eab60213337912c34966e2c77d3cfd50d2ee9eb77c6796 From 83afc4c2b26d0191b13d7d31dadd38248c8c393a Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 18 Oct 2024 16:47:54 +0000 Subject: [PATCH 060/522] Remove the problematic dbfuzz2-asan/msan targets, which Richard says are not used anymore. FossilOrigin-Name: 503ce205a1efe0d52b184b1b6a23b4b6b5adb7acf6f4617249a5fa1d81e523ef --- Makefile.in | 24 ------------------------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 31 deletions(-) diff --git a/Makefile.in b/Makefile.in index 875ac3571e..a4221176a5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1015,30 +1015,6 @@ dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir fuzzy: dbfuzz2$(TEXE) -@if BIN_CLANG -# ^^^ modern clangs are failing to build the dbfuzz2-... apps with the -# error "cannot find -lstdc++", even though we don't use C++ here. -CC_CLANG = @BIN_CLANG@ -dbfuzz2-asan$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - $(CC_CLANG) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ - -fsanitize=fuzzer,undefined,address -o dbfuzz2-asan$(TEXE) \ - $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS_libsqlite3) - mkdir -p dbfuzz2-dir - cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir -#fuzzy: dbfuzz2-asan$(TEXE) - -dbfuzz2-msan$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - $(CC_CLANG) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ - -fsanitize=fuzzer,undefined,memory -o dbfuzz2-msan$(TEXE) \ - $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS_libsqlite3) - mkdir -p dbfuzz2-dir - cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir -#fuzzy: dbfuzz2-msan$(TEXE) -@else -dbfuzz2-asan$(TEXE) dbfuzz2-ubsan$(TEXE): - @echo "Missing clang required by for $@"; exit 1 -@endif - #XX#mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c #XX# $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ #XX# $(TLIBS) -rpath "$(libdir)" diff --git a/manifest b/manifest index 76d4b224c9..8e82fed1e4 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Get\smost\sof\sthe\sfuzzing-related\sapps\sbuilding,\ssans\sdbuzz2-asan/msan,\sboth\sof\swhich\srefuse\sto\slink\swith\sclang\sv18\sbecause\sit's\strying\sto\suse\s-lstdc++\sdespite\sthe\sapp\sbeing\sonly\sC. -D 2024-10-18T16:39:17.498 +C Remove\sthe\sproblematic\sdbfuzz2-asan/msan\stargets,\swhich\sRichard\ssays\sare\snot\sused\sanymore. +D 2024-10-18T16:47:54.809 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 7cfcce78e311c64e04a28bb5695d2ef7c2c4d6e1a165e8e944150cf373bf8a4e +F Makefile.in b070ca8dd62ca803547f888f4e44391bf73d806789b3ea754bc6392140fdf3a6 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 352da23b46f13fbb2c38fcdd0b6092bf39a391a0bfed587004c85f7f5b99a58d -R c42c85ba5209b7fc0431438c5c54d35b +P 3e843452927aaea152eab60213337912c34966e2c77d3cfd50d2ee9eb77c6796 +R f96b7f8acba78c395f1ccebf70c56c0a U stephan -Z b9cb46d76e081b85eda921cc556eb271 +Z 8726b6ffa28a328589337a2d1c2ae656 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4d8ef72d21..357fce43f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e843452927aaea152eab60213337912c34966e2c77d3cfd50d2ee9eb77c6796 +503ce205a1efe0d52b184b1b6a23b4b6b5adb7acf6f4617249a5fa1d81e523ef From b08f1d5d97105d9d8ae9b673efa270d182b5d294 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 00:49:01 +0000 Subject: [PATCH 061/522] Get mptest(er) building. FossilOrigin-Name: f740f6a4447543751800465ddfa11c9e3c89fb7054a9dfb5450938885b8f9633 --- Makefile.in | 41 ++++++++++++++++++++--------------------- auto.def | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/Makefile.in b/Makefile.in index a4221176a5..10e949070d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -250,7 +250,7 @@ TLINK_shared = $(TLINK) @SHOBJ_LDFLAGS@ AS_AUTO_DEF = $(TOP)/auto.def USE_AMALGAMATION = @USE_AMALGAMATION@ -AMALGAMATION_LINE_MACROS = @AMALGAMATION_LINE_MACROS@ +AMALGAMATION_LINE_MACROS = --linemacros=@AMALGAMATION_LINE_MACROS@ # # Object files for the SQLite library (non-amalgamation). @@ -275,11 +275,11 @@ LIBOBJS0 = alter.o analyze.o attach.o auth.o \ random.o resolve.o rowset.o rtree.o \ sqlite3session.o select.o sqlite3rbu.o status.o stmt.o \ table.o threads.o tokenize.o treeview.o trigger.o \ - update.o userauth.o upsert.o util.o vacuum.o \ + update.o upsert.o userauth.o utf.o util.o vacuum.o \ vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ - vdbetrace.o vdbevtab.o \ + vdbetrace.o vdbevtab.o vtab.o \ wal.o walker.o where.o wherecode.o whereexpr.o \ - window.o utf.o vtab.o + window.o # Object files for the amalgamation. # @@ -1015,23 +1015,22 @@ dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir fuzzy: dbfuzz2$(TEXE) -#XX#mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c -#XX# $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ -#XX# $(TLIBS) -rpath "$(libdir)" -#XX# -#XX#MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 -#XX#MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 -#XX#mptest: mptester$(TEXE) -#XX# rm -f mptest.db -#XX# $(MPTEST1) --journalmode DELETE -#XX# $(MPTEST2) --journalmode WAL -#XX# $(MPTEST1) --journalmode WAL -#XX# $(MPTEST2) --journalmode PERSIST -#XX# $(MPTEST1) --journalmode PERSIST -#XX# $(MPTEST2) --journalmode TRUNCATE -#XX# $(MPTEST1) --journalmode TRUNCATE -#XX# $(MPTEST2) --journalmode DELETE -#XX# +mptester$(TEXE): $(libsqlite3.LIB) $(TOP)/mptest/mptest.c + $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c $(libsqlite3.LIB) \ + $(LDFLAGS_libsqlite3) + +MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 +MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 +mptest: mptester$(TEXE) + rm -f mptest.db + $(MPTEST1) --journalmode DELETE + $(MPTEST2) --journalmode WAL + $(MPTEST1) --journalmode WAL + $(MPTEST2) --journalmode PERSIST + $(MPTEST1) --journalmode PERSIST + $(MPTEST2) --journalmode TRUNCATE + $(MPTEST1) --journalmode TRUNCATE + $(MPTEST2) --journalmode DELETE has_tclsh84: sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) diff --git a/auto.def b/auto.def index 3b4befb652..95be21f7b5 100644 --- a/auto.def +++ b/auto.def @@ -307,7 +307,7 @@ hwaci-define-if-opt-truthy test-status TSTRNNR_OPTS \ "test-runner flags:" {--status} {} hwaci-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \ - "Use #line macros in the amalgamation:" {--linemacros=1} {--linemacros=0} + "Use #line macros in the amalgamation:" msg-checking "Debug build? " diff --git a/manifest b/manifest index 8e82fed1e4..c0854a57f0 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Remove\sthe\sproblematic\sdbfuzz2-asan/msan\stargets,\swhich\sRichard\ssays\sare\snot\sused\sanymore. -D 2024-10-18T16:47:54.809 +C Get\smptest(er)\sbuilding. +D 2024-10-19T00:49:01.662 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in b070ca8dd62ca803547f888f4e44391bf73d806789b3ea754bc6392140fdf3a6 +F Makefile.in d4188c8e3ff9bfd24deccf3512bd013d93cfa83d5c838618c45efe8638406a6e F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 74a6b53f7050ab342e21e96fd67fa7044421e8c700b0ba7a2bfa28253319db6c +F auto.def 0aea47e732fe1f71630413f9aba879fef838b8bac6c7b3c6199f23b37e541f67 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3e843452927aaea152eab60213337912c34966e2c77d3cfd50d2ee9eb77c6796 -R f96b7f8acba78c395f1ccebf70c56c0a +P 503ce205a1efe0d52b184b1b6a23b4b6b5adb7acf6f4617249a5fa1d81e523ef +R 903ee20ca58e95a3ec54b2ae83b8cf71 U stephan -Z 8726b6ffa28a328589337a2d1c2ae656 +Z 1c47ba01bcf0515056dd5c051b8e0105 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 357fce43f0..5758713a30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -503ce205a1efe0d52b184b1b6a23b4b6b5adb7acf6f4617249a5fa1d81e523ef +f740f6a4447543751800465ddfa11c9e3c89fb7054a9dfb5450938885b8f9633 From a1e6fbebdf69f4c50473dfb9252774029fe0652d Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 12:47:06 +0000 Subject: [PATCH 062/522] Get the spell-checking targets working. Rename some symbols. FossilOrigin-Name: e389ef9c14f2421fe8cad09a8539e6a3215c96da61af790b144fccbd8bf1ca12 --- Makefile.in | 120 ++++++++++++++++++++++++-------------------------- manifest | 12 ++--- manifest.uuid | 2 +- 3 files changed, 65 insertions(+), 69 deletions(-) diff --git a/Makefile.in b/Makefile.in index 10e949070d..b19a854a93 100644 --- a/Makefile.in +++ b/Makefile.in @@ -89,7 +89,7 @@ READLINE_FLAGS = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ # # With the autosetup build, the intended way to do this is to set # those in $(LDFLAGS_libsqlite3) and include those flags for both -# $(libsqlite3.DLL) and any apps which directly link in either +# $(libsqlite3.SO) and any apps which directly link in either # sqlite3.o or its origin sources. TLIBS = @LIBS@ $(LIBS) @@ -165,7 +165,8 @@ TLIB = @TARGET_LIBEXT@ HAVE_TCL = @HAVE_TCL@ # This is the command to use for tclsh - normally just "tclsh", but we may -# know the specific version we want to use +# know the specific version we want to use. This must point to the canonical +# TCL interpreter, not JimTCL. # TCLSH_CMD = @TCLSH_CMD@ TCL_CONFIG_SH = @TCL_CONFIG_SH@ @@ -744,9 +745,9 @@ ST_OPT = -DSQLITE_OS_KV_OPTIONAL @endif @if HAVE_TCL -libtclsqlite3.DLL = libtclsqlite3$(TDLL) +libtclsqlite3.SO = libtclsqlite3$(TDLL) @else -libtclsqlite3.DLL = +libtclsqlite3.SO = @endif # @@ -776,7 +777,7 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) $(AUTOREMAKE) @touch $@ -libsqlite3.DLL = libsqlite3$(TDLL) +libsqlite3.SO = libsqlite3$(TDLL) libsqlite3.LIB = libsqlite3$(TLIB) # LDFLAGS_libsqlite3 should be used with any target which # either results in building libsqlite3.so, builds sqlite3.c @@ -786,15 +787,15 @@ LDFLAGS_libsqlite3 = \ $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) @if ENABLE_SHARED -$(libsqlite3.DLL): $(LIBOBJ) +$(libsqlite3.SO): $(LIBOBJ) $(TLINK_shared) -o $@ \ $(LIBOBJ) $(TLIBS) $(LDFLAGS_libsqlite3) -all: dll +all: so @else -$(libsqlite3.DLL): +$(libsqlite3.SO): @echo "Build of $@ was explicitly disabled."; exit 1 @endif -dll: $(libsqlite3.DLL) +so: $(libsqlite3.SO) $(libsqlite3.LIB): $(LIBOBJ) $(AR) crs $@ $(LIBOBJ) @@ -802,22 +803,22 @@ lib: $(libsqlite3.LIB) all: lib # -# Install the $(libsqlite3.DLL) as $(libsqlite3.DLL).@RELEASE@ and +# Install the $(libsqlite3.SO) as $(libsqlite3.SO).@RELEASE@ and # create symlinks which point to it. Do we really need all of this # hoop-jumping? Can we not simply install the .so as-is to # libsqlite3.so (without the versioned bits)? # # The historical SQLite build always used a version number of 0.8.6 # for reasons lost to history. -install-dll: $(install.libdir) $(libsqlite3.DLL) - $(INSTALL) $(libsqlite3.DLL) $(install.libdir) +install-so: $(install.libdir) $(libsqlite3.SO) + $(INSTALL) $(libsqlite3.SO) $(install.libdir) cd $(install.libdir); \ - rm -f $(libsqlite3.DLL).3 $(libsqlite3.DLL).@RELEASE@; \ - mv $(libsqlite3.DLL) $(libsqlite3.DLL).@RELEASE@; \ - ln -s $(libsqlite3.DLL).@RELEASE@ $(libsqlite3.DLL).3; \ - ln -s $(libsqlite3.DLL).3 $(libsqlite3.DLL) + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).@RELEASE@; \ + mv $(libsqlite3.SO) $(libsqlite3.SO).@RELEASE@; \ + ln -s $(libsqlite3.SO).@RELEASE@ $(libsqlite3.SO).3; \ + ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) @if ENABLE_SHARED -install: install-dll +install: install-so @endif # @@ -833,23 +834,23 @@ install-includes: sqlite3.h $(install.includedir) install: install-includes @if HAVE_TCL -$(libtclsqlite3.DLL): tclsqlite.o $(libsqlite3.LIB) +$(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) $(TLINK_shared) -o $@ tclsqlite.o \ $(libsqlite3.LIB) $(TCL_INCLUDE_SPEC) \ $(TCL_STUB_LIB_SPEC) $(TLIBS) \ @TCLLIB_RPATH@ -libtcl: $(libtclsqlite3.DLL) +libtcl: $(libtclsqlite3.SO) -all: $(libtclsqlite3.DLL) +all: $(libtclsqlite3.SO) pkgIndex.tcl: echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ @if TCLLIBDIR install.tcldir = "$(DESTDIR)@TCLLIBDIR@" -install-tcl: $(libtclsqlite3.DLL) pkgIndex.tcl +install-tcl: $(libtclsqlite3.SO) pkgIndex.tcl $(INSTALL) -d $(install.tcldir) - $(INSTALL) $(libtclsqlite3.DLL) $(install.tcldir) + $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) install: install-tcl @endif @@ -1827,7 +1828,7 @@ tidy: rm -f lemon$(BEXE) sqlite*.tar.gz rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) rm -f parse.* fts5parse.* - rm -f $(libsqlite3.DLL) $(libsqlite3.LIB) + rm -f $(libsqlite3.SO) $(libsqlite3.LIB) rm -f tclsqlite3$(TEXE) $(TESTPROGS) rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) @@ -1842,8 +1843,7 @@ tidy: rm -f threadtest5$(TEXE) rm -f src-verify has_tclsh* has_tclconfig rm -f tclsqlite3.c - rm -f sqlite3rc.h -# FIXME? (rm *.def) from the historical build will remove auto.def (part of autosetup) + rm -f sqlite3rc.h sqlite3.def # # Removes build products and test logs. Retains ./configure outputs. @@ -1857,24 +1857,19 @@ distclean: clean rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile -gmake -C ext/wasm distclean 2>/dev/null; true -#XX## -#XX## Windows section -#XX## -#XX#dll: sqlite3.dll -#XX# -#XX#REAL_LIBOBJ = $(LIBOBJ:%.lo=.libs/%.o) -#XX# -#XX#$(REAL_LIBOBJ): $(LIBOBJ) -#XX# -#XX#sqlite3.def: $(REAL_LIBOBJ) -#XX# echo 'EXPORTS' >sqlite3.def -#XX# nm $(REAL_LIBOBJ) | grep ' T ' | grep ' _sqlite3_' \ -#XX# | sed 's/^.* _//' >>sqlite3.def -#XX# -#XX#sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def -#XX# $(TCC) @SHOBJ_LDFLAGS@ -o $@ sqlite3.def \ -#XX# -Wl,"--strip-all" $(REAL_LIBOBJ) -#XX# +# +# Windows section +# +dll: sqlite3.dll +sqlite3.def: $(LIBOBJ) + echo 'EXPORTS' >sqlite3.def + nm $(LIBOBJ) | grep ' T ' | grep ' _sqlite3_' \ + | sed 's/^.* _//' >>sqlite3.def + +sqlite3.dll: $(LIBOBJ) sqlite3.def + $(TCC) @SHOBJ_LDFLAGS@ -o $@ sqlite3.def \ + -Wl,"--strip-all" $(LIBOBJ) + # # Fiddle app @@ -1884,27 +1879,28 @@ fiddle: sqlite3.c shell.c make -C ext/wasm fiddle emcc_opt=-Os @else fiddle: - @echo "Configure script did not find emcc, so fiddle build is not available."; exit 1 + @echo "Configure script did not find emcc, so fiddle build is not available." 2>&1; exit 1 @endif -#XX## -#XX## Spell-checking for source comments -#XX## The sources checked are either C sources or C source templates. -#XX## Their comments are extracted and processed through aspell using -#XX## a custom dictionary that contains scads of odd identifiers that -#XX## find their way into the comments. -#XX## -#XX## Currently, this target is setup to be "made" in-tree only. -#XX## The output is ephemeral. Redirect it to guide spelling fixups, -#XX## either to correct spelling or add words to tool/custom.txt. -#XX## -#XX#./custom.rws: ./tool/custom.txt -#XX# @echo 'Updating custom dictionary from tool/custom.txt' -#XX# aspell --lang=en create master ./custom.rws < $< -#XX# -#XX#misspell: ./custom.rws has_tclsh84 -#XX# $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in -#XX# +# +# Spell-checking for source comments +# The sources checked are either C sources or C source templates. +# Their comments are extracted and processed through aspell using +# a custom dictionary that contains scads of odd identifiers that +# find their way into the comments. +# +# Currently, this target is setup to be "made" in-tree only. +# The output is ephemeral. Redirect it to guide spelling fixups, +# either to correct spelling or add words to tool/custom.txt. +# +./custom.rws: ./tool/custom.txt + @echo 'Updating custom dictionary from tool/custom.txt' + aspell --lang=en create master ./custom.rws < $< +# Note that jimsh does not work here: +# https://github.com/msteveb/jimtcl/issues/319 +misspell: ./custom.rws has_tclsh84 + $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in + # # tool/version-info: a utility for emitting sqlite3 version info # in various forms. diff --git a/manifest b/manifest index c0854a57f0..7815f20a00 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Get\smptest(er)\sbuilding. -D 2024-10-19T00:49:01.662 +C Get\sthe\sspell-checking\stargets\sworking.\sRename\ssome\ssymbols. +D 2024-10-19T12:47:06.049 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in d4188c8e3ff9bfd24deccf3512bd013d93cfa83d5c838618c45efe8638406a6e +F Makefile.in 2e171cb50ebbffcea1de43eea2134965d4aa7fe80f932226018ccaf97d1f3337 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 503ce205a1efe0d52b184b1b6a23b4b6b5adb7acf6f4617249a5fa1d81e523ef -R 903ee20ca58e95a3ec54b2ae83b8cf71 +P f740f6a4447543751800465ddfa11c9e3c89fb7054a9dfb5450938885b8f9633 +R 92bffff764d6aa32a69b501acd00c78b U stephan -Z 1c47ba01bcf0515056dd5c051b8e0105 +Z bf61fb6150d287bec94e8a376b3574aa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5758713a30..5e913eb0f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f740f6a4447543751800465ddfa11c9e3c89fb7054a9dfb5450938885b8f9633 +e389ef9c14f2421fe8cad09a8539e6a3215c96da61af790b144fccbd8bf1ca12 From 49de624e41bb5d923ca6056190c179410951f16b Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 13:18:56 +0000 Subject: [PATCH 063/522] Work around a JimTCL regsub incompatibility in mkccode.tcl. FossilOrigin-Name: c2e5dd791cce3ec4f1f009e945b8c66e8c5e01ae25077f345389f04e3c004ecf --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/mkccode.tcl | 13 ++++++++++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7815f20a00..115413a54d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sthe\sspell-checking\stargets\sworking.\sRename\ssome\ssymbols. -D 2024-10-19T12:47:06.049 +C Work\saround\sa\sJimTCL\sregsub\sincompatibility\sin\smkccode.tcl. +D 2024-10-19T13:18:56.950 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -2155,7 +2155,7 @@ F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a -F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x +F tool/mkccode.tcl 4cb8ad7e7330aaed052b0657a1bfacbc67103c400e41860aff643a482cfc2d3e x F tool/mkctimec.tcl e3af51acc2ef92062fe6d622de010a27a34b497258a248dada04388b916c61c6 x F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559 F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f740f6a4447543751800465ddfa11c9e3c89fb7054a9dfb5450938885b8f9633 -R 92bffff764d6aa32a69b501acd00c78b +P e389ef9c14f2421fe8cad09a8539e6a3215c96da61af790b144fccbd8bf1ca12 +R 4e3a079db29464a0ceb7d25aad967be0 U stephan -Z bf61fb6150d287bec94e8a376b3574aa +Z 5f082cb2e15de55893148dff61edc58e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5e913eb0f1..2484d523e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e389ef9c14f2421fe8cad09a8539e6a3215c96da61af790b144fccbd8bf1ca12 +c2e5dd791cce3ec4f1f009e945b8c66e8c5e01ae25077f345389f04e3c004ecf diff --git a/tool/mkccode.tcl b/tool/mkccode.tcl index 41b09f1e81..e847c8d3b8 100755 --- a/tool/mkccode.tcl +++ b/tool/mkccode.tcl @@ -6,7 +6,7 @@ # # Usage example: # -# tclsh mktclsqliteprog.tcl demoapp.c.in >demoapp.c +# tclsh mkccode.tcl demoapp.c.in >demoapp.c # # The demoapp.c.in file contains a mixture of C code, TCL script, and # processing directives used by mktclsqliteprog.tcl to build the final C-code @@ -56,8 +56,15 @@ while {1} { set line [gets $in] if {[eof $in]} break if {[regexp {^INCLUDE (.*)} $line all path]} { - regsub {^\$ROOT\y} $path $ROOT path - regsub {^\$HOME\y} $path $HOME path + if {0} { + # https://github.com/msteveb/jimtcl/issues/320 + regsub {^\$ROOT\y} $path $ROOT path + regsub {^\$HOME\y} $path $HOME path + } else { + set path [string map "\$ROOT $ROOT" $path] + set path [string map "\$HOME $HOME" $path] + # or: set path [string map "\$HOME $HOME \$ROOT $ROOT" $path] + } set in2 [open $path rb] puts "/* INCLUDE $path */" if {$instr} { From 7abd86c4b8067a126693f319e80031edaf8ac240 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 13:19:05 +0000 Subject: [PATCH 064/522] Get more of the test/utility targets building. FossilOrigin-Name: 24c81c6c52603c217134c233190499086240211763736aa10cb6d0be074e68a5 --- Makefile.in | 380 +++++++++++++++++++++++++------------------------- manifest | 12 +- manifest.uuid | 2 +- 3 files changed, 198 insertions(+), 196 deletions(-) diff --git a/Makefile.in b/Makefile.in index b19a854a93..da39acd8a2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -779,9 +779,10 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) libsqlite3.SO = libsqlite3$(TDLL) libsqlite3.LIB = libsqlite3$(TLIB) -# LDFLAGS_libsqlite3 should be used with any target which -# either results in building libsqlite3.so, builds sqlite3.c -# directly, links in either of $(LIBOBJSO) or $(LIBOBJS1). +# LDFLAGS_libsqlite3 should be used with any target which either +# results in building libsqlite3.so, compiles sqlite3.c directly, or +# links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these +# flags are for the target build platform, not necessarily localhost. LDFLAGS_libsqlite3 = \ $(LDFLAGS_RPATH) @LIBS@ $(LIBS) $(LDFLAGS_PTHREAD) \ $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) @@ -1554,195 +1555,196 @@ testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) -#XX#testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) -#XX# -#XX## A very detailed test running most or all test cases -#XX#fulltest: alltest fuzztest -#XX# -#XX## Run most or all tcl test cases -#XX#alltest: $(TESTPROGS) -#XX# ./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS) -#XX# -#XX## Really really long testing -#XX#soaktest: $(TESTPROGS) -#XX# ./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS) -#XX# -#XX## Do extra testing but not everything. -#XX#fulltestonly: $(TESTPROGS) fuzztest -#XX# ./testfixture$(TEXE) $(TOP)/test/full.test -#XX# -#XX## Fuzz testing -#XX## -#XX## WARNING: When the "fuzztest" target is run by the testrunner.tcl script, -#XX## it does not actually run this code. Instead, it schedules equivalent -#XX## commands. Therefore, if this target is updated, then code in -#XX## testrunner_data.tcl (search for "trd_fuzztest_data") must also be updated. -#XX## -#XX#fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) -#XX# ./fuzzcheck$(TEXE) $(FUZZDATA) -#XX# ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db -#XX# -#XX#valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) -#XX# valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) -#XX# valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db -#XX# -#XX## The veryquick.test TCL tests. -#XX## -#XX#tcltest: ./testfixture$(TEXE) -#XX# ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) -#XX# -#XX## Runs all the same tests cases as the "tcltest" target but uses -#XX## the testrunner.tcl script to run them in multiple cores -#XX## concurrently. -#XX#testrunner: testfixture$(TEXE) -#XX# ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl -#XX# -#XX## This is the testing target preferred by the core SQLite developers. -#XX## It runs tests under a standard configuration, regardless of how -#XX## ./configure was run. The devs run "make devtest" prior to each -#XX## check-in, at a minimum. Probably other tests too, but at least this -#XX## one. -#XX## -#XX#devtest: srctree-check sourcetest -#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) -#XX# -#XX#mdevtest: srctree-check has_tclsh85 -#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) -#XX# -#XX#sdevtest: has_tclsh85 -#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS) -#XX# -#XX## Validate that various generated files in the source tree -#XX## are up-to-date. -#XX## -#XX#srctree-check: $(TOP)/tool/srctree-check.tcl -#XX# $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl -#XX# -#XX## Testing for a release -#XX## -#XX#releasetest: srctree-check has_tclsh85 verify-source -#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS) -#XX# -#XX## Minimal testing that runs in less than 3 minutes -#XX## -#XX#quicktest: ./testfixture$(TEXE) -#XX# ./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS) -#XX# -#XX## Try to run tests on whatever options are specified by the -#XX## ./configure. The developers seldom use this target. Instead -#XX## they use "make devtest" which runs tests on a standard set of -#XX## options regardless of how SQLite is configured. This "test" -#XX## target is provided for legacy only. -#XX## -#XX#test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest -#XX# -#XX## Run a test using valgrind. This can take a really long time -#XX## because valgrind is so much slower than a native machine. -#XX## -#XX#valgrindtest: $(TESTPROGS) valgrindfuzz -#XX# OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) -#XX# -#XX## A very fast test that checks basic sanity. The name comes from -#XX## the 60s-era electronics testing: "Turn it on and see if smoke -#XX## comes out." -#XX## -#XX#smoketest: $(TESTPROGS) fuzzcheck$(TEXE) -#XX# ./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS) -#XX# -#XX#shelltest: -#XX# $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell -#XX# -#XX#sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 -#XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c -#XX# -#XX#sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c -#XX# $(TLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) -#XX# -#XX#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 has_tclsh85 -#XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c -#XX# -#XX#sqltclsh$(TEXE): has_tclconfig sqltclsh.c -#XX# $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS) -#XX# +testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) + +# A very detailed test running most or all test cases +fulltest: alltest fuzztest + +# Run most or all tcl test cases +alltest: $(TESTPROGS) + ./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS) + +# Really really long testing +soaktest: $(TESTPROGS) + ./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS) + +# Do extra testing but not everything. +fulltestonly: $(TESTPROGS) fuzztest + ./testfixture$(TEXE) $(TOP)/test/full.test + +# Fuzz testing +# +# WARNING: When the "fuzztest" target is run by the testrunner.tcl script, +# it does not actually run this code. Instead, it schedules equivalent +# commands. Therefore, if this target is updated, then code in +# testrunner_data.tcl (search for "trd_fuzztest_data") must also be updated. +# +fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) + ./fuzzcheck$(TEXE) $(FUZZDATA) + ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db + +valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) + valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) + valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db + +# The veryquick.test TCL tests. +# +tcltest: ./testfixture$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) + +# Runs all the same tests cases as the "tcltest" target but uses +# the testrunner.tcl script to run them in multiple cores +# concurrently. +testrunner: testfixture$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl + +# This is the testing target preferred by the core SQLite developers. +# It runs tests under a standard configuration, regardless of how +# ./configure was run. The devs run "make devtest" prior to each +# check-in, at a minimum. Probably other tests too, but at least this +# one. +# +devtest: srctree-check sourcetest + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) + +mdevtest: srctree-check has_tclsh85 + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) + +sdevtest: has_tclsh85 + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS) + +# Validate that various generated files in the source tree +# are up-to-date. +# +srctree-check: $(TOP)/tool/srctree-check.tcl + $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl + +# Testing for a release +# +releasetest: srctree-check has_tclsh85 verify-source + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS) + +# Minimal testing that runs in less than 3 minutes +# +quicktest: ./testfixture$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS) + +# Try to run tests on whatever options are specified by the +# ./configure. The developers seldom use this target. Instead +# they use "make devtest" which runs tests on a standard set of +# options regardless of how SQLite is configured. This "test" +# target is provided for legacy only. +# +test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest + +# Run a test using valgrind. This can take a really long time +# because valgrind is so much slower than a native machine. +# +valgrindtest: $(TESTPROGS) valgrindfuzz + OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) + +# A very fast test that checks basic sanity. The name comes from +# the 60s-era electronics testing: "Turn it on and see if smoke +# comes out." +# +smoketest: $(TESTPROGS) fuzzcheck$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS) + +shelltest: + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell + +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 + $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c + +sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c + $(TLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(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 has_tclsh85 + $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c + +sqltclsh$(TEXE): has_tclconfig sqltclsh.c + $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) + sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c - $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite3) - -#XX#CHECKER_DEPS =\ -#XX# $(TOP)/tool/mkccode.tcl \ -#XX# sqlite3.c \ -#XX# $(TOP)/src/tclsqlite.c \ -#XX# $(TOP)/ext/repair/sqlite3_checker.tcl \ -#XX# $(TOP)/ext/repair/checkindex.c \ -#XX# $(TOP)/ext/repair/checkfreelist.c \ -#XX# $(TOP)/ext/misc/btreeinfo.c \ -#XX# $(TOP)/ext/repair/sqlite3_checker.c.in -#XX# -#XX#sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 -#XX# $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ -#XX# -#XX#sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c -#XX# $(TLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS) -#XX# -#XX#dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo -#XX# $(TLINK) -DDBDUMP_STANDALONE -o $@ \ -#XX# $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS) -#XX# -#XX#dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c -#XX# $(TLINK)-o $@ $(TOP)/tool/dbtotxt.c -#XX# -#XX#showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS) -#XX# -#XX#showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(TLIBS) -#XX# -#XX#showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(TLIBS) -#XX# -#XX#showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(TLIBS) -#XX# -#XX#showshm$(TEXE): $(TOP)/tool/showshm.c -#XX# $(TLINK) -o $@ $(TOP)/tool/showshm.c -#XX# -#XX#index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo -#XX# $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(TLIBS) -#XX# -#XX#changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) -#XX# -#XX#changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS) -#XX# -#XX#rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) -#XX# -#XX#atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS) -#XX# -#XX#LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h -#XX# $(TLINK) -I. -o $@ $(TOP)/tool/logest.c -#XX# -#XX#wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo -#XX# $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS) -#XX# -#XX#speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile -#XX# $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) -#XX# + $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite3) + +CHECKER_DEPS =\ + $(TOP)/tool/mkccode.tcl \ + sqlite3.c \ + $(TOP)/src/tclsqlite.c \ + $(TOP)/ext/repair/sqlite3_checker.tcl \ + $(TOP)/ext/repair/checkindex.c \ + $(TOP)/ext/repair/checkfreelist.c \ + $(TOP)/ext/misc/btreeinfo.c \ + $(TOP)/ext/repair/sqlite3_checker.c.in + +sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 + $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ + +sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c + $(TLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) + +dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo + $(TLINK) -DDBDUMP_STANDALONE -o $@ \ + $(TOP)/ext/misc/dbdump.c sqlite3.lo $(LDFLAGS_libsqlite3) + +dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c + $(TLINK)-o $@ $(TOP)/tool/dbtotxt.c + +showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(LDFLAGS_libsqlite3) + +showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(LDFLAGS_libsqlite3) + +showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(LDFLAGS_libsqlite3) + +showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(LDFLAGS_libsqlite3) + +showshm$(TEXE): $(TOP)/tool/showshm.c + $(TLINK) -o $@ $(TOP)/tool/showshm.c + +index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo + $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(LDFLAGS_libsqlite3) + +changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(LDFLAGS_libsqlite3) + +changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(LDFLAGS_libsqlite3) + +rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(LDFLAGS_libsqlite3) + +atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(LDFLAGS_libsqlite3) + +LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h + $(TLINK) -I. -o $@ $(TOP)/tool/logest.c + +wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(LDFLAGS_libsqlite3) + +speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile + $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS_libsqlite3) + #XX#startup$(TEXE): $(TOP)/test/startup.c sqlite3.c #XX# $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) -#XX# -#XX#KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ -#XX# -#XX#kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c -#XX# $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS) -#XX# -#XX#rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo -#XX# $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS) -#XX# -#XX#loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la -#XX# $(TLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(TLIBS) -#XX# + +KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ + +kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c + $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS_libsqlite3) + +rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo + $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(LDFLAGS_libsqlite3) + +loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la + $(TLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(LDFLAGS_libsqlite3) + #XX## This target will fail if the SQLite amalgamation contains any exported #XX## symbols that do not begin with "sqlite3_". It is run as part of the #XX## releasetest.tcl script. diff --git a/manifest b/manifest index 115413a54d..3917755d8f 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Work\saround\sa\sJimTCL\sregsub\sincompatibility\sin\smkccode.tcl. -D 2024-10-19T13:18:56.950 +C Get\smore\sof\sthe\stest/utility\stargets\sbuilding. +D 2024-10-19T13:19:05.750 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 2e171cb50ebbffcea1de43eea2134965d4aa7fe80f932226018ccaf97d1f3337 +F Makefile.in f091aa7b46c21afce2dc7573004f44f46436eb3d831bf51a4f052241c339e410 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e389ef9c14f2421fe8cad09a8539e6a3215c96da61af790b144fccbd8bf1ca12 -R 4e3a079db29464a0ceb7d25aad967be0 +P c2e5dd791cce3ec4f1f009e945b8c66e8c5e01ae25077f345389f04e3c004ecf +R e01f3b946a09b5bd21efb738dbf29e3d U stephan -Z 5f082cb2e15de55893148dff61edc58e +Z fe21ae573c4d67c553a6b02aa3d73807 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2484d523e8..249e948e46 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2e5dd791cce3ec4f1f009e945b8c66e8c5e01ae25077f345389f04e3c004ecf +24c81c6c52603c217134c233190499086240211763736aa10cb6d0be074e68a5 From 6d8ec2aed4a037e703651845e0e27d03342e31dd Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 13:44:16 +0000 Subject: [PATCH 065/522] Get tool-zip target, and its prerequisites, building. FossilOrigin-Name: 38cc5db3a8f3079c9be18a9939dae9ba8f4411d4c2361369d697d32f536fc3a4 --- Makefile.in | 103 +++++++++++++++++++++++++++----------------------- manifest | 12 +++--- manifest.uuid | 2 +- 3 files changed, 63 insertions(+), 54 deletions(-) diff --git a/Makefile.in b/Makefile.in index da39acd8a2..78e35fe4d8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -148,7 +148,7 @@ TCC += @CFLAGS_ZLIB@ VERSION = @VERSION@ RELEASE = @RELEASE@ -# Filename extensions for binaries and shared libraries +# Filename extensions for binaries and libraries # BEXE = @BUILD_EXEEXT@ TEXE = @TARGET_EXEEXT@ @@ -783,6 +783,7 @@ libsqlite3.LIB = libsqlite3$(TLIB) # results in building libsqlite3.so, compiles sqlite3.c directly, or # links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these # flags are for the target build platform, not necessarily localhost. +# i.e. it should be used with $(TCC) or $(TLINK) but not $(BCC). LDFLAGS_libsqlite3 = \ $(LDFLAGS_RPATH) @LIBS@ $(LIBS) $(LDFLAGS_PTHREAD) \ $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) @@ -917,7 +918,7 @@ dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite3) RSYNC_SRC = \ - $(TOP)/tool/sqlite3-rsync.c \ + $(TOP)/tool/sqlite3_rsync.c \ sqlite3.c RSYNC_OPT = \ @@ -927,11 +928,11 @@ RSYNC_OPT = \ -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_OMIT_DEPRECATED -sqlite3-rsync$(TEXE): $(RSYNC_SRC) +sqlite3_rsync$(TEXE): $(RSYNC_SRC) $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) -install-rsync: sqlite3-rsync$(TEXE) $(install.bindir) - $(INSTALL) sqlite3-rsync$(TEXT) $(install.bindir) +install-rsync: sqlite3_rsync$(TEXE) $(install.bindir) + $(INSTALL) sqlite3_rsync$(TEXT) $(install.bindir) #install: install-rsync scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o @@ -1551,7 +1552,7 @@ TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) $(TLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ - -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(LDFLAGS_libsqlite3) @TCL_INCLUDE_SPEC@ + -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(LDFLAGS_libsqlite3) $(TCL_INCLUDE_SPEC) coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) @@ -1653,19 +1654,23 @@ smoketest: $(TESTPROGS) fuzzcheck$(TEXE) shelltest: $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ + $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c - $(TLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) + $(TLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TCL_INCLUDE_SPEC) $(LDFLAGS_libsqlite3) -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 has_tclsh85 +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 has_tclsh85 $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(TEXE): has_tclconfig sqltclsh.c $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) -sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c +sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/expert.c sqlite3.c $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite3) @@ -1733,6 +1738,8 @@ speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile #XX#startup$(TEXE): $(TOP)/test/startup.c sqlite3.c #XX# $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) +# ^^^ note that it wants $(TLIBS) (a.k.a. $(LDFLAGS_libsqlite3) but is using $(CC) +# instead of $(BCC). KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ @@ -1745,15 +1752,15 @@ rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la $(TLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(LDFLAGS_libsqlite3) -#XX## This target will fail if the SQLite amalgamation contains any exported -#XX## symbols that do not begin with "sqlite3_". It is run as part of the -#XX## releasetest.tcl script. -#XX## -#XX#VALIDIDS=' sqlite3(changeset|changegroup|session)?_' -#XX#checksymbols: sqlite3.o -#XX# nm -g --defined-only sqlite3.o -#XX# nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 -#XX# echo '0 errors out of 1 tests' +# This target will fail if the SQLite amalgamation contains any exported +# symbols that do not begin with "sqlite3_". It is run as part of the +# releasetest.tcl script. +# +VALIDIDS=' sqlite3(changeset|changegroup|session)?_' +checksymbols: sqlite3.o + nm -g --defined-only sqlite3.o + nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 + echo '0 errors out of 1 tests' #XX# #XX## Build the amalgamation-autoconf package. The amalamgation-tarball target builds #XX## a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. @@ -1765,33 +1772,35 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la #XX#snapshot-tarball: sqlite3.c sqlite3rc.h #XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot #XX# -#XX## Build a ZIP archive containing various command-line tools. -#XX## -#XX#tool-zip: testfixture sqlite3 sqldiff sqlite3_analyzer $(TOP)/tool/mktoolzip.tcl -#XX# ./testfixture $(TOP)/tool/mktoolzip.tcl -#XX# -#XX## The next two rules are used to support the "threadtest" target. Building -#XX## threadtest runs a few thread-safety tests that are implemented in C. This -#XX## target is invoked by the releasetest.tcl script. -#XX## -#XX#THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ -#XX# $(TOP)/test/tt3_checkpoint.c \ -#XX# $(TOP)/test/tt3_index.c \ -#XX# $(TOP)/test/tt3_vacuum.c \ -#XX# $(TOP)/test/tt3_stress.c \ -#XX# $(TOP)/test/tt3_lookaside1.c -#XX# -#XX#threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC) -#XX# $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(TLIBS) -#XX# -#XX#threadtest: threadtest3$(TEXE) -#XX# ./threadtest3$(TEXE) -#XX# -#XX#threadtest5: sqlite3.c $(TOP)/test/threadtest5.c -#XX# $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS) -#XX# -#XX## Standard install and cleanup targets -#XX## +# Build a ZIP archive containing various command-line tools. +# +tool-zip: testfixture$(TEXE) sqlite3$(TEXE) sqldiff$(TEXE) \ + sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) $(TOP)/tool/mktoolzip.tcl + strip sqlite3$(TEXE) sqldiff$(TEXE) sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) + ./testfixture$(TEXE) $(TOP)/tool/mktoolzip.tcl + +# The next two rules are used to support the "threadtest" target. Building +# threadtest runs a few thread-safety tests that are implemented in C. This +# target is invoked by the releasetest.tcl script. +# +THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ + $(TOP)/test/tt3_checkpoint.c \ + $(TOP)/test/tt3_index.c \ + $(TOP)/test/tt3_vacuum.c \ + $(TOP)/test/tt3_stress.c \ + $(TOP)/test/tt3_lookaside1.c + +threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC) + $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(LDFLAGS_libsqlite3) + +threadtest: threadtest3$(TEXE) + ./threadtest3$(TEXE) + +threadtest5: sqlite3.c $(TOP)/test/threadtest5.c + $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS_libsqlite3) + +# Standard install and cleanup targets +# #XX#lib_install: libsqlite3.la #XX# $(INSTALL) -d $(DESTDIR)$(libdir) #XX# $(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir) @@ -1836,7 +1845,7 @@ tidy: rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) rm -f *.dll *.lib *.exp *.pc *.vsix *.so *.dylib pkgIndex.tcl - rm -f sqlite3_analyzer$(TEXE) sqlite3-rsync$(TEXE) sqlite3_expert$(TEXE) + rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) sqlite3_expert$(TEXE) rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) dbfuzz2-asan$(TEXE) dbfuzz2-msan$(TEXE) diff --git a/manifest b/manifest index 3917755d8f..356d030ff5 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Get\smore\sof\sthe\stest/utility\stargets\sbuilding. -D 2024-10-19T13:19:05.750 +C Get\stool-zip\starget,\sand\sits\sprerequisites,\sbuilding. +D 2024-10-19T13:44:16.623 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in f091aa7b46c21afce2dc7573004f44f46436eb3d831bf51a4f052241c339e410 +F Makefile.in 6b04997777dc413628a51699c018152916e1619209e29a8a73709a9cc16b90aa F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2238,8 +2238,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c2e5dd791cce3ec4f1f009e945b8c66e8c5e01ae25077f345389f04e3c004ecf -R e01f3b946a09b5bd21efb738dbf29e3d +P 24c81c6c52603c217134c233190499086240211763736aa10cb6d0be074e68a5 +R 470f5348311bd3e9ef053b0a3bf4211c U stephan -Z fe21ae573c4d67c553a6b02aa3d73807 +Z 1c4cd42471612af680fdc4c3ad0c6235 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 249e948e46..311d20c71e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24c81c6c52603c217134c233190499086240211763736aa10cb6d0be074e68a5 +38cc5db3a8f3079c9be18a9939dae9ba8f4411d4c2361369d697d32f536fc3a4 From 816f4b9cc1db6aa6b55a8455f3a982133fcd3cde Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 16:58:17 +0000 Subject: [PATCH 066/522] Generic build cleanups. FossilOrigin-Name: 510afccf02dc9c3e3b928c64c34d10bee66a2343ecec6e24c4770cb0f139cd65 --- Makefile.in | 168 ++++++++++++++++++++++---------------------------- auto.def | 6 ++ manifest | 14 ++--- manifest.uuid | 2 +- 4 files changed, 87 insertions(+), 103 deletions(-) diff --git a/Makefile.in b/Makefile.in index 78e35fe4d8..6576b58f63 100644 --- a/Makefile.in +++ b/Makefile.in @@ -72,9 +72,9 @@ LIBTCL = @TCL_LIB_SPEC@ #XX# # Compiler options needed for programs that use the readline() library. # -READLINE_FLAGS = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ -#XX#READLINE_FLAGS += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ -#XX#READLINE_FLAGS += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ +CFLAGS_readline = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ +#XX#CFLAGS_readline += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ +#XX#CFLAGS_readline += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ #XX# #XX## The library that programs using readline() must link against. #XX## @@ -220,6 +220,9 @@ INSTALL = @BIN_INSTALL@ INSTALL_noexec = $(INSTALL) -m 0644 # ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... +# install.XYZ = dirs for installation. They're in quotes to +# accommodate installations where paths have spaces in them. +# install.bindir = "$(DESTDIR)$(bindir)" install.libdir = "$(DESTDIR)$(libdir)" install.includedir = "$(DESTDIR)$(prefix)/include" @@ -792,19 +795,18 @@ LDFLAGS_libsqlite3 = \ $(libsqlite3.SO): $(LIBOBJ) $(TLINK_shared) -o $@ \ $(LIBOBJ) $(TLIBS) $(LDFLAGS_libsqlite3) +so: $(libsqlite3.SO) all: so @else $(libsqlite3.SO): @echo "Build of $@ was explicitly disabled."; exit 1 @endif -so: $(libsqlite3.SO) -$(libsqlite3.LIB): $(LIBOBJ) +$(libsqlite3.LIB): $(LIBOBJ) $(AR) crs $@ $(LIBOBJ) lib: $(libsqlite3.LIB) all: lib -# # Install the $(libsqlite3.SO) as $(libsqlite3.SO).@RELEASE@ and # create symlinks which point to it. Do we really need all of this # hoop-jumping? Can we not simply install the .so as-is to @@ -812,6 +814,7 @@ all: lib # # The historical SQLite build always used a version number of 0.8.6 # for reasons lost to history. +# install-so: $(install.libdir) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) $(install.libdir) cd $(install.libdir); \ @@ -823,14 +826,14 @@ install-so: $(install.libdir) $(libsqlite3.SO) install: install-so @endif -# # Install $(libsqlite3.LIB) +# install-lib: $(install.libdir) $(libsqlite3.LIB) $(INSTALL_noexec) $(libsqlite3.LIB) $(install.libdir) install: install-lib -# # Install C header files +# install-includes: sqlite3.h $(install.includedir) $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install.includedir) install: install-includes @@ -838,9 +841,8 @@ install: install-includes @if HAVE_TCL $(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) $(TLINK_shared) -o $@ tclsqlite.o \ - $(libsqlite3.LIB) $(TCL_INCLUDE_SPEC) \ - $(TCL_STUB_LIB_SPEC) $(TLIBS) \ - @TCLLIB_RPATH@ + $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS_libsqlite3) \ + $(libsqlite3.LIB) @TCLLIB_RPATH@ libtcl: $(libtclsqlite3.SO) all: $(libtclsqlite3.SO) @@ -850,7 +852,7 @@ pkgIndex.tcl: @if TCLLIBDIR install.tcldir = "$(DESTDIR)@TCLLIBDIR@" -install-tcl: $(libtclsqlite3.SO) pkgIndex.tcl +install-tcl: install-lib $(libtclsqlite3.SO) pkgIndex.tcl $(INSTALL) -d $(install.tcldir) $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) @@ -894,7 +896,7 @@ tclextension-list: @endif sqlite3$(TEXE): shell.c sqlite3.c - $(TCC) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ + $(TCC) $(CFLAGS_readline) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ $(LDFLAGS_libsqlite3) $(LDFLAGS_READLINE) cli: sqlite3$(TEXE) @@ -904,7 +906,6 @@ all: cli install-cli: sqlite3$(TEXT) $(install.bindir) $(INSTALL) -s sqlite3$(TEXT) $(install.bindir) - install: install-cli sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h @@ -1067,7 +1068,11 @@ has_tclconfig: cp fts5.c fts5.h tsrc touch .target_source -sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify \ +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ + $(TOP)/VERSION $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h + +sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify \ $(BTCLSH) # has_tclsh84 $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . @@ -1381,10 +1386,6 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) cp $(TOP)/src/parse.y . ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ - $(TOP)/VERSION $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h - sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(BTCLSH) # has_tclsh84 echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ @@ -1761,6 +1762,15 @@ checksymbols: sqlite3.o nm -g --defined-only sqlite3.o nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 echo '0 errors out of 1 tests' + +# Build a ZIP archive containing various command-line tools. +# +tool-zip: testfixture$(TEXE) sqlite3$(TEXE) sqldiff$(TEXE) \ + sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) $(TOP)/tool/mktoolzip.tcl + strip sqlite3$(TEXE) sqldiff$(TEXE) sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) + ./testfixture$(TEXE) $(TOP)/tool/mktoolzip.tcl + +#XX# TODO: adapt the autoconf amalgamation for autosetup #XX# #XX## Build the amalgamation-autoconf package. The amalamgation-tarball target builds #XX## a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. @@ -1772,12 +1782,6 @@ checksymbols: sqlite3.o #XX#snapshot-tarball: sqlite3.c sqlite3rc.h #XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot #XX# -# Build a ZIP archive containing various command-line tools. -# -tool-zip: testfixture$(TEXE) sqlite3$(TEXE) sqldiff$(TEXE) \ - sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) $(TOP)/tool/mktoolzip.tcl - strip sqlite3$(TEXE) sqldiff$(TEXE) sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) - ./testfixture$(TEXE) $(TOP)/tool/mktoolzip.tcl # The next two rules are used to support the "threadtest" target. Building # threadtest runs a few thread-safety tests that are implemented in C. This @@ -1799,75 +1803,6 @@ threadtest: threadtest3$(TEXE) threadtest5: sqlite3.c $(TOP)/test/threadtest5.c $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS_libsqlite3) -# Standard install and cleanup targets -# -#XX#lib_install: libsqlite3.la -#XX# $(INSTALL) -d $(DESTDIR)$(libdir) -#XX# $(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir) -#XX# -#XX## Use $(tcl_install_$(HAVE_TCL)) to resolve to either tcl_install or -#XX## an empty value. -#XX#tcl_install_0 = -#XX#tcl_install_1 = tcl_install -#XX# -#XX#install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc $(tcl_install_$(HAVE_TCL)) -#XX# $(INSTALL) -d $(DESTDIR)$(bindir) -#XX# $(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir) -#XX# $(INSTALL) -d $(DESTDIR)$(includedir) -#XX# $(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir) -#XX# $(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir) -#XX# $(INSTALL) -d $(DESTDIR)$(pkgconfigdir) -#XX# $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir) -#XX# -#XX# -#XX#tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl -#XX# $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR) -#XX# $(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR) -#XX# rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a -#XX# $(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR) - -# Remove build products sufficient so that subsequent makes will recompile -# everything from scratch. Do not remove: -# -# * test results and test logs -# * output from ./configure -# -tidy: - rm -f *.lo *.la *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) - rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h - rm -rf .libs .deps tsrc .target_source - rm -f lemon$(BEXE) sqlite*.tar.gz - rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) - rm -f parse.* fts5parse.* - rm -f $(libsqlite3.SO) $(libsqlite3.LIB) - rm -f tclsqlite3$(TEXE) $(TESTPROGS) - rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) - rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) - rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) - rm -f *.dll *.lib *.exp *.pc *.vsix *.so *.dylib pkgIndex.tcl - rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) sqlite3_expert$(TEXE) - rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) - rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) - rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) dbfuzz2-asan$(TEXE) dbfuzz2-msan$(TEXE) - rm -f fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE) - rm -f sessionfuzz$(TEXE) - rm -f threadtest5$(TEXE) - rm -f src-verify has_tclsh* has_tclconfig - rm -f tclsqlite3.c - rm -f sqlite3rc.h sqlite3.def - -# -# Removes build products and test logs. Retains ./configure outputs. -# -clean: tidy - rm -rf omittest* testrunner* testdir* - -gmake -C ext/wasm distclean 2>/dev/null; true - -# Clean up everything. No exceptions. -distclean: clean - rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile - -gmake -C ext/wasm distclean 2>/dev/null; true - # # Windows section # @@ -1881,7 +1816,6 @@ sqlite3.dll: $(LIBOBJ) sqlite3.def $(TCC) @SHOBJ_LDFLAGS@ -o $@ sqlite3.def \ -Wl,"--strip-all" $(LIBOBJ) - # # Fiddle app # @@ -1918,3 +1852,47 @@ misspell: ./custom.rws has_tclsh84 # version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h $(TLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c + + +# Remove build products sufficient so that subsequent makes will recompile +# everything from scratch. Do not remove: +# +# * test results and test logs +# * output from ./configure +# +tidy: + rm -f *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) + rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h + rm -rf .libs .deps tsrc .target_source + rm -f lemon$(BEXE) sqlite*.tar.gz + rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) + rm -f parse.* fts5parse.* + rm -f $(libsqlite3.SO) $(libsqlite3.LIB) + rm -f tclsqlite3$(TEXE) $(TESTPROGS) + rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) + rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) + rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) + rm -f *.dll *.lib *.exp *.pc *.vsix *.so *.dylib pkgIndex.tcl + rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) sqlite3_expert$(TEXE) + rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) + rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) + rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) dbfuzz2-asan$(TEXE) dbfuzz2-msan$(TEXE) + rm -f fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE) + rm -f sessionfuzz$(TEXE) + rm -f threadtest5$(TEXE) + rm -f src-verify$(BEXE) has_tclsh* has_tclconfig + rm -f tclsqlite3.c + rm -f sqlite3rc.h sqlite3.def + +# +# Removes build products and test logs. Retains ./configure outputs. +# +clean: tidy + rm -rf omittest* testrunner* testdir* + -gmake -C ext/wasm distclean 2>/dev/null; true + +# Clean up everything. No exceptions. +distclean: clean + rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile + rm -f $(TOP)/tool/emcc.sh + -gmake -C ext/wasm distclean 2>/dev/null; true diff --git a/auto.def b/auto.def index 95be21f7b5..ee958ec23f 100644 --- a/auto.def +++ b/auto.def @@ -186,8 +186,14 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { # Programs needed if {"" eq [hwaci-bin-define install]} { msg-result "Cannot find install binary, so 'make install' will not work." + # Reminder: we historically have ./install-sh in the source tree. + # Can we not simply use that? + # define BIN_INSTALL "$top_srcdir/install-sh" + # Nope: it MOVES its source files over the target, which + # break the installation in some cases. } + ######################################################################## # Locate a compiler for the build machine. This compiler should # generate command-line programs that run on the build machine. diff --git a/manifest b/manifest index 423bc1521b..c2ac84e840 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Merge\strunk\sinto\sautosetup\sbranch. -D 2024-10-19T13:51:23.926 +C Generic\sbuild\scleanups. +D 2024-10-19T16:58:17.870 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 6b04997777dc413628a51699c018152916e1619209e29a8a73709a9cc16b90aa +F Makefile.in b9de6145692620a3176e9a0e6a1317a049d6bf2559896f642ae9fdc6aba3a627 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 0aea47e732fe1f71630413f9aba879fef838b8bac6c7b3c6199f23b37e541f67 +F auto.def c212e2066f75941113296d1120b3375388816eaee7f04e1342f0a8e82dec03fc F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 38cc5db3a8f3079c9be18a9939dae9ba8f4411d4c2361369d697d32f536fc3a4 5a594dbcd533aa1e37acea1702db993672c3c0e621add9ea26a497c52037617f -R e4c37ecd7ba282a9f70fee00d4c29fdd +P 2923a8924c92f62d07cb130462a8e6f4662837bad1a02bda53e630b64c692f60 +R e27a73e275f999d0b19f7fb9f885c617 U stephan -Z e05981fda14776e17a9ed904f59c6662 +Z 78428a8bc6db32b4f76584c8d3747578 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 22c213f24c..3bc8019b6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2923a8924c92f62d07cb130462a8e6f4662837bad1a02bda53e630b64c692f60 +510afccf02dc9c3e3b928c64c34d10bee66a2343ecec6e24c4770cb0f139cd65 From abf470d7a34f59f8b47e878c88e4f9041a344601 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 18:31:47 +0000 Subject: [PATCH 067/522] Factor out all autosetup-processed @if/@else blocks from Makefile.in in prep for moving most of the makefile code into main.mk (which has, so far, been completely overlooked in this port but will now become the main basis for the static parts of the build). The idea is that all build configuration goes into a platform-dependent makefile which then includes main.mk. FossilOrigin-Name: 707e0f5857d58ec8b457270f988126b1dd0f01b5a3445a43ff7b5429324b1b3d --- Makefile.in | 174 ++++---- auto.def | 20 +- main.mk | 1163 +------------------------------------------------ manifest | 16 +- manifest.uuid | 2 +- 5 files changed, 121 insertions(+), 1254 deletions(-) diff --git a/Makefile.in b/Makefile.in index 6576b58f63..fb9df642e3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -19,13 +19,15 @@ TOP = @abs_top_srcdir@ # top_srcdir = @top_srcdir@ # abs_top_srcdir = @abs_top_srcdir@ # abs_top_builddir = @abs_top_builddir@ -LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ -LDFLAGS_MATH = @LDFLAGS_MATH@ -LDFLAGS_RPATH = @LDFLAGS_RPATH@ -LDFLAGS_READLINE = @LDFLAGS_READLINE@ -LDFLAGS_PTHREAD = @LDFLAGS_PTHREAD@ -LD = @LD@ -AR = @AR@ +LDFLAGS_ZLIB ?= @LDFLAGS_ZLIB@ +LDFLAGS_MATH ?= @LDFLAGS_MATH@ +LDFLAGS_RPATH ?= @LDFLAGS_RPATH@ +LDFLAGS_READLINE ?= @LDFLAGS_READLINE@ +LDFLAGS_PTHREAD ?= @LDFLAGS_PTHREAD@ +ENABLE_SHARED ?= @ENABLE_SHARED@ +HAVE_WASI_SDK ?= @HAVE_WASI_SDK@ +AR ?= @AR@ +CC ?= @CC@ # C Compiler and options for use in building executables that # will run on the platform that is doing the build. @@ -38,12 +40,8 @@ BCC = @BUILD_CC@ @BUILD_CFLAGS@ # are provide so that these aspects of the build process can be changed # on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" # -CC = @CC@ -CFLAGS ?= @CFLAGS@ +CFLAGS ?= @CFLAGS@ @SH_CFLAGS@ CPPFLAGS ?= @CPPFLAGS@ -@if SH_CFLAGS -CFLAGS += @SH_CFLAGS@ -@endif # CFLAGS_stdio3 ==> for sqlite3_stdio.h CFLAGS_stdio3 := -I${TOP}/ext/misc TCC = ${CC} ${CFLAGS} @@ -91,7 +89,8 @@ CFLAGS_readline = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ # those in $(LDFLAGS_libsqlite3) and include those flags for both # $(libsqlite3.SO) and any apps which directly link in either # sqlite3.o or its origin sources. -TLIBS = @LIBS@ $(LIBS) +LIBS += @LIBS@ +TLIBS = $(LIBS) # # JimTCL is part of the autosetup suite and is suitable for all @@ -103,10 +102,9 @@ TLIBS = @LIBS@ $(LIBS) # generators. # JIMSH = @srcdir@/jimsh -@if CFLAGS_JIMSH +CFLAGS_JIMSH ?= @CFLAGS_JIMSH@ $(JIMSH): $(TOP)/autosetup/jimsh0.c - $(BCC) -o $(JIMSH) @CFLAGS_JIMSH@ $< -@endif + $(BCC) -o $(JIMSH) $(CFLAGS_JIMSH) $< # BTCLSH is the tclsh-compatible app used for running various code # generators and other in-tree tools, as opposed to the TCL-based @@ -177,6 +175,13 @@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@ TCL_VERSION = @TCL_VERSION@ +TCLLIB_RPATH = @TCLLIB_RPATH@ +TCLLIBDIR = @TCLLIBDIR@ + +# EMCC_WRAPPER must refer to the genuine emcc binary, or a +# call-compatible wrapper, e.g. $(TOP)/tool/emcc.sh. If it's empty, +# build components requiring Emscripten will not build. +EMCC_WRAPPER = @EMCC_WRAPPER@ # Additional options when running tests using testrunner.tcl @@ -210,12 +215,12 @@ TLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) # Some standard variables and programs # -prefix = @prefix@ -exec_prefix = @exec_prefix@ -libdir = @libdir@ -pkgconfigdir = $(libdir)/pkgconfig -bindir = @bindir@ -includedir = @includedir@ +prefix ?= @prefix@ +exec_prefix ?= @exec_prefix@ +libdir ?= @libdir@ +pkgconfigdir ?= $(libdir)/pkgconfig +bindir ?= @bindir@ +includedir ?= @includedir@ INSTALL = @BIN_INSTALL@ INSTALL_noexec = $(INSTALL) -m 0644 # ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... @@ -230,11 +235,6 @@ install.pkgconfigdir = "$(DESTDIR)$(pkgconfigdir)" $(install.bindir) $(install.libdir) $(install.includedir) $(install.pkgconfigdir): $(INSTALL) -d $@ -#XX## libtool compile/link/install -#XX#TCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(TCOMPILE_EXTRAS) -#XX#TLINK = $(LIBTOOL) --mode=link $(TCC) $(TCOMPILE_EXTRAS) @LDFLAGS@ $(TLINK_EXTRAS) -#XX#LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL) - # TCOMPILE = generic target platform compiler invocation TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) # TLINK = compiler invocation for when the target will be an executable @@ -741,90 +741,83 @@ ST_OPT = -DSQLITE_OS_KV_OPTIONAL # In wasi-sdk builds, remove the CLI shell build from 'all'. -@if HAVE_WASI_SDK - SQLITE3_SHELL_TARGET = -@else - SQLITE3_SHELL_TARGET = sqlite3$(TEXE) -@endif - -@if HAVE_TCL -libtclsqlite3.SO = libtclsqlite3$(TDLL) -@else -libtclsqlite3.SO = -@endif +target_sqlite3_shell_1 = +target_sqlite3_shell_0 = sqlite3$(TEXE) +target_sqlite3_shell = $(target_sqlite3_shell_$(HAVE_WASI_SDK)) # # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. # -all: sqlite3.h sqlite3.c shell.c $(SQLITE3_SHELL_TARGET) +all: sqlite3.h sqlite3.c shell.c $(target_sqlite3_shell) # Re-run $(TOP)/configure with the same args invoked to produce this # makefile. # -AUTOREMAKE = @SQLITE_AUTOREMAKE@ +AS_AUTOREMAKE = @SQLITE_AUTOREMAKE@ Makefile: $(TOP)/Makefile.in $(AS_AUTO_DEF) - $(AUTOREMAKE) + $(AS_AUTOREMAKE) @touch $@ sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF) - $(AUTOREMAKE) + $(AS_AUTOREMAKE) @touch $@ install-pc: sqlite3.pc $(install.pkgconfigdir) $(INSTALL_noexec) sqlite3.pc $(install.pkgconfigdir) install: install-pc sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) - $(AUTOREMAKE) + $(AS_AUTOREMAKE) @touch $@ -libsqlite3.SO = libsqlite3$(TDLL) libsqlite3.LIB = libsqlite3$(TLIB) + +$(libsqlite3.LIB): $(LIBOBJ) + $(AR) crs $@ $(LIBOBJ) +lib: $(libsqlite3.LIB) +all: lib + # LDFLAGS_libsqlite3 should be used with any target which either # results in building libsqlite3.so, compiles sqlite3.c directly, or # links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these # flags are for the target build platform, not necessarily localhost. # i.e. it should be used with $(TCC) or $(TLINK) but not $(BCC). LDFLAGS_libsqlite3 = \ - $(LDFLAGS_RPATH) @LIBS@ $(LIBS) $(LDFLAGS_PTHREAD) \ + $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_PTHREAD) \ $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) -@if ENABLE_SHARED +libsqlite3.SO = libsqlite3$(TDLL) +target_libsqlite3_so_0 = +target_libsqlite3_so_1 = $(libsqlite3.SO) +target_libsqlite3_so = $(target_libsqlite3_so_$(ENABLE_SHARED)) + $(libsqlite3.SO): $(LIBOBJ) + @if [ "x1" != "x$(ENABLE_SHARED)" ]; then echo "Shared lib build is disabled." 1>&2; exit 1; fi $(TLINK_shared) -o $@ \ $(LIBOBJ) $(TLIBS) $(LDFLAGS_libsqlite3) -so: $(libsqlite3.SO) +so: $(target_libsqlite3_so) all: so -@else -$(libsqlite3.SO): - @echo "Build of $@ was explicitly disabled."; exit 1 -@endif -$(libsqlite3.LIB): $(LIBOBJ) - $(AR) crs $@ $(LIBOBJ) -lib: $(libsqlite3.LIB) -all: lib - -# Install the $(libsqlite3.SO) as $(libsqlite3.SO).@RELEASE@ and +# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(RELEASE) and # create symlinks which point to it. Do we really need all of this # hoop-jumping? Can we not simply install the .so as-is to # libsqlite3.so (without the versioned bits)? # # The historical SQLite build always used a version number of 0.8.6 -# for reasons lost to history. +# for reasons lost to history but having something to do with libtool +# (which is not longer used in this tree). # -install-so: $(install.libdir) $(libsqlite3.SO) - $(INSTALL) $(libsqlite3.SO) $(install.libdir) +install-so-1: $(install.libdir) $(libsqlite3.SO) + $(INSTALL) $(libsqlite3.SO) $(install.libdir); \ cd $(install.libdir); \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).@RELEASE@; \ - mv $(libsqlite3.SO) $(libsqlite3.SO).@RELEASE@; \ - ln -s $(libsqlite3.SO).@RELEASE@ $(libsqlite3.SO).3; \ + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(RELEASE); \ + mv $(libsqlite3.SO) $(libsqlite3.SO).$(RELEASE); \ + ln -s $(libsqlite3.SO).$(RELEASE) $(libsqlite3.SO).3; \ ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) -@if ENABLE_SHARED -install: install-so -@endif +install-so-0: +install: install-so-$(ENABLE_SHARED) # Install $(libsqlite3.LIB) # @@ -838,26 +831,31 @@ install-includes: sqlite3.h $(install.includedir) $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install.includedir) install: install-includes -@if HAVE_TCL +# libtclsqlite3... +# +libtclsqlite3.SO = libtclsqlite3$(TDLL) +target_libtclsqlite3_1 = $(libtclsqlite3.SO) +target_libtclsqlite3_0 = +target_libtclsqlite3 = $(target_libtclsqlite3_$(HAVE_TCL)) $(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) $(TLINK_shared) -o $@ tclsqlite.o \ $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS_libsqlite3) \ - $(libsqlite3.LIB) @TCLLIB_RPATH@ -libtcl: $(libtclsqlite3.SO) + $(libsqlite3.LIB) $(TCLLIB_RPATH) -all: $(libtclsqlite3.SO) +libtcl: $(target_libtclsqlite3) + +all: $(target_libtclsqlite3) pkgIndex.tcl: echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ -@if TCLLIBDIR -install.tcldir = "$(DESTDIR)@TCLLIBDIR@" -install-tcl: install-lib $(libtclsqlite3.SO) pkgIndex.tcl +install.tcldir = "$(DESTDIR)$(TCLLIBDIR)" +install-tcl: install-lib $(target_libtclsqlite3) pkgIndex.tcl + @if [ "x$(DESTDIR)" = "x$(install.tcldir)" ]; then echo "TCLLIBDIR is not set." 1>&2; exit 1; fi $(INSTALL) -d $(install.tcldir) $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) install: install-tcl -@endif tclsqlite3.c: sqlite3.c echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c @@ -892,21 +890,15 @@ tclextension-uninstall: tclextension-list: $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info -# end of @if HAVE_TCL -@endif - sqlite3$(TEXE): shell.c sqlite3.c $(TCC) $(CFLAGS_readline) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ $(LDFLAGS_libsqlite3) $(LDFLAGS_READLINE) -cli: sqlite3$(TEXE) -@if !HAVE_WASI_SDK -all: cli -@endif -install-cli: sqlite3$(TEXT) $(install.bindir) +install-cli-0: sqlite3$(TEXT) $(install.bindir) $(INSTALL) -s sqlite3$(TEXT) $(install.bindir) -install: install-cli +install-cli-1: +install: install-cli-$(HAVE_WASI_SDK) sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite3) @@ -1045,11 +1037,10 @@ has_tclsh85: touch has_tclsh85 has_tclconfig: -@if !TCL_CONFIG_SH - @echo 'ERROR: Requires access to "tclConfig.sh" which "configure" was not able to locate'; exit 1; -@else + @if [ x = "x$(TCL_CONFIG_SH)" ]; then + echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ + fi touch has_tclconfig -@endif # # This target creates a directory named "tsrc" and fills it with @@ -1819,13 +1810,12 @@ sqlite3.dll: $(LIBOBJ) sqlite3.def # # Fiddle app # -@if EMCC_WRAPPER fiddle: sqlite3.c shell.c + @if [ x = "x$(EMCC_WRAPPER)" ]; then \ + echo "Emscripten's emcc not found. Cannot build fiddle." 1&>2; \ + exit 1; \ + fi make -C ext/wasm fiddle emcc_opt=-Os -@else -fiddle: - @echo "Configure script did not find emcc, so fiddle build is not available." 2>&1; exit 1 -@endif # # Spell-checking for source comments diff --git a/auto.def b/auto.def index ee958ec23f..c93aceef49 100644 --- a/auto.def +++ b/auto.def @@ -82,8 +82,7 @@ define RELEASE $RELEASE puts "RELEASE = $RELEASE" puts "VERSION = $VERSION" -define SQLITE_AUTOREMAKE cd -define-append SQLITE_AUTOREMAKE $autosetup(srcdir) && $top_srcdir/configure {*}$autosetup(argv) +define-append SQLITE_AUTOREMAKE cd $autosetup(srcdir) && $top_srcdir/configure {*}$autosetup(argv) set outOfTreeBuild 0 if {![file exists sqlite3.pc.in]} { @@ -188,9 +187,14 @@ if {"" eq [hwaci-bin-define install]} { msg-result "Cannot find install binary, so 'make install' will not work." # Reminder: we historically have ./install-sh in the source tree. # Can we not simply use that? + # # define BIN_INSTALL "$top_srcdir/install-sh" - # Nope: it MOVES its source files over the target, which - # break the installation in some cases. + # + # Nope: it MOVES its source files over the target, which breaks the + # installation in some cases. It's easy to hack to copy instead of + # mv (simply replace the instcmd=... bit) but that won't retain the + # source timestamp and permissions unless we use cp's -p flag, which + # may not be portable enough. } @@ -222,6 +226,7 @@ define BUILD_CFLAGS [get-env CFLAGS {-g}] # # It's unclear whether we can actually get away with making these # changes to the autosetup environment. +define HAVE_WASI_SDK 0 if {1} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" @@ -319,7 +324,7 @@ msg-checking "Debug build? " hwaci-if-opt-truthy with-debug { define SQLITE_DEBUG 1 - define TARGET_DEBUG {-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} + define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} msg-result yes } { define TARGET_DEBUG {-DNDEBUG} @@ -848,6 +853,11 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available }; # JimTCL +if {"" eq [get-define CFLAGS_JIMSH]} { + define USE_OWN_JIMSH 0 +} else { + define USE_OWN_JIMSH 1 +} ######################################################################## # Determine proper rpath-handling flags diff --git a/main.mk b/main.mk index 3c2c379a39..fa9f7cce1a 100644 --- a/main.mk +++ b/main.mk @@ -1,8 +1,14 @@ - ############################################################################### -# The following macros should be defined before this script is +# This is the main makefile for sqlite. It expects to be included from +# a higher-level makefile which configures any dynamic state needed by +# this one. +# +# The following variables must be defined before this script is # invoked: # +#XX# FIXME: the list of vars from the historical main.mk is dated and +#XX# needs to be updated for autosetup. +# # TOP The toplevel directory of the source tree. This is the # directory that contains this "Makefile.in" and the # "configure.in" script. @@ -10,1159 +16,20 @@ # BCC C Compiler and options for use in building executables that # will run on the platform that is doing the build. # -# THREADLIB Specify any extra linker options needed to make the library -# thread safe -# -# LIBS Extra libraries options -# -# OPTS Extra compiler command-line options. -# -# EXE The suffix to add to executable files. ".exe" for windows -# and "" for Unix. -# # TCC C Compiler and options for use in building executables that # will run on the target platform. This is usually the same # as BCC, unless you are cross-compiling. # # AR Tools used to build a static library. -# RANLIB # -# TCL_FLAGS Extra compiler options needed for programs that use the -# TCL library. +# BEXE File extension for executables on the build platform. ".exe" +# for Windows and "" everywhere else. # -# LIBTCL Linker options needed to link against the TCL library. +# TEXE File extension for executables on the target platform. ".exe" +# for Windows and "" everywhere else. # -# READLINE_FLAGS Compiler options needed for programs that use the -# readline() library. +# ... and many, many more ... # -# LIBREADLINE Linker options needed by programs using readline() must -# link against. -# -# Once the macros above are defined, the rest of this make script will -# build the SQLite library and testing tools. +# Once the variables above are defined, the rest of this make script +# will build the SQLite library and testing tools. ################################################################################ - -# If OPTIONS... is specified on the command-line, append its value to OPTS -# -OPTS += $(OPTIONS) - -# This is how we compile -# -TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) -TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3 -TCCX += -I$(TOP)/ext/async -I$(TOP)/ext/userauth -TCCX += -I$(TOP)/ext/session -TCCX += -I$(TOP)/ext/fts5 -THREADLIB += $(LIBS) - -# Object files for the SQLite library. -# -LIBOBJ+= vdbe.o parse.o \ - alter.o analyze.o attach.o auth.o \ - backup.o bitvec.o btmutex.o btree.o build.o \ - callback.o complete.o ctime.o \ - date.o dbpage.o dbstat.o delete.o expr.o \ - fault.o fkey.o \ - fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \ - fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \ - fts3_tokenize_vtab.o \ - fts3_unicode.o fts3_unicode2.o \ - fts3_write.o fts5.o func.o global.o hash.o \ - icu.o insert.o json.o legacy.o loadext.o \ - main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \ - memdb.o memjournal.o \ - mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \ - notify.o opcodes.o os.o os_kv.o os_unix.o os_win.o \ - pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \ - random.o resolve.o rowset.o rtree.o \ - select.o sqlite3rbu.o status.o stmt.o \ - table.o threads.o tokenize.o treeview.o trigger.o \ - update.o upsert.o userauth.o util.o vacuum.o \ - vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ - vdbetrace.o vdbevtab.o \ - wal.o walker.o where.o wherecode.o whereexpr.o \ - utf.o vtab.o window.o - -LIBOBJ += sqlite3session.o - -# All of the source code files. -# -SRC = \ - $(TOP)/src/alter.c \ - $(TOP)/src/analyze.c \ - $(TOP)/src/attach.c \ - $(TOP)/src/auth.c \ - $(TOP)/src/backup.c \ - $(TOP)/src/bitvec.c \ - $(TOP)/src/btmutex.c \ - $(TOP)/src/btree.c \ - $(TOP)/src/btree.h \ - $(TOP)/src/btreeInt.h \ - $(TOP)/src/build.c \ - $(TOP)/src/callback.c \ - $(TOP)/src/complete.c \ - $(TOP)/src/ctime.c \ - $(TOP)/src/date.c \ - $(TOP)/src/dbpage.c \ - $(TOP)/src/dbstat.c \ - $(TOP)/src/delete.c \ - $(TOP)/src/expr.c \ - $(TOP)/src/fault.c \ - $(TOP)/src/fkey.c \ - $(TOP)/src/func.c \ - $(TOP)/src/global.c \ - $(TOP)/src/hash.c \ - $(TOP)/src/hash.h \ - $(TOP)/src/hwtime.h \ - $(TOP)/src/insert.c \ - $(TOP)/src/json.c \ - $(TOP)/src/legacy.c \ - $(TOP)/src/loadext.c \ - $(TOP)/src/main.c \ - $(TOP)/src/malloc.c \ - $(TOP)/src/mem0.c \ - $(TOP)/src/mem1.c \ - $(TOP)/src/mem2.c \ - $(TOP)/src/mem3.c \ - $(TOP)/src/mem5.c \ - $(TOP)/src/memdb.c \ - $(TOP)/src/memjournal.c \ - $(TOP)/src/msvc.h \ - $(TOP)/src/mutex.c \ - $(TOP)/src/mutex.h \ - $(TOP)/src/mutex_noop.c \ - $(TOP)/src/mutex_unix.c \ - $(TOP)/src/mutex_w32.c \ - $(TOP)/src/notify.c \ - $(TOP)/src/os.c \ - $(TOP)/src/os.h \ - $(TOP)/src/os_common.h \ - $(TOP)/src/os_setup.h \ - $(TOP)/src/os_kv.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/os_win.h \ - $(TOP)/src/pager.c \ - $(TOP)/src/pager.h \ - $(TOP)/src/parse.y \ - $(TOP)/src/pcache.c \ - $(TOP)/src/pcache.h \ - $(TOP)/src/pcache1.c \ - $(TOP)/src/pragma.c \ - $(TOP)/src/pragma.h \ - $(TOP)/src/prepare.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/random.c \ - $(TOP)/src/resolve.c \ - $(TOP)/src/rowset.c \ - $(TOP)/src/select.c \ - $(TOP)/src/status.c \ - $(TOP)/src/shell.c.in \ - $(TOP)/src/sqlite.h.in \ - $(TOP)/src/sqlite3ext.h \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/sqliteLimit.h \ - $(TOP)/src/table.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/src/threads.c \ - $(TOP)/src/tokenize.c \ - $(TOP)/src/treeview.c \ - $(TOP)/src/trigger.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/update.c \ - $(TOP)/src/upsert.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vacuum.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/vdbe.h \ - $(TOP)/src/vdbeapi.c \ - $(TOP)/src/vdbeaux.c \ - $(TOP)/src/vdbeblob.c \ - $(TOP)/src/vdbemem.c \ - $(TOP)/src/vdbesort.c \ - $(TOP)/src/vdbetrace.c \ - $(TOP)/src/vdbevtab.c \ - $(TOP)/src/vdbeInt.h \ - $(TOP)/src/vtab.c \ - $(TOP)/src/vxworks.h \ - $(TOP)/src/wal.c \ - $(TOP)/src/wal.h \ - $(TOP)/src/walker.c \ - $(TOP)/src/where.c \ - $(TOP)/src/wherecode.c \ - $(TOP)/src/whereexpr.c \ - $(TOP)/src/whereInt.h \ - $(TOP)/src/window.c - -# Source code for extensions -# -SRC += \ - $(TOP)/ext/fts3/fts3.c \ - $(TOP)/ext/fts3/fts3.h \ - $(TOP)/ext/fts3/fts3Int.h \ - $(TOP)/ext/fts3/fts3_aux.c \ - $(TOP)/ext/fts3/fts3_expr.c \ - $(TOP)/ext/fts3/fts3_hash.c \ - $(TOP)/ext/fts3/fts3_hash.h \ - $(TOP)/ext/fts3/fts3_icu.c \ - $(TOP)/ext/fts3/fts3_porter.c \ - $(TOP)/ext/fts3/fts3_snippet.c \ - $(TOP)/ext/fts3/fts3_tokenizer.h \ - $(TOP)/ext/fts3/fts3_tokenizer.c \ - $(TOP)/ext/fts3/fts3_tokenizer1.c \ - $(TOP)/ext/fts3/fts3_tokenize_vtab.c \ - $(TOP)/ext/fts3/fts3_unicode.c \ - $(TOP)/ext/fts3/fts3_unicode2.c \ - $(TOP)/ext/fts3/fts3_write.c -SRC += \ - $(TOP)/ext/icu/sqliteicu.h \ - $(TOP)/ext/icu/icu.c -SRC += \ - $(TOP)/ext/rtree/sqlite3rtree.h \ - $(TOP)/ext/rtree/rtree.h \ - $(TOP)/ext/rtree/rtree.c \ - $(TOP)/ext/rtree/geopoly.c -SRC += \ - $(TOP)/ext/session/sqlite3session.c \ - $(TOP)/ext/session/sqlite3session.h -SRC += \ - $(TOP)/ext/userauth/userauth.c \ - $(TOP)/ext/userauth/sqlite3userauth.h -SRC += \ - $(TOP)/ext/rbu/sqlite3rbu.c \ - $(TOP)/ext/rbu/sqlite3rbu.h -SRC += \ - $(TOP)/ext/misc/stmt.c - -# FTS5 things -# -FTS5_HDR = \ - $(TOP)/ext/fts5/fts5.h \ - $(TOP)/ext/fts5/fts5Int.h \ - fts5parse.h - -FTS5_SRC = \ - $(TOP)/ext/fts5/fts5_aux.c \ - $(TOP)/ext/fts5/fts5_buffer.c \ - $(TOP)/ext/fts5/fts5_main.c \ - $(TOP)/ext/fts5/fts5_config.c \ - $(TOP)/ext/fts5/fts5_expr.c \ - $(TOP)/ext/fts5/fts5_hash.c \ - $(TOP)/ext/fts5/fts5_index.c \ - fts5parse.c \ - $(TOP)/ext/fts5/fts5_storage.c \ - $(TOP)/ext/fts5/fts5_tokenize.c \ - $(TOP)/ext/fts5/fts5_unicode2.c \ - $(TOP)/ext/fts5/fts5_varint.c \ - $(TOP)/ext/fts5/fts5_vocab.c \ - -LSM1_SRC = \ - $(TOP)/ext/lsm1/lsm.h \ - $(TOP)/ext/lsm1/lsmInt.h \ - $(TOP)/ext/lsm1/lsm_ckpt.c \ - $(TOP)/ext/lsm1/lsm_file.c \ - $(TOP)/ext/lsm1/lsm_log.c \ - $(TOP)/ext/lsm1/lsm_main.c \ - $(TOP)/ext/lsm1/lsm_mem.c \ - $(TOP)/ext/lsm1/lsm_mutex.c \ - $(TOP)/ext/lsm1/lsm_shared.c \ - $(TOP)/ext/lsm1/lsm_sorted.c \ - $(TOP)/ext/lsm1/lsm_str.c \ - $(TOP)/ext/lsm1/lsm_tree.c \ - $(TOP)/ext/lsm1/lsm_unix.c \ - $(TOP)/ext/lsm1/lsm_varint.c \ - $(TOP)/ext/lsm1/lsm_vtab.c \ - $(TOP)/ext/lsm1/lsm_win32.c - - -# Generated source code files -# -SRC += \ - keywordhash.h \ - opcodes.c \ - opcodes.h \ - parse.c \ - parse.h \ - shell.c \ - sqlite3.h - - -# Source code to the test files. -# -TESTSRC = \ - $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/test_expert.c \ - $(TOP)/ext/fts3/fts3_term.c \ - $(TOP)/ext/fts3/fts3_test.c \ - $(TOP)/ext/rbu/test_rbu.c \ - $(TOP)/src/test1.c \ - $(TOP)/src/test2.c \ - $(TOP)/src/test3.c \ - $(TOP)/src/test4.c \ - $(TOP)/src/test5.c \ - $(TOP)/src/test6.c \ - $(TOP)/src/test8.c \ - $(TOP)/src/test9.c \ - $(TOP)/src/test_autoext.c \ - $(TOP)/src/test_async.c \ - $(TOP)/src/test_backup.c \ - $(TOP)/src/test_bestindex.c \ - $(TOP)/src/test_blob.c \ - $(TOP)/src/test_btree.c \ - $(TOP)/src/test_config.c \ - $(TOP)/src/test_delete.c \ - $(TOP)/src/test_demovfs.c \ - $(TOP)/src/test_devsym.c \ - $(TOP)/src/test_fs.c \ - $(TOP)/src/test_func.c \ - $(TOP)/src/test_hexio.c \ - $(TOP)/src/test_init.c \ - $(TOP)/src/test_intarray.c \ - $(TOP)/src/test_journal.c \ - $(TOP)/src/test_malloc.c \ - $(TOP)/src/test_md5.c \ - $(TOP)/src/test_multiplex.c \ - $(TOP)/src/test_mutex.c \ - $(TOP)/src/test_onefile.c \ - $(TOP)/src/test_osinst.c \ - $(TOP)/src/test_pcache.c \ - $(TOP)/src/test_quota.c \ - $(TOP)/src/test_rtree.c \ - $(TOP)/src/test_schema.c \ - $(TOP)/src/test_sqllog.c \ - $(TOP)/src/test_superlock.c \ - $(TOP)/src/test_syscall.c \ - $(TOP)/src/test_tclsh.c \ - $(TOP)/src/test_tclvar.c \ - $(TOP)/src/test_thread.c \ - $(TOP)/src/test_vdbecov.c \ - $(TOP)/src/test_vfs.c \ - $(TOP)/src/test_windirent.c \ - $(TOP)/src/test_window.c \ - $(TOP)/src/test_wsd.c - -# Extensions to be statically loaded. -# -TESTSRC += \ - $(TOP)/ext/misc/amatch.c \ - $(TOP)/ext/misc/appendvfs.c \ - $(TOP)/ext/misc/basexx.c \ - $(TOP)/ext/misc/carray.c \ - $(TOP)/ext/misc/cksumvfs.c \ - $(TOP)/ext/misc/closure.c \ - $(TOP)/ext/misc/csv.c \ - $(TOP)/ext/misc/decimal.c \ - $(TOP)/ext/misc/eval.c \ - $(TOP)/ext/misc/explain.c \ - $(TOP)/ext/misc/fileio.c \ - $(TOP)/ext/misc/fuzzer.c \ - $(TOP)/ext/misc/ieee754.c \ - $(TOP)/ext/misc/mmapwarm.c \ - $(TOP)/ext/misc/nextchar.c \ - $(TOP)/ext/misc/normalize.c \ - $(TOP)/ext/misc/percentile.c \ - $(TOP)/ext/misc/prefixes.c \ - $(TOP)/ext/misc/qpvtab.c \ - $(TOP)/ext/misc/randomjson.c \ - $(TOP)/ext/misc/regexp.c \ - $(TOP)/ext/misc/remember.c \ - $(TOP)/ext/misc/series.c \ - $(TOP)/ext/misc/spellfix.c \ - $(TOP)/ext/misc/stmtrand.c \ - $(TOP)/ext/misc/totype.c \ - $(TOP)/ext/misc/unionvtab.c \ - $(TOP)/ext/misc/wholenumber.c \ - $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/fts5/fts5_tcl.c \ - $(TOP)/ext/fts5/fts5_test_mi.c \ - $(TOP)/ext/fts5/fts5_test_tok.c \ - $(TOP)/ext/rtree/test_rtreedoc.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/test_recover.c \ - $(TOP)/ext/intck/test_intck.c \ - $(TOP)/ext/intck/sqlite3intck.c - - -#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c - -TESTSRC2 = \ - $(TOP)/src/attach.c \ - $(TOP)/src/backup.c \ - $(TOP)/src/btree.c \ - $(TOP)/src/build.c \ - $(TOP)/src/date.c \ - $(TOP)/src/dbpage.c \ - $(TOP)/src/dbstat.c \ - $(TOP)/src/expr.c \ - $(TOP)/src/func.c \ - $(TOP)/src/global.c \ - $(TOP)/src/insert.c \ - $(TOP)/src/wal.c \ - $(TOP)/src/main.c \ - $(TOP)/src/mem5.c \ - $(TOP)/src/os.c \ - $(TOP)/src/os_kv.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/pager.c \ - $(TOP)/src/pragma.c \ - $(TOP)/src/prepare.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/random.c \ - $(TOP)/src/pcache.c \ - $(TOP)/src/pcache1.c \ - $(TOP)/src/select.c \ - $(TOP)/src/threads.c \ - $(TOP)/src/tokenize.c \ - $(TOP)/src/treeview.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vdbeapi.c \ - $(TOP)/src/vdbeaux.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/vdbemem.c \ - $(TOP)/src/vdbevtab.c \ - $(TOP)/src/where.c \ - $(TOP)/src/wherecode.c \ - $(TOP)/src/whereexpr.c \ - parse.c \ - $(TOP)/ext/fts3/fts3.c \ - $(TOP)/ext/fts3/fts3_aux.c \ - $(TOP)/ext/fts3/fts3_expr.c \ - $(TOP)/ext/fts3/fts3_tokenizer.c \ - $(TOP)/ext/fts3/fts3_write.c \ - $(TOP)/ext/async/sqlite3async.c \ - $(TOP)/ext/misc/stmt.c \ - $(TOP)/ext/session/sqlite3session.c \ - $(TOP)/ext/session/test_session.c \ - fts5.c - -# Header files used by all library source files. -# -HDR = \ - $(TOP)/src/btree.h \ - $(TOP)/src/btreeInt.h \ - $(TOP)/src/hash.h \ - $(TOP)/src/hwtime.h \ - keywordhash.h \ - $(TOP)/src/msvc.h \ - $(TOP)/src/mutex.h \ - opcodes.h \ - $(TOP)/src/os.h \ - $(TOP)/src/os_common.h \ - $(TOP)/src/os_setup.h \ - $(TOP)/src/os_win.h \ - $(TOP)/src/pager.h \ - $(TOP)/src/pcache.h \ - parse.h \ - $(TOP)/src/pragma.h \ - sqlite3.h \ - $(TOP)/src/sqlite3ext.h \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/sqliteLimit.h \ - $(TOP)/src/vdbe.h \ - $(TOP)/src/vdbeInt.h \ - $(TOP)/src/vxworks.h \ - $(TOP)/src/whereInt.h - -# Header files used by extensions -# -EXTHDR += \ - $(TOP)/ext/fts3/fts3.h \ - $(TOP)/ext/fts3/fts3Int.h \ - $(TOP)/ext/fts3/fts3_hash.h \ - $(TOP)/ext/fts3/fts3_tokenizer.h -EXTHDR += \ - $(TOP)/ext/rtree/rtree.h \ - $(TOP)/ext/rtree/geopoly.c -EXTHDR += \ - $(TOP)/ext/icu/sqliteicu.h -EXTHDR += \ - $(TOP)/ext/fts5/fts5Int.h \ - fts5parse.h \ - $(TOP)/ext/fts5/fts5.h -EXTHDR += \ - $(TOP)/ext/userauth/sqlite3userauth.h - -# executables needed for testing -# -TESTPROGS = \ - testfixture$(EXE) \ - sqlite3$(EXE) \ - sqlite3_analyzer$(EXE) \ - sqlite3_checker$(EXE) \ - sqldiff$(EXE) \ - dbhash$(EXE) \ - sqltclsh$(EXE) - -# Databases containing fuzzer test cases -# -FUZZDATA = \ - $(TOP)/test/fuzzdata1.db \ - $(TOP)/test/fuzzdata2.db \ - $(TOP)/test/fuzzdata3.db \ - $(TOP)/test/fuzzdata4.db \ - $(TOP)/test/fuzzdata5.db \ - $(TOP)/test/fuzzdata6.db \ - $(TOP)/test/fuzzdata7.db \ - $(TOP)/test/fuzzdata8.db - -# Standard options to testfixture -# -TESTOPTS = --verbose=file --output=test-out.txt - -# Extra compiler options for various shell tools -# -SHELL_OPT += -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -SHELL_OPT += -DSQLITE_ENABLE_RTREE -SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS -SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB -SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB -SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB -SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB -SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC -FUZZCHECK_OPT += -I$(TOP)/test -FUZZCHECK_OPT += -I$(TOP)/ext/recover -FUZZCHECK_OPT += -DSQLITE_ENABLE_MEMSYS5 -FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 -FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000 -FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4 -FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE -FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY -FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB -FUZZCHECK_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB -FUZZCHECK_OPT += -DSQLITE_STRICT_SUBTYPE=1 -FUZZCHECK_OPT += -DSQLITE_STATIC_RANDOMJSON -FUZZSRC += $(TOP)/test/fuzzcheck.c -FUZZSRC += $(TOP)/test/ossfuzz.c -FUZZSRC += $(TOP)/test/vt02.c -FUZZSRC += $(TOP)/test/fuzzinvariants.c -FUZZSRC += $(TOP)/ext/recover/dbdata.c -FUZZSRC += $(TOP)/ext/recover/sqlite3recover.c -FUZZSRC += $(TOP)/ext/misc/percentile.c -FUZZSRC += $(TOP)/ext/misc/randomjson.c -DBFUZZ_OPT = -KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ -ST_OPT = -DSQLITE_THREADSAFE=0 - -# This is the default Makefile target. The objects listed here -# are what get build when you type just "make" with no arguments. -# -all: sqlite3.h sqlite3ext.h libsqlite3.a sqlite3$(EXE) - -libsqlite3.a: sqlite3.h $(LIBOBJ) - $(AR) libsqlite3.a $(LIBOBJ) - $(RANLIB) libsqlite3.a - -sqlite3$(EXE): sqlite3.h libsqlite3.a shell.c - $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \ - shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) - -sqldiff$(EXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.c sqlite3.h - $(TCCX) -I$(TOP)/ext/misc -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ - $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB) - -dbhash$(EXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h - $(TCCX) -o dbhash$(EXE) -DSQLITE_THREADSAFE=0 \ - $(TOP)/tool/dbhash.c sqlite3.c $(TLIBS) $(THREADLIB) - -RSYNC_SRC = \ - $(TOP)/tool/sqlite3_rsync.c \ - sqlite3.c - -RSYNC_OPT = \ - -DSQLITE_ENABLE_DBPAGE_VTAB \ - -DSQLITE_THREADSAFE=0 \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_OMIT_DEPRECATED - -sqlite3_rsync$(EXE): $(RSYNC_SRC) - $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(TLIBS) - -scrub$(EXE): $(TOP)/ext/misc/scrub.c sqlite3.o - $(TCC) -I. -DSCRUB_STANDALONE -o scrub$(EXE) $(TOP)/ext/misc/scrub.c sqlite3.o $(THREADLIB) - -srcck1$(EXE): $(TOP)/tool/srcck1.c - $(BCC) -o srcck1$(EXE) $(TOP)/tool/srcck1.c - -sourcetest: srcck1$(EXE) sqlite3.c - ./srcck1 sqlite3.c - -src-verify: $(TOP)/tool/src-verify.c - $(BCC) -o src-verify$(EXE) $(TOP)/tool/src-verify.c - -verify-source: ./src-verify - ./src-verify $(TOP) - -fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h - $(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ - $(FUZZERSHELL_OPT) $(TOP)/tool/fuzzershell.c sqlite3.c \ - $(TLIBS) $(THREADLIB) - -dbfuzz$(EXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h - $(TCCX) -o dbfuzz$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ - $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c \ - $(TLIBS) $(THREADLIB) - -DBFUZZ2_OPTS = \ - -DSQLITE_THREADSAFE=0 \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_DEBUG \ - -DSQLITE_ENABLE_DBSTAT_VTAB \ - -DSQLITE_ENABLE_BYTECODE_VTAB \ - -DSQLITE_ENABLE_RTREE \ - -DSQLITE_ENABLE_FTS4 \ - -DSQLITE_ENABLE_FTS5 - -dbfuzz2$(EXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - $(TCCX) -I. -g -O0 -DSTANDALONE -o dbfuzz2$(EXE) \ - $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) $(THREADLIB) - -fuzzcheck$(EXE): $(FUZZSRC) sqlite3.c sqlite3.h $(FUZZDEP) - $(TCCX) -o $@ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ - $(FUZZSRC) sqlite3.c $(TLIBS) $(THREADLIB) - -fuzzcheck-asan$(EXE): $(FUZZSRC) sqlite3.c sqlite3.h $(FUZZDEP) - $(TCCX) -fsanitize=address -o $W -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ - $(FUZZSRC) sqlite3.c $(TLIBS) $(THREADLIB) - -fuzzcheck-ubsan$(EXE): $(FUZZSRC) sqlite3.c sqlite3.h $(FUZZDEP) - $(TCCX) -fsanitize=undefined -o $@ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ - $(FUZZSRC) sqlite3.c $(TLIBS) $(THREADLIB) - -ossshell$(EXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h - $(TCCX) -o ossshell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \ - $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c $(TLIBS) $(THREADLIB) - -sessionfuzz$(EXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h - $(TCC) -o sessionfuzz$(EXE) $(TOP)/test/sessionfuzz.c -lz $(TLIBS) $(THREADLIB) - -mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c - $(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ - $(TLIBS) $(THREADLIB) - -MPTEST1=./mptester$(EXE) mptest1.db $(TOP)/mptest/crash01.test --repeat 20 -MPTEST2=./mptester$(EXE) mptest2.db $(TOP)/mptest/multiwrite01.test --repeat 20 -mptest: mptester$(EXE) - $(MPTEST1) --journalmode DELETE - $(MPTEST2) --journalmode WAL - $(MPTEST1) --journalmode WAL - $(MPTEST2) --journalmode PERSIST - $(MPTEST1) --journalmode PERSIST - $(MPTEST2) --journalmode TRUNCATE - $(MPTEST1) --journalmode TRUNCATE - $(MPTEST2) --journalmode DELETE - -sqlite3.o: sqlite3.c - $(TCCX) -I. -c sqlite3.c - -# This target creates a directory named "tsrc" and fills it with -# copies of all of the C source code and header files needed to -# build on the target system. Some of the C source code and header -# files are automatically generated. This target takes care of -# all that automatic generation. -# -target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c - rm -rf tsrc - mkdir tsrc - cp -f $(SRC) tsrc - rm tsrc/sqlite.h.in tsrc/parse.y - tclsh $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new - mv vdbe.new tsrc/vdbe.c - cp fts5.c fts5.h tsrc - touch target_source - -sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl src-verify - tclsh $(TOP)/tool/mksqlite3c.tcl $(EXTRA_SRC) - cp tsrc/sqlite3ext.h . - cp $(TOP)/ext/session/sqlite3session.h . - 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 - -sqlite3ext.h: target_source - cp tsrc/sqlite3ext.h . - -sqlite3.c-debug: target_source $(TOP)/tool/mksqlite3c.tcl src-verify - tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros=1 $(EXTRA_SRC) - echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c - cat sqlite3.c >>tclsqlite3.c - echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c - echo '#line 1 "tclsqlite.c"' >>tclsqlite3.c - cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c - -sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl - tclsh $(TOP)/tool/split-sqlite3c.tcl - -# Rules to build the LEMON compiler generator -# -lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c - $(BCC) -o lemon $(TOP)/tool/lemon.c - cp $(TOP)/tool/lempar.c . - -# A tool to generate the source-id -# -mksourceid: $(TOP)/tool/mksourceid.c - $(BCC) -o mksourceid $(TOP)/tool/mksourceid.c - -# Rules to build individual *.o files from generated *.c files. This -# applies to: -# -# parse.o -# opcodes.o -# -%.o: %.c $(HDR) - $(TCCX) -c $< - -# Rules to build individual *.o files from files in the src directory. -# -%.o: $(TOP)/src/%.c $(HDR) - $(TCCX) -c $< - -tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) - $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c - - - -# Rules to build opcodes.c and opcodes.h -# -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl - tclsh $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c - -opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl - cat parse.h $(TOP)/src/vdbe.c | tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h - -# Rules to build parse.c and parse.h - the outputs of lemon. -# -parse.h: parse.c - -parse.c: $(TOP)/src/parse.y lemon - cp $(TOP)/src/parse.y . - ./lemon -s $(OPTS) parse.y - -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h - tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h - -sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION - echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ - echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ - cat $(TOP)/VERSION | tclsh $(TOP)/tool/replace.tcl exact . , >>$@ - echo '#endif' >>sqlite3rc.h - -keywordhash.h: $(TOP)/tool/mkkeywordhash.c - $(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c - ./mkkeywordhash >keywordhash.h - -# Source and header files that shell.c depends on -SHELL_DEP = \ - $(TOP)/src/shell.c.in \ - $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/sqlite3expert.h \ - $(TOP)/ext/intck/sqlite3intck.c \ - $(TOP)/ext/intck/sqlite3intck.h \ - $(TOP)/ext/misc/appendvfs.c \ - $(TOP)/ext/misc/base64.c \ - $(TOP)/ext/misc/base85.c \ - $(TOP)/ext/misc/completion.c \ - $(TOP)/ext/misc/decimal.c \ - $(TOP)/ext/misc/fileio.c \ - $(TOP)/ext/misc/ieee754.c \ - $(TOP)/ext/misc/memtrace.c \ - $(TOP)/ext/misc/pcachetrace.c \ - $(TOP)/ext/misc/percentile.c \ - $(TOP)/ext/misc/regexp.c \ - $(TOP)/ext/misc/series.c \ - $(TOP)/ext/misc/sha1.c \ - $(TOP)/ext/misc/shathree.c \ - $(TOP)/ext/misc/sqlar.c \ - $(TOP)/ext/misc/sqlite3_stdio.c \ - $(TOP)/ext/misc/sqlite3_stdio.h \ - $(TOP)/ext/misc/uint.c \ - $(TOP)/ext/misc/vfstrace.c \ - $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/sqlite3recover.h \ - $(TOP)/src/test_windirent.c \ - $(TOP)/src/test_windirent.h - -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl - tclsh $(TOP)/tool/mkshellc.tcl >shell.c - - - -# Rules to build the extension objects. -# -icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c - -fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c - -fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c - -fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c - -fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c - -fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c - -fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c - -fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c - -fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c - -fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c - -fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c - -fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c - -fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c - -fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c - -fts5.o: fts5.c sqlite3ext.h sqlite3.h - $(TCCX) -DSQLITE_CORE -c fts5.c - -stmt.o: $(TOP)/ext/misc/stmt.c sqlite3ext.h sqlite3.h - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c - -rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c - - - -fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon - cp $(TOP)/ext/fts5/fts5parse.y . - rm -f fts5parse.h - ./lemon $(OPTS) fts5parse.y - -fts5parse.h: fts5parse.c - -fts5.c: $(FTS5_SRC) $(FTS5_HDR) - tclsh $(TOP)/ext/fts5/tool/mkfts5c.tcl - cp $(TOP)/ext/fts5/fts5.h . - -lsm1.c: $(LSM1_SRC) - tclsh $(TOP)/ext/lsm1/tool/mklsm1c.tcl - cp $(TOP)/ext/lsm1/lsm.h . - -userauth.o: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c - -sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c - -sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) - $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c - -# Rules for building test programs and for running tests -# -tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a - $(TCCX) $(TCL_FLAGS) -DTCLSH -o tclsqlite3 \ - $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) - -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/sqlite3_analyzer.c.in $(TOP)/tool/mkccode.tcl - tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c - -sqlite3_analyzer$(EXE): sqlite3_analyzer.c - $(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) - -sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl - tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c - -sqltclsh$(EXE): sqltclsh.c - $(TCCX) $(TCL_FLAGS) sqltclsh.c -o $@ $(LIBTCL) $(THREADLIB) - -sqlite3_expert$(EXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c - $(TCCX) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert$(EXE) $(THREADLIB) - -CHECKER_DEPS =\ - $(TOP)/tool/mkccode.tcl \ - sqlite3.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/ext/repair/sqlite3_checker.tcl \ - $(TOP)/ext/repair/checkindex.c \ - $(TOP)/ext/repair/checkfreelist.c \ - $(TOP)/ext/misc/btreeinfo.c \ - $(TOP)/ext/repair/sqlite3_checker.c.in - -sqlite3_checker.c: $(CHECKER_DEPS) - tclsh $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ - -sqlite3_checker$(TEXE): sqlite3_checker.c - $(TCCX) $(TCL_FLAGS) sqlite3_checker.c -o $@ $(LIBTCL) $(THREADLIB) - -dbdump$(EXE): $(TOP)/ext/misc/dbdump.c sqlite3.o - $(TCCX) -DDBDUMP_STANDALONE -o dbdump$(EXE) \ - $(TOP)/ext/misc/dbdump.c sqlite3.o $(THREADLIB) - -# Rules to build the 'testfixture' application. -# -TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 -TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE -TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 -TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB -TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit -TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC -TESTFIXTURE_FLAGS += -DSQLITE_STATIC_RANDOMJSON -TESTFIXTURE_FLAGS += -DSQLITE_STRICT_SUBTYPE=1 - -testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c - $(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \ - $(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \ - -o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB) - -amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c \ - $(TOP)/ext/session/test_session.c - $(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \ - $(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \ - $(TOP)/ext/session/test_session.c \ - -o testfixture$(EXE) $(LIBTCL) $(THREADLIB) - -coretestprogs: $(TESTPROGS) - -testprogs: coretestprogs srcck1$(EXE) fuzzcheck$(EXE) sessionfuzz$(EXE) - -fulltest: $(TESTPROGS) fuzztest - ./testfixture$(EXE) $(TOP)/test/all.test $(TESTOPTS) - -soaktest: $(TESTPROGS) - ./testfixture$(EXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS) - -fulltestonly: $(TESTPROGS) fuzztest - ./testfixture$(EXE) $(TOP)/test/full.test $(TESTOPTS) - -queryplantest: testfixture$(EXE) sqlite3$(EXE) - ./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS) - -fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) - ./fuzzcheck$(EXE) $(FUZZDATA) - ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db - -valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) - valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M $(FUZZDATA) - valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db - -# The veryquick.test TCL tests. -# -tcltest: ./testfixture$(EXE) - ./testfixture$(EXE) $(TOP)/test/veryquick.test $(TESTOPTS) - -# Runs all the same tests cases as the "tcltest" target but uses -# the testrunner.tcl script to run them in multiple cores -# concurrently. -testrunner: testfixture$(EXE) - ./testfixture$(EXE) $(TOP)/test/testrunner.tcl - -# This is the testing target preferred by the core SQLite developers. -# It runs tests under a standard configuration, regardless of how -# ./configure was run. The devs run "make devtest" prior to each -# check-in, at a minimum. Probably other tests too, but at least this -# one. -# -devtest: srctree-check sourcetest - tclsh $(TOP)/test/testrunner.tcl mdevtest - -mdevtest: - tclsh $(TOP)/test/testrunner.tcl mdevtest - -# A very quick test using only testfixture and omitting all the slower -# tests. Designed to run in under 3 minutes on a workstation. -# -quicktest: ./testfixture$(EXE) - ./testfixture$(EXE) $(TOP)/test/extraquick.test $(TESTOPTS) - -# Validate that various generated files in the source tree -# are up-to-date. -# -srctree-check: $(TOP)/tool/srctree-check.tcl - tclsh $(TOP)/tool/srctree-check.tcl - -# Try to run tests on whatever options are specified by the -# environment variables. The SQLite developers seldom use this target. -# Instead# they use "make devtest" which runs tests on a standard set of -# options regardless of how SQLite is configured. This "test" -# target is provided for legacy only. -# -test: fuzztest sourcetest $(TESTPROGS) tcltest - -# Run a test using valgrind. This can take a really long time -# because valgrind is so much slower than a native machine. -# -valgrindtest: $(TESTPROGS) valgrindfuzz - OMIT_MISUSE=1 valgrind -v \ - ./testfixture$(EXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) - -# A very fast test that checks basic sanity. The name comes from -# the 60s-era electronics testing: "Turn it on and see if smoke -# comes out." -# -smoketest: $(TESTPROGS) fuzzcheck$(EXE) - ./testfixture$(EXE) $(TOP)/test/main.test $(TESTOPTS) - -shelltest: $(TESTPROGS) - ./testfixture$(EXT) $(TOP)/test/permutations.test shell - -# The next two rules are used to support the "threadtest" target. Building -# threadtest runs a few thread-safety tests that are implemented in C. This -# target is invoked by the releasetest.tcl script. -# -THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ - $(TOP)/test/tt3_checkpoint.c \ - $(TOP)/test/tt3_index.c \ - $(TOP)/test/tt3_vacuum.c \ - $(TOP)/test/tt3_stress.c \ - $(TOP)/test/tt3_lookaside1.c - -threadtest3$(EXE): sqlite3.o $(THREADTEST3_SRC) $(TOP)/src/test_multiplex.c - $(TCCX) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(THREADLIB) - -threadtest: threadtest3$(EXE) - ./threadtest3$(EXE) - -TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO) -$(TEST_EXTENSION): $(TOP)/src/test_loadext.c - $(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION) - -extensiontest: testfixture$(EXE) $(TEST_EXTENSION) - ./testfixture$(EXE) $(TOP)/test/loadext.test - -dbtotxt$(EXE): $(TOP)/tool/dbtotxt.c - $(TCC) -o dbtotxt$(EXE) $(TOP)/tool/dbtotxt.c - -showdb$(EXE): $(TOP)/tool/showdb.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showdb$(EXE) \ - $(TOP)/tool/showdb.c sqlite3.o $(THREADLIB) - -showstat4$(EXE): $(TOP)/tool/showstat4.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showstat4$(EXE) \ - $(TOP)/tool/showstat4.c sqlite3.o $(THREADLIB) - -showjournal$(EXE): $(TOP)/tool/showjournal.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showjournal$(EXE) \ - $(TOP)/tool/showjournal.c sqlite3.o $(THREADLIB) - -showwal$(EXE): $(TOP)/tool/showwal.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showwal$(EXE) \ - $(TOP)/tool/showwal.c sqlite3.o $(THREADLIB) - -showshm$(EXE): $(TOP)/tool/showshm.c - $(TCC) -o showshm$(EXE) $(TOP)/tool/showshm.c - -index_usage$(EXE): $(TOP)/tool/index_usage.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_DEPRECATED $(SHELL_OPTS) -o index_usage$(EXE) \ - $(TOP)/tool/index_usage.c sqlite3.o $(THREADLIB) - -changeset$(EXE): $(TOP)/ext/session/changeset.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changeset$(EXE) \ - $(TOP)/ext/session/changeset.c sqlite3.o $(THREADLIB) - -changesetfuzz$(EXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changesetfuzz$(EXE) \ - $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(THREADLIB) - -fts3view$(EXE): $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o fts3view$(EXE) \ - $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o $(THREADLIB) - -rollback-test$(EXE): $(TOP)/tool/rollback-test.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o rollback-test$(EXE) \ - $(TOP)/tool/rollback-test.c sqlite3.o $(THREADLIB) - -atrc$(EXE): $(TOP)/test/atrc.c sqlite3.o - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o atrc$(EXE) \ - $(TOP)/test/atrc.c sqlite3.o $(THREADLIB) - -LogEst$(EXE): $(TOP)/tool/logest.c sqlite3.h - $(TCC) -o LogEst$(EXE) $(TOP)/tool/logest.c - -wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c - $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o wordcount$(EXE) \ - $(TOP)/test/wordcount.c sqlite3.c - -speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c - $(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB) - -kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c - $(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB) - -rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o - $(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \ - $(THREADLIB) - -loadfts: $(TOP)/tool/loadfts.c libsqlite3.a - $(TCC) $(TOP)/tool/loadfts.c libsqlite3.a -o loadfts $(THREADLIB) - -threadtest5: $(TOP)/test/threadtest5.c libsqlite3.a - $(TCC) $(TOP)/test/threadtest5.c libsqlite3.a -o threadtest5 $(THREADLIB) - -# This target will fail if the SQLite amalgamation contains any exported -# symbols that do not begin with "sqlite3_". It is run as part of the -# releasetest.tcl script. -# -checksymbols: sqlite3.o - nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0 - -# Build the amalgamation-autoconf package. The amalamgation-tarball target builds -# a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. -# The snapshot-tarball target builds a tarball named by the SHA1 hash -# -amalgamation-tarball: sqlite3.c sqlite3rc.h - TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal - -snapshot-tarball: sqlite3.c sqlite3rc.h - TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot - - -# Standard install and cleanup targets -# -install: sqlite3 libsqlite3.a sqlite3.h - mv sqlite3 /usr/bin - mv libsqlite3.a /usr/lib - mv sqlite3.h /usr/include - -clean: - rm -f *.lo *.la *.o *.c *.h *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) - rm -rf .libs .deps tsrc libtool target_source testrunner_* - rm -f lemon$(BEXE) sqlite*.tar.gz - rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) - rm -f parse.* fts5parse.* - rm -rf tsrc .target_source testrunner_bld_* testdir* - rm -f tclsqlite3$(TEXE) - rm -f $(TESTPROGS) testrunner.* - rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) - rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) - rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) - rm -f *.dll *.lib *.exp *.def *.pc *.vsix - rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) - rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) - rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) - rm -f threadtest5$(TEXE) - rm -f src-verify has_tclsh* - -distclean: clean diff --git a/manifest b/manifest index c2ac84e840..2eb7bebd49 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Generic\sbuild\scleanups. -D 2024-10-19T16:58:17.870 +C Factor\sout\sall\sautosetup-processed\s@if/@else\sblocks\sfrom\sMakefile.in\sin\sprep\sfor\smoving\smost\sof\sthe\smakefile\scode\sinto\smain.mk\s(which\shas,\sso\sfar,\sbeen\scompletely\soverlooked\sin\sthis\sport\sbut\swill\snow\sbecome\sthe\smain\sbasis\sfor\sthe\sstatic\sparts\sof\sthe\sbuild).\sThe\sidea\sis\sthat\sall\sbuild\sconfiguration\sgoes\sinto\sa\splatform-dependent\smakefile\swhich\sthen\sincludes\smain.mk. +D 2024-10-19T18:31:47.423 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in b9de6145692620a3176e9a0e6a1317a049d6bf2559896f642ae9fdc6aba3a627 +F Makefile.in 799e30c5ea3622e4909e2befa455bfa4e90ec214cb06a714c469897da3166b9e F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def c212e2066f75941113296d1120b3375388816eaee7f04e1342f0a8e82dec03fc +F auto.def 3ee0c65b809262dab45d3a92c8af29a584fe0799cbe65c545214cabc2191f1ff F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk c6501abe2d915ed1a2ec3d074e652c096177f93c50ac91f815c831e3417f9019 +F main.mk ea3f49474ea443c294ca75820839fb43db4a9f72cd4b14b895ddc9fa73a4e9b0 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2923a8924c92f62d07cb130462a8e6f4662837bad1a02bda53e630b64c692f60 -R e27a73e275f999d0b19f7fb9f885c617 +P 510afccf02dc9c3e3b928c64c34d10bee66a2343ecec6e24c4770cb0f139cd65 +R 7a8eadbb3ae7a887d98a01ebf4e8c64c U stephan -Z 78428a8bc6db32b4f76584c8d3747578 +Z 7236fe64030e3971014f63694120dff4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3bc8019b6b..5d2c7d818b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -510afccf02dc9c3e3b928c64c34d10bee66a2343ecec6e24c4770cb0f139cd65 +707e0f5857d58ec8b457270f988126b1dd0f01b5a3445a43ff7b5429324b1b3d From 25557128fe59cab45a24158d61b2b72fc8f44f91 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 20:26:17 +0000 Subject: [PATCH 068/522] Move most of the makefile code into the static main.mk. FossilOrigin-Name: 09905ed094f7102dbb4fc81b059452c50b48b0f3a2bd9736bed364b0639d89d7 --- Makefile.in | 1620 +----------------------------------------------- main.mk | 1627 +++++++++++++++++++++++++++++++++++++++++++++++++ manifest | 14 +- manifest.uuid | 2 +- 4 files changed, 1654 insertions(+), 1609 deletions(-) diff --git a/Makefile.in b/Makefile.in index fb9df642e3..d414ca3d9b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -24,6 +24,7 @@ LDFLAGS_MATH ?= @LDFLAGS_MATH@ LDFLAGS_RPATH ?= @LDFLAGS_RPATH@ LDFLAGS_READLINE ?= @LDFLAGS_READLINE@ LDFLAGS_PTHREAD ?= @LDFLAGS_PTHREAD@ +LDFLAGS_SHOBJ ?= @SHOBJ_LDFLAGS@ ENABLE_SHARED ?= @ENABLE_SHARED@ HAVE_WASI_SDK ?= @HAVE_WASI_SDK@ AR ?= @AR@ @@ -33,6 +34,7 @@ CC ?= @CC@ # will run on the platform that is doing the build. # BCC = @BUILD_CC@ @BUILD_CFLAGS@ + # # TCC is the C Compile and options for use in building executables that # will run on the target platform. (BCC and TCC are usually the @@ -43,22 +45,21 @@ BCC = @BUILD_CC@ @BUILD_CFLAGS@ CFLAGS ?= @CFLAGS@ @SH_CFLAGS@ CPPFLAGS ?= @CPPFLAGS@ # CFLAGS_stdio3 ==> for sqlite3_stdio.h -CFLAGS_stdio3 := -I${TOP}/ext/misc -TCC = ${CC} ${CFLAGS} -TCC += -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu -TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session -TCC += -I${TOP}/ext/userauth - -# Define this for the autoconf-based build, so that the code knows it can -# include the generated sqlite_cfg.h -# -TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite +CFLAGS_stdio3 := -I$(TOP)/ext/misc +TCC = $(CC) $(CFLAGS) # Define -DNDEBUG to compile without debugging (i.e., for production usage) # Omitting the define will cause extra debugging code to be inserted and # includes extra comments when "EXPLAIN stmt" is used. # -TCC += @TARGET_DEBUG@ +TCCX ?= $(TCC) @TARGET_DEBUG@ +# Define this for the autoconf-based build, so that the code knows it can +# include the generated sqlite_cfg.h +# +TCCX += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite +# +# main.mk will fill out TCCX with some flags common to all builds. + #XX# #XX## Compiler options needed for programs that use the TCL library. #XX## @@ -67,7 +68,8 @@ TCC += @TARGET_DEBUG@ #XX## The library that programs using TCL must link against. #XX## LIBTCL = @TCL_LIB_SPEC@ -#XX# + +# # Compiler options needed for programs that use the readline() library. # CFLAGS_readline = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ @@ -119,7 +121,7 @@ $(BTCLSH): # default to file, 2 to default to memory, and 3 to force temporary # tables to always be in memory. # -TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@ +TEMP_STORE ?= -DSQLITE_TEMP_STORE=@TEMP_STORE@ # Enable/disable loadable extensions, and other optional features # based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). @@ -222,25 +224,6 @@ pkgconfigdir ?= $(libdir)/pkgconfig bindir ?= @bindir@ includedir ?= @includedir@ INSTALL = @BIN_INSTALL@ -INSTALL_noexec = $(INSTALL) -m 0644 -# ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... - -# install.XYZ = dirs for installation. They're in quotes to -# accommodate installations where paths have spaces in them. -# -install.bindir = "$(DESTDIR)$(bindir)" -install.libdir = "$(DESTDIR)$(libdir)" -install.includedir = "$(DESTDIR)$(prefix)/include" -install.pkgconfigdir = "$(DESTDIR)$(pkgconfigdir)" -$(install.bindir) $(install.libdir) $(install.includedir) $(install.pkgconfigdir): - $(INSTALL) -d $@ - -# TCOMPILE = generic target platform compiler invocation -TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) -# TLINK = compiler invocation for when the target will be an executable -TLINK = $(TCC) $(TLINK_EXTRAS) -# TLINK_shared = $(TLINK) invocation specifically for shared libraries -TLINK_shared = $(TLINK) @SHOBJ_LDFLAGS@ # # You should not have to change anything below this line @@ -253,495 +236,13 @@ TLINK_shared = $(TLINK) @SHOBJ_LDFLAGS@ # AS_AUTO_DEF = $(TOP)/auto.def -USE_AMALGAMATION = @USE_AMALGAMATION@ -AMALGAMATION_LINE_MACROS = --linemacros=@AMALGAMATION_LINE_MACROS@ +USE_AMALGAMATION ?= @USE_AMALGAMATION@ +AMALGAMATION_LINE_MACROS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ -# -# Object files for the SQLite library (non-amalgamation). -# -LIBOBJS0 = alter.o analyze.o attach.o auth.o \ - backup.o bitvec.o btmutex.o btree.o build.o \ - callback.o complete.o ctime.o \ - date.o dbpage.o dbstat.o delete.o \ - expr.o fault.o fkey.o \ - fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o \ - fts3_porter.o fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \ - fts3_tokenize_vtab.o \ - fts3_unicode.o fts3_unicode2.o fts3_write.o \ - fts5.o \ - func.o global.o hash.o \ - icu.o insert.o json.o legacy.o loadext.o \ - main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \ - memdb.o memjournal.o \ - mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \ - notify.o opcodes.o os.o os_kv.o os_unix.o os_win.o \ - pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \ - random.o resolve.o rowset.o rtree.o \ - sqlite3session.o select.o sqlite3rbu.o status.o stmt.o \ - table.o threads.o tokenize.o treeview.o trigger.o \ - update.o upsert.o userauth.o utf.o util.o vacuum.o \ - vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ - vdbetrace.o vdbevtab.o vtab.o \ - wal.o walker.o where.o wherecode.o whereexpr.o \ - window.o - -# Object files for the amalgamation. -# -LIBOBJS1 = sqlite3.o - -# Determine the real value of LIBOBJ based on the 'configure' script -# -LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) - -# All of the source code files. -# -SRC = \ - $(TOP)/src/alter.c \ - $(TOP)/src/analyze.c \ - $(TOP)/src/attach.c \ - $(TOP)/src/auth.c \ - $(TOP)/src/backup.c \ - $(TOP)/src/bitvec.c \ - $(TOP)/src/btmutex.c \ - $(TOP)/src/btree.c \ - $(TOP)/src/btree.h \ - $(TOP)/src/btreeInt.h \ - $(TOP)/src/build.c \ - $(TOP)/src/callback.c \ - $(TOP)/src/complete.c \ - $(TOP)/src/ctime.c \ - $(TOP)/src/date.c \ - $(TOP)/src/dbpage.c \ - $(TOP)/src/dbstat.c \ - $(TOP)/src/delete.c \ - $(TOP)/src/expr.c \ - $(TOP)/src/fault.c \ - $(TOP)/src/fkey.c \ - $(TOP)/src/func.c \ - $(TOP)/src/global.c \ - $(TOP)/src/hash.c \ - $(TOP)/src/hash.h \ - $(TOP)/src/hwtime.h \ - $(TOP)/src/insert.c \ - $(TOP)/src/json.c \ - $(TOP)/src/legacy.c \ - $(TOP)/src/loadext.c \ - $(TOP)/src/main.c \ - $(TOP)/src/malloc.c \ - $(TOP)/src/mem0.c \ - $(TOP)/src/mem1.c \ - $(TOP)/src/mem2.c \ - $(TOP)/src/mem3.c \ - $(TOP)/src/mem5.c \ - $(TOP)/src/memdb.c \ - $(TOP)/src/memjournal.c \ - $(TOP)/src/msvc.h \ - $(TOP)/src/mutex.c \ - $(TOP)/src/mutex.h \ - $(TOP)/src/mutex_noop.c \ - $(TOP)/src/mutex_unix.c \ - $(TOP)/src/mutex_w32.c \ - $(TOP)/src/notify.c \ - $(TOP)/src/os.c \ - $(TOP)/src/os.h \ - $(TOP)/src/os_common.h \ - $(TOP)/src/os_setup.h \ - $(TOP)/src/os_kv.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/os_win.h \ - $(TOP)/src/pager.c \ - $(TOP)/src/pager.h \ - $(TOP)/src/parse.y \ - $(TOP)/src/pcache.c \ - $(TOP)/src/pcache.h \ - $(TOP)/src/pcache1.c \ - $(TOP)/src/pragma.c \ - $(TOP)/src/pragma.h \ - $(TOP)/src/prepare.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/random.c \ - $(TOP)/src/resolve.c \ - $(TOP)/src/rowset.c \ - $(TOP)/src/select.c \ - $(TOP)/src/status.c \ - $(TOP)/src/shell.c.in \ - $(TOP)/src/sqlite.h.in \ - $(TOP)/src/sqlite3ext.h \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/sqliteLimit.h \ - $(TOP)/src/table.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/src/threads.c \ - $(TOP)/src/tokenize.c \ - $(TOP)/src/treeview.c \ - $(TOP)/src/trigger.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/update.c \ - $(TOP)/src/upsert.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vacuum.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/vdbe.h \ - $(TOP)/src/vdbeapi.c \ - $(TOP)/src/vdbeaux.c \ - $(TOP)/src/vdbeblob.c \ - $(TOP)/src/vdbemem.c \ - $(TOP)/src/vdbesort.c \ - $(TOP)/src/vdbetrace.c \ - $(TOP)/src/vdbevtab.c \ - $(TOP)/src/vdbeInt.h \ - $(TOP)/src/vtab.c \ - $(TOP)/src/vxworks.h \ - $(TOP)/src/wal.c \ - $(TOP)/src/wal.h \ - $(TOP)/src/walker.c \ - $(TOP)/src/where.c \ - $(TOP)/src/wherecode.c \ - $(TOP)/src/whereexpr.c \ - $(TOP)/src/whereInt.h \ - $(TOP)/src/window.c - -# Source code for extensions -# -SRC += \ - $(TOP)/ext/fts3/fts3.c \ - $(TOP)/ext/fts3/fts3.h \ - $(TOP)/ext/fts3/fts3Int.h \ - $(TOP)/ext/fts3/fts3_aux.c \ - $(TOP)/ext/fts3/fts3_expr.c \ - $(TOP)/ext/fts3/fts3_hash.c \ - $(TOP)/ext/fts3/fts3_hash.h \ - $(TOP)/ext/fts3/fts3_icu.c \ - $(TOP)/ext/fts3/fts3_porter.c \ - $(TOP)/ext/fts3/fts3_snippet.c \ - $(TOP)/ext/fts3/fts3_tokenizer.h \ - $(TOP)/ext/fts3/fts3_tokenizer.c \ - $(TOP)/ext/fts3/fts3_tokenizer1.c \ - $(TOP)/ext/fts3/fts3_tokenize_vtab.c \ - $(TOP)/ext/fts3/fts3_unicode.c \ - $(TOP)/ext/fts3/fts3_unicode2.c \ - $(TOP)/ext/fts3/fts3_write.c -SRC += \ - $(TOP)/ext/icu/sqliteicu.h \ - $(TOP)/ext/icu/icu.c -SRC += \ - $(TOP)/ext/rtree/rtree.h \ - $(TOP)/ext/rtree/rtree.c \ - $(TOP)/ext/rtree/geopoly.c -SRC += \ - $(TOP)/ext/session/sqlite3session.c \ - $(TOP)/ext/session/sqlite3session.h -SRC += \ - $(TOP)/ext/userauth/userauth.c \ - $(TOP)/ext/userauth/sqlite3userauth.h -SRC += \ - $(TOP)/ext/rbu/sqlite3rbu.h \ - $(TOP)/ext/rbu/sqlite3rbu.c -SRC += \ - $(TOP)/ext/misc/stmt.c - -# Generated source code files -# -SRC += \ - keywordhash.h \ - opcodes.c \ - opcodes.h \ - parse.c \ - parse.h \ - sqlite_cfg.h \ - shell.c \ - sqlite3.h - -# Source code to the test files. -# -TESTSRC = \ - $(TOP)/src/test1.c \ - $(TOP)/src/test2.c \ - $(TOP)/src/test3.c \ - $(TOP)/src/test4.c \ - $(TOP)/src/test5.c \ - $(TOP)/src/test6.c \ - $(TOP)/src/test8.c \ - $(TOP)/src/test9.c \ - $(TOP)/src/test_autoext.c \ - $(TOP)/src/test_async.c \ - $(TOP)/src/test_backup.c \ - $(TOP)/src/test_bestindex.c \ - $(TOP)/src/test_blob.c \ - $(TOP)/src/test_btree.c \ - $(TOP)/src/test_config.c \ - $(TOP)/src/test_delete.c \ - $(TOP)/src/test_demovfs.c \ - $(TOP)/src/test_devsym.c \ - $(TOP)/src/test_fs.c \ - $(TOP)/src/test_func.c \ - $(TOP)/src/test_hexio.c \ - $(TOP)/src/test_init.c \ - $(TOP)/src/test_intarray.c \ - $(TOP)/src/test_journal.c \ - $(TOP)/src/test_malloc.c \ - $(TOP)/src/test_md5.c \ - $(TOP)/src/test_multiplex.c \ - $(TOP)/src/test_mutex.c \ - $(TOP)/src/test_onefile.c \ - $(TOP)/src/test_osinst.c \ - $(TOP)/src/test_pcache.c \ - $(TOP)/src/test_quota.c \ - $(TOP)/src/test_rtree.c \ - $(TOP)/src/test_schema.c \ - $(TOP)/src/test_superlock.c \ - $(TOP)/src/test_syscall.c \ - $(TOP)/src/test_tclsh.c \ - $(TOP)/src/test_tclvar.c \ - $(TOP)/src/test_thread.c \ - $(TOP)/src/test_vdbecov.c \ - $(TOP)/src/test_vfs.c \ - $(TOP)/src/test_windirent.c \ - $(TOP)/src/test_window.c \ - $(TOP)/src/test_wsd.c \ - $(TOP)/ext/fts3/fts3_term.c \ - $(TOP)/ext/fts3/fts3_test.c \ - $(TOP)/ext/session/test_session.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/test_recover.c \ - $(TOP)/ext/intck/test_intck.c \ - $(TOP)/ext/intck/sqlite3intck.c \ - $(TOP)/ext/rbu/test_rbu.c - -# Statically linked extensions -# -TESTSRC += \ - $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/test_expert.c \ - $(TOP)/ext/misc/amatch.c \ - $(TOP)/ext/misc/appendvfs.c \ - $(TOP)/ext/misc/basexx.c \ - $(TOP)/ext/misc/carray.c \ - $(TOP)/ext/misc/cksumvfs.c \ - $(TOP)/ext/misc/closure.c \ - $(TOP)/ext/misc/csv.c \ - $(TOP)/ext/misc/decimal.c \ - $(TOP)/ext/misc/eval.c \ - $(TOP)/ext/misc/explain.c \ - $(TOP)/ext/misc/fileio.c \ - $(TOP)/ext/misc/fuzzer.c \ - $(TOP)/ext/fts5/fts5_tcl.c \ - $(TOP)/ext/fts5/fts5_test_mi.c \ - $(TOP)/ext/fts5/fts5_test_tok.c \ - $(TOP)/ext/misc/ieee754.c \ - $(TOP)/ext/misc/mmapwarm.c \ - $(TOP)/ext/misc/nextchar.c \ - $(TOP)/ext/misc/normalize.c \ - $(TOP)/ext/misc/percentile.c \ - $(TOP)/ext/misc/prefixes.c \ - $(TOP)/ext/misc/qpvtab.c \ - $(TOP)/ext/misc/randomjson.c \ - $(TOP)/ext/misc/regexp.c \ - $(TOP)/ext/misc/remember.c \ - $(TOP)/ext/misc/series.c \ - $(TOP)/ext/misc/spellfix.c \ - $(TOP)/ext/misc/stmtrand.c \ - $(TOP)/ext/misc/totype.c \ - $(TOP)/ext/misc/unionvtab.c \ - $(TOP)/ext/misc/wholenumber.c \ - $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/userauth/userauth.c \ - $(TOP)/ext/rtree/test_rtreedoc.c - -# Source code to the library files needed by the test fixture -# -TESTSRC2 = \ - $(TOP)/src/attach.c \ - $(TOP)/src/backup.c \ - $(TOP)/src/bitvec.c \ - $(TOP)/src/btree.c \ - $(TOP)/src/build.c \ - $(TOP)/src/ctime.c \ - $(TOP)/src/date.c \ - $(TOP)/src/dbpage.c \ - $(TOP)/src/dbstat.c \ - $(TOP)/src/expr.c \ - $(TOP)/src/func.c \ - $(TOP)/src/global.c \ - $(TOP)/src/insert.c \ - $(TOP)/src/wal.c \ - $(TOP)/src/main.c \ - $(TOP)/src/mem5.c \ - $(TOP)/src/os.c \ - $(TOP)/src/os_kv.c \ - $(TOP)/src/os_unix.c \ - $(TOP)/src/os_win.c \ - $(TOP)/src/pager.c \ - $(TOP)/src/pragma.c \ - $(TOP)/src/prepare.c \ - $(TOP)/src/printf.c \ - $(TOP)/src/random.c \ - $(TOP)/src/pcache.c \ - $(TOP)/src/pcache1.c \ - $(TOP)/src/select.c \ - $(TOP)/src/tokenize.c \ - $(TOP)/src/treeview.c \ - $(TOP)/src/utf.c \ - $(TOP)/src/util.c \ - $(TOP)/src/vdbeapi.c \ - $(TOP)/src/vdbeaux.c \ - $(TOP)/src/vdbe.c \ - $(TOP)/src/vdbemem.c \ - $(TOP)/src/vdbetrace.c \ - $(TOP)/src/vdbevtab.c \ - $(TOP)/src/where.c \ - $(TOP)/src/wherecode.c \ - $(TOP)/src/whereexpr.c \ - $(TOP)/src/window.c \ - parse.c \ - $(TOP)/ext/fts3/fts3.c \ - $(TOP)/ext/fts3/fts3_aux.c \ - $(TOP)/ext/fts3/fts3_expr.c \ - $(TOP)/ext/fts3/fts3_term.c \ - $(TOP)/ext/fts3/fts3_tokenizer.c \ - $(TOP)/ext/fts3/fts3_write.c \ - $(TOP)/ext/async/sqlite3async.c \ - $(TOP)/ext/session/sqlite3session.c \ - $(TOP)/ext/misc/stmt.c \ - fts5.c - -# Header files used by all library source files. -# -HDR = \ - $(TOP)/src/btree.h \ - $(TOP)/src/btreeInt.h \ - $(TOP)/src/hash.h \ - $(TOP)/src/hwtime.h \ - keywordhash.h \ - $(TOP)/src/msvc.h \ - $(TOP)/src/mutex.h \ - opcodes.h \ - $(TOP)/src/os.h \ - $(TOP)/src/os_common.h \ - $(TOP)/src/os_setup.h \ - $(TOP)/src/os_win.h \ - $(TOP)/src/pager.h \ - $(TOP)/src/pcache.h \ - parse.h \ - $(TOP)/src/pragma.h \ - sqlite3.h \ - $(TOP)/src/sqlite3ext.h \ - $(TOP)/src/sqliteInt.h \ - $(TOP)/src/sqliteLimit.h \ - $(TOP)/src/vdbe.h \ - $(TOP)/src/vdbeInt.h \ - $(TOP)/src/vxworks.h \ - $(TOP)/src/whereInt.h \ - sqlite_cfg.h - -# Header files used by extensions -# -EXTHDR += \ - $(TOP)/ext/fts3/fts3.h \ - $(TOP)/ext/fts3/fts3Int.h \ - $(TOP)/ext/fts3/fts3_hash.h \ - $(TOP)/ext/fts3/fts3_tokenizer.h -EXTHDR += \ - $(TOP)/ext/rtree/rtree.h \ - $(TOP)/ext/rtree/geopoly.c -EXTHDR += \ - $(TOP)/ext/icu/sqliteicu.h -EXTHDR += \ - $(TOP)/ext/rtree/sqlite3rtree.h -EXTHDR += \ - $(TOP)/ext/userauth/sqlite3userauth.h - -# executables needed for testing -# -TESTPROGS = \ - testfixture$(TEXE) \ - sqlite3$(TEXE) \ - sqlite3_analyzer$(TEXE) \ - sqldiff$(TEXE) \ - dbhash$(TEXE) \ - sqltclsh$(TEXE) - -# Databases containing fuzzer test cases -# -FUZZDATA = \ - $(TOP)/test/fuzzdata1.db \ - $(TOP)/test/fuzzdata2.db \ - $(TOP)/test/fuzzdata3.db \ - $(TOP)/test/fuzzdata4.db \ - $(TOP)/test/fuzzdata5.db \ - $(TOP)/test/fuzzdata6.db \ - $(TOP)/test/fuzzdata7.db \ - $(TOP)/test/fuzzdata8.db - -# Standard options to testfixture -# -TESTOPTS = --verbose=file --output=test-out.txt - -# Extra compiler options for various shell tools -# -SHELL_OPT = @OPT_SHELL@ -SHELL_OPT += -DSQLITE_DQS=0 -SHELL_OPT += -DSQLITE_ENABLE_FTS4 -#SHELL_OPT += -DSQLITE_ENABLE_FTS5 -SHELL_OPT += -DSQLITE_ENABLE_RTREE -SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS -SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB -SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB -SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB -SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB -SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC -SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1 -FUZZERSHELL_OPT = -FUZZCHECK_OPT += -I$(TOP)/test -FUZZCHECK_OPT += -I$(TOP)/ext/recover -FUZZCHECK_OPT += \ - -DSQLITE_OSS_FUZZ \ - -DSQLITE_ENABLE_BYTECODE_VTAB \ - -DSQLITE_ENABLE_DBPAGE_VTAB \ - -DSQLITE_ENABLE_DBSTAT_VTAB \ - -DSQLITE_ENABLE_BYTECODE_VTAB \ - -DSQLITE_ENABLE_DESERIALIZE \ - -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ - -DSQLITE_ENABLE_FTS3_PARENTHESIS \ - -DSQLITE_ENABLE_FTS4 \ - -DSQLITE_ENABLE_FTS5 \ - -DSQLITE_ENABLE_GEOPOLY \ - -DSQLITE_ENABLE_MATH_FUNCTIONS \ - -DSQLITE_ENABLE_MEMSYS5 \ - -DSQLITE_ENABLE_NORMALIZE \ - -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ - -DSQLITE_ENABLE_PREUPDATE_HOOK \ - -DSQLITE_ENABLE_RTREE \ - -DSQLITE_ENABLE_SESSION \ - -DSQLITE_ENABLE_STMTVTAB \ - -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \ - -DSQLITE_ENABLE_STAT4 \ - -DSQLITE_ENABLE_STMT_SCANSTATUS \ - -DSQLITE_MAX_MEMORY=50000000 \ - -DSQLITE_MAX_MMAP_SIZE=0 \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_PRINTF_PRECISION_LIMIT=1000 \ - -DSQLITE_PRIVATE="" \ - -DSQLITE_STRICT_SUBTYPE=1 \ - -DSQLITE_STATIC_RANDOMJSON - -FUZZCHECK_SRC += $(TOP)/test/fuzzcheck.c -FUZZCHECK_SRC += $(TOP)/test/ossfuzz.c -FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c -FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c -FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c -FUZZCHECK_SRC += $(TOP)/test/vt02.c -FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c -FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c -DBFUZZ_OPT = -ST_OPT = -DSQLITE_OS_KV_OPTIONAL +SHELL_OPT ?= @OPT_SHELL@ # In wasi-sdk builds, remove the CLI shell build from 'all'. -target_sqlite3_shell_1 = target_sqlite3_shell_0 = sqlite3$(TEXE) target_sqlite3_shell = $(target_sqlite3_shell_$(HAVE_WASI_SDK)) @@ -772,1040 +273,6 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) $(AS_AUTOREMAKE) @touch $@ -libsqlite3.LIB = libsqlite3$(TLIB) - -$(libsqlite3.LIB): $(LIBOBJ) - $(AR) crs $@ $(LIBOBJ) -lib: $(libsqlite3.LIB) -all: lib - -# LDFLAGS_libsqlite3 should be used with any target which either -# results in building libsqlite3.so, compiles sqlite3.c directly, or -# links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these -# flags are for the target build platform, not necessarily localhost. -# i.e. it should be used with $(TCC) or $(TLINK) but not $(BCC). -LDFLAGS_libsqlite3 = \ - $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_PTHREAD) \ - $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) - -libsqlite3.SO = libsqlite3$(TDLL) -target_libsqlite3_so_0 = -target_libsqlite3_so_1 = $(libsqlite3.SO) -target_libsqlite3_so = $(target_libsqlite3_so_$(ENABLE_SHARED)) - -$(libsqlite3.SO): $(LIBOBJ) - @if [ "x1" != "x$(ENABLE_SHARED)" ]; then echo "Shared lib build is disabled." 1>&2; exit 1; fi - $(TLINK_shared) -o $@ \ - $(LIBOBJ) $(TLIBS) $(LDFLAGS_libsqlite3) -so: $(target_libsqlite3_so) -all: so - -# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(RELEASE) and -# create symlinks which point to it. Do we really need all of this -# hoop-jumping? Can we not simply install the .so as-is to -# libsqlite3.so (without the versioned bits)? -# -# The historical SQLite build always used a version number of 0.8.6 -# for reasons lost to history but having something to do with libtool -# (which is not longer used in this tree). -# -install-so-1: $(install.libdir) $(libsqlite3.SO) - $(INSTALL) $(libsqlite3.SO) $(install.libdir); \ - cd $(install.libdir); \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(RELEASE); \ - mv $(libsqlite3.SO) $(libsqlite3.SO).$(RELEASE); \ - ln -s $(libsqlite3.SO).$(RELEASE) $(libsqlite3.SO).3; \ - ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) -install-so-0: -install: install-so-$(ENABLE_SHARED) - -# Install $(libsqlite3.LIB) -# -install-lib: $(install.libdir) $(libsqlite3.LIB) - $(INSTALL_noexec) $(libsqlite3.LIB) $(install.libdir) -install: install-lib - -# Install C header files -# -install-includes: sqlite3.h $(install.includedir) - $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install.includedir) -install: install-includes - -# libtclsqlite3... -# -libtclsqlite3.SO = libtclsqlite3$(TDLL) -target_libtclsqlite3_1 = $(libtclsqlite3.SO) -target_libtclsqlite3_0 = -target_libtclsqlite3 = $(target_libtclsqlite3_$(HAVE_TCL)) -$(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) - $(TLINK_shared) -o $@ tclsqlite.o \ - $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS_libsqlite3) \ - $(libsqlite3.LIB) $(TCLLIB_RPATH) - -libtcl: $(target_libtclsqlite3) - -all: $(target_libtclsqlite3) - -pkgIndex.tcl: - echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ - -install.tcldir = "$(DESTDIR)$(TCLLIBDIR)" -install-tcl: install-lib $(target_libtclsqlite3) pkgIndex.tcl - @if [ "x$(DESTDIR)" = "x$(install.tcldir)" ]; then echo "TCLLIBDIR is not set." 1>&2; exit 1; fi - $(INSTALL) -d $(install.tcldir) - $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) - $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) -install: install-tcl - -tclsqlite3.c: sqlite3.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 - -sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/split-sqlite3c.tcl - -# Build the SQLite TCL extension in a way that make it compatible -# with whatever version of TCL is running as $TCLSH_CMD, possibly defined -# by --with-tclsh= -# -tclextension: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) - -# Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD -# to find it. -# -tclextension-install: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) - -# Install the SQLite TCL extension that is used by $TCLSH_CMD -# -tclextension-uninstall: - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall - -# List all installed the SQLite TCL extension that is are accessible -# by $TCLSH_CMD, included prior versions. -# -tclextension-list: - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info - -sqlite3$(TEXE): shell.c sqlite3.c - $(TCC) $(CFLAGS_readline) $(SHELL_OPT) -o $@ \ - shell.c sqlite3.c \ - $(LDFLAGS_libsqlite3) $(LDFLAGS_READLINE) - -install-cli-0: sqlite3$(TEXT) $(install.bindir) - $(INSTALL) -s sqlite3$(TEXT) $(install.bindir) -install-cli-1: -install: install-cli-$(HAVE_WASI_SDK) - -sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h - $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite3) - -install-diff: sqldiff$(TEXE) $(install.bindir) - $(INSTALL) -s sqldiff$(TEXT) $(install.bindir) -#install: install-diff - -dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h - $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite3) - -RSYNC_SRC = \ - $(TOP)/tool/sqlite3_rsync.c \ - sqlite3.c - -RSYNC_OPT = \ - -DSQLITE_ENABLE_DBPAGE_VTAB \ - -USQLITE_THREADSAFE \ - -DSQLITE_THREADSAFE=0 \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_OMIT_DEPRECATED - -sqlite3_rsync$(TEXE): $(RSYNC_SRC) - $(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) - -install-rsync: sqlite3_rsync$(TEXE) $(install.bindir) - $(INSTALL) sqlite3_rsync$(TEXT) $(install.bindir) -#install: install-rsync - -scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o - $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ - $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS_libsqlite3) - -srcck1$(BEXE): $(TOP)/tool/srcck1.c - $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c - -sourcetest: srcck1$(BEXE) sqlite3.c - ./srcck1$(BEXE) sqlite3.c - -src-verify$(BEXE): $(TOP)/tool/src-verify.c - $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c - -verify-source: ./src-verify$(BEXE) - ./src-verify$(BEXE) $(TOP) - -fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ - $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS_libsqlite3) -fuzzy: fuzzershell$(TEXE) - -fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(LDFLAGS_libsqlite3) -fuzzy: fuzzcheck$(TEXE) - -fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(TLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ - sqlite3.c $(LDFLAGS_libsqlite3) -fuzzy: fuzzcheck-asan$(TEXE) - - -fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(TLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ - sqlite3.c $(LDFLAGS_libsqlite3) -fuzzy: fuzzcheck-ubsan$(TEXE) - -# Usage: FUZZDB=filename make run-fuzzcheck -# -# Where filename is a fuzzcheck database, this target builds and runs -# fuzzcheck, fuzzcheck-asan, and fuzzcheck-ubsan on that database. -# -# FUZZDB can be a glob pattern of two or more databases. Example: -# -# FUZZDB=test/fuzzdata*.db make run-fuzzcheck -# -run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) - @if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi - ./fuzzcheck$(TEXE) --spinner $(FUZZDB) - ./fuzzcheck-asan$(TEXE) --spinner $(FUZZDB) - ./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB) - -ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ - $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) -fuzzy: ossshell$(TEXE) - -sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(LDFLAGS_libsqlite3) -fuzzy: sessionfuzz$(TEXE) - -dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) -fuzzy: dbfuzz$(TEXE) - -DBFUZZ2_OPTS = \ - -USQLITE_THREADSAFE \ - -DSQLITE_THREADSAFE=0 \ - -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_DEBUG \ - -DSQLITE_ENABLE_DBSTAT_VTAB \ - -DSQLITE_ENABLE_BYTECODE_VTAB \ - -DSQLITE_ENABLE_RTREE \ - -DSQLITE_ENABLE_FTS4 \ - -DSQLITE_ENABLE_FTS5 - -dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - $(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ - -DSTANDALONE -o dbfuzz2 \ - $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS_libsqlite3) - mkdir -p dbfuzz2-dir - cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir -fuzzy: dbfuzz2$(TEXE) - -mptester$(TEXE): $(libsqlite3.LIB) $(TOP)/mptest/mptest.c - $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c $(libsqlite3.LIB) \ - $(LDFLAGS_libsqlite3) - -MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 -MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 -mptest: mptester$(TEXE) - rm -f mptest.db - $(MPTEST1) --journalmode DELETE - $(MPTEST2) --journalmode WAL - $(MPTEST1) --journalmode WAL - $(MPTEST2) --journalmode PERSIST - $(MPTEST1) --journalmode PERSIST - $(MPTEST2) --journalmode TRUNCATE - $(MPTEST1) --journalmode TRUNCATE - $(MPTEST2) --journalmode DELETE - -has_tclsh84: - sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) - touch has_tclsh84 - -has_tclsh85: - sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) - touch has_tclsh85 - -has_tclconfig: - @if [ x = "x$(TCL_CONFIG_SH)" ]; then - echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ - fi - touch has_tclconfig - -# -# This target creates a directory named "tsrc" and fills it with -# copies of all of the C source code and header files needed to -# build on the target system. Some of the C source code and header -# files are automatically generated. This target takes care of -# all that automatic generation. -# -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(BTCLSH) # has_tclsh84 - rm -rf tsrc - mkdir tsrc - cp -f $(SRC) tsrc - rm tsrc/sqlite.h.in tsrc/parse.y - $(BTCLSH) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new - mv vdbe.new tsrc/vdbe.c - cp fts5.c fts5.h tsrc - touch .target_source - -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ - $(TOP)/VERSION $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h - -sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify \ - $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) - cp tsrc/sqlite3ext.h . - cp $(TOP)/ext/session/sqlite3session.h . - -sqlite3r.h: sqlite3.h $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h - -sqlite3r.c: sqlite3.c sqlite3r.h $(BTCLSH) # has_tclsh84 - cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ - cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ - cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) - -sqlite3ext.h: .target_source - cp tsrc/sqlite3ext.h . - -# Rules to build the LEMON compiler generator -# -lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c - $(BCC) -o $@ $(TOP)/tool/lemon.c - cp $(TOP)/tool/lempar.c . - -# Rules to build the program that generates the source-id -# -mksourceid$(BEXE): $(TOP)/tool/mksourceid.c - $(BCC) -o $@ $(TOP)/tool/mksourceid.c - -# Rules to build individual *.o files from generated *.c files. This -# applies to: -# -# parse.o -# opcodes.o -# -parse.o: parse.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c parse.c - -opcodes.o: opcodes.c - $(TCOMPILE) $(TEMP_STORE) -c opcodes.c - -# Rules to build individual *.o files from files in the src directory. -# -alter.o: $(TOP)/src/alter.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c - -analyze.o: $(TOP)/src/analyze.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c - -attach.o: $(TOP)/src/attach.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c - -auth.o: $(TOP)/src/auth.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c - -backup.o: $(TOP)/src/backup.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c - -bitvec.o: $(TOP)/src/bitvec.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c - -btmutex.o: $(TOP)/src/btmutex.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c - -btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c - -build.o: $(TOP)/src/build.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c - -callback.o: $(TOP)/src/callback.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c - -complete.o: $(TOP)/src/complete.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c - -ctime.o: $(TOP)/src/ctime.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c - -date.o: $(TOP)/src/date.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c - -dbpage.o: $(TOP)/src/dbpage.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c - -dbstat.o: $(TOP)/src/dbstat.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c - -delete.o: $(TOP)/src/delete.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c - -expr.o: $(TOP)/src/expr.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c - -fault.o: $(TOP)/src/fault.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c - -fkey.o: $(TOP)/src/fkey.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c - -func.o: $(TOP)/src/func.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c - -global.o: $(TOP)/src/global.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c - -hash.o: $(TOP)/src/hash.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c - -insert.o: $(TOP)/src/insert.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c - -json.o: $(TOP)/src/json.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c - -legacy.o: $(TOP)/src/legacy.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c - -loadext.o: $(TOP)/src/loadext.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c - -main.o: $(TOP)/src/main.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c - -malloc.o: $(TOP)/src/malloc.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c - -mem0.o: $(TOP)/src/mem0.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c - -mem1.o: $(TOP)/src/mem1.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c - -mem2.o: $(TOP)/src/mem2.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c - -mem3.o: $(TOP)/src/mem3.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c - -mem5.o: $(TOP)/src/mem5.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c - -memdb.o: $(TOP)/src/memdb.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c - -memjournal.o: $(TOP)/src/memjournal.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c - -mutex.o: $(TOP)/src/mutex.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c - -mutex_noop.o: $(TOP)/src/mutex_noop.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c - -mutex_unix.o: $(TOP)/src/mutex_unix.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c - -mutex_w32.o: $(TOP)/src/mutex_w32.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c - -notify.o: $(TOP)/src/notify.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c - -pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c - -pcache.o: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c - -pcache1.o: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c - -os.o: $(TOP)/src/os.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c - -os_kv.o: $(TOP)/src/os_kv.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c - -os_unix.o: $(TOP)/src/os_unix.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c - -os_win.o: $(TOP)/src/os_win.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c - -pragma.o: $(TOP)/src/pragma.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c - -prepare.o: $(TOP)/src/prepare.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c - -printf.o: $(TOP)/src/printf.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c - -random.o: $(TOP)/src/random.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c - -resolve.o: $(TOP)/src/resolve.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c - -rowset.o: $(TOP)/src/rowset.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c - -select.o: $(TOP)/src/select.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c - -status.o: $(TOP)/src/status.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c - -table.o: $(TOP)/src/table.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c - -threads.o: $(TOP)/src/threads.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c - -tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c - -treeview.o: $(TOP)/src/treeview.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/treeview.c - -trigger.o: $(TOP)/src/trigger.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c - -update.o: $(TOP)/src/update.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c - -upsert.o: $(TOP)/src/upsert.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c - -utf.o: $(TOP)/src/utf.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c - -util.o: $(TOP)/src/util.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c - -vacuum.o: $(TOP)/src/vacuum.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c - -vdbe.o: $(TOP)/src/vdbe.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c - -vdbeapi.o: $(TOP)/src/vdbeapi.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c - -vdbeaux.o: $(TOP)/src/vdbeaux.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c - -vdbeblob.o: $(TOP)/src/vdbeblob.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c - -vdbemem.o: $(TOP)/src/vdbemem.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c - -vdbesort.o: $(TOP)/src/vdbesort.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c - -vdbetrace.o: $(TOP)/src/vdbetrace.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c - -vdbevtab.o: $(TOP)/src/vdbevtab.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c - -vtab.o: $(TOP)/src/vtab.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c - -wal.o: $(TOP)/src/wal.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c - -walker.o: $(TOP)/src/walker.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c - -where.o: $(TOP)/src/where.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c - -wherecode.o: $(TOP)/src/wherecode.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c - -whereexpr.o: $(TOP)/src/whereexpr.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c - -window.o: $(TOP)/src/window.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c - -tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) - $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) \ - -c $(TOP)/src/tclsqlite.c - -tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(HDR) - $(TCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c - -tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(HDR) - $(TCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c - -tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) - $(TLINK) -o $@ tclsqlite-shell.o \ - $(libsqlite3.LIB) $(LIBTCL) - -# Rules to build opcodes.c and opcodes.h -# -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c - -opcodes.h: parse.h $(TOP)/src/vdbe.c \ - $(TOP)/tool/mkopcodeh.tcl $(BTCLSH) # has_tclsh84 - cat parse.h $(TOP)/src/vdbe.c | $(BTCLSH) $(TOP)/tool/mkopcodeh.tcl >opcodes.h - -# Rules to build parse.c and parse.h - the outputs of lemon. -# -parse.h: parse.c - -parse.c: $(TOP)/src/parse.y lemon$(BEXE) - cp $(TOP)/src/parse.y . - ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y - -sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(BTCLSH) # has_tclsh84 - echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ - echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ - cat $(TOP)/VERSION | $(BTCLSH) $(TOP)/tool/replace.tcl exact . , >>$@ - echo '#endif' >>sqlite3rc.h - -keywordhash.h: $(TOP)/tool/mkkeywordhash.c - $(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c - ./mkkeywordhash$(BEXE) >keywordhash.h - -# Source and header files that shell.c depends on -SHELL_DEP = \ - $(TOP)/src/shell.c.in \ - $(TOP)/ext/consio/console_io.c \ - $(TOP)/ext/consio/console_io.h \ - $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/sqlite3expert.h \ - $(TOP)/ext/intck/sqlite3intck.c \ - $(TOP)/ext/intck/sqlite3intck.h \ - $(TOP)/ext/misc/appendvfs.c \ - $(TOP)/ext/misc/base64.c \ - $(TOP)/ext/misc/base85.c \ - $(TOP)/ext/misc/completion.c \ - $(TOP)/ext/misc/decimal.c \ - $(TOP)/ext/misc/fileio.c \ - $(TOP)/ext/misc/ieee754.c \ - $(TOP)/ext/misc/memtrace.c \ - $(TOP)/ext/misc/pcachetrace.c \ - $(TOP)/ext/misc/percentile.c \ - $(TOP)/ext/misc/regexp.c \ - $(TOP)/ext/misc/series.c \ - $(TOP)/ext/misc/sha1.c \ - $(TOP)/ext/misc/shathree.c \ - $(TOP)/ext/misc/sqlar.c \ - $(TOP)/ext/misc/uint.c \ - $(TOP)/ext/misc/vfstrace.c \ - $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/sqlite3recover.h \ - $(TOP)/src/test_windirent.c \ - $(TOP)/src/test_windirent.h - -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mkshellc.tcl >shell.c - - -# Rules to build the extension objects. -# -icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c - -fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c - -fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c - -fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c - -fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c - -fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c - -fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c - -fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c - -fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c - -fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c - -fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c - -fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c - -fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c - -fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c - -rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c - -userauth.o: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c - -sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c - -stmt.o: $(TOP)/ext/misc/stmt.c - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c - -# FTS5 things -# -FTS5_SRC = \ - $(TOP)/ext/fts5/fts5.h \ - $(TOP)/ext/fts5/fts5Int.h \ - $(TOP)/ext/fts5/fts5_aux.c \ - $(TOP)/ext/fts5/fts5_buffer.c \ - $(TOP)/ext/fts5/fts5_main.c \ - $(TOP)/ext/fts5/fts5_config.c \ - $(TOP)/ext/fts5/fts5_expr.c \ - $(TOP)/ext/fts5/fts5_hash.c \ - $(TOP)/ext/fts5/fts5_index.c \ - fts5parse.c fts5parse.h \ - $(TOP)/ext/fts5/fts5_storage.c \ - $(TOP)/ext/fts5/fts5_tokenize.c \ - $(TOP)/ext/fts5/fts5_unicode2.c \ - $(TOP)/ext/fts5/fts5_varint.c \ - $(TOP)/ext/fts5/fts5_vocab.c \ - -fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) - cp $(TOP)/ext/fts5/fts5parse.y . - rm -f fts5parse.h - ./lemon$(BEXE) $(OPTS) -S fts5parse.y - -fts5parse.h: fts5parse.c - -fts5.c: $(FTS5_SRC) $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/ext/fts5/tool/mkfts5c.tcl - cp $(TOP)/ext/fts5/fts5.h . - -fts5.o: fts5.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c fts5.c - -sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c - - -# Rules to build the 'testfixture' application. -# -# If using the amalgamation, use sqlite3.c directly to build the test -# fixture. Otherwise link against libsqlite3.a. (This distinction is -# necessary because the test fixture requires non-API symbols which are -# hidden when the library is built via the amalgamation). -# -TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 -TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit -TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE -TESTFIXTURE_FLAGS += -DBUILD_sqlite -TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 -TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB -TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB -TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC -TESTFIXTURE_FLAGS += -DSQLITE_STATIC_RANDOMJSON -TESTFIXTURE_FLAGS += -DSQLITE_STRICT_SUBTYPE=1 - -TESTFIXTURE_SRC0 = $(TESTSRC2) $(libsqlite3.LIB) -TESTFIXTURE_SRC1 = sqlite3.c -TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c -TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) - -testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) - $(TLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ - -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(LDFLAGS_libsqlite3) $(TCL_INCLUDE_SPEC) - -coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) - -testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) - -# A very detailed test running most or all test cases -fulltest: alltest fuzztest - -# Run most or all tcl test cases -alltest: $(TESTPROGS) - ./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS) - -# Really really long testing -soaktest: $(TESTPROGS) - ./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS) - -# Do extra testing but not everything. -fulltestonly: $(TESTPROGS) fuzztest - ./testfixture$(TEXE) $(TOP)/test/full.test - -# Fuzz testing -# -# WARNING: When the "fuzztest" target is run by the testrunner.tcl script, -# it does not actually run this code. Instead, it schedules equivalent -# commands. Therefore, if this target is updated, then code in -# testrunner_data.tcl (search for "trd_fuzztest_data") must also be updated. -# -fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) - ./fuzzcheck$(TEXE) $(FUZZDATA) - ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db - -valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) - valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) - valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db - -# The veryquick.test TCL tests. -# -tcltest: ./testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) - -# Runs all the same tests cases as the "tcltest" target but uses -# the testrunner.tcl script to run them in multiple cores -# concurrently. -testrunner: testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl - -# This is the testing target preferred by the core SQLite developers. -# It runs tests under a standard configuration, regardless of how -# ./configure was run. The devs run "make devtest" prior to each -# check-in, at a minimum. Probably other tests too, but at least this -# one. -# -devtest: srctree-check sourcetest - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) - -mdevtest: srctree-check has_tclsh85 - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) - -sdevtest: has_tclsh85 - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS) - -# Validate that various generated files in the source tree -# are up-to-date. -# -srctree-check: $(TOP)/tool/srctree-check.tcl - $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl - -# Testing for a release -# -releasetest: srctree-check has_tclsh85 verify-source - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS) - -# Minimal testing that runs in less than 3 minutes -# -quicktest: ./testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS) - -# Try to run tests on whatever options are specified by the -# ./configure. The developers seldom use this target. Instead -# they use "make devtest" which runs tests on a standard set of -# options regardless of how SQLite is configured. This "test" -# target is provided for legacy only. -# -test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest - -# Run a test using valgrind. This can take a really long time -# because valgrind is so much slower than a native machine. -# -valgrindtest: $(TESTPROGS) valgrindfuzz - OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) - -# A very fast test that checks basic sanity. The name comes from -# the 60s-era electronics testing: "Turn it on and see if smoke -# comes out." -# -smoketest: $(TESTPROGS) fuzzcheck$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS) - -shelltest: - $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell - -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ - $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 - $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c - -sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c - $(TLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TCL_INCLUDE_SPEC) $(LDFLAGS_libsqlite3) - -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 has_tclsh85 - $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c - -sqltclsh$(TEXE): has_tclconfig sqltclsh.c - $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) - -sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/expert.c sqlite3.c - $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite3) - -CHECKER_DEPS =\ - $(TOP)/tool/mkccode.tcl \ - sqlite3.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/ext/repair/sqlite3_checker.tcl \ - $(TOP)/ext/repair/checkindex.c \ - $(TOP)/ext/repair/checkfreelist.c \ - $(TOP)/ext/misc/btreeinfo.c \ - $(TOP)/ext/repair/sqlite3_checker.c.in - -sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 - $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ - -sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c - $(TLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) - -dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo - $(TLINK) -DDBDUMP_STANDALONE -o $@ \ - $(TOP)/ext/misc/dbdump.c sqlite3.lo $(LDFLAGS_libsqlite3) - -dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c - $(TLINK)-o $@ $(TOP)/tool/dbtotxt.c - -showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(LDFLAGS_libsqlite3) - -showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(LDFLAGS_libsqlite3) - -showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(LDFLAGS_libsqlite3) - -showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(LDFLAGS_libsqlite3) - -showshm$(TEXE): $(TOP)/tool/showshm.c - $(TLINK) -o $@ $(TOP)/tool/showshm.c - -index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo - $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(LDFLAGS_libsqlite3) - -changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(LDFLAGS_libsqlite3) - -changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(LDFLAGS_libsqlite3) - -rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(LDFLAGS_libsqlite3) - -atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(LDFLAGS_libsqlite3) - -LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h - $(TLINK) -I. -o $@ $(TOP)/tool/logest.c - -wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(LDFLAGS_libsqlite3) - -speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile - $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS_libsqlite3) - -#XX#startup$(TEXE): $(TOP)/test/startup.c sqlite3.c -#XX# $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) -# ^^^ note that it wants $(TLIBS) (a.k.a. $(LDFLAGS_libsqlite3) but is using $(CC) -# instead of $(BCC). - -KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ - -kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c - $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS_libsqlite3) - -rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo - $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(LDFLAGS_libsqlite3) - -loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la - $(TLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(LDFLAGS_libsqlite3) - -# This target will fail if the SQLite amalgamation contains any exported -# symbols that do not begin with "sqlite3_". It is run as part of the -# releasetest.tcl script. -# -VALIDIDS=' sqlite3(changeset|changegroup|session)?_' -checksymbols: sqlite3.o - nm -g --defined-only sqlite3.o - nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 - echo '0 errors out of 1 tests' - -# Build a ZIP archive containing various command-line tools. -# -tool-zip: testfixture$(TEXE) sqlite3$(TEXE) sqldiff$(TEXE) \ - sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) $(TOP)/tool/mktoolzip.tcl - strip sqlite3$(TEXE) sqldiff$(TEXE) sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) - ./testfixture$(TEXE) $(TOP)/tool/mktoolzip.tcl - -#XX# TODO: adapt the autoconf amalgamation for autosetup -#XX# -#XX## Build the amalgamation-autoconf package. The amalamgation-tarball target builds -#XX## a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. -#XX## The snapshot-tarball target builds a tarball named by the SHA1 hash -#XX## -#XX#amalgamation-tarball: sqlite3.c sqlite3rc.h -#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal -#XX# -#XX#snapshot-tarball: sqlite3.c sqlite3rc.h -#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot -#XX# - -# The next two rules are used to support the "threadtest" target. Building -# threadtest runs a few thread-safety tests that are implemented in C. This -# target is invoked by the releasetest.tcl script. -# -THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ - $(TOP)/test/tt3_checkpoint.c \ - $(TOP)/test/tt3_index.c \ - $(TOP)/test/tt3_vacuum.c \ - $(TOP)/test/tt3_stress.c \ - $(TOP)/test/tt3_lookaside1.c - -threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC) - $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(LDFLAGS_libsqlite3) - -threadtest: threadtest3$(TEXE) - ./threadtest3$(TEXE) - -threadtest5: sqlite3.c $(TOP)/test/threadtest5.c - $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS_libsqlite3) - -# -# Windows section -# -dll: sqlite3.dll -sqlite3.def: $(LIBOBJ) - echo 'EXPORTS' >sqlite3.def - nm $(LIBOBJ) | grep ' T ' | grep ' _sqlite3_' \ - | sed 's/^.* _//' >>sqlite3.def - -sqlite3.dll: $(LIBOBJ) sqlite3.def - $(TCC) @SHOBJ_LDFLAGS@ -o $@ sqlite3.def \ - -Wl,"--strip-all" $(LIBOBJ) # # Fiddle app @@ -1836,53 +303,4 @@ fiddle: sqlite3.c shell.c misspell: ./custom.rws has_tclsh84 $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in -# -# tool/version-info: a utility for emitting sqlite3 version info -# in various forms. -# -version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h - $(TLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c - - -# Remove build products sufficient so that subsequent makes will recompile -# everything from scratch. Do not remove: -# -# * test results and test logs -# * output from ./configure -# -tidy: - rm -f *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) - rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h - rm -rf .libs .deps tsrc .target_source - rm -f lemon$(BEXE) sqlite*.tar.gz - rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) - rm -f parse.* fts5parse.* - rm -f $(libsqlite3.SO) $(libsqlite3.LIB) - rm -f tclsqlite3$(TEXE) $(TESTPROGS) - rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) - rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) - rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) - rm -f *.dll *.lib *.exp *.pc *.vsix *.so *.dylib pkgIndex.tcl - rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) sqlite3_expert$(TEXE) - rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) - rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) - rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) dbfuzz2-asan$(TEXE) dbfuzz2-msan$(TEXE) - rm -f fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE) - rm -f sessionfuzz$(TEXE) - rm -f threadtest5$(TEXE) - rm -f src-verify$(BEXE) has_tclsh* has_tclconfig - rm -f tclsqlite3.c - rm -f sqlite3rc.h sqlite3.def - -# -# Removes build products and test logs. Retains ./configure outputs. -# -clean: tidy - rm -rf omittest* testrunner* testdir* - -gmake -C ext/wasm distclean 2>/dev/null; true - -# Clean up everything. No exceptions. -distclean: clean - rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile - rm -f $(TOP)/tool/emcc.sh - -gmake -C ext/wasm distclean 2>/dev/null; true +include $(TOP)/main.mk diff --git a/main.mk b/main.mk index fa9f7cce1a..848b859a22 100644 --- a/main.mk +++ b/main.mk @@ -33,3 +33,1630 @@ # Once the variables above are defined, the rest of this make script # will build the SQLite library and testing tools. ################################################################################ + +# +# Ideally these all come from the calling makefile, but we can provide some +# sane defaults for many of them... +# +prefix ?= /usr/local +exec_prefix ?= $(prefix) +libdir ?= $(prefix)/lib +pkgconfigdir ?= $(libdir)/pkgconfig +bindir ?= $(prefix)/bin +includedir ?= $(prefix)/include +USE_AMALGAMATION ?= 2 +AMALGAMATION_LINE_MACROS ?= --linemacros=0 +INSTALL ?= install + +LDFLAGS_ZLIB ?= -lz +LDFLAGS_MATH ?= -lm +LDFLAGS_RPATH ?= -Wl,-rpath -Wl,$(prefix)/lib +LDFLAGS_READLINE ?= -lreadline +LDFLAGS_PTHREAD ?= -lpthread +LDFLAGS_SHOBJ ?= -shared +ENABLE_SHARED ?= 1 +HAVE_WASI_SDK ?= 0 + +INSTALL_noexec = $(INSTALL) -m 0644 +# ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... + +# TCOMPILE = generic target platform compiler invocation +TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) +# TLINK = compiler invocation for when the target will be an executable +TLINK = $(TCC) $(TLINK_EXTRAS) +# TLINK_shared = $(TLINK) invocation specifically for shared libraries +LDFLAGS_SHOBJ ?= -shared +TLINK_shared = $(TLINK) $(LDFLAGS_SHOBJ) + +# TCCX is $(TCC) plus any CFLAGS which are common to most compilations +# for the target platform. In auto-configured builds it is typically +# defined by the main makefile to include configure-time-dependent +# options. +TCCX ?= $(TCC) +TCCX += -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu +TCCX += -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session +TCCX += -I$(TOP)/ext/userauth + +TEMP_STORE ?= -DSQLITE_TEMP_STORE=1 + +# +# LDFLAGS_libsqlite3 should be used with any target which either +# results in building libsqlite3.so, compiles sqlite3.c directly, or +# links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these +# flags are for the target build platform, not necessarily localhost. +# i.e. it should be used with $(TCCX) or $(TLINK) but not $(BCC). +# +LDFLAGS_libsqlite3 = \ + $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_PTHREAD) \ + $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) + +# +# install.XYZ = dirs for installation. They're in quotes to +# accommodate installations where paths have spaces in them. +# +install.bindir = "$(DESTDIR)$(bindir)" +install.libdir = "$(DESTDIR)$(libdir)" +install.includedir = "$(DESTDIR)$(prefix)/include" +install.pkgconfigdir = "$(DESTDIR)$(pkgconfigdir)" +$(install.bindir) $(install.libdir) $(install.includedir) $(install.pkgconfigdir): + $(INSTALL) -d $@ + + +# +# Object files for the SQLite library (non-amalgamation). +# +LIBOBJS0 = alter.o analyze.o attach.o auth.o \ + backup.o bitvec.o btmutex.o btree.o build.o \ + callback.o complete.o ctime.o \ + date.o dbpage.o dbstat.o delete.o \ + expr.o fault.o fkey.o \ + fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o \ + fts3_porter.o fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \ + fts3_tokenize_vtab.o \ + fts3_unicode.o fts3_unicode2.o fts3_write.o \ + fts5.o \ + func.o global.o hash.o \ + icu.o insert.o json.o legacy.o loadext.o \ + main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \ + memdb.o memjournal.o \ + mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \ + notify.o opcodes.o os.o os_kv.o os_unix.o os_win.o \ + pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \ + random.o resolve.o rowset.o rtree.o \ + sqlite3session.o select.o sqlite3rbu.o status.o stmt.o \ + table.o threads.o tokenize.o treeview.o trigger.o \ + update.o upsert.o userauth.o utf.o util.o vacuum.o \ + vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ + vdbetrace.o vdbevtab.o vtab.o \ + wal.o walker.o where.o wherecode.o whereexpr.o \ + window.o +LIBOBJS = $(LIBOBJS0) + +# Object files for the amalgamation. +# +LIBOBJS1 = sqlite3.o + +# Determine the real value of LIBOBJ based on the 'configure' script +# +LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) + +# All of the source code files. +# +SRC = \ + $(TOP)/src/alter.c \ + $(TOP)/src/analyze.c \ + $(TOP)/src/attach.c \ + $(TOP)/src/auth.c \ + $(TOP)/src/backup.c \ + $(TOP)/src/bitvec.c \ + $(TOP)/src/btmutex.c \ + $(TOP)/src/btree.c \ + $(TOP)/src/btree.h \ + $(TOP)/src/btreeInt.h \ + $(TOP)/src/build.c \ + $(TOP)/src/callback.c \ + $(TOP)/src/complete.c \ + $(TOP)/src/ctime.c \ + $(TOP)/src/date.c \ + $(TOP)/src/dbpage.c \ + $(TOP)/src/dbstat.c \ + $(TOP)/src/delete.c \ + $(TOP)/src/expr.c \ + $(TOP)/src/fault.c \ + $(TOP)/src/fkey.c \ + $(TOP)/src/func.c \ + $(TOP)/src/global.c \ + $(TOP)/src/hash.c \ + $(TOP)/src/hash.h \ + $(TOP)/src/hwtime.h \ + $(TOP)/src/insert.c \ + $(TOP)/src/json.c \ + $(TOP)/src/legacy.c \ + $(TOP)/src/loadext.c \ + $(TOP)/src/main.c \ + $(TOP)/src/malloc.c \ + $(TOP)/src/mem0.c \ + $(TOP)/src/mem1.c \ + $(TOP)/src/mem2.c \ + $(TOP)/src/mem3.c \ + $(TOP)/src/mem5.c \ + $(TOP)/src/memdb.c \ + $(TOP)/src/memjournal.c \ + $(TOP)/src/msvc.h \ + $(TOP)/src/mutex.c \ + $(TOP)/src/mutex.h \ + $(TOP)/src/mutex_noop.c \ + $(TOP)/src/mutex_unix.c \ + $(TOP)/src/mutex_w32.c \ + $(TOP)/src/notify.c \ + $(TOP)/src/os.c \ + $(TOP)/src/os.h \ + $(TOP)/src/os_common.h \ + $(TOP)/src/os_setup.h \ + $(TOP)/src/os_kv.c \ + $(TOP)/src/os_unix.c \ + $(TOP)/src/os_win.c \ + $(TOP)/src/os_win.h \ + $(TOP)/src/pager.c \ + $(TOP)/src/pager.h \ + $(TOP)/src/parse.y \ + $(TOP)/src/pcache.c \ + $(TOP)/src/pcache.h \ + $(TOP)/src/pcache1.c \ + $(TOP)/src/pragma.c \ + $(TOP)/src/pragma.h \ + $(TOP)/src/prepare.c \ + $(TOP)/src/printf.c \ + $(TOP)/src/random.c \ + $(TOP)/src/resolve.c \ + $(TOP)/src/rowset.c \ + $(TOP)/src/select.c \ + $(TOP)/src/status.c \ + $(TOP)/src/shell.c.in \ + $(TOP)/src/sqlite.h.in \ + $(TOP)/src/sqlite3ext.h \ + $(TOP)/src/sqliteInt.h \ + $(TOP)/src/sqliteLimit.h \ + $(TOP)/src/table.c \ + $(TOP)/src/tclsqlite.c \ + $(TOP)/src/threads.c \ + $(TOP)/src/tokenize.c \ + $(TOP)/src/treeview.c \ + $(TOP)/src/trigger.c \ + $(TOP)/src/utf.c \ + $(TOP)/src/update.c \ + $(TOP)/src/upsert.c \ + $(TOP)/src/util.c \ + $(TOP)/src/vacuum.c \ + $(TOP)/src/vdbe.c \ + $(TOP)/src/vdbe.h \ + $(TOP)/src/vdbeapi.c \ + $(TOP)/src/vdbeaux.c \ + $(TOP)/src/vdbeblob.c \ + $(TOP)/src/vdbemem.c \ + $(TOP)/src/vdbesort.c \ + $(TOP)/src/vdbetrace.c \ + $(TOP)/src/vdbevtab.c \ + $(TOP)/src/vdbeInt.h \ + $(TOP)/src/vtab.c \ + $(TOP)/src/vxworks.h \ + $(TOP)/src/wal.c \ + $(TOP)/src/wal.h \ + $(TOP)/src/walker.c \ + $(TOP)/src/where.c \ + $(TOP)/src/wherecode.c \ + $(TOP)/src/whereexpr.c \ + $(TOP)/src/whereInt.h \ + $(TOP)/src/window.c + +# Source code for extensions +# +SRC += \ + $(TOP)/ext/fts3/fts3.c \ + $(TOP)/ext/fts3/fts3.h \ + $(TOP)/ext/fts3/fts3Int.h \ + $(TOP)/ext/fts3/fts3_aux.c \ + $(TOP)/ext/fts3/fts3_expr.c \ + $(TOP)/ext/fts3/fts3_hash.c \ + $(TOP)/ext/fts3/fts3_hash.h \ + $(TOP)/ext/fts3/fts3_icu.c \ + $(TOP)/ext/fts3/fts3_porter.c \ + $(TOP)/ext/fts3/fts3_snippet.c \ + $(TOP)/ext/fts3/fts3_tokenizer.h \ + $(TOP)/ext/fts3/fts3_tokenizer.c \ + $(TOP)/ext/fts3/fts3_tokenizer1.c \ + $(TOP)/ext/fts3/fts3_tokenize_vtab.c \ + $(TOP)/ext/fts3/fts3_unicode.c \ + $(TOP)/ext/fts3/fts3_unicode2.c \ + $(TOP)/ext/fts3/fts3_write.c +SRC += \ + $(TOP)/ext/icu/sqliteicu.h \ + $(TOP)/ext/icu/icu.c +SRC += \ + $(TOP)/ext/rtree/rtree.h \ + $(TOP)/ext/rtree/rtree.c \ + $(TOP)/ext/rtree/geopoly.c +SRC += \ + $(TOP)/ext/session/sqlite3session.c \ + $(TOP)/ext/session/sqlite3session.h +SRC += \ + $(TOP)/ext/userauth/userauth.c \ + $(TOP)/ext/userauth/sqlite3userauth.h +SRC += \ + $(TOP)/ext/rbu/sqlite3rbu.h \ + $(TOP)/ext/rbu/sqlite3rbu.c +SRC += \ + $(TOP)/ext/misc/stmt.c + +# Generated source code files +# +SRC += \ + keywordhash.h \ + opcodes.c \ + opcodes.h \ + parse.c \ + parse.h \ + sqlite_cfg.h \ + shell.c \ + sqlite3.h + +# Source code to the test files. +# +TESTSRC = \ + $(TOP)/src/test1.c \ + $(TOP)/src/test2.c \ + $(TOP)/src/test3.c \ + $(TOP)/src/test4.c \ + $(TOP)/src/test5.c \ + $(TOP)/src/test6.c \ + $(TOP)/src/test8.c \ + $(TOP)/src/test9.c \ + $(TOP)/src/test_autoext.c \ + $(TOP)/src/test_async.c \ + $(TOP)/src/test_backup.c \ + $(TOP)/src/test_bestindex.c \ + $(TOP)/src/test_blob.c \ + $(TOP)/src/test_btree.c \ + $(TOP)/src/test_config.c \ + $(TOP)/src/test_delete.c \ + $(TOP)/src/test_demovfs.c \ + $(TOP)/src/test_devsym.c \ + $(TOP)/src/test_fs.c \ + $(TOP)/src/test_func.c \ + $(TOP)/src/test_hexio.c \ + $(TOP)/src/test_init.c \ + $(TOP)/src/test_intarray.c \ + $(TOP)/src/test_journal.c \ + $(TOP)/src/test_malloc.c \ + $(TOP)/src/test_md5.c \ + $(TOP)/src/test_multiplex.c \ + $(TOP)/src/test_mutex.c \ + $(TOP)/src/test_onefile.c \ + $(TOP)/src/test_osinst.c \ + $(TOP)/src/test_pcache.c \ + $(TOP)/src/test_quota.c \ + $(TOP)/src/test_rtree.c \ + $(TOP)/src/test_schema.c \ + $(TOP)/src/test_superlock.c \ + $(TOP)/src/test_syscall.c \ + $(TOP)/src/test_tclsh.c \ + $(TOP)/src/test_tclvar.c \ + $(TOP)/src/test_thread.c \ + $(TOP)/src/test_vdbecov.c \ + $(TOP)/src/test_vfs.c \ + $(TOP)/src/test_windirent.c \ + $(TOP)/src/test_window.c \ + $(TOP)/src/test_wsd.c \ + $(TOP)/ext/fts3/fts3_term.c \ + $(TOP)/ext/fts3/fts3_test.c \ + $(TOP)/ext/session/test_session.c \ + $(TOP)/ext/recover/sqlite3recover.c \ + $(TOP)/ext/recover/dbdata.c \ + $(TOP)/ext/recover/test_recover.c \ + $(TOP)/ext/intck/test_intck.c \ + $(TOP)/ext/intck/sqlite3intck.c \ + $(TOP)/ext/rbu/test_rbu.c + +# Statically linked extensions +# +TESTSRC += \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/test_expert.c \ + $(TOP)/ext/misc/amatch.c \ + $(TOP)/ext/misc/appendvfs.c \ + $(TOP)/ext/misc/basexx.c \ + $(TOP)/ext/misc/carray.c \ + $(TOP)/ext/misc/cksumvfs.c \ + $(TOP)/ext/misc/closure.c \ + $(TOP)/ext/misc/csv.c \ + $(TOP)/ext/misc/decimal.c \ + $(TOP)/ext/misc/eval.c \ + $(TOP)/ext/misc/explain.c \ + $(TOP)/ext/misc/fileio.c \ + $(TOP)/ext/misc/fuzzer.c \ + $(TOP)/ext/fts5/fts5_tcl.c \ + $(TOP)/ext/fts5/fts5_test_mi.c \ + $(TOP)/ext/fts5/fts5_test_tok.c \ + $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/mmapwarm.c \ + $(TOP)/ext/misc/nextchar.c \ + $(TOP)/ext/misc/normalize.c \ + $(TOP)/ext/misc/percentile.c \ + $(TOP)/ext/misc/prefixes.c \ + $(TOP)/ext/misc/qpvtab.c \ + $(TOP)/ext/misc/randomjson.c \ + $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/remember.c \ + $(TOP)/ext/misc/series.c \ + $(TOP)/ext/misc/spellfix.c \ + $(TOP)/ext/misc/stmtrand.c \ + $(TOP)/ext/misc/totype.c \ + $(TOP)/ext/misc/unionvtab.c \ + $(TOP)/ext/misc/wholenumber.c \ + $(TOP)/ext/misc/zipfile.c \ + $(TOP)/ext/userauth/userauth.c \ + $(TOP)/ext/rtree/test_rtreedoc.c + +# Source code to the library files needed by the test fixture +# +TESTSRC2 = \ + $(TOP)/src/attach.c \ + $(TOP)/src/backup.c \ + $(TOP)/src/bitvec.c \ + $(TOP)/src/btree.c \ + $(TOP)/src/build.c \ + $(TOP)/src/ctime.c \ + $(TOP)/src/date.c \ + $(TOP)/src/dbpage.c \ + $(TOP)/src/dbstat.c \ + $(TOP)/src/expr.c \ + $(TOP)/src/func.c \ + $(TOP)/src/global.c \ + $(TOP)/src/insert.c \ + $(TOP)/src/wal.c \ + $(TOP)/src/main.c \ + $(TOP)/src/mem5.c \ + $(TOP)/src/os.c \ + $(TOP)/src/os_kv.c \ + $(TOP)/src/os_unix.c \ + $(TOP)/src/os_win.c \ + $(TOP)/src/pager.c \ + $(TOP)/src/pragma.c \ + $(TOP)/src/prepare.c \ + $(TOP)/src/printf.c \ + $(TOP)/src/random.c \ + $(TOP)/src/pcache.c \ + $(TOP)/src/pcache1.c \ + $(TOP)/src/select.c \ + $(TOP)/src/tokenize.c \ + $(TOP)/src/treeview.c \ + $(TOP)/src/utf.c \ + $(TOP)/src/util.c \ + $(TOP)/src/vdbeapi.c \ + $(TOP)/src/vdbeaux.c \ + $(TOP)/src/vdbe.c \ + $(TOP)/src/vdbemem.c \ + $(TOP)/src/vdbetrace.c \ + $(TOP)/src/vdbevtab.c \ + $(TOP)/src/where.c \ + $(TOP)/src/wherecode.c \ + $(TOP)/src/whereexpr.c \ + $(TOP)/src/window.c \ + parse.c \ + $(TOP)/ext/fts3/fts3.c \ + $(TOP)/ext/fts3/fts3_aux.c \ + $(TOP)/ext/fts3/fts3_expr.c \ + $(TOP)/ext/fts3/fts3_term.c \ + $(TOP)/ext/fts3/fts3_tokenizer.c \ + $(TOP)/ext/fts3/fts3_write.c \ + $(TOP)/ext/async/sqlite3async.c \ + $(TOP)/ext/session/sqlite3session.c \ + $(TOP)/ext/misc/stmt.c \ + fts5.c + +# Header files used by all library source files. +# +HDR = \ + $(TOP)/src/btree.h \ + $(TOP)/src/btreeInt.h \ + $(TOP)/src/hash.h \ + $(TOP)/src/hwtime.h \ + keywordhash.h \ + $(TOP)/src/msvc.h \ + $(TOP)/src/mutex.h \ + opcodes.h \ + $(TOP)/src/os.h \ + $(TOP)/src/os_common.h \ + $(TOP)/src/os_setup.h \ + $(TOP)/src/os_win.h \ + $(TOP)/src/pager.h \ + $(TOP)/src/pcache.h \ + parse.h \ + $(TOP)/src/pragma.h \ + sqlite3.h \ + $(TOP)/src/sqlite3ext.h \ + $(TOP)/src/sqliteInt.h \ + $(TOP)/src/sqliteLimit.h \ + $(TOP)/src/vdbe.h \ + $(TOP)/src/vdbeInt.h \ + $(TOP)/src/vxworks.h \ + $(TOP)/src/whereInt.h \ + sqlite_cfg.h + +# Header files used by extensions +# +EXTHDR += \ + $(TOP)/ext/fts3/fts3.h \ + $(TOP)/ext/fts3/fts3Int.h \ + $(TOP)/ext/fts3/fts3_hash.h \ + $(TOP)/ext/fts3/fts3_tokenizer.h +EXTHDR += \ + $(TOP)/ext/rtree/rtree.h \ + $(TOP)/ext/rtree/geopoly.c +EXTHDR += \ + $(TOP)/ext/icu/sqliteicu.h +EXTHDR += \ + $(TOP)/ext/rtree/sqlite3rtree.h +EXTHDR += \ + $(TOP)/ext/userauth/sqlite3userauth.h + +# executables needed for testing +# +TESTPROGS = \ + testfixture$(TEXE) \ + sqlite3$(TEXE) \ + sqlite3_analyzer$(TEXE) \ + sqldiff$(TEXE) \ + dbhash$(TEXE) \ + sqltclsh$(TEXE) + +# Databases containing fuzzer test cases +# +FUZZDATA = \ + $(TOP)/test/fuzzdata1.db \ + $(TOP)/test/fuzzdata2.db \ + $(TOP)/test/fuzzdata3.db \ + $(TOP)/test/fuzzdata4.db \ + $(TOP)/test/fuzzdata5.db \ + $(TOP)/test/fuzzdata6.db \ + $(TOP)/test/fuzzdata7.db \ + $(TOP)/test/fuzzdata8.db + +# Standard options to testfixture +# +TESTOPTS = --verbose=file --output=test-out.txt + +# Extra compiler options for various shell tools +# +SHELL_OPT += -DSQLITE_DQS=0 +SHELL_OPT += -DSQLITE_ENABLE_FTS4 +#SHELL_OPT += -DSQLITE_ENABLE_FTS5 +SHELL_OPT += -DSQLITE_ENABLE_RTREE +SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS +SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB +SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB +SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB +SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB +SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC +SHELL_OPT += -DSQLITE_STRICT_SUBTYPE=1 +FUZZERSHELL_OPT = +FUZZCHECK_OPT += -I$(TOP)/test +FUZZCHECK_OPT += -I$(TOP)/ext/recover +FUZZCHECK_OPT += \ + -DSQLITE_OSS_FUZZ \ + -DSQLITE_ENABLE_BYTECODE_VTAB \ + -DSQLITE_ENABLE_DBPAGE_VTAB \ + -DSQLITE_ENABLE_DBSTAT_VTAB \ + -DSQLITE_ENABLE_BYTECODE_VTAB \ + -DSQLITE_ENABLE_DESERIALIZE \ + -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ + -DSQLITE_ENABLE_FTS3_PARENTHESIS \ + -DSQLITE_ENABLE_FTS4 \ + -DSQLITE_ENABLE_FTS5 \ + -DSQLITE_ENABLE_GEOPOLY \ + -DSQLITE_ENABLE_MATH_FUNCTIONS \ + -DSQLITE_ENABLE_MEMSYS5 \ + -DSQLITE_ENABLE_NORMALIZE \ + -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ + -DSQLITE_ENABLE_PREUPDATE_HOOK \ + -DSQLITE_ENABLE_RTREE \ + -DSQLITE_ENABLE_SESSION \ + -DSQLITE_ENABLE_STMTVTAB \ + -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \ + -DSQLITE_ENABLE_STAT4 \ + -DSQLITE_ENABLE_STMT_SCANSTATUS \ + -DSQLITE_MAX_MEMORY=50000000 \ + -DSQLITE_MAX_MMAP_SIZE=0 \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_PRINTF_PRECISION_LIMIT=1000 \ + -DSQLITE_PRIVATE="" \ + -DSQLITE_STRICT_SUBTYPE=1 \ + -DSQLITE_STATIC_RANDOMJSON + +FUZZCHECK_SRC += $(TOP)/test/fuzzcheck.c +FUZZCHECK_SRC += $(TOP)/test/ossfuzz.c +FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c +FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c +FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c +FUZZCHECK_SRC += $(TOP)/test/vt02.c +FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c +FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c +DBFUZZ_OPT = +ST_OPT = -DSQLITE_OS_KV_OPTIONAL + + +has_tclsh84: + sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) + touch has_tclsh84 + +has_tclsh85: + sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) + touch has_tclsh85 + +has_tclconfig: + @if [ x = "x$(TCL_CONFIG_SH)" ]; then \ + echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ + fi + touch has_tclconfig + +# +# This target creates a directory named "tsrc" and fills it with +# copies of all of the C source code and header files needed to +# build on the target system. Some of the C source code and header +# files are automatically generated. This target takes care of +# all that automatic generation. +# +.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(BTCLSH) # has_tclsh84 + rm -rf tsrc + mkdir tsrc + cp -f $(SRC) tsrc + rm tsrc/sqlite.h.in tsrc/parse.y + $(BTCLSH) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new + mv vdbe.new tsrc/vdbe.c + cp fts5.c fts5.h tsrc + touch .target_source + +libsqlite3.LIB = libsqlite3$(TLIB) +libsqlite3.SO = libsqlite3$(TDLL) + +# Rules to build the LEMON compiler generator +# +lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c + $(BCC) -o $@ $(TOP)/tool/lemon.c + cp $(TOP)/tool/lempar.c . + +# Rules to build the program that generates the source-id +# +mksourceid$(BEXE): $(TOP)/tool/mksourceid.c + $(BCC) -o $@ $(TOP)/tool/mksourceid.c + +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ + $(TOP)/VERSION $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h + +sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify \ + $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + cp tsrc/sqlite3ext.h . + cp $(TOP)/ext/session/sqlite3session.h . + +sqlite3r.h: sqlite3.h $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h + +sqlite3r.c: sqlite3.c sqlite3r.h $(BTCLSH) # has_tclsh84 + cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ + cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ + cp $(TOP)/ext/recover/dbdata.c tsrc/ + $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + +sqlite3ext.h: .target_source + cp tsrc/sqlite3ext.h . + +# Rules to build individual *.o files from generated *.c files. This +# applies to: +# +# parse.o +# opcodes.o +# +parse.o: parse.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c parse.c + +opcodes.o: opcodes.c + $(TCOMPILE) $(TEMP_STORE) -c opcodes.c + +# Rules to build individual *.o files from files in the src directory. +# +alter.o: $(TOP)/src/alter.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c + +analyze.o: $(TOP)/src/analyze.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c + +attach.o: $(TOP)/src/attach.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c + +auth.o: $(TOP)/src/auth.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c + +backup.o: $(TOP)/src/backup.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c + +bitvec.o: $(TOP)/src/bitvec.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c + +btmutex.o: $(TOP)/src/btmutex.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c + +btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c + +build.o: $(TOP)/src/build.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c + +callback.o: $(TOP)/src/callback.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c + +complete.o: $(TOP)/src/complete.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c + +ctime.o: $(TOP)/src/ctime.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c + +date.o: $(TOP)/src/date.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c + +dbpage.o: $(TOP)/src/dbpage.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c + +dbstat.o: $(TOP)/src/dbstat.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c + +delete.o: $(TOP)/src/delete.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c + +expr.o: $(TOP)/src/expr.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c + +fault.o: $(TOP)/src/fault.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c + +fkey.o: $(TOP)/src/fkey.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c + +func.o: $(TOP)/src/func.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c + +global.o: $(TOP)/src/global.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c + +hash.o: $(TOP)/src/hash.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c + +insert.o: $(TOP)/src/insert.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c + +json.o: $(TOP)/src/json.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c + +legacy.o: $(TOP)/src/legacy.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c + +loadext.o: $(TOP)/src/loadext.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c + +main.o: $(TOP)/src/main.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c + +malloc.o: $(TOP)/src/malloc.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c + +mem0.o: $(TOP)/src/mem0.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c + +mem1.o: $(TOP)/src/mem1.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c + +mem2.o: $(TOP)/src/mem2.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c + +mem3.o: $(TOP)/src/mem3.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c + +mem5.o: $(TOP)/src/mem5.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c + +memdb.o: $(TOP)/src/memdb.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c + +memjournal.o: $(TOP)/src/memjournal.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c + +mutex.o: $(TOP)/src/mutex.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c + +mutex_noop.o: $(TOP)/src/mutex_noop.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c + +mutex_unix.o: $(TOP)/src/mutex_unix.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c + +mutex_w32.o: $(TOP)/src/mutex_w32.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c + +notify.o: $(TOP)/src/notify.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c + +pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c + +pcache.o: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c + +pcache1.o: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c + +os.o: $(TOP)/src/os.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c + +os_kv.o: $(TOP)/src/os_kv.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c + +os_unix.o: $(TOP)/src/os_unix.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c + +os_win.o: $(TOP)/src/os_win.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c + +pragma.o: $(TOP)/src/pragma.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c + +prepare.o: $(TOP)/src/prepare.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c + +printf.o: $(TOP)/src/printf.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c + +random.o: $(TOP)/src/random.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c + +resolve.o: $(TOP)/src/resolve.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c + +rowset.o: $(TOP)/src/rowset.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c + +select.o: $(TOP)/src/select.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c + +status.o: $(TOP)/src/status.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c + +sqlite3.o: sqlite3.h sqlite3.c + $(TCOMPILE) $(TEMP_STORE) -c sqlite3.c + +table.o: $(TOP)/src/table.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c + +threads.o: $(TOP)/src/threads.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c + +tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c + +treeview.o: $(TOP)/src/treeview.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/treeview.c + +trigger.o: $(TOP)/src/trigger.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c + +update.o: $(TOP)/src/update.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c + +upsert.o: $(TOP)/src/upsert.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c + +utf.o: $(TOP)/src/utf.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c + +util.o: $(TOP)/src/util.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c + +vacuum.o: $(TOP)/src/vacuum.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c + +vdbe.o: $(TOP)/src/vdbe.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c + +vdbeapi.o: $(TOP)/src/vdbeapi.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c + +vdbeaux.o: $(TOP)/src/vdbeaux.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c + +vdbeblob.o: $(TOP)/src/vdbeblob.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c + +vdbemem.o: $(TOP)/src/vdbemem.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c + +vdbesort.o: $(TOP)/src/vdbesort.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c + +vdbetrace.o: $(TOP)/src/vdbetrace.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c + +vdbevtab.o: $(TOP)/src/vdbevtab.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c + +vtab.o: $(TOP)/src/vtab.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c + +wal.o: $(TOP)/src/wal.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c + +walker.o: $(TOP)/src/walker.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c + +where.o: $(TOP)/src/where.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c + +wherecode.o: $(TOP)/src/wherecode.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c + +whereexpr.o: $(TOP)/src/whereexpr.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c + +window.o: $(TOP)/src/window.c $(HDR) + $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c + +tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) + $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) \ + -c $(TOP)/src/tclsqlite.c + +tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(HDR) + $(TCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) + +tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(HDR) + $(TCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) + +tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) + $(TLINK) -o $@ tclsqlite-shell.o \ + $(libsqlite3.LIB) $(TCL_INCLUDE_SPEC) $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) + +# Rules to build opcodes.c and opcodes.h +# +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c + +opcodes.h: parse.h $(TOP)/src/vdbe.c \ + $(TOP)/tool/mkopcodeh.tcl $(BTCLSH) # has_tclsh84 + cat parse.h $(TOP)/src/vdbe.c | $(BTCLSH) $(TOP)/tool/mkopcodeh.tcl >opcodes.h + +# Rules to build parse.c and parse.h - the outputs of lemon. +# +parse.h: parse.c + +parse.c: $(TOP)/src/parse.y lemon$(BEXE) + cp $(TOP)/src/parse.y . + ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y + +sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(BTCLSH) # has_tclsh84 + echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ + echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ + cat $(TOP)/VERSION | $(BTCLSH) $(TOP)/tool/replace.tcl exact . , >>$@ + echo '#endif' >>sqlite3rc.h + +mkkeywordhash$(BEXE): $(TOP)/tool/mkkeywordhash.c + $(BCC) -o $@ $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c +keywordhash.h: mkkeywordhash$(BEXE) + ./mkkeywordhash$(BEXE) > $@ + + +$(libsqlite3.LIB): $(LIBOBJ) + $(AR) crs $@ $(LIBOBJ) +lib: $(libsqlite3.LIB) +all: lib + +target_libsqlite3_so_1 = $(libsqlite3.SO) +target_libsqlite3_so = $(target_libsqlite3_so_$(ENABLE_SHARED)) +$(libsqlite3.SO): $(LIBOBJ) + $(TLINK_shared) -o $@ $(LIBOBJ) $(LDFLAGS_libsqlite3) +so: $(target_libsqlite3_so) +all: so + +sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/split-sqlite3c.tcl + +# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(RELEASE) and +# create symlinks which point to it. Do we really need all of this +# hoop-jumping? Can we not simply install the .so as-is to +# libsqlite3.so (without the versioned bits)? +# +# The historical SQLite build always used a version number of 0.8.6 +# for reasons lost to history but having something to do with libtool +# (which is not longer used in this tree). +# +install-so-1: $(install.libdir) $(libsqlite3.SO) + $(INSTALL) $(libsqlite3.SO) $(install.libdir); \ + cd $(install.libdir); \ + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(RELEASE); \ + mv $(libsqlite3.SO) $(libsqlite3.SO).$(RELEASE); \ + ln -s $(libsqlite3.SO).$(RELEASE) $(libsqlite3.SO).3; \ + ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) +install-so-0: +install: install-so-$(ENABLE_SHARED) + +# Install $(libsqlite3.LIB) +# +install-lib: $(install.libdir) $(libsqlite3.LIB) + $(INSTALL_noexec) $(libsqlite3.LIB) $(install.libdir) +install: install-lib + +# Install C header files +# +install-includes: sqlite3.h $(install.includedir) + $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install.includedir) +install: install-includes + +# libtclsqlite3... +# +pkgIndex.tcl: + echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ +libtclsqlite3.SO = libtclsqlite3$(TDLL) +target_libtclsqlite3_1 = $(libtclsqlite3.SO) +target_libtclsqlite3 = $(target_libtclsqlite3_$(HAVE_TCL)) +$(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) + $(TLINK_shared) -o $@ tclsqlite.o \ + $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS_libsqlite3) \ + $(libsqlite3.LIB) $(TCLLIB_RPATH) +libtcl: $(target_libtclsqlite3) +all: libtcl + +install.tcldir = "$(DESTDIR)$(TCLLIBDIR)" +install-tcl-1: install-lib $(target_libtclsqlite3) pkgIndex.tcl + @if [ "x$(DESTDIR)" = "x$(install.tcldir)" ]; then echo "TCLLIBDIR is not set." 1>&2; exit 1; fi + $(INSTALL) -d $(install.tcldir) + $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) + $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) +install-tcl-0 install-tcl-: +install: install-tcl-$(HAVE_TCL) + +tclsqlite3.c: sqlite3.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 + +# Build the SQLite TCL extension in a way that make it compatible +# with whatever version of TCL is running as $TCLSH_CMD, possibly defined +# by --with-tclsh= +# +tclextension: tclsqlite3.c + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) + +# Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD +# to find it. +# +tclextension-install: tclsqlite3.c + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) + +# Install the SQLite TCL extension that is used by $TCLSH_CMD +# +tclextension-uninstall: + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall + +# List all installed the SQLite TCL extension that is are accessible +# by $TCLSH_CMD, included prior versions. +# +tclextension-list: + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info + +# FTS5 things +# +FTS5_SRC = \ + $(TOP)/ext/fts5/fts5.h \ + $(TOP)/ext/fts5/fts5Int.h \ + $(TOP)/ext/fts5/fts5_aux.c \ + $(TOP)/ext/fts5/fts5_buffer.c \ + $(TOP)/ext/fts5/fts5_main.c \ + $(TOP)/ext/fts5/fts5_config.c \ + $(TOP)/ext/fts5/fts5_expr.c \ + $(TOP)/ext/fts5/fts5_hash.c \ + $(TOP)/ext/fts5/fts5_index.c \ + fts5parse.c fts5parse.h \ + $(TOP)/ext/fts5/fts5_storage.c \ + $(TOP)/ext/fts5/fts5_tokenize.c \ + $(TOP)/ext/fts5/fts5_unicode2.c \ + $(TOP)/ext/fts5/fts5_varint.c \ + $(TOP)/ext/fts5/fts5_vocab.c \ + +fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) + cp $(TOP)/ext/fts5/fts5parse.y . + rm -f fts5parse.h + ./lemon$(BEXE) $(OPTS) -S fts5parse.y + +fts5parse.h: fts5parse.c + +fts5.c: $(FTS5_SRC) $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/ext/fts5/tool/mkfts5c.tcl + cp $(TOP)/ext/fts5/fts5.h . + +fts5.o: fts5.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c fts5.c + +sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c + + +# Rules to build the 'testfixture' application. +# +# If using the amalgamation, use sqlite3.c directly to build the test +# fixture. Otherwise link against libsqlite3.a. (This distinction is +# necessary because the test fixture requires non-API symbols which are +# hidden when the library is built via the amalgamation). +# +TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 +TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit +TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE +TESTFIXTURE_FLAGS += -DBUILD_sqlite +TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 +TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB +TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC +TESTFIXTURE_FLAGS += -DSQLITE_STATIC_RANDOMJSON +TESTFIXTURE_FLAGS += -DSQLITE_STRICT_SUBTYPE=1 + +TESTFIXTURE_SRC0 = $(TESTSRC2) $(libsqlite3.LIB) +TESTFIXTURE_SRC1 = sqlite3.c +TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c +TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) + +testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) + $(TLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ + -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(LDFLAGS_libsqlite3) $(TCL_INCLUDE_SPEC) + +coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) + +testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) + +# A very detailed test running most or all test cases +fulltest: alltest fuzztest + +# Run most or all tcl test cases +alltest: $(TESTPROGS) + ./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS) + +# Really really long testing +soaktest: $(TESTPROGS) + ./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS) + +# Do extra testing but not everything. +fulltestonly: $(TESTPROGS) fuzztest + ./testfixture$(TEXE) $(TOP)/test/full.test + +# Fuzz testing +# +# WARNING: When the "fuzztest" target is run by the testrunner.tcl script, +# it does not actually run this code. Instead, it schedules equivalent +# commands. Therefore, if this target is updated, then code in +# testrunner_data.tcl (search for "trd_fuzztest_data") must also be updated. +# +fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) + ./fuzzcheck$(TEXE) $(FUZZDATA) + ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db + +valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) + valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) + valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db + +# The veryquick.test TCL tests. +# +tcltest: ./testfixture$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) + +# Runs all the same tests cases as the "tcltest" target but uses +# the testrunner.tcl script to run them in multiple cores +# concurrently. +testrunner: testfixture$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl + +# This is the testing target preferred by the core SQLite developers. +# It runs tests under a standard configuration, regardless of how +# ./configure was run. The devs run "make devtest" prior to each +# check-in, at a minimum. Probably other tests too, but at least this +# one. +# +devtest: srctree-check sourcetest + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) + +mdevtest: srctree-check has_tclsh85 + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS) + +sdevtest: has_tclsh85 + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS) + +# Validate that various generated files in the source tree +# are up-to-date. +# +srctree-check: $(TOP)/tool/srctree-check.tcl + $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl + +# Testing for a release +# +releasetest: srctree-check has_tclsh85 verify-source + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS) + +# Minimal testing that runs in less than 3 minutes +# +quicktest: ./testfixture$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS) + +# Try to run tests on whatever options are specified by the +# ./configure. The developers seldom use this target. Instead +# they use "make devtest" which runs tests on a standard set of +# options regardless of how SQLite is configured. This "test" +# target is provided for legacy only. +# +test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest + +# Run a test using valgrind. This can take a really long time +# because valgrind is so much slower than a native machine. +# +valgrindtest: $(TESTPROGS) valgrindfuzz + OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) + +# A very fast test that checks basic sanity. The name comes from +# the 60s-era electronics testing: "Turn it on and see if smoke +# comes out." +# +smoketest: $(TESTPROGS) fuzzcheck$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS) + +shelltest: + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell + +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ + $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 + $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c + +sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c + $(TLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TCL_INCLUDE_SPEC) $(LDFLAGS_libsqlite3) + +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 has_tclsh85 + $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c + +sqltclsh$(TEXE): has_tclconfig sqltclsh.c + $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) + +sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/expert.c sqlite3.c + $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite3) + +CHECKER_DEPS =\ + $(TOP)/tool/mkccode.tcl \ + sqlite3.c \ + $(TOP)/src/tclsqlite.c \ + $(TOP)/ext/repair/sqlite3_checker.tcl \ + $(TOP)/ext/repair/checkindex.c \ + $(TOP)/ext/repair/checkfreelist.c \ + $(TOP)/ext/misc/btreeinfo.c \ + $(TOP)/ext/repair/sqlite3_checker.c.in + +sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 + $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ + +sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c + $(TLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) + +dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo + $(TLINK) -DDBDUMP_STANDALONE -o $@ \ + $(TOP)/ext/misc/dbdump.c sqlite3.lo $(LDFLAGS_libsqlite3) + +dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c + $(TLINK)-o $@ $(TOP)/tool/dbtotxt.c + +showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(LDFLAGS_libsqlite3) + +showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(LDFLAGS_libsqlite3) + +showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(LDFLAGS_libsqlite3) + +showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(LDFLAGS_libsqlite3) + +showshm$(TEXE): $(TOP)/tool/showshm.c + $(TLINK) -o $@ $(TOP)/tool/showshm.c + +index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo + $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(LDFLAGS_libsqlite3) + +changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(LDFLAGS_libsqlite3) + +changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(LDFLAGS_libsqlite3) + +rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(LDFLAGS_libsqlite3) + +atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(LDFLAGS_libsqlite3) + +LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h + $(TLINK) -I. -o $@ $(TOP)/tool/logest.c + +wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo + $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(LDFLAGS_libsqlite3) + +speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile + $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS_libsqlite3) + +#XX#startup$(TEXE): $(TOP)/test/startup.c sqlite3.c +#XX# $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) +# ^^^ note that it wants $(TLIBS) (a.k.a. $(LDFLAGS_libsqlite3) but is using $(CC) +# instead of $(BCC). + +KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ + +kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c + $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS_libsqlite3) + +rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o + $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS_libsqlite3) + +loadfts$(EXE): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) + $(TLINK) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS_libsqlite3) + +# This target will fail if the SQLite amalgamation contains any exported +# symbols that do not begin with "sqlite3_". It is run as part of the +# releasetest.tcl script. +# +VALIDIDS=' sqlite3(changeset|changegroup|session)?_' +checksymbols: sqlite3.o + nm -g --defined-only sqlite3.o + nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 + echo '0 errors out of 1 tests' + +# Build a ZIP archive containing various command-line tools. +# +tool-zip: testfixture$(TEXE) sqlite3$(TEXE) sqldiff$(TEXE) \ + sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) $(TOP)/tool/mktoolzip.tcl + strip sqlite3$(TEXE) sqldiff$(TEXE) sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) + ./testfixture$(TEXE) $(TOP)/tool/mktoolzip.tcl + +#XX# TODO: adapt the autoconf amalgamation for autosetup +#XX# +#XX## Build the amalgamation-autoconf package. The amalamgation-tarball target builds +#XX## a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. +#XX## The snapshot-tarball target builds a tarball named by the SHA1 hash +#XX## +#XX#amalgamation-tarball: sqlite3.c sqlite3rc.h +#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal +#XX# +#XX#snapshot-tarball: sqlite3.c sqlite3rc.h +#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot +#XX# + +# The next two rules are used to support the "threadtest" target. Building +# threadtest runs a few thread-safety tests that are implemented in C. This +# target is invoked by the releasetest.tcl script. +# +THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ + $(TOP)/test/tt3_checkpoint.c \ + $(TOP)/test/tt3_index.c \ + $(TOP)/test/tt3_vacuum.c \ + $(TOP)/test/tt3_stress.c \ + $(TOP)/test/tt3_lookaside1.c + +threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC) + $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(LDFLAGS_libsqlite3) + +threadtest: threadtest3$(TEXE) + ./threadtest3$(TEXE) + +threadtest5: sqlite3.c $(TOP)/test/threadtest5.c + $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS_libsqlite3) + +sqlite3$(TEXE): shell.c sqlite3.c + $(TCCX) $(CFLAGS_readline) $(SHELL_OPT) -o $@ \ + shell.c sqlite3.c \ + $(LDFLAGS_libsqlite3) $(LDFLAGS_READLINE) + +install-cli-0: sqlite3$(TEXT) $(install.bindir) + $(INSTALL) -s sqlite3$(TEXT) $(install.bindir) +install-cli-1: +install: install-cli-$(HAVE_WASI_SDK) + +sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h + $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite3) + +install-diff: sqldiff$(TEXE) $(install.bindir) + $(INSTALL) -s sqldiff$(TEXT) $(install.bindir) +#install: install-diff + +dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h + $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite3) + +RSYNC_SRC = \ + $(TOP)/tool/sqlite3_rsync.c \ + sqlite3.c + +RSYNC_OPT = \ + -DSQLITE_ENABLE_DBPAGE_VTAB \ + -USQLITE_THREADSAFE \ + -DSQLITE_THREADSAFE=0 \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_OMIT_DEPRECATED + +sqlite3_rsync$(TEXE): $(RSYNC_SRC) + $(TCCX) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) + +install-rsync: sqlite3_rsync$(TEXE) $(install.bindir) + $(INSTALL) sqlite3_rsync$(TEXT) $(install.bindir) +#install: install-rsync + +scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o + $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ + $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS_libsqlite3) + +srcck1$(BEXE): $(TOP)/tool/srcck1.c + $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c + +sourcetest: srcck1$(BEXE) sqlite3.c + ./srcck1$(BEXE) sqlite3.c + +src-verify$(BEXE): $(TOP)/tool/src-verify.c + $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c + +verify-source: ./src-verify$(BEXE) + ./src-verify$(BEXE) $(TOP) + +fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h + $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ + $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: fuzzershell$(TEXE) + +fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: fuzzcheck$(TEXE) + +fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(TLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ + sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: fuzzcheck-asan$(TEXE) + + +fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(TLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ + sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: fuzzcheck-ubsan$(TEXE) + +# Usage: FUZZDB=filename make run-fuzzcheck +# +# Where filename is a fuzzcheck database, this target builds and runs +# fuzzcheck, fuzzcheck-asan, and fuzzcheck-ubsan on that database. +# +# FUZZDB can be a glob pattern of two or more databases. Example: +# +# FUZZDB=test/fuzzdata*.db make run-fuzzcheck +# +run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) + @if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi + ./fuzzcheck$(TEXE) --spinner $(FUZZDB) + ./fuzzcheck-asan$(TEXE) --spinner $(FUZZDB) + ./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB) + +ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h + $(TLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ + $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: ossshell$(TEXE) + +sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h + $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(LDFLAGS_libsqlite3) +fuzzy: sessionfuzz$(TEXE) + +dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h + $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) +fuzzy: dbfuzz$(TEXE) + +DBFUZZ2_OPTS = \ + -USQLITE_THREADSAFE \ + -DSQLITE_THREADSAFE=0 \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_DEBUG \ + -DSQLITE_ENABLE_DBSTAT_VTAB \ + -DSQLITE_ENABLE_BYTECODE_VTAB \ + -DSQLITE_ENABLE_RTREE \ + -DSQLITE_ENABLE_FTS4 \ + -DSQLITE_ENABLE_FTS5 + +dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h + $(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ + -DSTANDALONE -o dbfuzz2 \ + $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS_libsqlite3) + mkdir -p dbfuzz2-dir + cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir +fuzzy: dbfuzz2$(TEXE) + +mptester$(TEXE): $(libsqlite3.LIB) $(TOP)/mptest/mptest.c + $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c $(libsqlite3.LIB) \ + $(LDFLAGS_libsqlite3) + +MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 +MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 +mptest: mptester$(TEXE) + rm -f mptest.db + $(MPTEST1) --journalmode DELETE + $(MPTEST2) --journalmode WAL + $(MPTEST1) --journalmode WAL + $(MPTEST2) --journalmode PERSIST + $(MPTEST1) --journalmode PERSIST + $(MPTEST2) --journalmode TRUNCATE + $(MPTEST1) --journalmode TRUNCATE + $(MPTEST2) --journalmode DELETE + +# Source and header files that shell.c depends on +SHELL_DEP = \ + $(TOP)/src/shell.c.in \ + $(TOP)/ext/consio/console_io.c \ + $(TOP)/ext/consio/console_io.h \ + $(TOP)/ext/expert/sqlite3expert.c \ + $(TOP)/ext/expert/sqlite3expert.h \ + $(TOP)/ext/intck/sqlite3intck.c \ + $(TOP)/ext/intck/sqlite3intck.h \ + $(TOP)/ext/misc/appendvfs.c \ + $(TOP)/ext/misc/base64.c \ + $(TOP)/ext/misc/base85.c \ + $(TOP)/ext/misc/completion.c \ + $(TOP)/ext/misc/decimal.c \ + $(TOP)/ext/misc/fileio.c \ + $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/memtrace.c \ + $(TOP)/ext/misc/pcachetrace.c \ + $(TOP)/ext/misc/percentile.c \ + $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/series.c \ + $(TOP)/ext/misc/sha1.c \ + $(TOP)/ext/misc/shathree.c \ + $(TOP)/ext/misc/sqlar.c \ + $(TOP)/ext/misc/uint.c \ + $(TOP)/ext/misc/vfstrace.c \ + $(TOP)/ext/misc/zipfile.c \ + $(TOP)/ext/recover/dbdata.c \ + $(TOP)/ext/recover/sqlite3recover.c \ + $(TOP)/ext/recover/sqlite3recover.h \ + $(TOP)/src/test_windirent.c \ + $(TOP)/src/test_windirent.h + +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/mkshellc.tcl >shell.c + + +# Rules to build the extension objects. +# +icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c + +fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c + +fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c + +fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c + +fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c + +fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c + +fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c + +fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c + +fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c + +fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c + +fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c + +fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c + +fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c + +fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c + +rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c + +userauth.o: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c + +sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c + +stmt.o: $(TOP)/ext/misc/stmt.c + $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c + +# +# tool/version-info: a utility for emitting sqlite3 version info +# in various forms. +# +version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h + $(TLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c + +# +# Windows section +# +dll: sqlite3.dll +sqlite3.def: $(LIBOBJ) + echo 'EXPORTS' >sqlite3.def + nm $(LIBOBJ) | grep ' T ' | grep ' _sqlite3_' \ + | sed 's/^.* _//' >>sqlite3.def + +sqlite3.dll: $(LIBOBJ) sqlite3.def + $(TCCX) $(LDFLAGS_SHOBJ) -o $@ sqlite3.def \ + -Wl,"--strip-all" $(LIBOBJ) + + +# Remove build products sufficient so that subsequent makes will recompile +# everything from scratch. Do not remove: +# +# * test results and test logs +# * output from ./configure +# +tidy: + rm -f *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) + rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h + rm -rf .libs .deps tsrc .target_source + rm -f lemon$(BEXE) sqlite*.tar.gz + rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) + rm -f parse.* fts5parse.* + rm -f $(libsqlite3.SO) $(libsqlite3.LIB) + rm -f tclsqlite3$(TEXE) $(TESTPROGS) + rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) + rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) + rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) + rm -f *.dll *.lib *.exp *.pc *.vsix *.so *.dylib pkgIndex.tcl + rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) sqlite3_expert$(TEXE) + rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) + rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) + rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) dbfuzz2-asan$(TEXE) dbfuzz2-msan$(TEXE) + rm -f fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE) + rm -f sessionfuzz$(TEXE) + rm -f threadtest5$(TEXE) + rm -f src-verify$(BEXE) has_tclsh* has_tclconfig + rm -f tclsqlite3.c + rm -f sqlite3rc.h sqlite3.def + +# +# Removes build products and test logs. Retains ./configure outputs. +# +clean: tidy + rm -rf omittest* testrunner* testdir* + -gmake -C ext/wasm distclean 2>/dev/null; true + +# Clean up everything. No exceptions. +distclean: clean + rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile + rm -f $(TOP)/tool/emcc.sh + -gmake -C ext/wasm distclean 2>/dev/null; true diff --git a/manifest b/manifest index 2eb7bebd49..d31f53fa5b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Factor\sout\sall\sautosetup-processed\s@if/@else\sblocks\sfrom\sMakefile.in\sin\sprep\sfor\smoving\smost\sof\sthe\smakefile\scode\sinto\smain.mk\s(which\shas,\sso\sfar,\sbeen\scompletely\soverlooked\sin\sthis\sport\sbut\swill\snow\sbecome\sthe\smain\sbasis\sfor\sthe\sstatic\sparts\sof\sthe\sbuild).\sThe\sidea\sis\sthat\sall\sbuild\sconfiguration\sgoes\sinto\sa\splatform-dependent\smakefile\swhich\sthen\sincludes\smain.mk. -D 2024-10-19T18:31:47.423 +C Move\smost\sof\sthe\smakefile\scode\sinto\sthe\sstatic\smain.mk. +D 2024-10-19T20:26:17.451 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 799e30c5ea3622e4909e2befa455bfa4e90ec214cb06a714c469897da3166b9e +F Makefile.in 1167ba2d57c63bbcbf96e919b6783665f751cc04e4b75985ed67f2a59b8074e6 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ea3f49474ea443c294ca75820839fb43db4a9f72cd4b14b895ddc9fa73a4e9b0 +F main.mk 10bec40eca5f1e371130e12d0eef005d630b7f0885d3a0137ad489c54a78f9b7 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 510afccf02dc9c3e3b928c64c34d10bee66a2343ecec6e24c4770cb0f139cd65 -R 7a8eadbb3ae7a887d98a01ebf4e8c64c +P 707e0f5857d58ec8b457270f988126b1dd0f01b5a3445a43ff7b5429324b1b3d +R 7e557d1ad5ee2c5b2e44bb3a9becbb6a U stephan -Z 7236fe64030e3971014f63694120dff4 +Z 03e1de4c6fd20e15dd82a14719fd967a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5d2c7d818b..72e5783713 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -707e0f5857d58ec8b457270f988126b1dd0f01b5a3445a43ff7b5429324b1b3d +09905ed094f7102dbb4fc81b059452c50b48b0f3a2bd9736bed364b0639d89d7 From 003d304c9ba78235b57878d76e8577e530cfb014 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 19 Oct 2024 20:53:46 +0000 Subject: [PATCH 069/522] More build cleanups and get it working with BSD make (which apparently does not support $< and behaves slightly differently than gmake with X?=Y). FossilOrigin-Name: dcf4fc78fb2813d37eb56c358009f1e5225f28a0c85c710c8127db330efaf319 --- Makefile.in | 14 +++++++------- auto.def | 16 ++++++++++------ autosetup/hwaci-common.tcl | 15 +++++++++++++-- main.mk | 17 ++++++++++++++--- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 6 files changed, 54 insertions(+), 28 deletions(-) diff --git a/Makefile.in b/Makefile.in index d414ca3d9b..756790d099 100644 --- a/Makefile.in +++ b/Makefile.in @@ -27,8 +27,8 @@ LDFLAGS_PTHREAD ?= @LDFLAGS_PTHREAD@ LDFLAGS_SHOBJ ?= @SHOBJ_LDFLAGS@ ENABLE_SHARED ?= @ENABLE_SHARED@ HAVE_WASI_SDK ?= @HAVE_WASI_SDK@ -AR ?= @AR@ -CC ?= @CC@ +AR = @AR@ +CC = @CC@ # C Compiler and options for use in building executables that # will run on the platform that is doing the build. @@ -42,11 +42,11 @@ BCC = @BUILD_CC@ @BUILD_CFLAGS@ # are provide so that these aspects of the build process can be changed # on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" # -CFLAGS ?= @CFLAGS@ @SH_CFLAGS@ -CPPFLAGS ?= @CPPFLAGS@ +CFLAGS = @CFLAGS@ @SH_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ # CFLAGS_stdio3 ==> for sqlite3_stdio.h CFLAGS_stdio3 := -I$(TOP)/ext/misc -TCC = $(CC) $(CFLAGS) +TCC ?= $(CC) $(CFLAGS) # Define -DNDEBUG to compile without debugging (i.e., for production usage) # Omitting the define will cause extra debugging code to be inserted and @@ -106,7 +106,7 @@ TLIBS = $(LIBS) JIMSH = @srcdir@/jimsh CFLAGS_JIMSH ?= @CFLAGS_JIMSH@ $(JIMSH): $(TOP)/autosetup/jimsh0.c - $(BCC) -o $(JIMSH) $(CFLAGS_JIMSH) $< + $(BCC) -o $(JIMSH) $(CFLAGS_JIMSH) $(TOP)/autosetup/jimsh0.c # BTCLSH is the tclsh-compatible app used for running various code # generators and other in-tree tools, as opposed to the TCL-based @@ -297,7 +297,7 @@ fiddle: sqlite3.c shell.c # ./custom.rws: ./tool/custom.txt @echo 'Updating custom dictionary from tool/custom.txt' - aspell --lang=en create master ./custom.rws < $< + aspell --lang=en create master ./custom.rws < ./tool/custom.txt # Note that jimsh does not work here: # https://github.com/msteveb/jimtcl/issues/319 misspell: ./custom.rws has_tclsh84 diff --git a/auto.def b/auto.def index c93aceef49..071d95c66d 100644 --- a/auto.def +++ b/auto.def @@ -345,17 +345,21 @@ hwaci-if-opt-truthy with-debug { # infrastructure. This must only be 1 for environments where # tclConfig.sh can be found. # -# - TCLSH_CMD is the path to the canonical tclsh. It never refers to -# jimtcl. +# - TCLSH_CMD is the path to the canonical tclsh or "". It never +# refers to jimtcl. # # - TCL_CONFIG_SH is the path to tclConfig.sh or "". # # - TCLLIBDIR is the dir to which libtclsqlite3 gets installed. # -# - TCLLIB_RPATH = the -rpath flag specific to libtclsqlite3. +# - TCLLIB_RPATH = the -rpath flag specific to libtclsqlite3, which +# will usually differ from the rpath used by the rest of the lib. # # - BTCLSH = the path to the tcl interpreter used for in-tree code -# generation. It may be jimtcl or the canonical tclsh. +# generation. It may be jimtcl or the canonical tclsh but may not +# be empty - this tree requires TCL to generated numerous +# components. +# define HAVE_TCL 0 define TCLSH_CMD {exit 1} proc hwaci-check-tcl {} { @@ -551,7 +555,7 @@ if {[cc-check-functions realpath]} { set cgtcl [get-define TCLSH_CMD] define BTCLSH "\$(TCLSH_CMD)" } -puts "TCL for code generation: $cgtcl" +msg-result "TCL for code generation: $cgtcl" unset cgtcl # /TCL @@ -559,7 +563,7 @@ unset cgtcl ######################################################################## # Some of the fuzzer bits require clang -define BIN_CLANG [hwaci-first-bin-of clang-6.0 clang] +define BIN_CLANG [hwaci-first-bin-of clang-18] ######################################################################## diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 35ba1b3819..532bc465b8 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -132,10 +132,18 @@ proc hwaci-bin-define {binName {defName {}}} { # Each argument is passed to cc-path-progs. If that function returns # true, the full path to that binary is returned. If no matches are # found, "" is returned. +# +# Despite using cc-path-progs to do the search, this function clears +# any define'd name that function stores for the result (because the +# caller has no sensible way of knowing which result it was unless +# they pass only a single argument). proc hwaci-first-bin-of {args} { foreach b $args { if {[cc-path-progs $b]} { - return [get-define [string toupper $b]] + set u [string toupper $b] + set x [get-define $u] + undefine $u + return $x } } return "" @@ -144,10 +152,13 @@ proc hwaci-first-bin-of {args} { ######################################################################## # Looks for `bash` binary and dies if not found. On success, defines # BIN_BASH to the full path to bash and returns that value. +# +# TODO: move this out of this file and back into the 1 or 2 downstream +# trees which use it. proc hwaci-require-bash {} { set bash [hwaci-bin-define bash] if {"" eq $bash} { - user-error "Our Makefiles require the bash shell." + user-error "Cannot find required bash shell" } return $bash } diff --git a/main.mk b/main.mk index 848b859a22..5d529e741a 100644 --- a/main.mk +++ b/main.mk @@ -35,8 +35,9 @@ ################################################################################ # -# Ideally these all come from the calling makefile, but we can provide some -# sane defaults for many of them... +# Ideally these all come from the calling makefile, but we can provide +# some sane defaults for many of them, where "sane" essentially means +# "should suffice for conventional Unix-style OSes"... # prefix ?= /usr/local exec_prefix ?= $(prefix) @@ -44,10 +45,20 @@ libdir ?= $(prefix)/lib pkgconfigdir ?= $(libdir)/pkgconfig bindir ?= $(prefix)/bin includedir ?= $(prefix)/include -USE_AMALGAMATION ?= 2 + +USE_AMALGAMATION ?= 1 AMALGAMATION_LINE_MACROS ?= --linemacros=0 INSTALL ?= install +BCC ?= $(CC) +TCC ?= $(BCC) +BEXE ?= +TEXE ?= +BDLL ?= .so +TDLL ?= .so +BLIB ?= .lib +TLIB ?= .lib + LDFLAGS_ZLIB ?= -lz LDFLAGS_MATH ?= -lm LDFLAGS_RPATH ?= -Wl,-rpath -Wl,$(prefix)/lib diff --git a/manifest b/manifest index d31f53fa5b..57deec006a 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Move\smost\sof\sthe\smakefile\scode\sinto\sthe\sstatic\smain.mk. -D 2024-10-19T20:26:17.451 +C More\sbuild\scleanups\sand\sget\sit\sworking\swith\sBSD\smake\s(which\sapparently\sdoes\snot\ssupport\s$<\sand\sbehaves\sslightly\sdifferently\sthan\sgmake\swith\sX?=Y). +D 2024-10-19T20:53:46.370 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 1167ba2d57c63bbcbf96e919b6783665f751cc04e4b75985ed67f2a59b8074e6 +F Makefile.in 6df46358ff2db2a88d18f8d827513d87a60525d75e3156a32220bf6f23344a03 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 3ee0c65b809262dab45d3a92c8af29a584fe0799cbe65c545214cabc2191f1ff +F auto.def 9573eee350d0fde25473d4a221e99d6bc818296ee59a06dd6e1770ac501a0da9 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 8bb16ac39af463ad58a499a12ab3c813e003d6d7dd8ed90f94375b05ae4cdbd4 +F autosetup/hwaci-common.tcl 940f337970affdc3958c49620cb4565f3e47956cbd65bb5c42f7d121699e2301 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 10bec40eca5f1e371130e12d0eef005d630b7f0885d3a0137ad489c54a78f9b7 +F main.mk 5ca16e37a99044ef67f386e96a2ce5b39e0adcb8ecae0e709131c5a968eebb2a F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 707e0f5857d58ec8b457270f988126b1dd0f01b5a3445a43ff7b5429324b1b3d -R 7e557d1ad5ee2c5b2e44bb3a9becbb6a +P 09905ed094f7102dbb4fc81b059452c50b48b0f3a2bd9736bed364b0639d89d7 +R 126cdd45532fc2c4fa2ebf63ee339ba7 U stephan -Z 03e1de4c6fd20e15dd82a14719fd967a +Z 1f20d077d4fd19ab2a63a6f4aa9c0e5c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 72e5783713..daa62969d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09905ed094f7102dbb4fc81b059452c50b48b0f3a2bd9736bed364b0639d89d7 +dcf4fc78fb2813d37eb56c358009f1e5225f28a0c85c710c8127db330efaf319 From f9c73ef7c5549c5929e197236c7995ed3f7210bd Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 20 Oct 2024 01:09:51 +0000 Subject: [PATCH 070/522] Generic build cleanups and reorgs. FossilOrigin-Name: 365a3d71cf9e0be11e7b3e90b6500142619102d8321c1d6f8111f37117a57929 --- Makefile.in | 184 ++++++++++++-------- auto.def | 42 +++-- autosetup/hwaci-common.tcl | 11 +- main.mk | 347 ++++++++++++++++++++++--------------- manifest | 22 +-- manifest.uuid | 2 +- sqlite_cfg.h.in | 2 +- tool/mktoolzip.tcl | 1 + 8 files changed, 361 insertions(+), 250 deletions(-) diff --git a/Makefile.in b/Makefile.in index 756790d099..d43a12f31a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,5 @@ #!/usr/bin/make +# ^^^^ help out editors which guess this file's type. # # Makefile for SQLITE # @@ -7,34 +8,90 @@ # certain blocks are added or removed depending on configure-time # information. # + +######################################################################## +#XX# Lines starting with #XX# are TODOs for the port to autosetup. +# +# Known TODOs/FIXMEs/TOIMPROVEs for the autosetup port, in no +# particular order... +# +# - libreadline detection and handling of its -I, -L, and -l flags. +# These can vary considerably across systems. e.g. some need -lncurses, +# and some don't know what -lncurses is. +# +# - TEA pieces +# +# - Replace the autotools-specific distribution deliverable(s). +# +# - Provide Makefile.msc, Makefile.linux-gcc, and any required similar +# makefile stubs for platforms where the configure script will not +# run. The core makefile rules in main.mk "should" apply as-is for +# most platforms. +# +# - Confirm whether cross-compilation works and patch it +# appropriately. +# all: -#XX# Lines starting with #XX# are TODOs for the port to autosetup +clean: -# The toplevel directory of the source tree. This is the directory +# +# Maintenance reminder: When using the X?=Y variable assignment +# formulation, please test the build with both GNU make and a POSIX +# make (e.g. BSD make, a.k.a. bmake). On at least one occassion, that +# formulation has led to inconsistent behavior between the two major +# make flavors when used with variable names which might sensibly be +# in the developer's environment (namely CC). +# + +# +# The top-most directory of the source tree. This is the directory # that contains this "Makefile.in" and the "configure" script. # TOP = @abs_top_srcdir@ -# Just testing expansions... + +# +# Just testing some default dir expansions... # srcdir = @srcdir@ # top_srcdir = @top_srcdir@ # abs_top_srcdir = @abs_top_srcdir@ # abs_top_builddir = @abs_top_builddir@ -LDFLAGS_ZLIB ?= @LDFLAGS_ZLIB@ -LDFLAGS_MATH ?= @LDFLAGS_MATH@ -LDFLAGS_RPATH ?= @LDFLAGS_RPATH@ -LDFLAGS_READLINE ?= @LDFLAGS_READLINE@ -LDFLAGS_PTHREAD ?= @LDFLAGS_PTHREAD@ -LDFLAGS_SHOBJ ?= @SHOBJ_LDFLAGS@ -ENABLE_SHARED ?= @ENABLE_SHARED@ -HAVE_WASI_SDK ?= @HAVE_WASI_SDK@ +# + +# +# Some standard variables and programs +# +prefix ?= @prefix@ +exec_prefix ?= @exec_prefix@ +libdir ?= @libdir@ +pkgconfigdir ?= $(libdir)/pkgconfig +bindir ?= @bindir@ +includedir ?= @includedir@ +INSTALL = @BIN_INSTALL@ AR = @AR@ CC = @CC@ +#LD = @LD@ # isn't actually needed, at least on modern Unixes. +# # C Compiler and options for use in building executables that # will run on the platform that is doing the build. # BCC = @BUILD_CC@ @BUILD_CFLAGS@ +# +# Rather that stuffing all CFLAGS and LDFLAGS into a single set, we +# break them down on a per-feature basis and expect the build targets +# to use the one(s) it needs. +# +LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ +LDFLAGS_MATH = @LDFLAGS_MATH@ +LDFLAGS_RPATH = @LDFLAGS_RPATH@ +LDFLAGS_READLINE = @LDFLAGS_READLINE@ +LDFLAGS_PTHREAD = @LDFLAGS_PTHREAD@ +LDFLAGS_SHOBJ = @SHOBJ_LDFLAGS@ + +ENABLE_SHARED = @ENABLE_SHARED@ +HAVE_WASI_SDK = @HAVE_WASI_SDK@ + # # TCC is the C Compile and options for use in building executables that # will run on the target platform. (BCC and TCC are usually the @@ -43,38 +100,26 @@ BCC = @BUILD_CC@ @BUILD_CFLAGS@ # on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" # CFLAGS = @CFLAGS@ @SH_CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -# CFLAGS_stdio3 ==> for sqlite3_stdio.h -CFLAGS_stdio3 := -I$(TOP)/ext/misc -TCC ?= $(CC) $(CFLAGS) +TCC = $(CC) $(CFLAGS) # Define -DNDEBUG to compile without debugging (i.e., for production usage) # Omitting the define will cause extra debugging code to be inserted and # includes extra comments when "EXPLAIN stmt" is used. # -TCCX ?= $(TCC) @TARGET_DEBUG@ -# Define this for the autoconf-based build, so that the code knows it can -# include the generated sqlite_cfg.h +TCCX = $(TCC) @TARGET_DEBUG@ +# Define this for the autoconf-based build, so that the code knows it +# can include the generated sqlite_cfg.h. # TCCX += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # # main.mk will fill out TCCX with some flags common to all builds. -#XX# -#XX## Compiler options needed for programs that use the TCL library. -#XX## -#XX#TCC += @TCL_INCLUDE_SPEC@ -#XX# -#XX## The library that programs using TCL must link against. -#XX## -LIBTCL = @TCL_LIB_SPEC@ - # # Compiler options needed for programs that use the readline() library. # -CFLAGS_readline = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ -#XX#CFLAGS_readline += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ -#XX#CFLAGS_readline += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ +CFLAGS_READLINE = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ +#XX#CFLAGS_READLINE += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ +#XX#CFLAGS_READLINE += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ #XX# #XX## The library that programs using readline() must link against. #XX## @@ -115,14 +160,20 @@ $(JIMSH): $(TOP)/autosetup/jimsh0.c BTCLSH = @BTCLSH@ $(BTCLSH): -# Flags controlling use of the in memory btree implementation # -# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to -# default to file, 2 to default to memory, and 3 to force temporary +# $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for +# compiling the library's own sources, including (sometimes) when +# compiling sqlite3.c directly in to another app. Most notably, it +# should always contain -DSQLITE_TEMP_STORE=N for the sake of +# historical build expecations. +# +# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 +# to default to file, 2 to default to memory, and 3 to force temporary # tables to always be in memory. # -TEMP_STORE ?= -DSQLITE_TEMP_STORE=@TEMP_STORE@ +CFLAGS_libsqlite3 = -DSQLITE_TEMP_STORE=@TEMP_STORE@ +# # Enable/disable loadable extensions, and other optional features # based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). # The same set of OMIT and ENABLE flags should be passed to the @@ -141,7 +192,7 @@ TCC += $(OPT_FEATURE_FLAGS) TCC += $(OPTS) # Add in compile-time options for some libraries used by extensions -TCC += @CFLAGS_ZLIB@ +#TCC += @CFLAGS_ZLIB@ # Version numbers and release number for the SQLite being compiled. # @@ -180,12 +231,6 @@ TCL_VERSION = @TCL_VERSION@ TCLLIB_RPATH = @TCLLIB_RPATH@ TCLLIBDIR = @TCLLIBDIR@ -# EMCC_WRAPPER must refer to the genuine emcc binary, or a -# call-compatible wrapper, e.g. $(TOP)/tool/emcc.sh. If it's empty, -# build components requiring Emscripten will not build. -EMCC_WRAPPER = @EMCC_WRAPPER@ - - # Additional options when running tests using testrunner.tcl # This is usually either blank, or else --status # @@ -213,18 +258,6 @@ USE_GCOV = @USE_GCOV@ TCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) TLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) -# The directory into which to store package information for - -# Some standard variables and programs -# -prefix ?= @prefix@ -exec_prefix ?= @exec_prefix@ -libdir ?= @libdir@ -pkgconfigdir ?= $(libdir)/pkgconfig -bindir ?= @bindir@ -includedir ?= @includedir@ -INSTALL = @BIN_INSTALL@ - # # You should not have to change anything below this line ################################################################################ @@ -235,29 +268,25 @@ INSTALL = @BIN_INSTALL@ # AS_AUTO_DEF is the main configure script. # AS_AUTO_DEF = $(TOP)/auto.def +# +# Shell commands to re-run $(TOP)/configure with the same args it was +# invoked with to produce this makefile. +# +AS_AUTOREMAKE = @SQLITE_AUTOREMAKE@ USE_AMALGAMATION ?= @USE_AMALGAMATION@ AMALGAMATION_LINE_MACROS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ +# +# CFLAGS for sqlite3$(TEXE) +# SHELL_OPT ?= @OPT_SHELL@ - -# In wasi-sdk builds, remove the CLI shell build from 'all'. -target_sqlite3_shell_0 = sqlite3$(TEXE) -target_sqlite3_shell = $(target_sqlite3_shell_$(HAVE_WASI_SDK)) - # # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. # -all: sqlite3.h sqlite3.c shell.c $(target_sqlite3_shell) - -# Re-run $(TOP)/configure with the same args invoked to produce this -# makefile. -# -AS_AUTOREMAKE = @SQLITE_AUTOREMAKE@ - Makefile: $(TOP)/Makefile.in $(AS_AUTO_DEF) $(AS_AUTOREMAKE) @touch $@ @@ -265,24 +294,26 @@ Makefile: $(TOP)/Makefile.in $(AS_AUTO_DEF) sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF) $(AS_AUTOREMAKE) @touch $@ -install-pc: sqlite3.pc $(install.pkgconfigdir) - $(INSTALL_noexec) sqlite3.pc $(install.pkgconfigdir) install: install-pc sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) $(AS_AUTOREMAKE) @touch $@ - # # Fiddle app # +# EMCC_WRAPPER must refer to the genuine emcc binary, or a +# call-compatible wrapper, e.g. $(TOP)/tool/emcc.sh. If it's empty, +# build components requiring Emscripten will not build. +# +EMCC_WRAPPER = @EMCC_WRAPPER@ fiddle: sqlite3.c shell.c @if [ x = "x$(EMCC_WRAPPER)" ]; then \ echo "Emscripten's emcc not found. Cannot build fiddle." 1&>2; \ exit 1; \ fi - make -C ext/wasm fiddle emcc_opt=-Os + $(MAKE) -C ext/wasm fiddle emcc_opt=-Os # # Spell-checking for source comments @@ -303,4 +334,19 @@ fiddle: sqlite3.c shell.c misspell: ./custom.rws has_tclsh84 $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in +# +# clean/distclean are mostly defined in main.mk. In this makefile we +# perform cleanup only known to be relevant to (only) the canonical +# (autosetup-driven) build. +# +clean-autosetup: + -gmake -C ext/wasm distclean 2>/dev/null; true +clean: clean-autosetup + +distclean-autosetup: clean + rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile sqlite3.pc + rm -f $(TOP)/tool/emcc.sh + -gmake -C ext/wasm distclean 2>/dev/null; true +distclean: distclean-autosetup + include $(TOP)/main.mk diff --git a/auto.def b/auto.def index 071d95c66d..84c6e0b2ac 100644 --- a/auto.def +++ b/auto.def @@ -13,16 +13,15 @@ if {[get-define host] ne [get-define build]} { ######################################################################## # A very long story made short, autosetup's --flag handling has # some behaviors which make it impossible to implement 100% identical -# flags, compared to the historical autotools build. The differences +# flags compared to the historical autotools build. The differences # are documented here: # -# # 1) --debug is used by autosetup itself, so we have to rename it to # --with-debug. We cannot use --enable-debug because that is, for # autosetup, and alias for --debug=1. # # 2) In autosetup, all flags starting with (--enable, --disable) are -# forced to be booleans and received special handling in how they're +# forced to be booleans and receive special handling in how they're # resolved. Because of that we have to rename: # # 2.1) --enable-tempstore[=no] to --with-tempstore[=no]. @@ -870,26 +869,25 @@ hwaci-check-rpath ######################################################################## # Generate the output files. # -if {1} { - hwaci-make-from-dot-in Makefile - hwaci-make-from-dot-in sqlite3.pc - if {1} { - # for sqlite_cfg.h - define PACKAGE_URL {https://sqlite.org} - define PACKAGE_VERSION [get-define VERSION] - } - if {0} { - # Requires a hand-written sqlite_cfg.h.in... - hwaci-make-from-dot-in sqlite_cfg.h - # vs... - } else { - # Requires no input template... - make-config-header sqlite_cfg.h \ - -bare {SIZEOF_* HAVE_DECL_*} \ - -auto {HAVE_* PACKAGE_*} -none * - } - #hwaci-make-from-dot-in ext/wasm/GNUmakefile +hwaci-make-from-dot-in Makefile +hwaci-make-from-dot-in sqlite3.pc +# for sqlite_cfg.h +define PACKAGE_URL {https://sqlite.org} +define PACKAGE_VERSION [get-define VERSION] +if {0} { + # Requires a hand-written sqlite_cfg.h.in... + hwaci-make-from-dot-in sqlite_cfg.h + # vs... +} else { + # Requires no input template... + make-config-header sqlite_cfg.h \ + -bare {SIZEOF_* HAVE_DECL_*} \ + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE + TARGET_* USE_GCOV USE_OWN_JIMSH TCL_*} \ + -auto {HAVE_* PACKAGE_*} \ + -none * } +#TODO hwaci-make-from-dot-in ext/wasm/GNUmakefile set oFF [get-define OPT_FEATURE_FLAGS] if {"" ne $oFF} { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 532bc465b8..84402ba048 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -621,10 +621,10 @@ proc hwaci-check-emsdk {} { define BIN_EMCC "" # define EMCC_OPT "-Oz" msg-checking "Emscripten SDK? " - if {$emsdkHome eq "" && [info exists ::env(EMSDK)]} { - # Fall back to checking the environment. $EMSDK gets set - # by sourcing emsdk_env.sh. - set emsdkHome $::env(EMSDK) + if {$emsdkHome eq ""} { + # Fall back to checking the environment. $EMSDK gets set by + # sourcing emsdk_env.sh. + set emsdkHome [get-env EMSDK ""] } set rc 0 if {$emsdkHome ne ""} { @@ -633,9 +633,6 @@ proc hwaci-check-emsdk {} { if {[file exists $emsdkEnv]} { msg-result "$emsdkHome" define EMSDK_ENV $emsdkEnv -# if {[info exists ::env(EMCC_OPT)]} { -# define EMCC_OPT $::env(EMCC_OPT) -# } set rc 1 set emcc "$emsdkHome/upstream/emscripten/emcc" if {[file exists $emcc]} { diff --git a/main.mk b/main.mk index 5d529e741a..5ca48a147f 100644 --- a/main.mk +++ b/main.mk @@ -1,8 +1,15 @@ +#!/do/not/make +# ^^^^ help out editors which guess this file's type. ############################################################################### # This is the main makefile for sqlite. It expects to be included from # a higher-level makefile which configures any dynamic state needed by # this one. # +# Maintenance reminder: this file must remain devoid of GNU Make-isms. +# i.e. it must be POSIX Make compatible. +# +#XX# Lines starting with #XX# are TODOs for the port to autosetup +# # The following variables must be defined before this script is # invoked: # @@ -20,7 +27,7 @@ # will run on the target platform. This is usually the same # as BCC, unless you are cross-compiling. # -# AR Tools used to build a static library. +# AR Tool used to build a static library. # # BEXE File extension for executables on the build platform. ".exe" # for Windows and "" everywhere else. @@ -28,16 +35,20 @@ # TEXE File extension for executables on the target platform. ".exe" # for Windows and "" everywhere else. # +# BTCLSH The TCL interpreter for in-tree code generation. May be +# either JimTCL or the canonical TCL. +# # ... and many, many more ... # # Once the variables above are defined, the rest of this make script # will build the SQLite library and testing tools. ################################################################################ +all: sqlite3.h sqlite3.c # -# Ideally these all come from the calling makefile, but we can provide -# some sane defaults for many of them, where "sane" essentially means -# "should suffice for conventional Unix-style OSes"... +# Ideally these variables are all defined in the calling makefile, but +# we can provide some sensible defaults for many of them which should +# suffice for conventional Unix-style OSes. # prefix ?= /usr/local exec_prefix ?= $(prefix) @@ -63,32 +74,54 @@ LDFLAGS_ZLIB ?= -lz LDFLAGS_MATH ?= -lm LDFLAGS_RPATH ?= -Wl,-rpath -Wl,$(prefix)/lib LDFLAGS_READLINE ?= -lreadline +CFLAGS_READLINE ?= LDFLAGS_PTHREAD ?= -lpthread LDFLAGS_SHOBJ ?= -shared ENABLE_SHARED ?= 1 HAVE_WASI_SDK ?= 0 +OPT_FEATURE_FLAGS ?= +# +# $(INSTALL) invocation for use with non-executable files. +# INSTALL_noexec = $(INSTALL) -m 0644 # ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... # TCOMPILE = generic target platform compiler invocation TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) # TLINK = compiler invocation for when the target will be an executable -TLINK = $(TCC) $(TLINK_EXTRAS) +TLINK = $(TCCX) $(TLINK_EXTRAS) # TLINK_shared = $(TLINK) invocation specifically for shared libraries LDFLAGS_SHOBJ ?= -shared TLINK_shared = $(TLINK) $(LDFLAGS_SHOBJ) # TCCX is $(TCC) plus any CFLAGS which are common to most compilations -# for the target platform. In auto-configured builds it is typically -# defined by the main makefile to include configure-time-dependent -# options. +# for the target platform. In auto-configured builds it is defined by +# the main makefile to include configure-time-dependent options. TCCX ?= $(TCC) TCCX += -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu TCCX += -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session TCCX += -I$(TOP)/ext/userauth +# CFLAGS_stdio3 ==> for sqlite3_stdio.h +CFLAGS_stdio3 := -I$(TOP)/ext/misc + +CFLAGS_libsqlite3 ?= -DSQLITE_TEMP_STORE=1 + +# +# The following TCL_vars come from tclConfig.sh +# +TCL_INCLUDE_SPEC ?= +TCL_LIB_SPEC ?= +TCL_STUB_LIB_SPEC ?= +TCL_EXEC_PREFIX ?= +TCL_VERSION ?= +TCLLIBDIR ?= +# +# $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not +# libsqlite3, and will usually differ from $(LDFLAGS_RPATH). +# +TCLLIB_RPATH ?= -TEMP_STORE ?= -DSQLITE_TEMP_STORE=1 # # LDFLAGS_libsqlite3 should be used with any target which either @@ -102,17 +135,27 @@ LDFLAGS_libsqlite3 = \ $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) # -# install.XYZ = dirs for installation. They're in quotes to -# accommodate installations where paths have spaces in them. -# -install.bindir = "$(DESTDIR)$(bindir)" -install.libdir = "$(DESTDIR)$(libdir)" -install.includedir = "$(DESTDIR)$(prefix)/include" -install.pkgconfigdir = "$(DESTDIR)$(pkgconfigdir)" -$(install.bindir) $(install.libdir) $(install.includedir) $(install.pkgconfigdir): +# install-dir.XYZ = dirs for installation. +# +# Design note: these should arguably all be defined with surrounding +# double-quotes so that targets which have spaces in their paths will +# work, but that leads to Make treating the quotes as part of the dir +# name, which in turn leads to it never finding a matching name in the +# filesystem and always invoking ($(INSTALL) -d ...) for them. The +# moral of this story is that spaces in installation paths will break +# the install process. +# +install-dir.bin = $(DESTDIR)$(bindir) +install-dir.lib = $(DESTDIR)$(libdir) +install-dir.include = $(DESTDIR)$(prefix)/include +install-dir.pkgconfig = $(DESTDIR)$(pkgconfigdir) +install-dir.man1 = $(DESTDIR)$(prefix)/share/man/man1 +install-dir.all = $(install-dir.bin) $(install-dir.include) \ + $(install-dir.lib) $(install-dir.man1) \ + $(install-dir.pkgconfig) +$(install-dir.all): $(INSTALL) -d $@ - # # Object files for the SQLite library (non-amalgamation). # @@ -493,6 +536,7 @@ HDR = \ $(TOP)/src/vxworks.h \ $(TOP)/src/whereInt.h \ sqlite_cfg.h +# Reminder: sqlite_cfg.h is typically created by the configure script # Header files used by extensions # @@ -511,7 +555,8 @@ EXTHDR += \ EXTHDR += \ $(TOP)/ext/userauth/sqlite3userauth.h -# executables needed for testing +# +# Executables needed for testing # TESTPROGS = \ testfixture$(TEXE) \ @@ -533,10 +578,12 @@ FUZZDATA = \ $(TOP)/test/fuzzdata7.db \ $(TOP)/test/fuzzdata8.db +# # Standard options to testfixture # TESTOPTS = --verbose=file --output=test-out.txt +# # Extra compiler options for various shell tools # SHELL_OPT += -DSQLITE_DQS=0 @@ -671,255 +718,255 @@ sqlite3ext.h: .target_source # opcodes.o # parse.o: parse.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c parse.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c parse.c opcodes.o: opcodes.c - $(TCOMPILE) $(TEMP_STORE) -c opcodes.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c opcodes.c # Rules to build individual *.o files from files in the src directory. # alter.o: $(TOP)/src/alter.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/alter.c analyze.o: $(TOP)/src/analyze.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/analyze.c attach.o: $(TOP)/src/attach.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/attach.c auth.o: $(TOP)/src/auth.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/auth.c backup.o: $(TOP)/src/backup.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/backup.c bitvec.o: $(TOP)/src/bitvec.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/bitvec.c btmutex.o: $(TOP)/src/btmutex.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/btmutex.c btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/btree.c build.o: $(TOP)/src/build.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/build.c callback.o: $(TOP)/src/callback.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/callback.c complete.o: $(TOP)/src/complete.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/complete.c ctime.o: $(TOP)/src/ctime.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/ctime.c date.o: $(TOP)/src/date.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/date.c dbpage.o: $(TOP)/src/dbpage.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbpage.c dbstat.o: $(TOP)/src/dbstat.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbstat.c delete.o: $(TOP)/src/delete.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/delete.c expr.o: $(TOP)/src/expr.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/expr.c fault.o: $(TOP)/src/fault.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/fault.c fkey.o: $(TOP)/src/fkey.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/fkey.c func.o: $(TOP)/src/func.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/func.c global.o: $(TOP)/src/global.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/global.c hash.o: $(TOP)/src/hash.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/insert.c json.o: $(TOP)/src/json.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/json.c legacy.o: $(TOP)/src/legacy.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/legacy.c loadext.o: $(TOP)/src/loadext.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/loadext.c main.o: $(TOP)/src/main.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/main.c malloc.o: $(TOP)/src/malloc.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/malloc.c mem0.o: $(TOP)/src/mem0.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem0.c mem1.o: $(TOP)/src/mem1.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem1.c mem2.o: $(TOP)/src/mem2.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem2.c mem3.o: $(TOP)/src/mem3.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem3.c mem5.o: $(TOP)/src/mem5.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem5.c memdb.o: $(TOP)/src/memdb.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/memdb.c memjournal.o: $(TOP)/src/memjournal.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/memjournal.c mutex.o: $(TOP)/src/mutex.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex.c mutex_noop.o: $(TOP)/src/mutex_noop.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_noop.c mutex_unix.o: $(TOP)/src/mutex_unix.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_unix.c mutex_w32.o: $(TOP)/src/mutex_w32.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_w32.c notify.o: $(TOP)/src/notify.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/notify.c pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/pager.c pcache.o: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache.c pcache1.o: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache1.c os.o: $(TOP)/src/os.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/os.c os_kv.o: $(TOP)/src/os_kv.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_kv.c os_unix.o: $(TOP)/src/os_unix.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_unix.c os_win.o: $(TOP)/src/os_win.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_win.c pragma.o: $(TOP)/src/pragma.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/pragma.c prepare.o: $(TOP)/src/prepare.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/prepare.c printf.o: $(TOP)/src/printf.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/printf.c random.o: $(TOP)/src/random.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/random.c resolve.o: $(TOP)/src/resolve.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/resolve.c rowset.o: $(TOP)/src/rowset.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/rowset.c select.o: $(TOP)/src/select.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/select.c status.o: $(TOP)/src/status.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/status.c sqlite3.o: sqlite3.h sqlite3.c - $(TCOMPILE) $(TEMP_STORE) -c sqlite3.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c sqlite3.c table.o: $(TOP)/src/table.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/table.c threads.o: $(TOP)/src/threads.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/threads.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/threads.c tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/tokenize.c treeview.o: $(TOP)/src/treeview.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/treeview.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/treeview.c trigger.o: $(TOP)/src/trigger.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/trigger.c update.o: $(TOP)/src/update.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/update.c upsert.o: $(TOP)/src/upsert.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/upsert.c utf.o: $(TOP)/src/utf.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/utf.c util.o: $(TOP)/src/util.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/util.c vacuum.o: $(TOP)/src/vacuum.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vacuum.c vdbe.o: $(TOP)/src/vdbe.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbe.c vdbeapi.o: $(TOP)/src/vdbeapi.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeapi.c vdbeaux.o: $(TOP)/src/vdbeaux.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeaux.c vdbeblob.o: $(TOP)/src/vdbeblob.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeblob.c vdbemem.o: $(TOP)/src/vdbemem.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbemem.c vdbesort.o: $(TOP)/src/vdbesort.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbesort.c vdbetrace.o: $(TOP)/src/vdbetrace.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbetrace.c vdbevtab.o: $(TOP)/src/vdbevtab.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbevtab.c vtab.o: $(TOP)/src/vtab.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vtab.c wal.o: $(TOP)/src/wal.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/wal.c walker.o: $(TOP)/src/walker.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/walker.c where.o: $(TOP)/src/where.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/where.c wherecode.o: $(TOP)/src/wherecode.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/wherecode.c whereexpr.o: $(TOP)/src/whereexpr.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/whereexpr.c window.o: $(TOP)/src/window.c $(HDR) - $(TCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c + $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/window.c tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) \ @@ -963,16 +1010,19 @@ mkkeywordhash$(BEXE): $(TOP)/tool/mkkeywordhash.c keywordhash.h: mkkeywordhash$(BEXE) ./mkkeywordhash$(BEXE) > $@ - +# Static libsqlite3 +# $(libsqlite3.LIB): $(LIBOBJ) $(AR) crs $@ $(LIBOBJ) lib: $(libsqlite3.LIB) all: lib -target_libsqlite3_so_1 = $(libsqlite3.SO) -target_libsqlite3_so = $(target_libsqlite3_so_$(ENABLE_SHARED)) +# Dynamic libsqlite3 +# $(libsqlite3.SO): $(LIBOBJ) $(TLINK_shared) -o $@ $(LIBOBJ) $(LDFLAGS_libsqlite3) +target_libsqlite3_so_1 = $(libsqlite3.SO) +target_libsqlite3_so = $(target_libsqlite3_so_$(ENABLE_SHARED)) so: $(target_libsqlite3_so) all: so @@ -988,26 +1038,28 @@ sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCLSH) # has_tclsh84 # for reasons lost to history but having something to do with libtool # (which is not longer used in this tree). # -install-so-1: $(install.libdir) $(libsqlite3.SO) - $(INSTALL) $(libsqlite3.SO) $(install.libdir); \ - cd $(install.libdir); \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(RELEASE); \ - mv $(libsqlite3.SO) $(libsqlite3.SO).$(RELEASE); \ - ln -s $(libsqlite3.SO).$(RELEASE) $(libsqlite3.SO).3; \ - ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) -install-so-0: +install-so-1: $(install-dir.lib) $(libsqlite3.SO) + $(INSTALL) $(libsqlite3.SO) $(install-dir.lib) + @echo "Setting up SO symlinks..."; \ + cd $(install-dir.lib) || exit $$?; \ + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(RELEASE) || exit $$?; \ + mv $(libsqlite3.SO) $(libsqlite3.SO).$(RELEASE) || exit $$?; \ + ln -s $(libsqlite3.SO).$(RELEASE) $(libsqlite3.SO).3 || exit $$?; \ + ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ + ls -la $(libsqlite3.SO) $(libsqlite3.SO).3 $(libsqlite3.SO).$(RELEASE) +install-so-0 install-so-: install: install-so-$(ENABLE_SHARED) # Install $(libsqlite3.LIB) # -install-lib: $(install.libdir) $(libsqlite3.LIB) - $(INSTALL_noexec) $(libsqlite3.LIB) $(install.libdir) +install-lib: $(install-dir.lib) $(libsqlite3.LIB) + $(INSTALL_noexec) $(libsqlite3.LIB) $(install-dir.lib) install: install-lib # Install C header files # -install-includes: sqlite3.h $(install.includedir) - $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install.includedir) +install-includes: sqlite3.h $(install-dir.include) + $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install-dir.include) install: install-includes # libtclsqlite3... @@ -1024,7 +1076,7 @@ $(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) libtcl: $(target_libtclsqlite3) all: libtcl -install.tcldir = "$(DESTDIR)$(TCLLIBDIR)" +install.tcldir = $(DESTDIR)$(TCLLIBDIR) install-tcl-1: install-lib $(target_libtclsqlite3) pkgIndex.tcl @if [ "x$(DESTDIR)" = "x$(install.tcldir)" ]; then echo "TCLLIBDIR is not set." 1>&2; exit 1; fi $(INSTALL) -d $(install.tcldir) @@ -1126,8 +1178,10 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) - $(TLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ - -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(LDFLAGS_libsqlite3) $(TCL_INCLUDE_SPEC) + $(TLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ + -o $@ $(TESTFIXTURE_SRC) \ + $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) \ + $(CFLAGS_libsqlite3) $(LDFLAGS_libsqlite3) coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) @@ -1234,7 +1288,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c - $(TLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TCL_INCLUDE_SPEC) $(LDFLAGS_libsqlite3) + $(TLINK) sqlite3_analyzer.c -o $@ $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) $(LDFLAGS_libsqlite3) sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl \ @@ -1242,7 +1296,7 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(TEXE): has_tclconfig sqltclsh.c - $(TLINK) sqltclsh.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) + $(TLINK) sqltclsh.c -o $@ $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c @@ -1263,7 +1317,7 @@ sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c - $(TLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(LDFLAGS_libsqlite3) + $(TLINK) sqlite3_checker.c -o $@ $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLINK) -DDBDUMP_STANDALONE -o $@ \ @@ -1343,7 +1397,9 @@ tool-zip: testfixture$(TEXE) sqlite3$(TEXE) sqldiff$(TEXE) \ sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) $(TOP)/tool/mktoolzip.tcl strip sqlite3$(TEXE) sqldiff$(TEXE) sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) ./testfixture$(TEXE) $(TOP)/tool/mktoolzip.tcl - +clean-tool-zip: + rm -f sqlite-tools-*.zip +clean: clean-tool-zip #XX# TODO: adapt the autoconf amalgamation for autosetup #XX# #XX## Build the amalgamation-autoconf package. The amalamgation-tarball target builds @@ -1378,20 +1434,27 @@ threadtest5: sqlite3.c $(TOP)/test/threadtest5.c $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS_libsqlite3) sqlite3$(TEXE): shell.c sqlite3.c - $(TCCX) $(CFLAGS_readline) $(SHELL_OPT) -o $@ \ + $(TCCX) $(CFLAGS_READLINE) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ $(LDFLAGS_libsqlite3) $(LDFLAGS_READLINE) +# +# Build sqlite3$(TEXE) by default except in wasi-sdk builds. Yes, the +# semantics of 0 and 1 are confusingly swapped here. +# +target_sqlite3_shell_1 = +target_sqlite3_shell_0 = sqlite3$(TEXE) +all: $(target_sqlite3_shell_$(HAVE_WASI_SDK)) -install-cli-0: sqlite3$(TEXT) $(install.bindir) - $(INSTALL) -s sqlite3$(TEXT) $(install.bindir) -install-cli-1: -install: install-cli-$(HAVE_WASI_SDK) +install-shell-0: sqlite3$(TEXT) $(install-dir.bin) + $(INSTALL) -s sqlite3$(TEXT) $(install-dir.bin) +install-shell-1 install-shell-: +install: install-shell-$(HAVE_WASI_SDK) sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite3) -install-diff: sqldiff$(TEXE) $(install.bindir) - $(INSTALL) -s sqldiff$(TEXT) $(install.bindir) +install-diff: sqldiff$(TEXE) $(install-dir.bin) + $(INSTALL) -s sqldiff$(TEXT) $(install-dir.bin) #install: install-diff dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h @@ -1411,10 +1474,20 @@ RSYNC_OPT = \ sqlite3_rsync$(TEXE): $(RSYNC_SRC) $(TCCX) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) -install-rsync: sqlite3_rsync$(TEXE) $(install.bindir) - $(INSTALL) sqlite3_rsync$(TEXT) $(install.bindir) +install-rsync: sqlite3_rsync$(TEXE) $(install-dir.bin) + $(INSTALL) sqlite3_rsync$(TEXT) $(install-dir.bin) #install: install-rsync +install-man1: $(install-dir.man1) + $(INSTALL_noexec) $(TOP)/sqlite3.1 $(install-dir.man1) +install: install-man1 + +# +# sqlite3.pc is typically generated by the configure script but could +# conceivably be generated by hand. +install-pc: sqlite3.pc $(install-dir.pkgconfig) + $(INSTALL_noexec) sqlite3.pc $(install-dir.pkgconfig) + scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS_libsqlite3) @@ -1647,11 +1720,11 @@ tidy: rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) - rm -f *.dll *.lib *.exp *.pc *.vsix *.so *.dylib pkgIndex.tcl + rm -f *.exp *.vsix pkgIndex.tcl rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) sqlite3_expert$(TEXE) rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) - rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) dbfuzz2-asan$(TEXE) dbfuzz2-msan$(TEXE) + rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) rm -f fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE) rm -f sessionfuzz$(TEXE) rm -f threadtest5$(TEXE) @@ -1664,10 +1737,6 @@ tidy: # clean: tidy rm -rf omittest* testrunner* testdir* - -gmake -C ext/wasm distclean 2>/dev/null; true # Clean up everything. No exceptions. distclean: clean - rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile - rm -f $(TOP)/tool/emcc.sh - -gmake -C ext/wasm distclean 2>/dev/null; true diff --git a/manifest b/manifest index 57deec006a..d690074f97 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C More\sbuild\scleanups\sand\sget\sit\sworking\swith\sBSD\smake\s(which\sapparently\sdoes\snot\ssupport\s$<\sand\sbehaves\sslightly\sdifferently\sthan\sgmake\swith\sX?=Y). -D 2024-10-19T20:53:46.370 +C Generic\sbuild\scleanups\sand\sreorgs. +D 2024-10-20T01:09:51.225 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 6df46358ff2db2a88d18f8d827513d87a60525d75e3156a32220bf6f23344a03 +F Makefile.in 70a3accb7281cde5c9b8aac9501e1a1e4f935e567820fe58c2ee98e612a4cace F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 9573eee350d0fde25473d4a221e99d6bc818296ee59a06dd6e1770ac501a0da9 +F auto.def 573b50cfefc60cecb28548519ad7105c5af07ae611204d05a842339fc95986d1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 940f337970affdc3958c49620cb4565f3e47956cbd65bb5c42f7d121699e2301 +F autosetup/hwaci-common.tcl 43fb22444faf261e7b23078cd15eaa235d59b2baefba1834750f79fcc4966e9d F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 5ca16e37a99044ef67f386e96a2ce5b39e0adcb8ecae0e709131c5a968eebb2a +F main.mk 6b6d1deaa55692b21903573b24f2215dea8068cab5626928a3fed8ed86ec314f F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -722,7 +722,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F sqlite_cfg.h.in e820a04b0ea3da638858927513f5ac8a5e8b9a822b531ebfeeac32a2fa396dcd +F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb F src/attach.c 08235ab62ed5ccc93c22bf36e640d19effcd632319615851bccf724ec9341333 @@ -2172,7 +2172,7 @@ F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6 F tool/mksqlite3c.tcl c6acfdf4e4ef93478ff3ce3cd593e17abb03f446036ce710c3156bcfa18665e0 F tool/mksqlite3h.tcl d391cff7cad0a372ee1406faee9ccc7dad9cb80a0c95cae0f73d10dd26e06762 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b -F tool/mktoolzip.tcl 1b3383c6cd1ca3e1bfdf157d1383f29d6264b9600c381e682789c83617dc1014 +F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c7a27c F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845 F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 09905ed094f7102dbb4fc81b059452c50b48b0f3a2bd9736bed364b0639d89d7 -R 126cdd45532fc2c4fa2ebf63ee339ba7 +P dcf4fc78fb2813d37eb56c358009f1e5225f28a0c85c710c8127db330efaf319 +R 5d187fc41a2a5eefcf1982b38f70e6e6 U stephan -Z 1f20d077d4fd19ab2a63a6f4aa9c0e5c +Z 98274b66f6dd84bbce9457a00b5c9351 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index daa62969d1..cd182c7898 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dcf4fc78fb2813d37eb56c358009f1e5225f28a0c85c710c8127db330efaf319 +365a3d71cf9e0be11e7b3e90b6500142619102d8321c1d6f8111f37117a57929 diff --git a/sqlite_cfg.h.in b/sqlite_cfg.h.in index 8a6b5cc7a3..be6329e341 100644 --- a/sqlite_cfg.h.in +++ b/sqlite_cfg.h.in @@ -165,7 +165,7 @@ /* Define to the home page for this package. */ /*#undef PACKAGE_URL*/ -#define PACKAGE_URL "" +#define PACKAGE_URL @PACKAGE_URL@ /* Define to the version of this package. */ /*#undef PACKAGE_VERSION*/ diff --git a/tool/mktoolzip.tcl b/tool/mktoolzip.tcl index a5951168a8..c22318441e 100644 --- a/tool/mktoolzip.tcl +++ b/tool/mktoolzip.tcl @@ -10,6 +10,7 @@ # sqlite3 -- the SQLite CLI # sqldiff -- Program to diff two databases # sqlite3_analyzer -- Space analyzer +# sqlite3_rsync -- Remote db sync # switch $tcl_platform(os) { {Windows NT} { From 8bdece9034df1beecc1abf58a241582d9c9eb89d Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 20 Oct 2024 01:14:54 +0000 Subject: [PATCH 071/522] Do not check for Emscripten when doing a --with-wasi-sdk build. FossilOrigin-Name: 111cff2cf38886ccec11b45db8b891ec84e24d0b61d413b35fd474b51003e8f2 --- auto.def | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/auto.def b/auto.def index 84c6e0b2ac..18b4f49cdf 100644 --- a/auto.def +++ b/auto.def @@ -230,8 +230,8 @@ if {1} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" if {$wasiSdkDir ne ""} { - msg-checking "Checking WASI SDK directory \[$wasiSdkDir]... " - puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" + puts "Checking WASI SDK directory \[$wasiSdkDir]... " + #puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" hwaci-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading" define HAVE_WASI_SDK 1 @@ -759,7 +759,7 @@ define cross_compiling ${cross_compiling} ######################################################################## # Emscripten SDK for building the web-based wasm components. # -if {[hwaci-check-emsdk]} { +if {0 eq [get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} { set wrapper $srcdir/tool/emcc.sh define EMCC_WRAPPER $wrapper hwaci-make-from-dot-in $wrapper diff --git a/manifest b/manifest index d690074f97..f8cb8729c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Generic\sbuild\scleanups\sand\sreorgs. -D 2024-10-20T01:09:51.225 +C Do\snot\scheck\sfor\sEmscripten\swhen\sdoing\sa\s--with-wasi-sdk\sbuild. +D 2024-10-20T01:14:54.879 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 573b50cfefc60cecb28548519ad7105c5af07ae611204d05a842339fc95986d1 +F auto.def 0a2c00810f7de3d92ec7d5b3716bdaa9877993437ba428873322d9c59fc1ec64 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dcf4fc78fb2813d37eb56c358009f1e5225f28a0c85c710c8127db330efaf319 -R 5d187fc41a2a5eefcf1982b38f70e6e6 +P 365a3d71cf9e0be11e7b3e90b6500142619102d8321c1d6f8111f37117a57929 +R ca118f6891ab0e7efdc6f8f4f1170e5b U stephan -Z 98274b66f6dd84bbce9457a00b5c9351 +Z a1d75beedd7dcb8e17ae83d7df54d589 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cd182c7898..21f885bbf9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -365a3d71cf9e0be11e7b3e90b6500142619102d8321c1d6f8111f37117a57929 +111cff2cf38886ccec11b45db8b891ec84e24d0b61d413b35fd474b51003e8f2 From 857bcb60356e4af341afb6c9d0190593061cc4e6 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 20 Oct 2024 01:34:13 +0000 Subject: [PATCH 072/522] Minor doc updates. FossilOrigin-Name: 6578a8d59e351182ee16a1f4e4b2c88a042a92dd8b32049947aa0436464b8588 --- Makefile.in | 13 +++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index d43a12f31a..b0c00e79d4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,16 +17,17 @@ # # - libreadline detection and handling of its -I, -L, and -l flags. # These can vary considerably across systems. e.g. some need -lncurses, -# and some don't know what -lncurses is. +# and some don't know what an -lncurses is. # -# - TEA pieces +# - TEA pieces. # # - Replace the autotools-specific distribution deliverable(s). # # - Provide Makefile.msc, Makefile.linux-gcc, and any required similar -# makefile stubs for platforms where the configure script will not +# makefile stubs for environments where the configure script will not # run. The core makefile rules in main.mk "should" apply as-is for -# most platforms. +# most platforms. We can potentially generate those makefiles, along +# with main.mk, like we do in the Fossil project. # # - Confirm whether cross-compilation works and patch it # appropriately. @@ -336,8 +337,8 @@ misspell: ./custom.rws has_tclsh84 # # clean/distclean are mostly defined in main.mk. In this makefile we -# perform cleanup only known to be relevant to (only) the canonical -# (autosetup-driven) build. +# perform cleanup known to be relevant to (only) the autosetup-driven +# build. # clean-autosetup: -gmake -C ext/wasm distclean 2>/dev/null; true diff --git a/manifest b/manifest index f8cb8729c6..5a49f76622 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Do\snot\scheck\sfor\sEmscripten\swhen\sdoing\sa\s--with-wasi-sdk\sbuild. -D 2024-10-20T01:14:54.879 +C Minor\sdoc\supdates. +D 2024-10-20T01:34:13.073 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 70a3accb7281cde5c9b8aac9501e1a1e4f935e567820fe58c2ee98e612a4cace +F Makefile.in ac87216a9dfbcdcc9262badd7caad8ed3a67e75ad7b744ac68bab677e37e3015 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 365a3d71cf9e0be11e7b3e90b6500142619102d8321c1d6f8111f37117a57929 -R ca118f6891ab0e7efdc6f8f4f1170e5b +P 111cff2cf38886ccec11b45db8b891ec84e24d0b61d413b35fd474b51003e8f2 +R eb1d3ad6d8fd4deffdae2ad46361c659 U stephan -Z a1d75beedd7dcb8e17ae83d7df54d589 +Z 5c51cfa3902f73d3236a2a627a46a106 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 21f885bbf9..5bee5b775d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -111cff2cf38886ccec11b45db8b891ec84e24d0b61d413b35fd474b51003e8f2 +6578a8d59e351182ee16a1f4e4b2c88a042a92dd8b32049947aa0436464b8588 From ec5e61193583b1be8fd56d0877d2c0e55b564c7a Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 20 Oct 2024 01:41:36 +0000 Subject: [PATCH 073/522] Cosmetic tweaks to auto.def. FossilOrigin-Name: 476d2407e52ebf66e18f4f5f70c7c2a37bb4d253969c23e1e75d4cb0460a93e0 --- auto.def | 18 ++++++++++-------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/auto.def b/auto.def index 18b4f49cdf..2c631ba749 100644 --- a/auto.def +++ b/auto.def @@ -1,10 +1,11 @@ -# Created by migrate-autoconf - fix items marked XXX +# This is the main autosetup-compatible configure script for the +# SQLite project. global autosetup use cc cc-db cc-shared cc-lib hwaci-common -set DUMP_DEFINES_FILE defines.list +set DUMP_DEFINES_FILE ./defines.list define ENABLE_SHARED 1 -# Are we cross compiling? +# Are we cross-compiling? set cross_compiling 0 if {[get-define host] ne [get-define build]} { set cross_compiling 1 @@ -26,7 +27,7 @@ if {[get-define host] ne [get-define build]} { # # 2.1) --enable-tempstore[=no] to --with-tempstore[=no]. # -options { +options [subst { with-debug:=1 => {Enable debug build flags} with-tclsh:PATH => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} @@ -59,8 +60,8 @@ options { with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build.} with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} - dump-defines=1 => {Disable dump of autosetup defines to $DUMP_DEFINES_FILE} -} + dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_FILE} +}] ######################################################################## # Notes about certain historical flags: @@ -892,11 +893,12 @@ if {0} { set oFF [get-define OPT_FEATURE_FLAGS] if {"" ne $oFF} { define OPT_FEATURE_FLAGS [lsort -unique $oFF] - msg-result "Final feature flags: [get-define OPT_FEATURE_FLAGS]" + msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]" } set oFF [get-define OPT_SHELL] if {"" ne $oFF} { - msg-result "Final shell opts: [get-define OPT_SHELL]" + define OPT_SHELL [lsort -unique $oFF] + msg-result "Shell options: [get-define OPT_SHELL]" } unset oFF diff --git a/manifest b/manifest index 5a49f76622..52d535f1c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sdoc\supdates. -D 2024-10-20T01:34:13.073 +C Cosmetic\stweaks\sto\sauto.def. +D 2024-10-20T01:41:36.276 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 0a2c00810f7de3d92ec7d5b3716bdaa9877993437ba428873322d9c59fc1ec64 +F auto.def afe12f8c9d4cf77fe3defba7a8118f7616590cfdf8068d04890c14475a3463e2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 111cff2cf38886ccec11b45db8b891ec84e24d0b61d413b35fd474b51003e8f2 -R eb1d3ad6d8fd4deffdae2ad46361c659 +P 6578a8d59e351182ee16a1f4e4b2c88a042a92dd8b32049947aa0436464b8588 +R 5f54b7f4d43245e67f911311e0b2a7d6 U stephan -Z 5c51cfa3902f73d3236a2a627a46a106 +Z fca397da1036769e5affb85d40ffe113 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5bee5b775d..9fb20d3ef7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6578a8d59e351182ee16a1f4e4b2c88a042a92dd8b32049947aa0436464b8588 +476d2407e52ebf66e18f4f5f70c7c2a37bb4d253969c23e1e75d4cb0460a93e0 From 84f952ba8fa402dc6212a0613074a1f69321155a Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 20 Oct 2024 02:35:25 +0000 Subject: [PATCH 074/522] A possible fix for some as-yet-unused configure code which looks for a module loader. FossilOrigin-Name: c6c799a54b3fad2f8c2b73b0a88f64dda38736a283bbf4dd286ac9dd6d6bf153 --- autosetup/hwaci-common.tcl | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 84402ba048..b3b12e53af 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -291,7 +291,7 @@ proc hwaci-opt-define-bool {args} { # report only that is has LIBLTDL. proc hwaci-check-module-loader {} { msg-checking "Looking for module-loader APIs... " - if {99 ne [get-define LDFLAGS_MODULE_LOADER]} { + if {99 ne [get-define LDFLAGS_MODULE_LOADER 99]} { if {1 eq [get-define HAVE_LIBLTDL 0]} { msg-result "(cached) libltdl" return 1 diff --git a/manifest b/manifest index 52d535f1c0..3d9ba4e88f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cosmetic\stweaks\sto\sauto.def. -D 2024-10-20T01:41:36.276 +C A\spossible\sfix\sfor\ssome\sas-yet-unused\sconfigure\scode\swhich\slooks\sfor\sa\smodule\sloader. +D 2024-10-20T02:35:25.520 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 43fb22444faf261e7b23078cd15eaa235d59b2baefba1834750f79fcc4966e9d +F autosetup/hwaci-common.tcl 83d6520660b17c00ae56e453c4a9e18ed37bae9a2a2a62db68ca49e2a454052a F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6578a8d59e351182ee16a1f4e4b2c88a042a92dd8b32049947aa0436464b8588 -R 5f54b7f4d43245e67f911311e0b2a7d6 +P 476d2407e52ebf66e18f4f5f70c7c2a37bb4d253969c23e1e75d4cb0460a93e0 +R 2daa11b12a9e137050615d079bdc23b8 U stephan -Z fca397da1036769e5affb85d40ffe113 +Z 4cd6b6db6fabc4cf1ad86e43ed022c8a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9fb20d3ef7..76bedb1f89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -476d2407e52ebf66e18f4f5f70c7c2a37bb4d253969c23e1e75d4cb0460a93e0 +c6c799a54b3fad2f8c2b73b0a88f64dda38736a283bbf4dd286ac9dd6d6bf153 From a3d219a7946700ff9c4cb3985909591264d6503f Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 20 Oct 2024 02:47:56 +0000 Subject: [PATCH 075/522] Build doc touchups. FossilOrigin-Name: 109d441bf1bcdbc01d1f3f2aa145039539fc5aad02f91fc987a0c3702e21809d --- Makefile.in | 8 ++++++++ auto.def | 37 +++++++++++++++---------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/Makefile.in b/Makefile.in index b0c00e79d4..d79fa66f51 100644 --- a/Makefile.in +++ b/Makefile.in @@ -32,6 +32,14 @@ # - Confirm whether cross-compilation works and patch it # appropriately. # +# - There are some lingering dependencies issues which cause a +# re-configure to trigger more often than it should. This is +# especially a problem in parallel builds, which may launch multiple +# re-configures in parallel. GNU Make offers ways of controlling +# that, but we're limited to POSIX Make compatibility here. The +# automatic reconfigures are not too onerous, though, because they're +# much, much faster than Autotools configure runs. +# all: clean: diff --git a/auto.def b/auto.def index 2c631ba749..050d3a4af8 100644 --- a/auto.def +++ b/auto.def @@ -157,13 +157,16 @@ cc-check-tools ld ar # OPT_FEATURE_FLAGS = -DSQLITE_OMIT/ENABLE flags. define OPT_FEATURE_FLAGS {} define OPT_SHELL {}; # CFLAGS for the sqlite3 CLI app -# Adds $flag, if not empty, to OPT_FEATURE_FLAGS. + +# Adds $args, if not empty, to OPT_FEATURE_FLAGS. proc add-feature-flag {args} { if {"" ne $args} { define-append OPT_FEATURE_FLAGS {*}$args } } # add-feature-flag -DSQLITE_JUST_TESTING=3 + +# Adds $args, if not empty, to OPT_SHELL. proc add-shell-opt {args} { if {"" ne $args} { define-append OPT_SHELL {*}$args @@ -191,30 +194,20 @@ if {"" eq [hwaci-bin-define install]} { # define BIN_INSTALL "$top_srcdir/install-sh" # # Nope: it MOVES its source files over the target, which breaks the - # installation in some cases. It's easy to hack to copy instead of - # mv (simply replace the instcmd=... bit) but that won't retain the - # source timestamp and permissions unless we use cp's -p flag, which - # may not be portable enough. + # installation in some cases, e.g. when libtclsqlite3.so is built in + # response to 'make install' and libsqlite3.a is moved before + # libtclsqlite3.so is linked. It's easy to hack to use cp instead + # of mv (simply replace the instcmd=... bit) but that won't retain + # the source timestamp and permissions unless we use cp's -p flag, + # which may not be portable enough. } - ######################################################################## -# Locate a compiler for the build machine. This compiler should -# generate command-line programs that run on the build machine. -# -# XXX if test x"$cross_compiling" = xno; then -# XXX BUILD_CC=$CC -# XXX BUILD_CFLAGS=$CFLAGS -# XXX else -# XXX if test "${BUILD_CC+set}" != set; then -# XXX AC_CHECK_PROGS BUILD_CC gcc cc cl -# XXX fi -# XXX if test "${BUILD_CFLAGS+set}" != set; then -# XXX BUILD_CFLAGS="-g" -# XXX fi -# XXX fi -# XXX AC_SUBST BUILD_CC - +# We differentiate between two C compilers: the one used for binaries +# which are to run on the build system (BUILD_CC, a.k.a. BCC) and the +# one used for compiling binaries for the target system (CC, +# a.k.a. TCC). Normally they're the same, but they will differ when +# cross-compiling. define BUILD_CC [get-define CC_FOR_BUILD] define BUILD_CFLAGS [get-env CFLAGS {-g}] diff --git a/manifest b/manifest index 3d9ba4e88f..d942e56b06 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C A\spossible\sfix\sfor\ssome\sas-yet-unused\sconfigure\scode\swhich\slooks\sfor\sa\smodule\sloader. -D 2024-10-20T02:35:25.520 +C Build\sdoc\stouchups. +D 2024-10-20T02:47:56.420 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in ac87216a9dfbcdcc9262badd7caad8ed3a67e75ad7b744ac68bab677e37e3015 +F Makefile.in a2c1b0e12796a0c3f26cde2bf1d6d872168c64e0e8121641df36f248a217b67f F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def afe12f8c9d4cf77fe3defba7a8118f7616590cfdf8068d04890c14475a3463e2 +F auto.def a392650e2c34738c179f2f7d2c731f90906dcbfb78c236348930997d79281702 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 476d2407e52ebf66e18f4f5f70c7c2a37bb4d253969c23e1e75d4cb0460a93e0 -R 2daa11b12a9e137050615d079bdc23b8 +P c6c799a54b3fad2f8c2b73b0a88f64dda38736a283bbf4dd286ac9dd6d6bf153 +R c96bca98bb7bd5eb71921b8f1e5fa399 U stephan -Z 4cd6b6db6fabc4cf1ad86e43ed022c8a +Z af40e261971f2302deaf71840d9cb2e5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 76bedb1f89..6cc2e7ff7a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6c799a54b3fad2f8c2b73b0a88f64dda38736a283bbf4dd286ac9dd6d6bf153 +109d441bf1bcdbc01d1f3f2aa145039539fc5aad02f91fc987a0c3702e21809d From 59ac8f4c7fe534a13bdfeafb1fd3d4585ec4d9fb Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 21 Oct 2024 16:06:49 +0000 Subject: [PATCH 076/522] Add docs introducing how to define and use autosetup configure flags. Use -DJIM_COMPAT when building jimsh to force its expr command to be syntax-compatible with canonical TCL. FossilOrigin-Name: a6a275de3d975fdf7432d71a915b40426a976725ebd81a178b5e80d14cf3a2df --- auto.def | 122 +++++++++++++++++++++++++++++++++++++++++--------- manifest | 12 ++--- manifest.uuid | 2 +- 3 files changed, 107 insertions(+), 29 deletions(-) diff --git a/auto.def b/auto.def index 050d3a4af8..2c8a476e90 100644 --- a/auto.def +++ b/auto.def @@ -1,9 +1,10 @@ +#/usr/bin/tclsh +# ^^^ help out editors which guess this file's content type. +# # This is the main autosetup-compatible configure script for the # SQLite project. -global autosetup use cc cc-db cc-shared cc-lib hwaci-common set DUMP_DEFINES_FILE ./defines.list -define ENABLE_SHARED 1 # Are we cross-compiling? set cross_compiling 0 @@ -27,6 +28,83 @@ if {[get-define host] ne [get-define build]} { # # 2.1) --enable-tempstore[=no] to --with-tempstore[=no]. # +######################################################################## +# A gentle introduction to flags handling in autosetup +# +# Reference: https://msteveb.github.io/autosetup/developer/ +# +# All configure flags must be described in an 'options' call, which +# must appear very early on in this script. The general syntax is: +# +# FLAG => {Help text} +# +# Where FLAG can have any of the following formats: +# +# boolopt => "a boolean option which defaults to disabled" +# boolopt2=1 => "a boolean option which defaults to enabled" +# stringopt: => "an option which takes an argument, e.g. --stringopt=value" +# stringopt2:=value => "an option where the argument is optional and defaults to 'value'" +# optalias booltopt3 => "a boolean with a hidden alias. --optalias is not shown in --help" +# +# Autosetup does no small amount of specialized handling for flags, +# especially booleans. Each bool-type --FLAG implicitly gets +# --enable-FLAG and --disable-FLAG forms, and explicitly adding flags +# with those prefixes will force them to be boolean flags. e.g. we +# define a flag "readline", which will be interpreted in one of two +# ways, depending on how it's invoked and how its default is defined: +# +# --enable-readline ==> boolean true +# --disable-readline ==> boolean false +# +# Trying to pass --readline or --readline=1 or --readline=0 will +# result in an "unrecognized option" error, despite the the options +# call listing the flag as "readline". +# +# The behavior described above can lead lead to some confusion when +# writing help text. For example: +# +# options { json=1 {Disable JSON functions} } +# +# The reason the help text says "disable" is because a boolean option +# defaulting to true is, in the --help text, rendered as: +# +# --disable-json Disable JSON functions +# +# Whereas a bool flag which defaults to false will instead render as: +# +# --enable-FLAG +# +# Non-boolean flags, in contrast, use the names specifically given to +# them in the 'options' invocation. e.g. "with-tcl" is the --with-tcl +# flag. Autosetup may, however, choose to automatically alter the help +# text, as demonstrated here: +# +# options { +# readline=1 => {Disable readline support} +# with-readline-lib: => {Readline library} +# with-readline-inc: => {Readline include paths} +# } +# +# $ ./configure --help | grep readline +# --disable-readline disable readline support +# --with-readline-lib specify readline library +# --with-readline-inc specify readline include paths +# +# Note that it prefixed and lower-case the help message. Whether +# that's a feature or a bug can be debated. +# +# Fetching values for flags: +# +# booleans: use one of: +# - [opt-bool FLAG] is autosetup's built-in command for this, but we +# have some convenience variants: +# - [hwaci-opt-truthy FLAG] +# - [hwaci-opt-if-truthy FLAG {THEN} {ELSE}] +# +# Non-boolean (i.e. string) flags: +# - [opt-val FLAG] +# +######################################################################## options [subst { with-debug:=1 => {Enable debug build flags} with-tclsh:PATH => {Full pathname of tclsh to use} @@ -38,8 +116,8 @@ options [subst { editline=0 => {BSD editline support} readline=1 => {Disable readline support} largefile=1 => {Disable large file support} - with-readline-lib => {readline library} - with-readline-inc => {readline include paths} + with-readline-lib: => {Readline library} + with-readline-inc: => {Readline include paths} with-linenoise:DIR => {} amalgamation=1 => {Disable the amalgamation and instead build all files separately} load-extension=1 => {Disable loading of external extensions} @@ -60,7 +138,7 @@ options [subst { with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build.} with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} - dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_FILE} + dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_FILE (for build debugging)} }] ######################################################################## @@ -69,20 +147,18 @@ options [subst { # --releasemode: libtool-specific (which we don't have now) # # - - -set srcdir $autosetup(srcdir) +set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] puts "srcdir = $srcdir" puts "top_srcdir = $top_srcdir" -set RELEASE [readfile $autosetup(srcdir)/VERSION] +set RELEASE [readfile $::autosetup(srcdir)/VERSION] regsub {([0-9]*\.*[0-9]*).*} $RELEASE {\1} VERSION define VERSION $VERSION define RELEASE $RELEASE puts "RELEASE = $RELEASE" puts "VERSION = $VERSION" -define-append SQLITE_AUTOREMAKE cd $autosetup(srcdir) && $top_srcdir/configure {*}$autosetup(argv) +define-append SQLITE_AUTOREMAKE cd $::autosetup(srcdir) && $top_srcdir/configure {*}$::autosetup(argv) set outOfTreeBuild 0 if {![file exists sqlite3.pc.in]} { @@ -210,6 +286,7 @@ if {"" eq [hwaci-bin-define install]} { # cross-compiling. define BUILD_CC [get-define CC_FOR_BUILD] define BUILD_CFLAGS [get-env CFLAGS {-g}] +define ENABLE_SHARED 1 ######################################################################## # Handle --with-wasi-sdk=DIR @@ -443,9 +520,10 @@ proc hwaci-check-tcl {} { define TCL_CONFIG_SH $cfg # The historical configure.ac sources tclConfig.sh so that it can # use the several TCL_... env vars. We obviously cannot do that from - # TCL, so we apply a level of indirection. If the config is not - # available, this generates empty-string entries for the various - # options we're interested in. + # TCL, so we apply a level of indirection which sources that script + # then emits the pieces we're interested in as TCL code. If the + # config is not available, this emits empty-string entries for the + # various options we're interested in. eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]"] #puts "hwaci-check-tcl: with_tclsh=$with_tclsh" #puts "hwaci-check-tcl: with_tcl=$with_tcl" @@ -500,7 +578,6 @@ proc hwaci-check-tcl {} { define TCLLIB_RPATH "" } - if {"" eq $with_tclsh} { hwaci-warn "Cannot find a usable tclsh." } else { @@ -513,16 +590,23 @@ hwaci-check-tcl ######################################################################## # Check which TCL to use as a code generator. Prefer jimsh simply # because we have it in-tree (it's part of autosetup). -define CFLAGS_JIMSH {} +# +# Building jimsh0.c with -DJIM_COMPAT changes certain behavior to be +# compatible with canonical TCL. Specifically: jim's [expr] only +# accepts one arg unless JIM_COMPAT is defined. +define CFLAGS_JIMSH {-DJIM_COMPAT} +set useOwnJimsh 0 puts "Which TCL to use for code generation... " set cgtcl jimtcl if {[cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE_REALPATH define BTCLSH "\$(JIMSH)" + set useOwnJimsh 1 } elseif {[cc-check-functions _fullpath]} { # _fullpath() is a Windows API define-append CFLAGS_JIMSH -DHAVE__FULLPATH define BTCLSH "\$(JIMSH)" + set useOwnJimsh 1 } elseif {"" ne [get-define TCLSH_CMD]} { set cgtcl [get-define TCLSH_CMD] define BTCLSH "\$(TCLSH_CMD)" @@ -850,12 +934,6 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available }; # JimTCL -if {"" eq [get-define CFLAGS_JIMSH]} { - define USE_OWN_JIMSH 0 -} else { - define USE_OWN_JIMSH 1 -} - ######################################################################## # Determine proper rpath-handling flags hwaci-check-rpath @@ -877,7 +955,7 @@ if {0} { make-config-header sqlite_cfg.h \ -bare {SIZEOF_* HAVE_DECL_*} \ -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE - TARGET_* USE_GCOV USE_OWN_JIMSH TCL_*} \ + TARGET_* USE_GCOV TCL_*} \ -auto {HAVE_* PACKAGE_*} \ -none * } diff --git a/manifest b/manifest index bb21f1d2b6..3b6cbe82b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\sinto\sautosetup\sbranch. -D 2024-10-21T13:11:43.662 +C Add\sdocs\sintroducing\show\sto\sdefine\sand\suse\sautosetup\sconfigure\sflags.\sUse\s-DJIM_COMPAT\swhen\sbuilding\sjimsh\sto\sforce\sits\sexpr\scommand\sto\sbe\ssyntax-compatible\swith\scanonical\sTCL. +D 2024-10-21T16:06:49.337 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a392650e2c34738c179f2f7d2c731f90906dcbfb78c236348930997d79281702 +F auto.def aec40855b0321857f679ff53cbb72042e5006260f72d1526db786d0bbcf254e3 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 109d441bf1bcdbc01d1f3f2aa145039539fc5aad02f91fc987a0c3702e21809d 9f642b3dbc8febfacad97076030f44e9b40067e27222f2bcb84813c5765d3d2a -R efd09ae4017e3cac1b5cf47493ec2640 +P 347a50e66fa17bba997f6cbaa5bd693d029df488e54c24f7e4db47b65e84ce81 +R 4ae42afdfc94f9c9fa6e904f46862477 U stephan -Z 9f0bf45ab85b7fbd154d377a0233cf43 +Z 1d7aa6ac6fc1c8fa8cc634105d5b45fa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5807b3fb2d..1b90055c32 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -347a50e66fa17bba997f6cbaa5bd693d029df488e54c24f7e4db47b65e84ce81 +a6a275de3d975fdf7432d71a915b40426a976725ebd81a178b5e80d14cf3a2df From b124098e51891490b3685830a5bb18cc00444e09 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 21 Oct 2024 17:50:55 +0000 Subject: [PATCH 077/522] Start moving most Makefile.in docs over to main.mk. Fix compilation of tclsqlite.c. FossilOrigin-Name: 5b154e08ab5e8a8fd1ac1b28debd46824ef55b533a60ca5711c55b5a59a871cd --- Makefile.in | 112 +++++++++------------------ main.mk | 204 ++++++++++++++++++++++++++++++++++++-------------- manifest | 14 ++-- manifest.uuid | 2 +- 4 files changed, 190 insertions(+), 142 deletions(-) diff --git a/Makefile.in b/Makefile.in index d79fa66f51..7b6bfedcd2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -8,6 +8,11 @@ # certain blocks are added or removed depending on configure-time # information. # +# The docs for many of its variables are in the primary static +# makefile, main.mk (which this one includes at runtime). +# +all: +clean: ######################################################################## #XX# Lines starting with #XX# are TODOs for the port to autosetup. @@ -39,9 +44,6 @@ # that, but we're limited to POSIX Make compatibility here. The # automatic reconfigures are not too onerous, though, because they're # much, much faster than Autotools configure runs. -# -all: -clean: # # Maintenance reminder: When using the X?=Y variable assignment @@ -57,15 +59,6 @@ clean: # that contains this "Makefile.in" and the "configure" script. # TOP = @abs_top_srcdir@ - -# -# Just testing some default dir expansions... -# srcdir = @srcdir@ -# top_srcdir = @top_srcdir@ -# abs_top_srcdir = @abs_top_srcdir@ -# abs_top_builddir = @abs_top_builddir@ -# - # # Some standard variables and programs # @@ -75,45 +68,34 @@ libdir ?= @libdir@ pkgconfigdir ?= $(libdir)/pkgconfig bindir ?= @bindir@ includedir ?= @includedir@ +# +# Just testing some default dir expansions... +# srcdir = @srcdir@ +# top_srcdir = @top_srcdir@ +# abs_top_srcdir = @abs_top_srcdir@ +# abs_top_builddir = @abs_top_builddir@ +# + INSTALL = @BIN_INSTALL@ AR = @AR@ CC = @CC@ -#LD = @LD@ # isn't actually needed, at least on modern Unixes. - -# -# C Compiler and options for use in building executables that -# will run on the platform that is doing the build. -# BCC = @BUILD_CC@ @BUILD_CFLAGS@ +TCC = $(CC) $(CFLAGS) +CFLAGS = @CFLAGS@ @SH_CFLAGS@ -# -# Rather that stuffing all CFLAGS and LDFLAGS into a single set, we -# break them down on a per-feature basis and expect the build targets -# to use the one(s) it needs. -# +LDFLAGS_SHOBJ = @SHOBJ_LDFLAGS@ LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ LDFLAGS_MATH = @LDFLAGS_MATH@ LDFLAGS_RPATH = @LDFLAGS_RPATH@ -LDFLAGS_READLINE = @LDFLAGS_READLINE@ LDFLAGS_PTHREAD = @LDFLAGS_PTHREAD@ -LDFLAGS_SHOBJ = @SHOBJ_LDFLAGS@ +LDFLAGS_READLINE = @LDFLAGS_READLINE@ +CFLAGS_READLINE = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ ENABLE_SHARED = @ENABLE_SHARED@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ -# -# TCC is the C Compile and options for use in building executables that -# will run on the target platform. (BCC and TCC are usually the -# same unless your are cross-compiling.) Separate CC and CFLAGS macros -# are provide so that these aspects of the build process can be changed -# on the "make" command-line. Ex: "make CC=clang CFLAGS=-fsanitize=undefined" -# -CFLAGS = @CFLAGS@ @SH_CFLAGS@ -TCC = $(CC) $(CFLAGS) - -# Define -DNDEBUG to compile without debugging (i.e., for production usage) -# Omitting the define will cause extra debugging code to be inserted and -# includes extra comments when "EXPLAIN stmt" is used. +# TCCX is $(TCC) plus any flags which are desired for the library +# as a whole, but not necessarily needed for every binary. # TCCX = $(TCC) @TARGET_DEBUG@ # Define this for the autoconf-based build, so that the code knows it @@ -123,10 +105,6 @@ TCCX += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # # main.mk will fill out TCCX with some flags common to all builds. -# -# Compiler options needed for programs that use the readline() library. -# -CFLAGS_READLINE = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ #XX#CFLAGS_READLINE += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ #XX#CFLAGS_READLINE += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ #XX# @@ -143,19 +121,18 @@ CFLAGS_READLINE = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ # # With the autosetup build, the intended way to do this is to set # those in $(LDFLAGS_libsqlite3) and include those flags for both -# $(libsqlite3.SO) and any apps which directly link in either -# sqlite3.o or its origin sources. +# $(libsqlite3.SO) and any apps which directly compile/link in either +# sqlite3.c/o or its origin sources. LIBS += @LIBS@ -TLIBS = $(LIBS) # # JimTCL is part of the autosetup suite and is suitable for all # current in-tree code-generation TCL jobs, but it requires that we # build it with non-default flags. Note that the build tree will, if -# no system-level tclsh is found, also have a ./jimsh0. That one is a -# bare-bones build for the configure process, whereas we need to build -# it with another option enabled for use with the various code -# generators. +# no system-level tclsh is found, also have a ./jimsh0 binary. That +# one is a bare-bones build for the configure process, whereas we need +# to build it with another option enabled for use with the various +# code generators. # JIMSH = @srcdir@/jimsh CFLAGS_JIMSH ?= @CFLAGS_JIMSH@ @@ -169,43 +146,24 @@ $(JIMSH): $(TOP)/autosetup/jimsh0.c BTCLSH = @BTCLSH@ $(BTCLSH): -# -# $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for -# compiling the library's own sources, including (sometimes) when -# compiling sqlite3.c directly in to another app. Most notably, it -# should always contain -DSQLITE_TEMP_STORE=N for the sake of -# historical build expecations. -# -# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 -# to default to file, 2 to default to memory, and 3 to force temporary -# tables to always be in memory. -# +# $(CFLAGS_libsqlite3) is documented in main.mk. CFLAGS_libsqlite3 = -DSQLITE_TEMP_STORE=@TEMP_STORE@ -# -# Enable/disable loadable extensions, and other optional features -# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). -# The same set of OMIT and ENABLE flags should be passed to the -# LEMON parser generator and the mkkeywordhash tool as well. -# -# Add OPTIONS=... on the command line to append additional options -# to the OPT_FEATURE_FLAGS. Note that some flags only work if -# the build is specifically configured to account for them. -# OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) TCC += $(OPT_FEATURE_FLAGS) -# Add in any optional parameters specified on the make commane line -# ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". +# +# Add in any optional global compilation flags on the make commane +# line ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". +# +#XX# FIXME: rename one or the other of $(OPTS) and $(OPTIONS), as they +#XX# serve different purposes. TCC += $(OPTS) -# Add in compile-time options for some libraries used by extensions -#TCC += @CFLAGS_ZLIB@ - # Version numbers and release number for the SQLite being compiled. # -VERSION = @VERSION@ +# VERSION = @VERSION@ RELEASE = @RELEASE@ # Filename extensions for binaries and libraries @@ -284,7 +242,7 @@ AS_AUTO_DEF = $(TOP)/auto.def AS_AUTOREMAKE = @SQLITE_AUTOREMAKE@ USE_AMALGAMATION ?= @USE_AMALGAMATION@ -AMALGAMATION_LINE_MACROS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ +AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ # # CFLAGS for sqlite3$(TEXE) diff --git a/main.mk b/main.mk index 5ca48a147f..6cd6e5dcc4 100644 --- a/main.mk +++ b/main.mk @@ -6,70 +6,93 @@ # this one. # # Maintenance reminder: this file must remain devoid of GNU Make-isms. -# i.e. it must be POSIX Make compatible. +# i.e. it must be POSIX Make compatible. "bmake" (BSD make) is +# available on most Linux systems, so compatibility is relatively easy +# to test. # #XX# Lines starting with #XX# are TODOs for the port to autosetup # -# The following variables must be defined before this script is -# invoked: +# The variables listed below must be defined before this script is +# invoked. This file will use defaults, very possibly invalid, for any +# which are not defined. # #XX# FIXME: the list of vars from the historical main.mk is dated and #XX# needs to be updated for autosetup. + # -# TOP The toplevel directory of the source tree. This is the -# directory that contains this "Makefile.in" and the -# "configure.in" script. +# RELEASE = # -# BCC C Compiler and options for use in building executables that -# will run on the platform that is doing the build. +# The MAJOR.MINOR.PATCH version number of this build. +RELEASE ?= MAJOR.MINOR.PATCH # -# TCC C Compiler and options for use in building executables that -# will run on the target platform. This is usually the same -# as BCC, unless you are cross-compiling. +# TOP = # -# AR Tool used to build a static library. +# The toplevel directory of the source tree. For canonical builds +# this is the directory that contains this "Makefile.in" and the +# "configure.in" script. +TOP ?= $(PWD) # -# BEXE File extension for executables on the build platform. ".exe" -# for Windows and "" everywhere else. +# BCC = # -# TEXE File extension for executables on the target platform. ".exe" -# for Windows and "" everywhere else. +# C Compiler and options for use in building executables that will run +# on the platform that is doing the build. +BCC ?= $(CC) # -# BTCLSH The TCL interpreter for in-tree code generation. May be -# either JimTCL or the canonical TCL. +# TCC = # -# ... and many, many more ... +# C Compiler and options for use in building executables that will run +# on the target platform. This is usually the same as BCC, unless you +# are cross-compiling. Note that it should only contain flags which +# are used by _all_ build targets. Flags needed only by specific +# targets are defined elsewhere. +TCC ?= $(BCC) # -# Once the variables above are defined, the rest of this make script -# will build the SQLite library and testing tools. -################################################################################ -all: sqlite3.h sqlite3.c - +# AR = +# Tool used to build a static library from object files. # -# Ideally these variables are all defined in the calling makefile, but -# we can provide some sensible defaults for many of them which should -# suffice for conventional Unix-style OSes. +AR ?= ar # -prefix ?= /usr/local -exec_prefix ?= $(prefix) -libdir ?= $(prefix)/lib -pkgconfigdir ?= $(libdir)/pkgconfig -bindir ?= $(prefix)/bin -includedir ?= $(prefix)/include - -USE_AMALGAMATION ?= 1 -AMALGAMATION_LINE_MACROS ?= --linemacros=0 -INSTALL ?= install - -BCC ?= $(CC) -TCC ?= $(BCC) +# BEXE = +# +# File extension for executables on the build platform. ".exe" for +# Windows and "" everywhere else. BEXE ?= -TEXE ?= +# +# BDLL and BLIB = +# +# The DLL resp. static library counterparts of BEXE. BDLL ?= .so -TDLL ?= .so BLIB ?= .lib +# +# TEXE = +# +# File extension for executables on the target platform. ".exe" for +# Windows and "" everywhere else. +TEXE ?= +# +# TDLL and TLIB The DLL resp. static library counterparts of TEXE. +TDLL ?= .so TLIB ?= .lib - +# +# TCLSH_CMD = +# +# The canonical tclsh. +TCLSH_CMD ?= tclsh +# +# BTCLSH = +# +# The TCL interpreter for in-tree code generation. May be either the +# in-tree JimTCL or the canonical TCL. +BTCLSH ?= $(TCLSH_CMD) +# +# LDFLAGS_(FEATURE) and CFLAGS_(FEATURE) = +# +# Linker resp. C/CPP flags required by a specific feature, e.g. +# LDFLAGS_PTHREAD or CFLAGS_READLINE. +# +# Rather that stuffing all CFLAGS and LDFLAGS into a single set, we +# break them down on a per-feature basis and expect the build targets +# to use the one(s) it needs. LDFLAGS_ZLIB ?= -lz LDFLAGS_MATH ?= -lm LDFLAGS_RPATH ?= -Wl,-rpath -Wl,$(prefix)/lib @@ -77,9 +100,64 @@ LDFLAGS_READLINE ?= -lreadline CFLAGS_READLINE ?= LDFLAGS_PTHREAD ?= -lpthread LDFLAGS_SHOBJ ?= -shared +# +# Various system-level directories, mostly needed for installation and +# for finding system-level dependencies. +prefix ?= /usr/local +exec_prefix ?= $(prefix) +libdir ?= $(prefix)/lib +pkgconfigdir ?= $(libdir)/pkgconfig +bindir ?= $(prefix)/bin +includedir ?= $(prefix)/include +# +# INSTALL = +# +# Tool for installing files and directories. It must be compatible +# with conventional Unix /usr/bin/install. Note that libtool's +# install-sh is _not_ compatible with this because it _moves_ targets +# during installation, which may break the build of targets which are +# built after others are installed. +INSTALL ?= install +# +# ENABLE_SHARED +# +# 1 if libsqlite3.$(TDLL) should be built. ENABLE_SHARED ?= 1 +# +# USE_AMALGAMATION 1 if the amalgamation (sqlite3.c/h) should be built/used, +# otherwise the library is built from all of its original +# source files. +USE_AMALGAMATION ?= 1 +# +# AMALGAMATION_GEN_FLAGS Optional flags for the amalgamation generator. +AMALGAMATION_GEN_FLAGS ?= --linemacros=0 +# +# HAVE_WASI_SDK 1 when building with the WASI SDK. This disables certain +# build targets. HAVE_WASI_SDK ?= 0 +# +# OPT_FEATURE_FLAGS is intended to hold preprocessor flags for +# enabling and disabling specific libsqlite3 features (-DSQLITE_OMIT*, +# -DSQLITE_ENABLE*). The same set of OMIT and ENABLE flags must be +# passed to the LEMON parser generator and the mkkeywordhash tool as +# well. +# +# Add OPTIONS=... on the command line to append additional options to +# the OPT_FEATURE_FLAGS. Note that some flags only work if the build +# is specifically configured to account for them. Adding them later, +# when compiling the amalgamation, may or may not work. OPT_FEATURE_FLAGS ?= +# +# ... and many, many more. Sane defaults are selected where possible. +# +# With the above-described defined, the rest of this make script will +# build the project's deliverables and testing tools. +################################################################################ +all: sqlite3.h sqlite3.c + +######################################################################## +# Modifying what follows should not be necessary for most builds. +######################################################################## # # $(INSTALL) invocation for use with non-executable files. @@ -92,19 +170,31 @@ TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) # TLINK = compiler invocation for when the target will be an executable TLINK = $(TCCX) $(TLINK_EXTRAS) # TLINK_shared = $(TLINK) invocation specifically for shared libraries -LDFLAGS_SHOBJ ?= -shared TLINK_shared = $(TLINK) $(LDFLAGS_SHOBJ) -# TCCX is $(TCC) plus any CFLAGS which are common to most compilations -# for the target platform. In auto-configured builds it is defined by -# the main makefile to include configure-time-dependent options. +# TCCX is $(TCC) plus any flags which are desired for the library +# as a whole, but not necessarily needed for every binary. +# TCCX ?= $(TCC) -TCCX += -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -TCCX += -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session -TCCX += -I$(TOP)/ext/userauth +CFLAGS_intree_includes = \ + -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \ + -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session \ + -I$(TOP)/ext/userauth +TCCX += $(CFLAGS_intree_includes) # CFLAGS_stdio3 ==> for sqlite3_stdio.h CFLAGS_stdio3 := -I$(TOP)/ext/misc +# +# $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for +# compiling the library's own sources, including (sometimes) when +# compiling sqlite3.c directly in to another app. Most notably, it +# should always contain -DSQLITE_TEMP_STORE=N for the sake of +# historical build expecations. +# +# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 +# to default to file, 2 to default to memory, and 3 to force temporary +# tables to always be in memory. +# CFLAGS_libsqlite3 ?= -DSQLITE_TEMP_STORE=1 # @@ -122,7 +212,6 @@ TCLLIBDIR ?= # TCLLIB_RPATH ?= - # # LDFLAGS_libsqlite3 should be used with any target which either # results in building libsqlite3.so, compiles sqlite3.c directly, or @@ -131,7 +220,7 @@ TCLLIB_RPATH ?= # i.e. it should be used with $(TCCX) or $(TLINK) but not $(BCC). # LDFLAGS_libsqlite3 = \ - $(LDFLAGS_RPATH) $(TLIBS) $(LDFLAGS_PTHREAD) \ + $(LDFLAGS_RPATH) $(LDFLAGS_PTHREAD) \ $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) # @@ -695,7 +784,7 @@ sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify \ $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . @@ -706,7 +795,7 @@ sqlite3r.c: sqlite3.c sqlite3r.h $(BTCLSH) # has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC) + $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . @@ -969,7 +1058,7 @@ window.o: $(TOP)/src/window.c $(HDR) $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/window.c tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) - $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) \ + $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS_intree_includes) \ -c $(TOP)/src/tclsqlite.c tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(HDR) @@ -1091,18 +1180,19 @@ tclsqlite3.c: sqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c +CFLAGS_tclextension = $(CFLAGS_intree_includes) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) # Build the SQLite TCL extension in a way that make it compatible # with whatever version of TCL is running as $TCLSH_CMD, possibly defined # by --with-tclsh= # tclextension: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS_tclextension) # Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD # to find it. # tclextension-install: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS_tclextension) # Install the SQLite TCL extension that is used by $TCLSH_CMD # diff --git a/manifest b/manifest index 3b6cbe82b1..983a96d4e0 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\sdocs\sintroducing\show\sto\sdefine\sand\suse\sautosetup\sconfigure\sflags.\sUse\s-DJIM_COMPAT\swhen\sbuilding\sjimsh\sto\sforce\sits\sexpr\scommand\sto\sbe\ssyntax-compatible\swith\scanonical\sTCL. -D 2024-10-21T16:06:49.337 +C Start\smoving\smost\sMakefile.in\sdocs\sover\sto\smain.mk.\sFix\scompilation\sof\stclsqlite.c. +D 2024-10-21T17:50:55.726 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in a2c1b0e12796a0c3f26cde2bf1d6d872168c64e0e8121641df36f248a217b67f +F Makefile.in cc4a99cf1a47782713206d07ab1ddd18b21e2ba44406696bed649523561f97e5 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 6b6d1deaa55692b21903573b24f2215dea8068cab5626928a3fed8ed86ec314f +F main.mk 596c8c96cd37135e54196f4af0d344e24d0ee19c156b06f81805d1637d5fab5c F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 347a50e66fa17bba997f6cbaa5bd693d029df488e54c24f7e4db47b65e84ce81 -R 4ae42afdfc94f9c9fa6e904f46862477 +P a6a275de3d975fdf7432d71a915b40426a976725ebd81a178b5e80d14cf3a2df +R faf3b808c7fc9f5622befc03c8536d67 U stephan -Z 1d7aa6ac6fc1c8fa8cc634105d5b45fa +Z c53b4cc7ea6efe1093758b649c27a18e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1b90055c32..dce868e947 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6a275de3d975fdf7432d71a915b40426a976725ebd81a178b5e80d14cf3a2df +5b154e08ab5e8a8fd1ac1b28debd46824ef55b533a60ca5711c55b5a59a871cd From 5bae363b99b2218a1157e855cdd500050aabbcff Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 21 Oct 2024 19:51:32 +0000 Subject: [PATCH 078/522] More build doc tweaks and get ./startup building. FossilOrigin-Name: cee285029c7225a2457062eb2b4ea7c6a17a3a5ba5fb776ebbb4ea8be62b9fff --- auto.def | 4 +- main.mk | 131 +++++++++++++++++++++++++++++++------------------- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 92 insertions(+), 59 deletions(-) diff --git a/auto.def b/auto.def index 2c8a476e90..3b621cc488 100644 --- a/auto.def +++ b/auto.def @@ -545,7 +545,7 @@ proc hwaci-check-tcl {} { if {$use_tcl} { # Set up the TCLLIBDIR and TCLLIB_RPATH - set tcllibdir [getenv TCLLIBDIR ""] + set tcllibdir [get-env TCLLIBDIR ""] if {"" eq $tcllibdir} { if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { foreach i $result { @@ -565,7 +565,7 @@ proc hwaci-check-tcl {} { set tclrpath [string map [list "%s" $tcllibdir] $rp] # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the # rpath but (A) it includes an unexpand var ref to - # ${LIB_RUNTIME_DIR}, which must tbe set in the makefile and (B) + # ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B) # that flag is inherently compiler-dependent so it's not as # portable as tclConfig.sh assumes. We'll instead use the rpath # flag which autosetup determines for the current compiler. diff --git a/main.mk b/main.mk index 6cd6e5dcc4..9c8aac8365 100644 --- a/main.mk +++ b/main.mk @@ -20,25 +20,25 @@ #XX# needs to be updated for autosetup. # -# RELEASE = +# $(RELEASE) = # # The MAJOR.MINOR.PATCH version number of this build. RELEASE ?= MAJOR.MINOR.PATCH # -# TOP = +# $(TOP) = # # The toplevel directory of the source tree. For canonical builds # this is the directory that contains this "Makefile.in" and the # "configure.in" script. TOP ?= $(PWD) # -# BCC = +# $(BCC) = # # C Compiler and options for use in building executables that will run # on the platform that is doing the build. BCC ?= $(CC) # -# TCC = +# $(TCC) = # # C Compiler and options for use in building executables that will run # on the target platform. This is usually the same as BCC, unless you @@ -47,48 +47,50 @@ BCC ?= $(CC) # targets are defined elsewhere. TCC ?= $(BCC) # -# AR = +# $(AR) = # Tool used to build a static library from object files. # AR ?= ar # -# BEXE = +# $(BEXE) = # # File extension for executables on the build platform. ".exe" for # Windows and "" everywhere else. BEXE ?= # -# BDLL and BLIB = +# $(BDLL) and $(BLIB) = # -# The DLL resp. static library counterparts of BEXE. +# The DLL resp. static library counterparts of $(BEXE). BDLL ?= .so BLIB ?= .lib # -# TEXE = +# $(TEXE) = # # File extension for executables on the target platform. ".exe" for # Windows and "" everywhere else. TEXE ?= # -# TDLL and TLIB The DLL resp. static library counterparts of TEXE. +# $(TDLL) and $(TLIB) = +# +# The DLL resp. static library counterparts of $(TEXE). TDLL ?= .so TLIB ?= .lib # -# TCLSH_CMD = +# $(TCLSH_CMD) = # # The canonical tclsh. TCLSH_CMD ?= tclsh # -# BTCLSH = +# $(BTCLSH) = # # The TCL interpreter for in-tree code generation. May be either the # in-tree JimTCL or the canonical TCL. BTCLSH ?= $(TCLSH_CMD) # -# LDFLAGS_(FEATURE) and CFLAGS_(FEATURE) = +# $(LDFLAGS_{FEATURE}) and $(CFLAGS_{FEATURE}) = # # Linker resp. C/CPP flags required by a specific feature, e.g. -# LDFLAGS_PTHREAD or CFLAGS_READLINE. +# $(LDFLAGS_PTHREAD) or $(CFLAGS_READLINE). # # Rather that stuffing all CFLAGS and LDFLAGS into a single set, we # break them down on a per-feature basis and expect the build targets @@ -110,7 +112,7 @@ pkgconfigdir ?= $(libdir)/pkgconfig bindir ?= $(prefix)/bin includedir ?= $(prefix)/include # -# INSTALL = +# $(INSTALL) = # # Tool for installing files and directories. It must be compatible # with conventional Unix /usr/bin/install. Note that libtool's @@ -119,28 +121,34 @@ includedir ?= $(prefix)/include # built after others are installed. INSTALL ?= install # -# ENABLE_SHARED +# $(ENABLE_SHARED) = # # 1 if libsqlite3.$(TDLL) should be built. ENABLE_SHARED ?= 1 # -# USE_AMALGAMATION 1 if the amalgamation (sqlite3.c/h) should be built/used, -# otherwise the library is built from all of its original -# source files. +# $(USE_AMALGAMATION) +# +# 1 if the amalgamation (sqlite3.c/h) should be built/used, otherwise +# the library is built from all of its original source files. USE_AMALGAMATION ?= 1 # -# AMALGAMATION_GEN_FLAGS Optional flags for the amalgamation generator. +# $(AMALGAMATION_GEN_FLAGS) = +# +# Optional flags for the amalgamation generator. AMALGAMATION_GEN_FLAGS ?= --linemacros=0 # -# HAVE_WASI_SDK 1 when building with the WASI SDK. This disables certain -# build targets. +# $(HAVE_WASI_SDK) = +# +# 1 when building with the WASI SDK. This disables certain build +# targets. HAVE_WASI_SDK ?= 0 # -# OPT_FEATURE_FLAGS is intended to hold preprocessor flags for -# enabling and disabling specific libsqlite3 features (-DSQLITE_OMIT*, -# -DSQLITE_ENABLE*). The same set of OMIT and ENABLE flags must be -# passed to the LEMON parser generator and the mkkeywordhash tool as -# well. +# $(OPT_FEATURE_FLAGS) = +# +# Preprocessor flags for enabling and disabling specific libsqlite3 +# features (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). The same set of OMIT +# and ENABLE flags must be passed to the LEMON parser generator and +# the mkkeywordhash tool as well. # # Add OPTIONS=... on the command line to append additional options to # the OPT_FEATURE_FLAGS. Note that some flags only work if the build @@ -148,6 +156,21 @@ HAVE_WASI_SDK ?= 0 # when compiling the amalgamation, may or may not work. OPT_FEATURE_FLAGS ?= # +# The following TCL_vars come from tclConfig.sh +# +# Potential TODO: a shell script, similar tool/tclConfigShToTcl.sh, +# which emits these vars in a format which we can include from this +# makefile. +TCL_INCLUDE_SPEC ?= +TCL_LIB_SPEC ?= +TCL_STUB_LIB_SPEC ?= +TCL_EXEC_PREFIX ?= +TCL_VERSION ?= +TCLLIBDIR ?= +# $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not +# libsqlite3, and will usually differ from $(LDFLAGS_RPATH). +TCLLIB_RPATH ?= +# # ... and many, many more. Sane defaults are selected where possible. # # With the above-described defined, the rest of this make script will @@ -172,17 +195,24 @@ TLINK = $(TCCX) $(TLINK_EXTRAS) # TLINK_shared = $(TLINK) invocation specifically for shared libraries TLINK_shared = $(TLINK) $(LDFLAGS_SHOBJ) -# TCCX is $(TCC) plus any flags which are desired for the library -# as a whole, but not necessarily needed for every binary. +# +# $(TCCX) is $(TCC) plus any flags which are desired for the library +# as a whole, but not necessarily needed for every binary. It will +# normally get initially populated by the configure-generated +# makefile, so should not be overwritten here. # TCCX ?= $(TCC) +# +# $(CFLAGS_intree_includes) = -I... flags relevant specifically to +# this tree, including any subdirectories commonly needed for building +# various tools. CFLAGS_intree_includes = \ -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \ -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session \ -I$(TOP)/ext/userauth -TCCX += $(CFLAGS_intree_includes) # CFLAGS_stdio3 ==> for sqlite3_stdio.h CFLAGS_stdio3 := -I$(TOP)/ext/misc +TCCX += $(CFLAGS_intree_includes) # # $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for @@ -197,21 +227,6 @@ CFLAGS_stdio3 := -I$(TOP)/ext/misc # CFLAGS_libsqlite3 ?= -DSQLITE_TEMP_STORE=1 -# -# The following TCL_vars come from tclConfig.sh -# -TCL_INCLUDE_SPEC ?= -TCL_LIB_SPEC ?= -TCL_STUB_LIB_SPEC ?= -TCL_EXEC_PREFIX ?= -TCL_VERSION ?= -TCLLIBDIR ?= -# -# $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not -# libsqlite3, and will usually differ from $(LDFLAGS_RPATH). -# -TCLLIB_RPATH ?= - # # LDFLAGS_libsqlite3 should be used with any target which either # results in building libsqlite3.so, compiles sqlite3.c directly, or @@ -1118,6 +1133,7 @@ all: so sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCLSH) # has_tclsh84 $(BTCLSH) $(TOP)/tool/split-sqlite3c.tcl +# # Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(RELEASE) and # create symlinks which point to it. Do we really need all of this # hoop-jumping? Can we not simply install the .so as-is to @@ -1139,18 +1155,21 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) install-so-0 install-so-: install: install-so-$(ENABLE_SHARED) +# # Install $(libsqlite3.LIB) # install-lib: $(install-dir.lib) $(libsqlite3.LIB) $(INSTALL_noexec) $(libsqlite3.LIB) $(install-dir.lib) install: install-lib +# # Install C header files # install-includes: sqlite3.h $(install-dir.include) $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install-dir.include) install: install-includes +# # libtclsqlite3... # pkgIndex.tcl: @@ -1181,6 +1200,7 @@ tclsqlite3.c: sqlite3.c cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c CFLAGS_tclextension = $(CFLAGS_intree_includes) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) +# # Build the SQLite TCL extension in a way that make it compatible # with whatever version of TCL is running as $TCLSH_CMD, possibly defined # by --with-tclsh= @@ -1188,23 +1208,27 @@ CFLAGS_tclextension = $(CFLAGS_intree_includes) $(CFLAGS) $(OPT_FEATURE_FLAGS) $ tclextension: tclsqlite3.c $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS_tclextension) +# # Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD # to find it. # tclextension-install: tclsqlite3.c $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS_tclextension) +# # Install the SQLite TCL extension that is used by $TCLSH_CMD # tclextension-uninstall: $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall +# # List all installed the SQLite TCL extension that is are accessible # by $TCLSH_CMD, included prior versions. # tclextension-list: $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info +# # FTS5 things # FTS5_SRC = \ @@ -1242,6 +1266,7 @@ sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c +# # Rules to build the 'testfixture' application. # # If using the amalgamation, use sqlite3.c directly to build the test @@ -1292,6 +1317,7 @@ soaktest: $(TESTPROGS) fulltestonly: $(TESTPROGS) fuzztest ./testfixture$(TEXE) $(TOP)/test/full.test +# # Fuzz testing # # WARNING: When the "fuzztest" target is run by the testrunner.tcl script, @@ -1307,17 +1333,20 @@ valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db +# # The veryquick.test TCL tests. # tcltest: ./testfixture$(TEXE) ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) +# # Runs all the same tests cases as the "tcltest" target but uses # the testrunner.tcl script to run them in multiple cores # concurrently. testrunner: testfixture$(TEXE) ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl +# # This is the testing target preferred by the core SQLite developers. # It runs tests under a standard configuration, regardless of how # ./configure was run. The devs run "make devtest" prior to each @@ -1333,22 +1362,26 @@ mdevtest: srctree-check has_tclsh85 sdevtest: has_tclsh85 $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS) +# # Validate that various generated files in the source tree # are up-to-date. # srctree-check: $(TOP)/tool/srctree-check.tcl $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl +# # Testing for a release # releasetest: srctree-check has_tclsh85 verify-source $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS) +# # Minimal testing that runs in less than 3 minutes # quicktest: ./testfixture$(TEXE) ./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS) +# # Try to run tests on whatever options are specified by the # ./configure. The developers seldom use this target. Instead # they use "make devtest" which runs tests on a standard set of @@ -1357,12 +1390,14 @@ quicktest: ./testfixture$(TEXE) # test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest +# # Run a test using valgrind. This can take a really long time # because valgrind is so much slower than a native machine. # valgrindtest: $(TESTPROGS) valgrindfuzz OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) +# # A very fast test that checks basic sanity. The name comes from # the 60s-era electronics testing: "Turn it on and see if smoke # comes out." @@ -1455,10 +1490,8 @@ wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS_libsqlite3) -#XX#startup$(TEXE): $(TOP)/test/startup.c sqlite3.c -#XX# $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) -# ^^^ note that it wants $(TLIBS) (a.k.a. $(LDFLAGS_libsqlite3) but is using $(CC) -# instead of $(BCC). +startup$(TEXE): $(TOP)/test/startup.c sqlite3.c + $(TLINK) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS_libsqlite3) KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ diff --git a/manifest b/manifest index 983a96d4e0..80b9c65ecd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Start\smoving\smost\sMakefile.in\sdocs\sover\sto\smain.mk.\sFix\scompilation\sof\stclsqlite.c. -D 2024-10-21T17:50:55.726 +C More\sbuild\sdoc\stweaks\sand\sget\s./startup\sbuilding. +D 2024-10-21T19:51:32.121 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def aec40855b0321857f679ff53cbb72042e5006260f72d1526db786d0bbcf254e3 +F auto.def 01ec2c4c8b77cd82d4e47a5ea32e10e8f70ed786f0afd229688f7863a22c77b9 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 596c8c96cd37135e54196f4af0d344e24d0ee19c156b06f81805d1637d5fab5c +F main.mk 24bd22f0842104f6087eba735c346b232547b83200fd00a0af376c0a38cad554 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a6a275de3d975fdf7432d71a915b40426a976725ebd81a178b5e80d14cf3a2df -R faf3b808c7fc9f5622befc03c8536d67 +P 5b154e08ab5e8a8fd1ac1b28debd46824ef55b533a60ca5711c55b5a59a871cd +R a48807d1193f2982a4a8c8a20649c7aa U stephan -Z c53b4cc7ea6efe1093758b649c27a18e +Z 65a54bc5359adb6f88f5fee08eab16c3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dce868e947..efb899a6c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b154e08ab5e8a8fd1ac1b28debd46824ef55b533a60ca5711c55b5a59a871cd +cee285029c7225a2457062eb2b4ea7c6a17a3a5ba5fb776ebbb4ea8be62b9fff From ad8e79ce53bb616561e2b0c983daf716a9bbfc6d Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 21 Oct 2024 20:12:03 +0000 Subject: [PATCH 079/522] Simplify how the targets which may or may not be enabled, depending on config flags, are formulated in main.mk. FossilOrigin-Name: 7bea793ce46ab5c41b242c5e69b4f9bd8536a9b106e8c39f7ac002451d5db6ea --- Makefile.in | 5 +---- main.mk | 53 +++++++++++++++++++++++++++++++-------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7b6bfedcd2..30fb0ec2f6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -94,9 +94,6 @@ CFLAGS_READLINE = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ ENABLE_SHARED = @ENABLE_SHARED@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ -# TCCX is $(TCC) plus any flags which are desired for the library -# as a whole, but not necessarily needed for every binary. -# TCCX = $(TCC) @TARGET_DEBUG@ # Define this for the autoconf-based build, so that the code knows it # can include the generated sqlite_cfg.h. @@ -261,7 +258,7 @@ Makefile: $(TOP)/Makefile.in $(AS_AUTO_DEF) sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF) $(AS_AUTOREMAKE) @touch $@ -install: install-pc +install: install-pc # defined in main.mk sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) $(AS_AUTOREMAKE) diff --git a/main.mk b/main.mk index 9c8aac8365..462bb5233f 100644 --- a/main.mk +++ b/main.mk @@ -137,12 +137,6 @@ USE_AMALGAMATION ?= 1 # Optional flags for the amalgamation generator. AMALGAMATION_GEN_FLAGS ?= --linemacros=0 # -# $(HAVE_WASI_SDK) = -# -# 1 when building with the WASI SDK. This disables certain build -# targets. -HAVE_WASI_SDK ?= 0 -# # $(OPT_FEATURE_FLAGS) = # # Preprocessor flags for enabling and disabling specific libsqlite3 @@ -156,6 +150,12 @@ HAVE_WASI_SDK ?= 0 # when compiling the amalgamation, may or may not work. OPT_FEATURE_FLAGS ?= # +# $(SHELL_OPT) = +# +# CFLAGS specific to the sqlite3 CLI shell app and its close cousins. +# +SHELL_OPT ?= +# # The following TCL_vars come from tclConfig.sh # # Potential TODO: a shell script, similar tool/tclConfigShToTcl.sh, @@ -171,6 +171,12 @@ TCLLIBDIR ?= # libsqlite3, and will usually differ from $(LDFLAGS_RPATH). TCLLIB_RPATH ?= # +# $(HAVE_WASI_SDK) = +# +# 1 when building with the WASI SDK. This disables certain build +# targets. +HAVE_WASI_SDK ?= 0 +# # ... and many, many more. Sane defaults are selected where possible. # # With the above-described defined, the rest of this make script will @@ -1114,6 +1120,13 @@ mkkeywordhash$(BEXE): $(TOP)/tool/mkkeywordhash.c keywordhash.h: mkkeywordhash$(BEXE) ./mkkeywordhash$(BEXE) > $@ +# +# sqlite3.c split into many smaller files. +# +sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCLSH) # has_tclsh84 + $(BTCLSH) $(TOP)/tool/split-sqlite3c.tcl + +# # Static libsqlite3 # $(libsqlite3.LIB): $(LIBOBJ) @@ -1121,18 +1134,16 @@ $(libsqlite3.LIB): $(LIBOBJ) lib: $(libsqlite3.LIB) all: lib +# # Dynamic libsqlite3 # $(libsqlite3.SO): $(LIBOBJ) $(TLINK_shared) -o $@ $(LIBOBJ) $(LDFLAGS_libsqlite3) -target_libsqlite3_so_1 = $(libsqlite3.SO) -target_libsqlite3_so = $(target_libsqlite3_so_$(ENABLE_SHARED)) -so: $(target_libsqlite3_so) +$(libsqlite3.SO)-1: $(libsqlite3.SO) +$(libsqlite3.SO)-0 $(libsqlite3.SO)-: +so: $(libsqlite3.SO)-$(ENABLE_SHARED) all: so -sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/split-sqlite3c.tcl - # # Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(RELEASE) and # create symlinks which point to it. Do we really need all of this @@ -1175,17 +1186,17 @@ install: install-includes pkgIndex.tcl: echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(TDLL) -target_libtclsqlite3_1 = $(libtclsqlite3.SO) -target_libtclsqlite3 = $(target_libtclsqlite3_$(HAVE_TCL)) $(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) $(TLINK_shared) -o $@ tclsqlite.o \ $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS_libsqlite3) \ $(libsqlite3.LIB) $(TCLLIB_RPATH) -libtcl: $(target_libtclsqlite3) -all: libtcl +$(libtclsqlite3.SO)-1: $(libtclsqlite3.SO) +$(libtclsqlite3.SO)-0 $(libtclsqlite3.SO)-: +libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL) +all: libtcl install.tcldir = $(DESTDIR)$(TCLLIBDIR) -install-tcl-1: install-lib $(target_libtclsqlite3) pkgIndex.tcl +install-tcl-1: install-lib $(libtclsqlite3.SO) pkgIndex.tcl @if [ "x$(DESTDIR)" = "x$(install.tcldir)" ]; then echo "TCLLIBDIR is not set." 1>&2; exit 1; fi $(INSTALL) -d $(install.tcldir) $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) @@ -1557,16 +1568,16 @@ threadtest5: sqlite3.c $(TOP)/test/threadtest5.c $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS_libsqlite3) sqlite3$(TEXE): shell.c sqlite3.c - $(TCCX) $(CFLAGS_READLINE) $(SHELL_OPT) -o $@ \ + $(TLINK) $(CFLAGS_READLINE) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ $(LDFLAGS_libsqlite3) $(LDFLAGS_READLINE) # # Build sqlite3$(TEXE) by default except in wasi-sdk builds. Yes, the # semantics of 0 and 1 are confusingly swapped here. # -target_sqlite3_shell_1 = -target_sqlite3_shell_0 = sqlite3$(TEXE) -all: $(target_sqlite3_shell_$(HAVE_WASI_SDK)) +sqlite3$(TEXE)-1: +sqlite3$(TEXE)-0 sqlite3$(TEXE)-: sqlite3$(TEXE) +all: sqlite3$(TEXE)-$(HAVE_WASI_SDK) install-shell-0: sqlite3$(TEXT) $(install-dir.bin) $(INSTALL) -s sqlite3$(TEXT) $(install-dir.bin) diff --git a/manifest b/manifest index 80b9c65ecd..369c10cf63 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C More\sbuild\sdoc\stweaks\sand\sget\s./startup\sbuilding. -D 2024-10-21T19:51:32.121 +C Simplify\show\sthe\stargets\swhich\smay\sor\smay\snot\sbe\senabled,\sdepending\son\sconfig\sflags,\sare\sformulated\sin\smain.mk. +D 2024-10-21T20:12:03.749 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in cc4a99cf1a47782713206d07ab1ddd18b21e2ba44406696bed649523561f97e5 +F Makefile.in fe28490b3f7a785623b7ad6852c2b2069ee685d6dcf654730829827db65d66d1 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 24bd22f0842104f6087eba735c346b232547b83200fd00a0af376c0a38cad554 +F main.mk ca16a0ccaeefd27b882f5d9dbf7d21d94c0ecd3334f6012e6cc14fbc967dea37 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5b154e08ab5e8a8fd1ac1b28debd46824ef55b533a60ca5711c55b5a59a871cd -R a48807d1193f2982a4a8c8a20649c7aa +P cee285029c7225a2457062eb2b4ea7c6a17a3a5ba5fb776ebbb4ea8be62b9fff +R 711c4e9e2bfbd6aa9dec039b634bf530 U stephan -Z 65a54bc5359adb6f88f5fee08eab16c3 +Z a23261a16f21cdb759a93ef73201f9de # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index efb899a6c7..4ede9ec753 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cee285029c7225a2457062eb2b4ea7c6a17a3a5ba5fb776ebbb4ea8be62b9fff +7bea793ce46ab5c41b242c5e69b4f9bd8536a9b106e8c39f7ac002451d5db6ea From 7968c385409a2adf7a25863ae5649a3980cb6b41 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 21 Oct 2024 21:22:18 +0000 Subject: [PATCH 080/522] Get most of the numerous misc tool binaries building. FossilOrigin-Name: fa74cbb40c0f2e0135ac97fc4fa899b2ab7973f925f154e8e18c85661d60e17f --- Makefile.in | 23 ++------- main.mk | 127 ++++++++++++++++++++++++++++++++++---------------- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 99 insertions(+), 67 deletions(-) diff --git a/Makefile.in b/Makefile.in index 30fb0ec2f6..29f9e8ee86 100644 --- a/Makefile.in +++ b/Makefile.in @@ -113,15 +113,6 @@ TCCX += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite #XX## #XX#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ -# -# Any target libraries which libsqlite must be linked against -# -# With the autosetup build, the intended way to do this is to set -# those in $(LDFLAGS_libsqlite3) and include those flags for both -# $(libsqlite3.SO) and any apps which directly compile/link in either -# sqlite3.c/o or its origin sources. -LIBS += @LIBS@ - # # JimTCL is part of the autosetup suite and is suitable for all # current in-tree code-generation TCL jobs, but it requires that we @@ -216,11 +207,12 @@ TCLLIBDIR = @TCLLIBDIR@ # # for more info. # -GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage -GCOV_LDFLAGS1 = -lgcov + +CFLAGS_GCOV1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage +LDFLAGS_GCOV1 = -lgcov USE_GCOV = @USE_GCOV@ -TCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV)) -TLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV)) +TCOMPILE_EXTRAS += $(CFLAGS_GCOV$(USE_GCOV)) +TLINK_EXTRAS += $(LDFLAGS_GCOV$(USE_GCOV)) # # You should not have to change anything below this line @@ -246,11 +238,6 @@ AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ # SHELL_OPT ?= @OPT_SHELL@ -# -# This is the default Makefile target. The objects listed here -# are what get build when you type just "make" with no arguments. -# - Makefile: $(TOP)/Makefile.in $(AS_AUTO_DEF) $(AS_AUTOREMAKE) @touch $@ diff --git a/main.mk b/main.mk index 462bb5233f..dcc87f168d 100644 --- a/main.mk +++ b/main.mk @@ -15,10 +15,7 @@ # The variables listed below must be defined before this script is # invoked. This file will use defaults, very possibly invalid, for any # which are not defined. -# -#XX# FIXME: the list of vars from the historical main.mk is dated and -#XX# needs to be updated for autosetup. - +######################################################################## # # $(RELEASE) = # @@ -84,7 +81,8 @@ TCLSH_CMD ?= tclsh # $(BTCLSH) = # # The TCL interpreter for in-tree code generation. May be either the -# in-tree JimTCL or the canonical TCL. +# in-tree JimTCL or the canonical TCL. If it's JimTCL, it must be +# compiled with -DJIM_COMPAT and -DHAVE_REALPATH. BTCLSH ?= $(TCLSH_CMD) # # $(LDFLAGS_{FEATURE}) and $(CFLAGS_{FEATURE}) = @@ -194,11 +192,19 @@ all: sqlite3.h sqlite3.c INSTALL_noexec = $(INSTALL) -m 0644 # ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... -# TCOMPILE = generic target platform compiler invocation +# +# $(TCOMPILE) = generic target platform compiler invocation +# $(TCOMPILE_EXTRAS) = config-specific flags for $(TCOMPILE) +# TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) -# TLINK = compiler invocation for when the target will be an executable +# +# $(TLINK) = compiler invocation for when the target will be an executable +# $(TLINK_EXTRAS) = config-specific flags for $(TLINK) +# TLINK = $(TCCX) $(TLINK_EXTRAS) -# TLINK_shared = $(TLINK) invocation specifically for shared libraries +# +# $(TLINK_shared) = $(TLINK) invocation specifically for shared libraries +# TLINK_shared = $(TLINK) $(LDFLAGS_SHOBJ) # @@ -212,12 +218,11 @@ TCCX ?= $(TCC) # $(CFLAGS_intree_includes) = -I... flags relevant specifically to # this tree, including any subdirectories commonly needed for building # various tools. +# CFLAGS_intree_includes = \ -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \ -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session \ - -I$(TOP)/ext/userauth -# CFLAGS_stdio3 ==> for sqlite3_stdio.h -CFLAGS_stdio3 := -I$(TOP)/ext/misc + -I$(TOP)/ext/misc -I$(TOP)/ext/userauth TCCX += $(CFLAGS_intree_includes) # @@ -1432,12 +1437,16 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(TEXE): has_tclconfig sqltclsh.c - $(TLINK) sqltclsh.c -o $@ $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) + $(TLINK) sqltclsh.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS_libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) +# xbin: target for generic binaries which aren't usually built. It is +# used primarily for testing the build process. +xbin: sqltclsh$(TEXE) sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite3) +xbin: sqlite3_expert$(TEXE) CHECKER_DEPS =\ $(TOP)/tool/mkccode.tcl \ @@ -1453,67 +1462,89 @@ sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c - $(TLINK) sqlite3_checker.c -o $@ $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) + $(TLINK) sqlite3_checker.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS_libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) +xbin: sqlite3_checker$(TEXE) -dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo +dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.o $(TLINK) -DDBDUMP_STANDALONE -o $@ \ - $(TOP)/ext/misc/dbdump.c sqlite3.lo $(LDFLAGS_libsqlite3) + $(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: dbdump$(TEXE) dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c $(TLINK)-o $@ $(TOP)/tool/dbtotxt.c +xbin: dbtotxt$(TEXE) -showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(LDFLAGS_libsqlite3) +showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.o + $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: showdb$(TEXE) -showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(LDFLAGS_libsqlite3) +showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.o + $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: showstat4$(TEXE) -showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(LDFLAGS_libsqlite3) +showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.o + $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: showjournal$(TEXE) -showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(LDFLAGS_libsqlite3) +showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.o + $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: showwal$(TEXE) showshm$(TEXE): $(TOP)/tool/showshm.c $(TLINK) -o $@ $(TOP)/tool/showshm.c +xbin: showshm$(TEXE) -index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo - $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(LDFLAGS_libsqlite3) +index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.o + $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: index_usage$(TEXE) -changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(LDFLAGS_libsqlite3) +changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.o + @echo "FIXME: $@"; touch $@ +# $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: changeset$(TEXE) -changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(LDFLAGS_libsqlite3) +changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.o + $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: changesetfuzz$(TEXE) -rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(LDFLAGS_libsqlite3) +rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.o + $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: rollback-test$(TEXE) -atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(LDFLAGS_libsqlite3) +atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.o + $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: atrc$(TEXX) LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h $(TLINK) -I. -o $@ $(TOP)/tool/logest.c +xbin: LogEst$(TEXE) -wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo - $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(LDFLAGS_libsqlite3) +wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.o + $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: wordcount$(TEXE) speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS_libsqlite3) +xbin: speedtest1$(TEXE) startup$(TEXE): $(TOP)/test/startup.c sqlite3.c $(TLINK) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS_libsqlite3) +xbin: startup$(TEXE) KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS_libsqlite3) +xbin: kvtest$(TEXE) rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o - $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS_libsqlite3) + @echo "FIXME: $@"; touch $@ +# $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: rbu$(EXE) loadfts$(EXE): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) $(TLINK) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS_libsqlite3) +xbin: loadfts$(EXE) # This target will fail if the SQLite amalgamation contains any exported # symbols that do not begin with "sqlite3_". It is run as part of the @@ -1558,14 +1589,16 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ $(TOP)/test/tt3_stress.c \ $(TOP)/test/tt3_lookaside1.c -threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC) - $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(LDFLAGS_libsqlite3) +threadtest3$(TEXE): sqlite3.o $(THREADTEST3_SRC) + $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(LDFLAGS_libsqlite3) +xbin: threadtest3$(TEXE) threadtest: threadtest3$(TEXE) ./threadtest3$(TEXE) threadtest5: sqlite3.c $(TOP)/test/threadtest5.c $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS_libsqlite3) +xbin: threadtest5 sqlite3$(TEXE): shell.c sqlite3.c $(TLINK) $(CFLAGS_READLINE) $(SHELL_OPT) -o $@ \ @@ -1585,7 +1618,7 @@ install-shell-1 install-shell-: install: install-shell-$(HAVE_WASI_SDK) sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h - $(TLINK) $(CFLAGS_stdio3) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite3) install-diff: sqldiff$(TEXE) $(install-dir.bin) $(INSTALL) -s sqldiff$(TEXT) $(install-dir.bin) @@ -1593,6 +1626,7 @@ install-diff: sqldiff$(TEXE) $(install-dir.bin) dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: dbhash$(TEXE) RSYNC_SRC = \ $(TOP)/tool/sqlite3_rsync.c \ @@ -1607,6 +1641,7 @@ RSYNC_OPT = \ sqlite3_rsync$(TEXE): $(RSYNC_SRC) $(TCCX) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) +xbin: sqlite3_rsync$(TEXE) install-rsync: sqlite3_rsync$(TEXE) $(install-dir.bin) $(INSTALL) sqlite3_rsync$(TEXT) $(install-dir.bin) @@ -1625,15 +1660,18 @@ install-pc: sqlite3.pc $(install-dir.pkgconfig) scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS_libsqlite3) +xbin: scrub$(TEXE) srcck1$(BEXE): $(TOP)/tool/srcck1.c $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c +xbin: srcck1$(BEXE) sourcetest: srcck1$(BEXE) sqlite3.c ./srcck1$(BEXE) sqlite3.c src-verify$(BEXE): $(TOP)/tool/src-verify.c $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c +xbin: src-verify$(BEXE) verify-source: ./src-verify$(BEXE) ./src-verify$(BEXE) $(TOP) @@ -1642,21 +1680,24 @@ fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS_libsqlite3) fuzzy: fuzzershell$(TEXE) +xbin: fuzzershell$(TEXE) fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(LDFLAGS_libsqlite3) fuzzy: fuzzcheck$(TEXE) +xbin: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) $(TLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ sqlite3.c $(LDFLAGS_libsqlite3) fuzzy: fuzzcheck-asan$(TEXE) - +xbin: fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) $(TLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ sqlite3.c $(LDFLAGS_libsqlite3) fuzzy: fuzzcheck-ubsan$(TEXE) +xbin: fuzzcheck-ubsan$(TEXE) # Usage: FUZZDB=filename make run-fuzzcheck # @@ -1677,6 +1718,7 @@ ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3. $(TLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) fuzzy: ossshell$(TEXE) +xbin: ossshell$(TEXE) sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(LDFLAGS_libsqlite3) @@ -1685,6 +1727,7 @@ fuzzy: sessionfuzz$(TEXE) dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) fuzzy: dbfuzz$(TEXE) +xbin: dbfuzz$(TEXE) DBFUZZ2_OPTS = \ -USQLITE_THREADSAFE \ @@ -1704,10 +1747,12 @@ dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h mkdir -p dbfuzz2-dir cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir fuzzy: dbfuzz2$(TEXE) +xbin: dbfuzz2$(TEXE) mptester$(TEXE): $(libsqlite3.LIB) $(TOP)/mptest/mptest.c $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c $(libsqlite3.LIB) \ $(LDFLAGS_libsqlite3) +xbin: mptester$(TEXE) MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 @@ -1758,7 +1803,7 @@ SHELL_DEP = \ shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCLSH) # has_tclsh84 $(BTCLSH) $(TOP)/tool/mkshellc.tcl >shell.c - +# # Rules to build the extension objects. # icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) diff --git a/manifest b/manifest index 369c10cf63..f406164133 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Simplify\show\sthe\stargets\swhich\smay\sor\smay\snot\sbe\senabled,\sdepending\son\sconfig\sflags,\sare\sformulated\sin\smain.mk. -D 2024-10-21T20:12:03.749 +C Get\smost\sof\sthe\snumerous\smisc\stool\sbinaries\sbuilding. +D 2024-10-21T21:22:18.453 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in fe28490b3f7a785623b7ad6852c2b2069ee685d6dcf654730829827db65d66d1 +F Makefile.in d1c02c09e3e05d8f5daffb49adfb83fa0a9b5872d7e74a4997ce734d29916032 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ca16a0ccaeefd27b882f5d9dbf7d21d94c0ecd3334f6012e6cc14fbc967dea37 +F main.mk f123e87f3b4dd8d508f3758cd185ec53560731918c64c9993d7358c5c86eb81d F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cee285029c7225a2457062eb2b4ea7c6a17a3a5ba5fb776ebbb4ea8be62b9fff -R 711c4e9e2bfbd6aa9dec039b634bf530 +P 7bea793ce46ab5c41b242c5e69b4f9bd8536a9b106e8c39f7ac002451d5db6ea +R 9cb9f93cb255e0456660e5d24fe32c31 U stephan -Z a23261a16f21cdb759a93ef73201f9de +Z 2b07fc524ef2b46294a607b5dc16781d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4ede9ec753..22b1aa202f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7bea793ce46ab5c41b242c5e69b4f9bd8536a9b106e8c39f7ac002451d5db6ea +fa74cbb40c0f2e0135ac97fc4fa899b2ab7973f925f154e8e18c85661d60e17f From 744d986d17b11ef8adf505ae282dbc7eafdc82b1 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 21 Oct 2024 21:32:58 +0000 Subject: [PATCH 081/522] Resolve two build FIXMEs. FossilOrigin-Name: 4de51c165ca4d0ad66f5dd7aa16fc82c673c6791b65990339134fb26b858ec33 --- main.mk | 9 ++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/main.mk b/main.mk index dcc87f168d..3b401728d1 100644 --- a/main.mk +++ b/main.mk @@ -1498,9 +1498,9 @@ index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.o $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS_libsqlite3) xbin: index_usage$(TEXE) +# Reminder: changeset does not build without -DSQLITE_ENABLE_SESSION changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.o - @echo "FIXME: $@"; touch $@ -# $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS_libsqlite3) xbin: changeset$(TEXE) changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.o @@ -1537,10 +1537,9 @@ kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS_libsqlite3) xbin: kvtest$(TEXE) -rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o - @echo "FIXME: $@"; touch $@ +#rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o # $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS_libsqlite3) -xbin: rbu$(EXE) +#xbin: rbu$(EXE) loadfts$(EXE): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) $(TLINK) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS_libsqlite3) diff --git a/manifest b/manifest index f406164133..69080ecc5a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\smost\sof\sthe\snumerous\smisc\stool\sbinaries\sbuilding. -D 2024-10-21T21:22:18.453 +C Resolve\stwo\sbuild\sFIXMEs. +D 2024-10-21T21:32:58.702 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk f123e87f3b4dd8d508f3758cd185ec53560731918c64c9993d7358c5c86eb81d +F main.mk a29ea875e6761a37430dd4bd9b3a7311a277b095d95f2bd9701d23a41d7623bd F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7bea793ce46ab5c41b242c5e69b4f9bd8536a9b106e8c39f7ac002451d5db6ea -R 9cb9f93cb255e0456660e5d24fe32c31 +P fa74cbb40c0f2e0135ac97fc4fa899b2ab7973f925f154e8e18c85661d60e17f +R 6a47b82222a3234924b44815565335fb U stephan -Z 2b07fc524ef2b46294a607b5dc16781d +Z 5b595eb789738b4c53b49a8868024628 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 22b1aa202f..0b8761020d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa74cbb40c0f2e0135ac97fc4fa899b2ab7973f925f154e8e18c85661d60e17f +4de51c165ca4d0ad66f5dd7aa16fc82c673c6791b65990339134fb26b858ec33 From e6c2759acb09923f73b254c8a0583fb9d7698b1a Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 21 Oct 2024 21:53:08 +0000 Subject: [PATCH 082/522] Add sqlite3rebaser_... to the API symbols accepted by the 'checksymbols' makefile target. FossilOrigin-Name: 0284590f212b2d6ac6516e60350e924a1c29602e8ac8b997d0a5fa488a2dc9c1 --- Makefile.in | 2 +- manifest | 17 +++++++---------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Makefile.in b/Makefile.in index 583d81ef7e..ef40d82506 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1526,7 +1526,7 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la # symbols that do not begin with "sqlite3_". It is run as part of the # releasetest.tcl script. # -VALIDIDS=' sqlite3(changeset|changegroup|session)?_' +VALIDIDS=' sqlite3(changeset|changegroup|session|rebaser)?_' checksymbols: sqlite3.o nm -g --defined-only sqlite3.o nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 diff --git a/manifest b/manifest index 607e331693..b9f39809b7 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Version\s3.47.0 -D 2024-10-21T16:30:22.476 +C Add\ssqlite3rebaser_...\sto\sthe\sAPI\ssymbols\saccepted\sby\sthe\s'checksymbols'\smakefile\starget. +D 2024-10-21T21:53:08.916 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 93330c792ece8b4c4bc7ea39bd52eca2a9fad37943811f9f773a725ad76f2e7c +F Makefile.in 1376a160cd98a14d118a9f8c2db88f0f906586234a0b0f49f2af13e95c1ebbcd F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2219,11 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e904b37fb2621e6bd5e761f3ecb75adb34350f2d1d7b229e655e74bc6a2f5321 -R a76584af8bedcd13de97df48304b6b29 -T +sym-major-release * -T +sym-release * -T +sym-version-3.47.0 * -U drh -Z 06d21548d99c4222144faa895fe216f7 +P 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e +R 6ee4864245abc117fdbf4575b6f7f982 +U stephan +Z 125137dcf74d7a719c01e300208c0b76 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7613608be5..5779696ae6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e +0284590f212b2d6ac6516e60350e924a1c29602e8ac8b997d0a5fa488a2dc9c1 From 31465666ff6c5815885fc46000cb413267612307 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 21 Oct 2024 22:15:04 +0000 Subject: [PATCH 083/522] Bring checksymbols target up to date and add a TODO based on a feature request from the forum. FossilOrigin-Name: c00a03256b3f06411f93e690f875e9bc59a750aeea3ecf84bf8c8bec7c08b8ae --- Makefile.in | 7 ++++++- main.mk | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Makefile.in b/Makefile.in index 29f9e8ee86..5b1b7c756c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -44,7 +44,12 @@ clean: # that, but we're limited to POSIX Make compatibility here. The # automatic reconfigures are not too onerous, though, because they're # much, much faster than Autotools configure runs. - +# +# - Add target(s) to dump out specific vars, e.g. SQLITE_OPT, as +# requested at https://sqlite.org/forum/forumpost/75cb3179216f8d86. +# This would also be useful for the ext/wasm build, which fishes +# SHELL_OPT out of the makefile. +# # # Maintenance reminder: When using the X?=Y variable assignment # formulation, please test the build with both GNU make and a POSIX diff --git a/main.mk b/main.mk index 3b401728d1..399c22fddf 100644 --- a/main.mk +++ b/main.mk @@ -1549,7 +1549,7 @@ xbin: loadfts$(EXE) # symbols that do not begin with "sqlite3_". It is run as part of the # releasetest.tcl script. # -VALIDIDS=' sqlite3(changeset|changegroup|session)?_' +VALIDIDS=' sqlite3(changeset|changegroup|session|rebaser)?_' checksymbols: sqlite3.o nm -g --defined-only sqlite3.o nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 diff --git a/manifest b/manifest index 69080ecc5a..af8ae8f298 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Resolve\stwo\sbuild\sFIXMEs. -D 2024-10-21T21:32:58.702 +C Bring\schecksymbols\starget\sup\sto\sdate\sand\sadd\sa\sTODO\sbased\son\sa\sfeature\srequest\sfrom\sthe\sforum. +D 2024-10-21T22:15:04.157 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in d1c02c09e3e05d8f5daffb49adfb83fa0a9b5872d7e74a4997ce734d29916032 +F Makefile.in 88f9238a6fcf4ea77c24942fa58772bd206f14b0cd604b6267e7075d609b878a F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk a29ea875e6761a37430dd4bd9b3a7311a277b095d95f2bd9701d23a41d7623bd +F main.mk 420e9df512d6f7095392af26bc6bb1699c66251b8feb6cf848484378ea6f8980 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fa74cbb40c0f2e0135ac97fc4fa899b2ab7973f925f154e8e18c85661d60e17f -R 6a47b82222a3234924b44815565335fb +P 4de51c165ca4d0ad66f5dd7aa16fc82c673c6791b65990339134fb26b858ec33 +R 4ba0a87f98ffeda9c845a486f8f418cb U stephan -Z 5b595eb789738b4c53b49a8868024628 +Z ee571add5e230eaf56e3d8be4b067a81 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0b8761020d..2536260322 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4de51c165ca4d0ad66f5dd7aa16fc82c673c6791b65990339134fb26b858ec33 +c00a03256b3f06411f93e690f875e9bc59a750aeea3ecf84bf8c8bec7c08b8ae From 0d7ede8d1c90c9781136e6f6e6d48f556c98f288 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 21 Oct 2024 22:45:59 +0000 Subject: [PATCH 084/522] In testrunner.tcl: Better estimates for ETC (Estimated Time to Completion). Show the ETC even for the single-line status reports. FossilOrigin-Name: 2a2f5f4e378338951cc2030ffbacd678e6a6eab142e39ee632c61be42345b092 --- manifest | 14 +++++------ manifest.uuid | 2 +- test/testrunner.tcl | 61 ++++++++++++++++++++++++++++++++------------- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index b9f39809b7..6c891d3ca4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssqlite3rebaser_...\sto\sthe\sAPI\ssymbols\saccepted\sby\sthe\s'checksymbols'\smakefile\starget. -D 2024-10-21T21:53:08.916 +C In\stestrunner.tcl:\s\sBetter\sestimates\sfor\sETC\s(Estimated\sTime\sto\sCompletion).\nShow\sthe\sETC\seven\sfor\sthe\ssingle-line\sstatus\sreports. +D 2024-10-21T22:45:59.158 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1721,7 +1721,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 -F test/testrunner.tcl 6215e11be403a16947bbb3b31cf4905b417155df242e4c5229f85bcda1c28f50 x +F test/testrunner.tcl 1472b8c57c124c7eed934a2cbc955b0c0e0a948a4608546598195267bbd4b2fd x F test/testrunner_data.tcl c7b3b911e44f7e8c01cc6bc7571e16115cdc2e4db46630bd2acd7a931a46380e F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2219,8 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e -R 6ee4864245abc117fdbf4575b6f7f982 -U stephan -Z 125137dcf74d7a719c01e300208c0b76 +P 0284590f212b2d6ac6516e60350e924a1c29602e8ac8b997d0a5fa488a2dc9c1 +R 2ac47cb3cae83d7727a58a5f1336d6ea +U drh +Z e2b1dfbad8a2776fb071a8b0b9eafb7e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5779696ae6..0d5c9c8489 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0284590f212b2d6ac6516e60350e924a1c29602e8ac8b997d0a5fa488a2dc9c1 +2a2f5f4e378338951cc2030ffbacd678e6a6eab142e39ee632c61be42345b092 diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 266d65e2dc..55d1add183 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -324,6 +324,8 @@ set TRG(schema) { /* Fields updated as jobs run */ starttime INTEGER, -- Start time (milliseconds since 1970) endtime INTEGER, -- End time + span INTEGER, -- Total run-time in milliseconds + estwork INTEGER, -- Estimated amount of work state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ), ntest INT, -- Number of test cases run nerr INT, -- Number of errors reported @@ -342,6 +344,13 @@ set TRG(schema) { } #------------------------------------------------------------------------- +# Estimated amount of work required by displaytype, relative to 'tcl' +# +set estwork(tcl) 1 +set estwork(fuzz) 11 +set estwork(bld) 56 +set estwork(make) 97 + #-------------------------------------------------------------------------- # Check if this script is being invoked to run a single file. If so, # run it. @@ -495,19 +504,21 @@ proc show_status {db cls} { }] set total 0 - foreach s {"" ready running done failed} { set S($s) 0 } + foreach s {"" ready running done failed omit} { set S($s) 0; set W($s) 0; } + set workpending 0 $db eval { - SELECT state, count(*) AS cnt FROM jobs GROUP BY 1 + SELECT state, count(*) AS cnt, sum(estwork) AS ew FROM jobs GROUP BY 1 } { incr S($state) $cnt - incr total $cnt + incr W($state) $ew + incr totalw $ew } set nt 0 set ne 0 $db eval { SELECT sum(ntest) AS nt, sum(nerr) AS ne FROM jobs HAVING nt>0 } break - set fin [expr $S(done)+$S(failed)] + set fin [expr $W(done)+$W(failed)+$W(omit)] if {$cmdline!=""} {set cmdline " $cmdline"} if {$cls} { @@ -522,15 +533,12 @@ proc show_status {db cls} { set srcdir [file dirname [file dirname $TRG(info_script)]] set line "Running: $S(running) (max: $nJob)" - if {$S(running)>0 && $fin>100 && $fin>0.05*$total} { - # Only estimate the time remaining after completing at least 100 - # jobs amounting to 10% of the total. Never estimate less than - # 2% of the total time used so far. - set tmleft [expr {($tm/$fin)*($total-$fin)}] + if {$S(running)>0 && $fin>10} { + set tmleft [expr {($tm/$fin)*($totalw-$fin)}] if {$tmleft<0.02*$tm} { set tmleft [expr {$tm*0.02}] } - append line " est time left [elapsetime $tmleft]" + append line " ETC [elapsetime $tmleft]" } puts [format %-79.79s $line] if {$S(running)>0} { @@ -914,6 +922,7 @@ proc r_get_next_job {iJob} { # Returns the jobid value for the new job. # proc add_job {args} { + global estwork set options { -displaytype -displayname -build -dirname @@ -938,25 +947,29 @@ proc add_job {args} { set state "" if {$A(-depid)==""} { set state ready } + set type $A(-displaytype) + set ew $estwork($type) trdb eval { INSERT INTO jobs( - displaytype, displayname, build, dirname, cmd, depid, priority, + displaytype, displayname, build, dirname, cmd, depid, priority, estwork, state ) VALUES ( - $A(-displaytype), + $type, $A(-displayname), $A(-build), $A(-dirname), $A(-cmd), $A(-depid), $A(-priority), + $ew, $state ) } trdb last_insert_rowid } + # Argument $build is either an empty string, or else a list of length 3 # describing the job to build testfixture. In the usual form: @@ -1283,8 +1296,8 @@ proc make_new_testset {} { trdb eval { REPLACE INTO config VALUES('start', $tm ); } add_jobs_from_cmdline $TRG(patternlist) - } + } } proc mark_job_as_finished {jobid output state endtm} { @@ -1309,10 +1322,12 @@ proc mark_job_as_finished {jobid output state endtm} { if {[info exists pltfm]} {set pltfm [string trim $pltfm]} trdb eval { UPDATE jobs - SET output=$output, state=$state, endtime=$endtm, + SET output=$output, state=$state, endtime=$endtm, span=$endtm-starttime, ntest=$ntest, nerr=$nerr, svers=$svers, pltfm=$pltfm WHERE jobid=$jobid; UPDATE jobs SET state=$childstate WHERE depid=$jobid; + UPDATE config SET value=value+$nerr WHERE name='nfail'; + UPDATE config SET value=value+$ntest WHERE name='ntest'; } } } @@ -1460,17 +1475,23 @@ proc progress_report {} { show_status trdb 1 } } else { - set tm [expr [clock_milliseconds] - $TRG(starttime)] - set tm [format "%d" [expr int($tm/1000.0 + 0.5)]] + set tmms [expr [clock_milliseconds] - $TRG(starttime)] + set tm [format "%d" [expr int($tmms/1000.0 + 0.5)]] + set wtotal 0 + set wdone 0 r_write_db { trdb eval { - SELECT displaytype, state, count(*) AS cnt + SELECT displaytype, state, count(*) AS cnt, sum(estwork) AS ew FROM jobs GROUP BY 1, 2 } { set v($state,$displaytype) $cnt incr t($displaytype) $cnt + incr wtotal $ew + if {$state=="done" || $state=="failed" || $state=="omit"} { + incr wdone $ew + } } } @@ -1486,11 +1507,15 @@ proc progress_report {} { lappend text "r$v(running,$j)" } } + if {$wdone>0} { + set tmleft [expr {($tmms/$wdone)*($wtotal-$wdone)}] + append text " ETC [elapsetime $tmleft]" + } if {[info exists TRG(reportlength)]} { puts -nonewline "[string repeat " " $TRG(reportlength)]\r" } - set report "${tm} [join $text { }]" + set report "[elapsetime $tmms] [join $text { }]" set TRG(reportlength) [string length $report] if {[string length $report]<100} { puts -nonewline "$report\r" From f4ab0ad8eed65f901a61e3a3e015c862ee321984 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 22 Oct 2024 03:12:11 +0000 Subject: [PATCH 085/522] Rename hwaci-error to the more descriptive hwaci-fatal. Use autosetup's file-isexec instead of [file executable] for portability. Remove the binary file lookup cache - unnecessary complexity. When searching for tools like tclsh, check under $prefix/bin before checking the $PATH. This seems like the right thing to do, but the fact that autosetup's file-search API's do not do that by default leaves some room for doubt about the wisdom of this change. FossilOrigin-Name: 4d4423df8d14fb683bb89bebeac4b108a40847259a116fcb634b9e6594907026 --- auto.def | 24 +++++----- autosetup/hwaci-common.tcl | 94 +++++++++++++++++++++++--------------- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 77 insertions(+), 57 deletions(-) diff --git a/auto.def b/auto.def index 3b621cc488..f1739f64fa 100644 --- a/auto.def +++ b/auto.def @@ -263,7 +263,7 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { ######### # Programs needed if {"" eq [hwaci-bin-define install]} { - msg-result "Cannot find install binary, so 'make install' will not work." + hwaci-warn "Cannot find install binary, so 'make install' will not work." # Reminder: we historically have ./install-sh in the source tree. # Can we not simply use that? # @@ -449,9 +449,9 @@ proc hwaci-check-tcl {} { if {"" ne $with_tclsh} { if {![file isfile $with_tclsh]} { - hwaci-error "TCL shell $with_tclsh is not a file" - } elseif {![file executable $with_tclsh]} { - hwaci-error "TCL shell $with_tclsh is not executable" + hwaci-fatal "TCL shell $with_tclsh is not a file" + } elseif {![file-isexec $with_tclsh]} { + hwaci-fatal "TCL shell $with_tclsh is not executable" } else { define TCLSH_CMD $with_tclsh puts "Using tclsh at \"$with_tclsh\"" @@ -484,7 +484,7 @@ proc hwaci-check-tcl {} { } } if {"" eq $cfg} { - hwaci-error "No tclConfig.sh found under ${with_tcl}" + hwaci-fatal "No tclConfig.sh found under ${with_tcl}" } } else { # If we have not yet found a tclConfig.sh file, look in $libdir which is @@ -502,7 +502,7 @@ proc hwaci-check-tcl {} { } } if {![file readable $cfg]} { - hwaci-error { + hwaci-fatal { Cannot find a usable tclConfig.sh file. Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. SQLite does not use TCL internally, but TCL is required to build SQLite @@ -532,9 +532,9 @@ proc hwaci-check-tcl {} { if {"" eq $with_tclsh} { set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] - if {![file executable $with_tclsh]} { + if {![file-isexec $with_tclsh]} { set with_tclsh2 [get-define TCL_EXEC_PREFIX]/bin/tclsh - if {![file executable $with_tclsh2]} { + if {![file-isexec $with_tclsh2]} { hwaci-warn "Cannot find a usable tclsh as $with_tclsh or $with_tclsh2" } else { set with_tclsh $with_tclsh2 @@ -572,7 +572,7 @@ proc hwaci-check-tcl {} { } define TCLLIBDIR $tcllibdir define TCLLIB_RPATH $tclrpath - #hwaci-error "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" + #hwaci-fatal "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" } else { define TCLLIBDIR "" define TCLLIB_RPATH "" @@ -617,16 +617,16 @@ if {[cc-check-functions realpath]} { set tpre [get-define TCL_EXEC_PREFIX] if {"" ne $tpre} { set tv [get-define TCL_VERSION] - if {[file executable "${tpre}/bin/tclsh${tv}"]} { + if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { define TCLSH_CMD "${tpre}/bin/tclsh${tv}" - } elseif {[file executable "${tpre}/bin/tclsh"]} { + } elseif {[file-isexec "${tpre}/bin/tclsh"]} { define TCLSH_CMD "${tpre}/bin/tclsh" } unset tv } unset tpre if {"" eq [get-define TCLSH_CMD]} { - hwaci-error "Cannot find a tclsh to use for code generation." + hwaci-fatal "Cannot find a tclsh to use for code generation." } } set cgtcl [get-define TCLSH_CMD] diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index b3b12e53af..81987db647 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -41,15 +41,13 @@ # updating global state via feature tests. ######################################################################## -array set hwaci-cache- {} ; # used for caching various results. - proc hwaci-warn {msg} { puts "WARNING: $msg" } proc hwaci-notice {msg} { puts "NOTICE: $msg" } -proc hwaci-error {msg} { +proc hwaci-fatal {msg} { user-error "ERROR: $msg" } @@ -88,39 +86,52 @@ proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { } ######################################################################## -# Looks for binary named $binName and `define`s $defName to that full -# path, or an empty string if not found. Returns the value it defines. -# This caches the result for a given $binName/$defName combination, so -# calls after the first for a given combination will always return the -# same result. -# -# If defName is empty then "BIN_X" is used, where X is the upper-case -# form of $binName with any '-' characters replaced with '_'. -proc hwaci-bin-define {binName {defName {}}} { - global hwaci-cache- - set cacheName "$binName:$defName" - set check {} - if {[info exists hwaci-cache-($cacheName)]} { - set check $hwaci-cache-($cacheName) - } - msg-checking "Looking for $binName ... " - if {"" ne $check} { - set lbl $check - if {"" eq $check} { - set lbl "not found" - set check "" - } - msg-result "(cached) $lbl" - return $check +# If $v is true, [puts $msg] is called, else puts is not called. +#proc hwaci-maybe-verbose {v msg} { +# if {$v} { +# puts $msg +# } +#} + +######################################################################## +# Works similarly to autosetup's [find-executable-path $binName] but +# first checks for [get-define prefix]/bin/$binName. Returns the full +# path to the result or an empty string. If the first argument is -v +# then it emits info about its status, otherwise it works silently. +proc hwaci-find-executable-path {args} { + set binName $args + set verbose 0 + if {[lindex $args 0] eq "-v"} { + set verbose 1 + set binName [lrange $args 1 end] } - set check [find-executable-path $binName] - if {"" eq $check} { - msg-result "not found" - set hwaci-cache-($cacheName) "" - } else { - msg-result $check - set hwaci-cache-($cacheName) $check + if {$verbose} { + msg-checking "Looking for $binName ... " } + set check [get-define prefix]/bin/$binName + if {"" eq $check || ![file-isexec $check]} { + set check [find-executable-path $binName] + } + if {$verbose} { + if {"" eq $check} { + msg-result "not found" + } else { + msg-result $check + } + } + return $check +} + +######################################################################## +# Uses [hwaci-find-executable-path $binName] to (verbosely) search for +# a binary, sets a define (see below) to the result, and returns the +# result (an empty string if not found). +# +# The define'd name is: if defName is empty then "BIN_X" is used, +# where X is the upper-case form of $binName with any '-' characters +# replaced with '_'. +proc hwaci-bin-define {binName {defName {}}} { + set check [hwaci-find-executable-path -v $binName] if {"" eq $defName} { set defName "BIN_[string toupper [string map {- _} $binName]]" } @@ -129,16 +140,25 @@ proc hwaci-bin-define {binName {defName {}}} { } ######################################################################## -# Each argument is passed to cc-path-progs. If that function returns -# true, the full path to that binary is returned. If no matches are -# found, "" is returned. +# Looks for the first binary found of the names passed to this +# function. It first looks in [get-define prefix]/bin, then falls back +# to [cc-path-progs]. If a match is found, the full path to that +# binary is returned, else "" is returned. # # Despite using cc-path-progs to do the search, this function clears # any define'd name that function stores for the result (because the # caller has no sensible way of knowing which result it was unless # they pass only a single argument). proc hwaci-first-bin-of {args} { + set p [get-define prefix]/bin foreach b $args { + set pb $p/$b + msg-checking "Checking for $pb ... " + if {[file-isexec $pb]} { + msg-result yes + return $pb + } + msg-result no if {[cc-path-progs $b]} { set u [string toupper $b] set x [get-define $u] diff --git a/manifest b/manifest index af8ae8f298..0ccac60d99 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bring\schecksymbols\starget\sup\sto\sdate\sand\sadd\sa\sTODO\sbased\son\sa\sfeature\srequest\sfrom\sthe\sforum. -D 2024-10-21T22:15:04.157 +C Rename\shwaci-error\sto\sthe\smore\sdescriptive\shwaci-fatal.\sUse\sautosetup's\sfile-isexec\sinstead\sof\s[file\sexecutable]\sfor\sportability.\sRemove\sthe\sbinary\sfile\slookup\scache\s-\sunnecessary\scomplexity.\sWhen\ssearching\sfor\stools\slike\stclsh,\scheck\sunder\s$prefix/bin\sbefore\schecking\sthe\s$PATH.\sThis\sseems\slike\sthe\sright\sthing\sto\sdo,\sbut\sthe\sfact\sthat\sautosetup's\sfile-search\sAPI's\sdo\snot\sdo\sthat\sby\sdefault\sleaves\ssome\sroom\sfor\sdoubt\sabout\sthe\swisdom\sof\sthis\schange. +D 2024-10-22T03:12:11.011 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 01ec2c4c8b77cd82d4e47a5ea32e10e8f70ed786f0afd229688f7863a22c77b9 +F auto.def b4eaca56a2ad8911a848aa0f14dfe2e60f6358edbe1dc846e7f91295613cf2f4 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 83d6520660b17c00ae56e453c4a9e18ed37bae9a2a2a62db68ca49e2a454052a +F autosetup/hwaci-common.tcl 4a11759d8cd202cba850787c0b4861fff3924404700e211b6b669b15ad448a5e F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4de51c165ca4d0ad66f5dd7aa16fc82c673c6791b65990339134fb26b858ec33 -R 4ba0a87f98ffeda9c845a486f8f418cb +P c00a03256b3f06411f93e690f875e9bc59a750aeea3ecf84bf8c8bec7c08b8ae +R 0bfab33c3e9fc3e64d010c7b8b0822a3 U stephan -Z ee571add5e230eaf56e3d8be4b067a81 +Z 6a399f67a3c0dba538ebcc158b7d53df # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2536260322..389201d33b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c00a03256b3f06411f93e690f875e9bc59a750aeea3ecf84bf8c8bec7c08b8ae +4d4423df8d14fb683bb89bebeac4b108a40847259a116fcb634b9e6594907026 From 894bd83f524815b0846a54094e3daa135f589347 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 22 Oct 2024 03:33:11 +0000 Subject: [PATCH 086/522] Touch configure-generated files at configure-time even if autosetup does not update them because their contents would not be changed. Works around wonky deps causing too-frequent rebuilds. FossilOrigin-Name: 339b48af1728f6acb4c3a02f84bd432466dcc728d3d01f9728e82f3c6aedb002 --- Makefile.in | 1 - auto.def | 4 ++-- autosetup/hwaci-common.tcl | 37 +++++++++++++++++++++++++------------ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/Makefile.in b/Makefile.in index 5b1b7c756c..8f559e4570 100644 --- a/Makefile.in +++ b/Makefile.in @@ -13,7 +13,6 @@ # all: clean: - ######################################################################## #XX# Lines starting with #XX# are TODOs for the port to autosetup. # diff --git a/auto.def b/auto.def index f1739f64fa..cfe4e6dcae 100644 --- a/auto.def +++ b/auto.def @@ -941,8 +941,7 @@ hwaci-check-rpath ######################################################################## # Generate the output files. # -hwaci-make-from-dot-in Makefile -hwaci-make-from-dot-in sqlite3.pc +hwaci-make-from-dot-in -touch Makefile sqlite3.pc # for sqlite_cfg.h define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION [get-define VERSION] @@ -958,6 +957,7 @@ if {0} { TARGET_* USE_GCOV TCL_*} \ -auto {HAVE_* PACKAGE_*} \ -none * + hwaci-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTOREMAKE@ } #TODO hwaci-make-from-dot-in ext/wasm/GNUmakefile diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 81987db647..bc4e214fb8 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -419,26 +419,39 @@ proc hwaci-check-compile-commands {{configOpt {}}} { } ######################################################################## -# Uses [make-template] to create makefile(-like) file $filename from -# $filename.in but explicitly makes the output read-only, to avoid -# inadvertent editing (who, me?). +# Runs the 'touch' command on one or more files, ignoring any errors. +proc hwaci-touch {filename} { + catch { exec touch {*}$filename } +} + +######################################################################## +# Usage: +# +# hwaci-make-from-dot-in ?-touch? filename(s)... # -# The second argument is an optional boolean specifying whether to -# `touch` the generated files. This can be used as a workaround for +# Uses [make-template] to create makefile(-like) file(s) $filename +# from $filename.in but explicitly makes the output read-only, to +# avoid inadvertent editing (who, me?). +# +# If the first argument is -touch then the generated file is touched +# to update its timestamp. This can be used as a workaround for # cases where (A) autosetup does not update the file because it was # not really modified and (B) the file *really* needs to be updated to -# please the build process. Pass any non-0 value to enable touching. -# -# The argument may be a list of filenames. +# please the build process. # # Failures when running chmod or touch are silently ignored. -proc hwaci-make-from-dot-in {filename {touch 0}} { +proc hwaci-make-from-dot-in {args} { + set filename $args + set touch 0 + if {[lindex $args 0] eq "-touch"} { + set touch 1 + set filename [lrange $args 1 end] + } foreach f $filename { catch { exec chmod u+w $f } make-template $f.in $f - if {0 != $touch} { - puts "Touching $f" - catch { exec touch $f } + if {$touch} { + hwaci-touch $f } catch { exec chmod -w $f } } diff --git a/manifest b/manifest index 0ccac60d99..cfff6aedc3 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Rename\shwaci-error\sto\sthe\smore\sdescriptive\shwaci-fatal.\sUse\sautosetup's\sfile-isexec\sinstead\sof\s[file\sexecutable]\sfor\sportability.\sRemove\sthe\sbinary\sfile\slookup\scache\s-\sunnecessary\scomplexity.\sWhen\ssearching\sfor\stools\slike\stclsh,\scheck\sunder\s$prefix/bin\sbefore\schecking\sthe\s$PATH.\sThis\sseems\slike\sthe\sright\sthing\sto\sdo,\sbut\sthe\sfact\sthat\sautosetup's\sfile-search\sAPI's\sdo\snot\sdo\sthat\sby\sdefault\sleaves\ssome\sroom\sfor\sdoubt\sabout\sthe\swisdom\sof\sthis\schange. -D 2024-10-22T03:12:11.011 +C Touch\sconfigure-generated\sfiles\sat\sconfigure-time\seven\sif\sautosetup\sdoes\snot\supdate\sthem\sbecause\stheir\scontents\swould\snot\sbe\schanged.\sWorks\saround\swonky\sdeps\scausing\stoo-frequent\srebuilds. +D 2024-10-22T03:33:11.322 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 88f9238a6fcf4ea77c24942fa58772bd206f14b0cd604b6267e7075d609b878a +F Makefile.in c6f6af495b8bdbc106a258efcafa15f007e00d883ce7bbc4567d88ab674b3e1b F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def b4eaca56a2ad8911a848aa0f14dfe2e60f6358edbe1dc846e7f91295613cf2f4 +F auto.def f09183abc026e18248b6ea08ff6729534c9085593e1792242b85d117e17d21a2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 4a11759d8cd202cba850787c0b4861fff3924404700e211b6b669b15ad448a5e +F autosetup/hwaci-common.tcl 35741010b16e295831b9f0509eefabde296393077dcdfbacfac08664024a571b F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c00a03256b3f06411f93e690f875e9bc59a750aeea3ecf84bf8c8bec7c08b8ae -R 0bfab33c3e9fc3e64d010c7b8b0822a3 +P 4d4423df8d14fb683bb89bebeac4b108a40847259a116fcb634b9e6594907026 +R 11d74630845ef40c7f6ed5b9fbaad6cc U stephan -Z 6a399f67a3c0dba538ebcc158b7d53df +Z 563969555f9e1585b74abf0a638fb9ce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 389201d33b..86533e1c0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d4423df8d14fb683bb89bebeac4b108a40847259a116fcb634b9e6594907026 +339b48af1728f6acb4c3a02f84bd432466dcc728d3d01f9728e82f3c6aedb002 From 1e38a9cc1af73b2ee811f750c8f59e7d48b5b75c Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 22 Oct 2024 03:56:21 +0000 Subject: [PATCH 087/522] After discussing [4d4423df8d14] with Steve Bennett, do not prepend $prefix/bin to the search path for binaries, as that path is commonly used for cross-compiled targets and we want binaries which will run on the build host. FossilOrigin-Name: f2008a7d797263de25eaed60d4b6bd5c87cdb917bb92cfc8700f91e6416d744c --- auto.def | 3 ++- autosetup/hwaci-common.tcl | 33 ++++++++++++--------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/auto.def b/auto.def index cfe4e6dcae..43cfb5f753 100644 --- a/auto.def +++ b/auto.def @@ -454,7 +454,7 @@ proc hwaci-check-tcl {} { hwaci-fatal "TCL shell $with_tclsh is not executable" } else { define TCLSH_CMD $with_tclsh - puts "Using tclsh at \"$with_tclsh\"" + puts "Using tclsh: $with_tclsh" } if {$use_tcl} { if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { @@ -510,6 +510,7 @@ proc hwaci-check-tcl {} { } } } + puts "Using tclConfig.sh: $cfg" } elseif {!$optTcl} { puts "Unable to run tests because of --disable-tcl" } else { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index bc4e214fb8..0729abacf0 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -94,24 +94,22 @@ proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { #} ######################################################################## -# Works similarly to autosetup's [find-executable-path $binName] but -# first checks for [get-define prefix]/bin/$binName. Returns the full -# path to the result or an empty string. If the first argument is -v -# then it emits info about its status, otherwise it works silently. +# Usage: hwaci-find-executable-path ?-v? binaryName +# +# Works similarly to autosetup's [find-executable-path $binName] but: +# +# - If the first arg is -v, it's verbose about searching, else it's quiet. +# +# Returns the full path to the result or an empty string. proc hwaci-find-executable-path {args} { set binName $args set verbose 0 if {[lindex $args 0] eq "-v"} { set verbose 1 set binName [lrange $args 1 end] - } - if {$verbose} { msg-checking "Looking for $binName ... " } - set check [get-define prefix]/bin/$binName - if {"" eq $check || ![file-isexec $check]} { - set check [find-executable-path $binName] - } + set check [find-executable-path $binName] if {$verbose} { if {"" eq $check} { msg-result "not found" @@ -140,25 +138,18 @@ proc hwaci-bin-define {binName {defName {}}} { } ######################################################################## +# Usage: hwaci-first-bin-of bin... +# # Looks for the first binary found of the names passed to this -# function. It first looks in [get-define prefix]/bin, then falls back -# to [cc-path-progs]. If a match is found, the full path to that -# binary is returned, else "" is returned. +# function. If a match is found, the full path to that binary is +# returned, else "" is returned. # # Despite using cc-path-progs to do the search, this function clears # any define'd name that function stores for the result (because the # caller has no sensible way of knowing which result it was unless # they pass only a single argument). proc hwaci-first-bin-of {args} { - set p [get-define prefix]/bin foreach b $args { - set pb $p/$b - msg-checking "Checking for $pb ... " - if {[file-isexec $pb]} { - msg-result yes - return $pb - } - msg-result no if {[cc-path-progs $b]} { set u [string toupper $b] set x [get-define $u] diff --git a/manifest b/manifest index cfff6aedc3..fdea4ff68f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Touch\sconfigure-generated\sfiles\sat\sconfigure-time\seven\sif\sautosetup\sdoes\snot\supdate\sthem\sbecause\stheir\scontents\swould\snot\sbe\schanged.\sWorks\saround\swonky\sdeps\scausing\stoo-frequent\srebuilds. -D 2024-10-22T03:33:11.322 +C After\sdiscussing\s[4d4423df8d14]\swith\sSteve\sBennett,\sdo\snot\sprepend\s$prefix/bin\sto\sthe\ssearch\spath\sfor\sbinaries,\sas\sthat\spath\sis\scommonly\sused\sfor\scross-compiled\stargets\sand\swe\swant\sbinaries\swhich\swill\srun\son\sthe\sbuild\shost. +D 2024-10-22T03:56:21.378 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def f09183abc026e18248b6ea08ff6729534c9085593e1792242b85d117e17d21a2 +F auto.def 8bdc3871a7acb7091841aacc7dee8131f2e529c8fdb09b939085adc846fee144 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 35741010b16e295831b9f0509eefabde296393077dcdfbacfac08664024a571b +F autosetup/hwaci-common.tcl e2a8a47eae0540179922cebc71c8f89a9dd57e1fbd87baa608d1ef68c84f79b8 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4d4423df8d14fb683bb89bebeac4b108a40847259a116fcb634b9e6594907026 -R 11d74630845ef40c7f6ed5b9fbaad6cc +P 339b48af1728f6acb4c3a02f84bd432466dcc728d3d01f9728e82f3c6aedb002 +R 14a9823295475261e592b5a3cbc7b5e0 U stephan -Z 563969555f9e1585b74abf0a638fb9ce +Z da5168a3b869cb4b5385423bf4ef4565 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 86533e1c0d..d6656dcfd8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -339b48af1728f6acb4c3a02f84bd432466dcc728d3d01f9728e82f3c6aedb002 +f2008a7d797263de25eaed60d4b6bd5c87cdb917bb92cfc8700f91e6416d744c From 49f293ba581fc54f14348c01114ecf1ff95df26c Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 22 Oct 2024 09:43:27 +0000 Subject: [PATCH 088/522] Set I/O mode to binary in Windows in sqlite3_rsync. FossilOrigin-Name: 67175287440cf363df01bed2464122c3b686a82ea82aeecd3f45fe90c359495c --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/sqlite3_rsync.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6c891d3ca4..256770551b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\stestrunner.tcl:\s\sBetter\sestimates\sfor\sETC\s(Estimated\sTime\sto\sCompletion).\nShow\sthe\sETC\seven\sfor\sthe\ssingle-line\sstatus\sreports. -D 2024-10-21T22:45:59.158 +C Set\sI/O\smode\sto\sbinary\sin\sWindows\sin\ssqlite3_rsync. +D 2024-10-22T09:43:27.018 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -2181,7 +2181,7 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b F tool/sqlite3_analyzer.c.in 348ba349bbdc93c9866439f9f935d7284866a2a4e6898bc906ae1204ade56918 -F tool/sqlite3_rsync.c d832c69265d32d3694e469d5ccb2da03360d2088d7871743a76a32f71854ad91 +F tool/sqlite3_rsync.c 501ffba428d5150bdf7e178369e5d70af4c93e87bb943ae11f5d3889fcb17aec F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c d00f93263aa2fa6ba0cba0106d95458e6effb94fdb5fc634f56834f90c05bbb4 @@ -2219,8 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0284590f212b2d6ac6516e60350e924a1c29602e8ac8b997d0a5fa488a2dc9c1 -R 2ac47cb3cae83d7727a58a5f1336d6ea +P 2a2f5f4e378338951cc2030ffbacd678e6a6eab142e39ee632c61be42345b092 +R bd59add05d030d8e620303bf0a3a15a0 U drh -Z e2b1dfbad8a2776fb071a8b0b9eafb7e +Z 9922bc02103a3015dbb6c18ac09bbbb9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0d5c9c8489..33bcc19d3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a2f5f4e378338951cc2030ffbacd678e6a6eab142e39ee632c61be42345b092 +67175287440cf363df01bed2464122c3b686a82ea82aeecd3f45fe90c359495c diff --git a/tool/sqlite3_rsync.c b/tool/sqlite3_rsync.c index ae8107c8cd..9f7c302cb6 100644 --- a/tool/sqlite3_rsync.c +++ b/tool/sqlite3_rsync.c @@ -240,9 +240,9 @@ static int popen2( hStdinRd, hStdoutWr, hStderr,&childPid); *pChildPid = childPid; fd = _open_osfhandle(PTR_TO_INT(hStdoutRd), 0); - *ppIn = fdopen(fd, "r"); + *ppIn = fdopen(fd, "rb"); fd = _open_osfhandle(PTR_TO_INT(hStdinWr), 0); - *ppOut = _fdopen(fd, "w"); + *ppOut = _fdopen(fd, "wb"); CloseHandle(hStdinRd); CloseHandle(hStdoutWr); return 0; From 8f90c664071ac0abc6611c6294570d5890d72e5f Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 22 Oct 2024 10:29:13 +0000 Subject: [PATCH 089/522] Further changes to sqlite3_rsync.c to work around Windows issues. FossilOrigin-Name: e2bd3219d9f7bab377ebcfa9a737ca59899c68dad1e3d1d16347bbfdd25652ee --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/sqlite3_rsync.c | 9 +++++++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 256770551b..95098fae8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Set\sI/O\smode\sto\sbinary\sin\sWindows\sin\ssqlite3_rsync. -D 2024-10-22T09:43:27.018 +C Further\schanges\sto\ssqlite3_rsync.c\sto\swork\saround\sWindows\sissues. +D 2024-10-22T10:29:13.094 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -2181,7 +2181,7 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b F tool/sqlite3_analyzer.c.in 348ba349bbdc93c9866439f9f935d7284866a2a4e6898bc906ae1204ade56918 -F tool/sqlite3_rsync.c 501ffba428d5150bdf7e178369e5d70af4c93e87bb943ae11f5d3889fcb17aec +F tool/sqlite3_rsync.c 6c9cac5a9197f591985b271aeff803ec4fb4db36c8eab97e1331ff64aa1b8d94 F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c d00f93263aa2fa6ba0cba0106d95458e6effb94fdb5fc634f56834f90c05bbb4 @@ -2219,8 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2a2f5f4e378338951cc2030ffbacd678e6a6eab142e39ee632c61be42345b092 -R bd59add05d030d8e620303bf0a3a15a0 +P 67175287440cf363df01bed2464122c3b686a82ea82aeecd3f45fe90c359495c +R 58b5147977291d7ab43e6696ae456e76 U drh -Z 9922bc02103a3015dbb6c18ac09bbbb9 +Z c3d98da9f482cd0d68ad72a19eedb45b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 33bcc19d3a..e532379d68 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67175287440cf363df01bed2464122c3b686a82ea82aeecd3f45fe90c359495c +e2bd3219d9f7bab377ebcfa9a737ca59899c68dad1e3d1d16347bbfdd25652ee diff --git a/tool/sqlite3_rsync.c b/tool/sqlite3_rsync.c index 9f7c302cb6..7a453b6cc3 100644 --- a/tool/sqlite3_rsync.c +++ b/tool/sqlite3_rsync.c @@ -93,6 +93,7 @@ struct SQLiteRsync { ****************************************************************************/ #ifdef _WIN32 #include +#include #include /* ** Print a fatal error and quit. @@ -1756,6 +1757,10 @@ int main(int argc, char const * const *argv){ ctx.pIn = stdin; ctx.pOut = stdout; ctx.isRemote = 1; +#ifdef _WIN32 + _setmode(_fileno(ctx.pIn), _O_BINARY); + _setmode(_fileno(ctx.pOut), _O_BINARY); +#endif originSide(&ctx); return 0; } @@ -1763,6 +1768,10 @@ int main(int argc, char const * const *argv){ ctx.pIn = stdin; ctx.pOut = stdout; ctx.isRemote = 1; +#ifdef _WIN32 + _setmode(_fileno(ctx.pIn), _O_BINARY); + _setmode(_fileno(ctx.pOut), _O_BINARY); +#endif replicaSide(&ctx); return 0; } From 6ac6bedc80167db7b82ff650b5728ca17a9447f7 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 22 Oct 2024 12:56:00 +0000 Subject: [PATCH 090/522] Teach ext/wasm/GNUmakefile to use tool/emcc.sh and fix a syntax error in tool/emcc.sh.in. Work around a JimTCL incompatibility in tool/mkshellc.tcl. FossilOrigin-Name: 24e0f6ecc67615a2a8c2df08aa47a782cf692fb1a5a59246eab83c0232e78edc --- auto.def | 2 +- ext/wasm/GNUmakefile | 13 ++++--------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- tool/emcc.sh.in | 2 +- tool/mkshellc.tcl | 3 ++- 6 files changed, 18 insertions(+), 22 deletions(-) diff --git a/auto.def b/auto.def index 43cfb5f753..0b1a48e934 100644 --- a/auto.def +++ b/auto.def @@ -838,7 +838,7 @@ define cross_compiling ${cross_compiling} ######################################################################## # Emscripten SDK for building the web-based wasm components. # -if {0 eq [get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} { +if {![get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} { set wrapper $srcdir/tool/emcc.sh define EMCC_WRAPPER $wrapper hwaci-make-from-dot-in $wrapper diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 918f52655d..19ad759905 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -38,7 +38,7 @@ ######################################################################## default: all #default: quick -SHELL := $(firstword $(wildcard /usr/local/bin/bash /usr/bin/bash /bin/bash)) +SHELL := $(firstword $(shell which bash) $(wildcard /usr/local/bin/bash /usr/bin/bash /bin/bash)) ifeq (,$(SHELL)) $(error Cannot find the bash shell) endif @@ -174,14 +174,9 @@ ifeq (1,$(MAKING_CLEAN)) emcc.bin := echo emcc.version := unknown else - emcc.bin := $(shell which emcc 2>/dev/null) - ifeq (,$(emcc.bin)) - ifneq (,$(EMSDK_HOME)) - emcc.bin := $(wildcard $(EMSDK_HOME)/upstream/emscripten/emcc) - endif - ifeq (,$(emcc.bin)) - $(error Cannot find emcc in path.) - endif + emcc.bin := $(dir.tool)/emcc.sh + ifeq (,$(wildcard $(emcc.bin))) + $(error Configure script did not find emcc.) endif emcc.version := $(shell $(emcc.bin) --version | sed -n 1p | sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;') $(info using emcc version [$(emcc.version)]) diff --git a/manifest b/manifest index fdea4ff68f..87c9f44a67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C After\sdiscussing\s[4d4423df8d14]\swith\sSteve\sBennett,\sdo\snot\sprepend\s$prefix/bin\sto\sthe\ssearch\spath\sfor\sbinaries,\sas\sthat\spath\sis\scommonly\sused\sfor\scross-compiled\stargets\sand\swe\swant\sbinaries\swhich\swill\srun\son\sthe\sbuild\shost. -D 2024-10-22T03:56:21.378 +C Teach\sext/wasm/GNUmakefile\sto\suse\stool/emcc.sh\sand\sfix\sa\ssyntax\serror\sin\stool/emcc.sh.in.\sWork\saround\sa\sJimTCL\sincompatibility\sin\stool/mkshellc.tcl. +D 2024-10-22T12:56:00.929 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 8bdc3871a7acb7091841aacc7dee8131f2e529c8fdb09b939085adc846fee144 +F auto.def 2539fa219ed9689601fa1568f0ebe09de028c1916e1dcba154f2b906bbeadc63 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -627,7 +627,7 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 128f8e9830dd8c50c14558649a6f13a2742e9d48223cc67485779baeebbc7391 +F ext/wasm/GNUmakefile 311aa0d5edc7006409962cc77cc26560d92f9be69c2c4302e8bbc68189fd02db F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193 F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -2136,7 +2136,7 @@ F tool/custom.txt 24ed55e71c5edae0067ba159bbf09240d58b160331f7716e95816cd3aa0ba5 F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c -F tool/emcc.sh.in ccd415e9784d8efdb6e29bd2289bff57d37a928122620a244fcb99f445ae276c +F tool/emcc.sh.in 5a3534af8d437747cf4141abaab3db558756f4a1ac8f3ebf28a16ffa26209921 F tool/enlargedb.c 3e8b2612b985cfa7e3e8800031ee191b43ae80de96abb5abbd5eada62651ee21 F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -2165,7 +2165,7 @@ F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61 F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa F tool/mkpragmatab.tcl 32e359ccb21011958a821955254bd7a5fa7915d01a8c16fed91ffc8b40cb4adf -F tool/mkshellc.tcl b7adf08b82de60811d2cb6af05ff59fc17e5cd6f3e98743c14eaaa3f8971fed0 +F tool/mkshellc.tcl 2bc29c201933ae72a16a79070fe80aded80c24ea487ecd2f8df20c2973c87bfc F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 339b48af1728f6acb4c3a02f84bd432466dcc728d3d01f9728e82f3c6aedb002 -R 14a9823295475261e592b5a3cbc7b5e0 +P f2008a7d797263de25eaed60d4b6bd5c87cdb917bb92cfc8700f91e6416d744c +R 82fed5141642968aff8ff825cd13834f U stephan -Z da5168a3b869cb4b5385423bf4ef4565 +Z ede5ca6f72a35dcc638e3268758ee837 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d6656dcfd8..a5ccc7bd34 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2008a7d797263de25eaed60d4b6bd5c87cdb917bb92cfc8700f91e6416d744c +24e0f6ecc67615a2a8c2df08aa47a782cf692fb1a5a59246eab83c0232e78edc diff --git a/tool/emcc.sh.in b/tool/emcc.sh.in index 3edc65fb42..fb849545f8 100644 --- a/tool/emcc.sh.in +++ b/tool/emcc.sh.in @@ -16,7 +16,7 @@ EMSDK_HOME="@EMSDK_HOME@" EMSDK_ENV="@EMSDK_ENV@" emcc="@BIN_EMCC@" -if [x = "x${emcc}" ]; then +if [ x = "x${emcc}" ]; then emcc=`which emcc 2>/dev/null` fi diff --git a/tool/mkshellc.tcl b/tool/mkshellc.tcl index 4f16a772e3..af9804e4fa 100644 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@ -34,7 +34,8 @@ set in [open $topdir/src/shell.c.in] fconfigure $in -translation binary proc omit_redundant_typedefs {line} { global typedef_seen - if {[regexp {^typedef .*\y([a-zA-Z0-9_]+);} $line all typename]} { + if {[regexp {^typedef .* ([a-zA-Z0-9_]+);} $line all typename]} { + # --------------------\y jimtcl does not support \y if {[info exists typedef_seen($typename)]} { return "/* [string map {/* // */ //} $line] */" } From 4f72770b3462f60c74f5f674bed39338489a1aa8 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 22 Oct 2024 13:02:48 +0000 Subject: [PATCH 091/522] Minor cleanups to how configure generates tool/emcc.sh. FossilOrigin-Name: 4484b4623684b09df018f85d95a2b2894a13f38013902831be20a263db605001 --- auto.def | 12 ++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/auto.def b/auto.def index 0b1a48e934..890a767bd7 100644 --- a/auto.def +++ b/auto.def @@ -838,16 +838,16 @@ define cross_compiling ${cross_compiling} ######################################################################## # Emscripten SDK for building the web-based wasm components. # +set emccsh $srcdir/tool/emcc.sh if {![get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} { - set wrapper $srcdir/tool/emcc.sh - define EMCC_WRAPPER $wrapper - hwaci-make-from-dot-in $wrapper - catch {exec chmod u+x $wrapper} - unset wrapper + define EMCC_WRAPPER $emccsh + hwaci-make-from-dot-in $emccsh + catch {exec chmod u+x $emccsh} } else { define EMCC_WRAPPER "" - catch {exec rm -f $srcdir/tool/emcc.sh} + catch {file delete -force $emccsh} } +unset emccsh ######################################################################## # Check for log(3) in libm and die with an error if it is not diff --git a/manifest b/manifest index 87c9f44a67..5904c03a3e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Teach\sext/wasm/GNUmakefile\sto\suse\stool/emcc.sh\sand\sfix\sa\ssyntax\serror\sin\stool/emcc.sh.in.\sWork\saround\sa\sJimTCL\sincompatibility\sin\stool/mkshellc.tcl. -D 2024-10-22T12:56:00.929 +C Minor\scleanups\sto\show\sconfigure\sgenerates\stool/emcc.sh. +D 2024-10-22T13:02:48.260 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 2539fa219ed9689601fa1568f0ebe09de028c1916e1dcba154f2b906bbeadc63 +F auto.def 161d52a60891a6d17beca0ad79838d6dbbff6b1cfb079dc1afc1b6ae25ef031c F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f2008a7d797263de25eaed60d4b6bd5c87cdb917bb92cfc8700f91e6416d744c -R 82fed5141642968aff8ff825cd13834f +P 24e0f6ecc67615a2a8c2df08aa47a782cf692fb1a5a59246eab83c0232e78edc +R d8de8f893f2f9d4ef4213358a88a8c4d U stephan -Z ede5ca6f72a35dcc638e3268758ee837 +Z 14f63c9cbf98b7ad4195a656fe3f2aa0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a5ccc7bd34..ce7b24f5d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24e0f6ecc67615a2a8c2df08aa47a782cf692fb1a5a59246eab83c0232e78edc +4484b4623684b09df018f85d95a2b2894a13f38013902831be20a263db605001 From 76e48f4d6648f514a47a4c769c931126da2a7696 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 22 Oct 2024 16:19:14 +0000 Subject: [PATCH 092/522] Do not typedef Tcl_Size if it is already #defined. FossilOrigin-Name: 53491688cf622ca317b3ff56156e601c2bdfffc94e4fe471ca82d5ba1d9e875f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 2 +- src/tclsqlite.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 95098fae8a..e6b9e05840 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\schanges\sto\ssqlite3_rsync.c\sto\swork\saround\sWindows\sissues. -D 2024-10-22T10:29:13.094 +C Do\snot\stypedef\sTcl_Size\sif\sit\sis\salready\s#defined. +D 2024-10-22T16:19:14.101 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -781,8 +781,8 @@ F src/sqliteInt.h baae24292817e13e7fe748851c62efc381dcc4dac241b1182eac3d2f05eae5 F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c e2b752dd08034c834e3639afa3300940d6e847fcd94207e1f2f1b83ce08b87be -F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262 +F src/tclsqlite.c 47d4bb6eb06aab48d643eeb8c4f65b5fa9529fa5526fdcbf223ea32277ed1b56 +F src/tclsqlite.h 529047feec49e7f463374749147f64d3f17505b0ebd84b3477a364c6f46a9de1 F src/test1.c 8bf8b74145b768f42386787f93f6d6dad7bc400a4ee2d50e4ad5a06a20a97ef1 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b @@ -2219,8 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 67175287440cf363df01bed2464122c3b686a82ea82aeecd3f45fe90c359495c -R 58b5147977291d7ab43e6696ae456e76 +P e2bd3219d9f7bab377ebcfa9a737ca59899c68dad1e3d1d16347bbfdd25652ee +R ca8802466a5e5918921ffde8ccadae70 U drh -Z c3d98da9f482cd0d68ad72a19eedb45b +Z ec07baffb11da349364a8e022541c4d6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e532379d68..36baf2fb8a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2bd3219d9f7bab377ebcfa9a737ca59899c68dad1e3d1d16347bbfdd25652ee +53491688cf622ca317b3ff56156e601c2bdfffc94e4fe471ca82d5ba1d9e875f diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 9ed6669515..e572d1d6c0 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -47,7 +47,7 @@ /* Compatability between Tcl8.6 and Tcl9.0 */ #if TCL_MAJOR_VERSION==9 # define CONST const -#else +#elif !defined(Tcl_Size) typedef int Tcl_Size; #endif /**** End copy of tclsqlite.h ****/ diff --git a/src/tclsqlite.h b/src/tclsqlite.h index b9a948ef14..9997e4de26 100644 --- a/src/tclsqlite.h +++ b/src/tclsqlite.h @@ -35,7 +35,7 @@ /* Compatability between Tcl8.6 and Tcl9.0 */ #if TCL_MAJOR_VERSION==9 # define CONST const -#else +#elif !defined(Tcl_Size) typedef int Tcl_Size; #endif From fa8a7f88ff69abb4738dc41b1f01077fdeb6e261 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 22 Oct 2024 17:57:22 +0000 Subject: [PATCH 093/522] Minor build docs and cleanups. FossilOrigin-Name: 0eb96ea2d153c0f7bd9743b759849c95b3e9f1e6e4a9cdb30c26aa2ca43c1e14 --- Makefile.in | 5 ++++- auto.def | 14 +++++++++++++- autosetup/hwaci-common.tcl | 2 -- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 8f559e4570..46e9b70b2a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -262,10 +262,13 @@ sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) # call-compatible wrapper, e.g. $(TOP)/tool/emcc.sh. If it's empty, # build components requiring Emscripten will not build. # +# Achtung: though _this_ makefile is POSIX-make compatible, the fiddle +# build requires GNU make. +# EMCC_WRAPPER = @EMCC_WRAPPER@ fiddle: sqlite3.c shell.c @if [ x = "x$(EMCC_WRAPPER)" ]; then \ - echo "Emscripten's emcc not found. Cannot build fiddle." 1&>2; \ + echo "Emscripten SDK not found by configure. Cannot build fiddle." 1&>2; \ exit 1; \ fi $(MAKE) -C ext/wasm fiddle emcc_opt=-Os diff --git a/auto.def b/auto.def index 890a767bd7..1a574ebc08 100644 --- a/auto.def +++ b/auto.def @@ -3,6 +3,15 @@ # # This is the main autosetup-compatible configure script for the # SQLite project. +# +# This script should be kept compatible with JimTCL, a copy of which +# is included in this source tree as ./autosetup/jimsh0.c. The number +# of incompatibilities between canonical TCL and JimTCL is very low +# and alternative formulations of incompatible constructs have, so +# far, been easy to find. +# +# JimTCL: https://jim.tcl.tk +# use cc cc-db cc-shared cc-lib hwaci-common set DUMP_DEFINES_FILE ./defines.list @@ -13,6 +22,9 @@ if {[get-define host] ne [get-define build]} { } ######################################################################## +# Regarding flag compatibility with the historical autotool configure +# script: +# # A very long story made short, autosetup's --flag handling has # some behaviors which make it impossible to implement 100% identical # flags compared to the historical autotools build. The differences @@ -845,7 +857,7 @@ if {![get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} { catch {exec chmod u+x $emccsh} } else { define EMCC_WRAPPER "" - catch {file delete -force $emccsh} + file delete -force $emccsh } unset emccsh diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 0729abacf0..30cce478be 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -643,7 +643,6 @@ proc hwaci-check-emsdk {} { define EMSDK_HOME "" define EMSDK_ENV "" define BIN_EMCC "" - # define EMCC_OPT "-Oz" msg-checking "Emscripten SDK? " if {$emsdkHome eq ""} { # Fall back to checking the environment. $EMSDK gets set by @@ -660,7 +659,6 @@ proc hwaci-check-emsdk {} { set rc 1 set emcc "$emsdkHome/upstream/emscripten/emcc" if {[file exists $emcc]} { - # puts "is emcc == $emcc ???" define BIN_EMCC $emcc } } else { diff --git a/manifest b/manifest index 5904c03a3e..02c18db413 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Minor\scleanups\sto\show\sconfigure\sgenerates\stool/emcc.sh. -D 2024-10-22T13:02:48.260 +C Minor\sbuild\sdocs\sand\scleanups. +D 2024-10-22T17:57:22.975 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in c6f6af495b8bdbc106a258efcafa15f007e00d883ce7bbc4567d88ab674b3e1b +F Makefile.in 0997c8fc9c49bf2f4ac0df34575e3b502aa56255d86d2e3c66712296ee64fdf2 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 161d52a60891a6d17beca0ad79838d6dbbff6b1cfb079dc1afc1b6ae25ef031c +F auto.def 3902f1d2f338750039b67e8b873635a6dc4127070d702f46d80010d71d9d81b8 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl e2a8a47eae0540179922cebc71c8f89a9dd57e1fbd87baa608d1ef68c84f79b8 +F autosetup/hwaci-common.tcl 7a033b0b799960363530abfdff156da8c74a8822cf4dfcab4c7c86c5e918c6e5 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 24e0f6ecc67615a2a8c2df08aa47a782cf692fb1a5a59246eab83c0232e78edc -R d8de8f893f2f9d4ef4213358a88a8c4d +P 4484b4623684b09df018f85d95a2b2894a13f38013902831be20a263db605001 +R b34fe42beb3d9914cf9f463eff0df795 U stephan -Z 14f63c9cbf98b7ad4195a656fe3f2aa0 +Z c63a701aa7d14ae8f70fde7cbc469898 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ce7b24f5d9..ca07943c97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4484b4623684b09df018f85d95a2b2894a13f38013902831be20a263db605001 +0eb96ea2d153c0f7bd9743b759849c95b3e9f1e6e4a9cdb30c26aa2ca43c1e14 From c8284c766a7e525898a72858540bc12365fa55f6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 22 Oct 2024 18:00:26 +0000 Subject: [PATCH 094/522] Add the SQLITE_IOCAP_BYPASS device characteristic. Do not allow the SQLITE_DIRECT_OVERFLOW_READ optimization if that capability is missing. FossilOrigin-Name: f50ae00ce9ff572e6bd5e2788602ba356383526ab7289622a32fbf52926c6df0 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/os_unix.c | 1 + src/os_win.c | 2 +- src/pager.c | 20 ++++++++++++++------ src/sqlite.h.in | 7 +++++++ 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index e6b9e05840..e5f6f369f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\stypedef\sTcl_Size\sif\sit\sis\salready\s#defined. -D 2024-10-22T16:19:14.101 +C Add\sthe\sSQLITE_IOCAP_BYPASS\sdevice\scharacteristic.\s\sDo\snot\sallow\sthe\nSQLITE_DIRECT_OVERFLOW_READ\soptimization\sif\sthat\scapability\sis\smissing. +D 2024-10-22T18:00:26.006 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -756,10 +756,10 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 14d0f80e4779f5f76bcc71e7af97e3efe318fa3d0b22335623c59fab7d39302b -F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a +F src/os_unix.c 60dd0dbbcf82a351f62da9719bc652e866050413618c37b111e8a6e4087730ae +F src/os_win.c e682c5d822b0a4a8faa1e74aebb36c6b62a23b8f8a96cdc6cf224c1a5d830812 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3 +F src/pager.c a621100d4b19251d9825fe0a560c12da6ad02b9bf89d6d34b2c77cfbfadf6333 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 @@ -774,7 +774,7 @@ F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe F src/shell.c.in 0662f9bcf0725461778d0254a06150e5d61c08c5a87a7281ccdf45552050c79d -F src/sqlite.h.in add9e064d6b42af8f1a4a3322bddadec76696e520aedebd83e0d3211c15ac999 +F src/sqlite.h.in 26f82d2ad6f1285b4d7f6d7c2067310a177cf39c5ffa139d724c7d8efba5cb17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqliteInt.h baae24292817e13e7fe748851c62efc381dcc4dac241b1182eac3d2f05eae52c @@ -2219,8 +2219,11 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e2bd3219d9f7bab377ebcfa9a737ca59899c68dad1e3d1d16347bbfdd25652ee -R ca8802466a5e5918921ffde8ccadae70 +P 53491688cf622ca317b3ff56156e601c2bdfffc94e4fe471ca82d5ba1d9e875f +R 5dd71efbba0819b90a27d697905cee09 +T *branch * bypass-iocap +T *sym-bypass-iocap * +T -sym-trunk * U drh -Z ec07baffb11da349364a8e022541c4d6 +Z 80285e6bf3f9959bc9d1afa1996b9b4a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 36baf2fb8a..07302b8369 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53491688cf622ca317b3ff56156e601c2bdfffc94e4fe471ca82d5ba1d9e875f +f50ae00ce9ff572e6bd5e2788602ba356383526ab7289622a32fbf52926c6df0 diff --git a/src/os_unix.c b/src/os_unix.c index f71fa8e029..d999658210 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4128,6 +4128,7 @@ static void setDeviceCharacteristics(unixFile *pFd){ if( pFd->ctrlFlags & UNIXFILE_PSOW ){ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; } + pFd->deviceCharacteristics |= SQLITE_IOCAP_BYPASS; pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; } diff --git a/src/os_win.c b/src/os_win.c index 442c108e9d..47fff58cc9 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3660,7 +3660,7 @@ static int winSectorSize(sqlite3_file *id){ */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_BYPASS | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } diff --git a/src/pager.c b/src/pager.c index 1ac858a070..1b624a3000 100644 --- a/src/pager.c +++ b/src/pager.c @@ -808,18 +808,26 @@ static const unsigned char aJournalMagic[] = { ** Return true if page pgno can be read directly from the database file ** by the b-tree layer. This is the case if: ** -** * the database file is open, -** * there are no dirty pages in the cache, and -** * the desired page is not currently in the wal file. +** (1) the database file is open +** (2) the VFS for the database has BYPASS capability +** (3) there are no dirty pages in the cache, and +** (4) the desired page is not currently in the wal file. */ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ - if( pPager->fd->pMethods==0 ) return 0; - if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; + assert( pPager!=0 ); + assert( pPager->fd!=0 ); + if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ + assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); + if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) + & SQLITE_IOCAP_BYPASS)==0 ){ + return 0; /* Case (2) */ + } + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ u32 iRead = 0; (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); - return iRead==0; + return iRead==0; /* Condition (4) */ } #endif return 1; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7097e6bb55..2db643b28a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -652,6 +652,11 @@ int sqlite3_exec( ** filesystem supports doing multiple write operations atomically when those ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. +** +** The SQLITE_IOCAP_BYPASS property means that it is ok for the +** B-tree layer to bypass the pager and VFS and read content directly +** from the filesystem (the SQLITE_DIRECT_OVERFLOW_READ optimization) +** when that is beneficial for performance. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -668,6 +673,7 @@ int sqlite3_exec( #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 +#define SQLITE_IOCAP_BYPASS 0x00008000 /* ** CAPI3REF: File Locking Levels @@ -814,6 +820,7 @@ struct sqlite3_file { **
  • [SQLITE_IOCAP_POWERSAFE_OVERWRITE] **
  • [SQLITE_IOCAP_IMMUTABLE] **
  • [SQLITE_IOCAP_BATCH_ATOMIC] +**
  • [SQLITE_IOCAP_BYPASS] ** ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of From 96501c89d504d56fbef8c6d5b8f9bcab85a735d0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 22 Oct 2024 18:26:03 +0000 Subject: [PATCH 095/522] Rename to SQLITE_IOCAP_SUBPAGE_READ. FossilOrigin-Name: dd446ef1816f4e95ce29de0b3841dd0a6c983646fd2dd271c2db8f3263478164 --- manifest | 21 +++++++++------------ manifest.uuid | 2 +- src/os_unix.c | 2 +- src/os_win.c | 2 +- src/pager.c | 4 ++-- src/sqlite.h.in | 14 ++++++++------ 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index e5f6f369f7..3a2a48bdaa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_IOCAP_BYPASS\sdevice\scharacteristic.\s\sDo\snot\sallow\sthe\nSQLITE_DIRECT_OVERFLOW_READ\soptimization\sif\sthat\scapability\sis\smissing. -D 2024-10-22T18:00:26.006 +C Rename\sto\sSQLITE_IOCAP_SUBPAGE_READ. +D 2024-10-22T18:26:03.401 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -756,10 +756,10 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 60dd0dbbcf82a351f62da9719bc652e866050413618c37b111e8a6e4087730ae -F src/os_win.c e682c5d822b0a4a8faa1e74aebb36c6b62a23b8f8a96cdc6cf224c1a5d830812 +F src/os_unix.c 0ad4e0885294b3a0e135a18533590ec9ad91ffe82f6a08e55b40babd51772928 +F src/os_win.c 69fa1aaff68270423c85cff4327ba17ef99a1eb017e1a2bfb97416d9b8398b05 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c a621100d4b19251d9825fe0a560c12da6ad02b9bf89d6d34b2c77cfbfadf6333 +F src/pager.c d57287cd0864c88740d20618e5e595b144b85bfdaefccafd353d596f254a7b35 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 @@ -774,7 +774,7 @@ F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe F src/shell.c.in 0662f9bcf0725461778d0254a06150e5d61c08c5a87a7281ccdf45552050c79d -F src/sqlite.h.in 26f82d2ad6f1285b4d7f6d7c2067310a177cf39c5ffa139d724c7d8efba5cb17 +F src/sqlite.h.in 29fc900a58f394c7488d093fd7a8dcb14d3fa6399d5178cb20adcf88dbedfe39 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqliteInt.h baae24292817e13e7fe748851c62efc381dcc4dac241b1182eac3d2f05eae52c @@ -2219,11 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 53491688cf622ca317b3ff56156e601c2bdfffc94e4fe471ca82d5ba1d9e875f -R 5dd71efbba0819b90a27d697905cee09 -T *branch * bypass-iocap -T *sym-bypass-iocap * -T -sym-trunk * +P f50ae00ce9ff572e6bd5e2788602ba356383526ab7289622a32fbf52926c6df0 +R ca0e4d7e96f02509781264c3f3c418db U drh -Z 80285e6bf3f9959bc9d1afa1996b9b4a +Z d00e64e05989e514a073b51697b3ec37 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 07302b8369..bc89b0f2b4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f50ae00ce9ff572e6bd5e2788602ba356383526ab7289622a32fbf52926c6df0 +dd446ef1816f4e95ce29de0b3841dd0a6c983646fd2dd271c2db8f3263478164 diff --git a/src/os_unix.c b/src/os_unix.c index d999658210..c13c5cece0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4128,7 +4128,7 @@ static void setDeviceCharacteristics(unixFile *pFd){ if( pFd->ctrlFlags & UNIXFILE_PSOW ){ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; } - pFd->deviceCharacteristics |= SQLITE_IOCAP_BYPASS; + pFd->deviceCharacteristics |= SQLITE_IOCAP_SUBPAGE_READ; pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; } diff --git a/src/os_win.c b/src/os_win.c index 47fff58cc9..97743412e9 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3660,7 +3660,7 @@ static int winSectorSize(sqlite3_file *id){ */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_BYPASS | + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_SUBPAGE_READ | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } diff --git a/src/pager.c b/src/pager.c index 1b624a3000..baaf4afbfe 100644 --- a/src/pager.c +++ b/src/pager.c @@ -809,7 +809,7 @@ static const unsigned char aJournalMagic[] = { ** by the b-tree layer. This is the case if: ** ** (1) the database file is open -** (2) the VFS for the database has BYPASS capability +** (2) the VFS for the database is able to do unaligned sub-page reads ** (3) there are no dirty pages in the cache, and ** (4) the desired page is not currently in the wal file. */ @@ -819,7 +819,7 @@ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) - & SQLITE_IOCAP_BYPASS)==0 ){ + & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ return 0; /* Case (2) */ } if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 2db643b28a..f91088a772 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -653,10 +653,12 @@ int sqlite3_exec( ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. ** -** The SQLITE_IOCAP_BYPASS property means that it is ok for the -** B-tree layer to bypass the pager and VFS and read content directly -** from the filesystem (the SQLITE_DIRECT_OVERFLOW_READ optimization) -** when that is beneficial for performance. +** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read +** from the database file in amounts that are not a multiple of the +** page size and that do not begin at a page boundary. Without this +** property, SQLite is careful to only do full-page reads and write +** on aligned pages, with the one exception that it will do a sub-page +** read of the first page to access the database header. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -673,7 +675,7 @@ int sqlite3_exec( #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 -#define SQLITE_IOCAP_BYPASS 0x00008000 +#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 /* ** CAPI3REF: File Locking Levels @@ -820,7 +822,7 @@ struct sqlite3_file { **
  • [SQLITE_IOCAP_POWERSAFE_OVERWRITE] **
  • [SQLITE_IOCAP_IMMUTABLE] **
  • [SQLITE_IOCAP_BATCH_ATOMIC] -**
  • [SQLITE_IOCAP_BYPASS] +**
  • [SQLITE_IOCAP_SUBPAGE_READ] ** ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of From f896e2bd5b4d095ec22955eb359aad17aa125928 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 22 Oct 2024 20:09:18 +0000 Subject: [PATCH 096/522] Add the "halt" command to testrunner.tcl FossilOrigin-Name: 2cc25d5dbbc729f3b6deb8c6a45b975c535b4d20ad240e4ec0c85b3733a170ed --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/testrunner.tcl | 18 ++++++++++++++++-- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index dd3c34e811..cdd5eab5b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_IOCAP_SUBPAGE_READ\sbit\sto\sthe\spossible\sreturns\svalues\nfrom\sxDeviceCharacteristics\smethod\sof\sthe\ssystem-IO\sabstract\sclass.\s\sThe\ndirect-overflow-read\soptimization\sis\sdisabled\sfor\sany\sVFS\sthat\sdoes\snot\nset\sthis\sbit.\s\sThe\sbit\sis\sset\sfor\sstandard\sVFSes. -D 2024-10-22T19:33:20.597 +C Add\sthe\s"halt"\scommand\sto\stestrunner.tcl +D 2024-10-22T20:09:18.729 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1721,7 +1721,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 -F test/testrunner.tcl 1472b8c57c124c7eed934a2cbc955b0c0e0a948a4608546598195267bbd4b2fd x +F test/testrunner.tcl bc1a8d21a1aa3a5cf7c4883cbee4b6748790fe960fad06ca5db74ec914bd6525 x F test/testrunner_data.tcl c7b3b911e44f7e8c01cc6bc7571e16115cdc2e4db46630bd2acd7a931a46380e F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2219,9 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 53491688cf622ca317b3ff56156e601c2bdfffc94e4fe471ca82d5ba1d9e875f dd446ef1816f4e95ce29de0b3841dd0a6c983646fd2dd271c2db8f3263478164 -R ca0e4d7e96f02509781264c3f3c418db -T +closed dd446ef1816f4e95ce29de0b3841dd0a6c983646fd2dd271c2db8f3263478164 +P 6e7d498cda1d8fa76f3efac0ee0540dd8241db75e85b863097cab2ed530aabb0 +R 3f2f8232d3d7a010fd492d1d7a07579d U drh -Z c62b27a13345423a196a9df8f7a1e878 +Z 0f04567a08f24373cd91fb87cc03186b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8982839893..ea81351092 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e7d498cda1d8fa76f3efac0ee0540dd8241db75e85b863097cab2ed530aabb0 +2cc25d5dbbc729f3b6deb8c6a45b975c535b4d20ad240e4ec0c85b3733a170ed diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 55d1add183..964465d9b2 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -91,6 +91,7 @@ Usage: $a0 njob ?NJOB? $a0 script ?-msvc? CONFIG $a0 status ?-d SECS? ?--cls? + $a0 halt where SWITCHES are: --buildonly Build test exes but do not run tests @@ -326,7 +327,7 @@ set TRG(schema) { endtime INTEGER, -- End time span INTEGER, -- Total run-time in milliseconds estwork INTEGER, -- Estimated amount of work - state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ), + state TEXT CHECK( state IN ('','ready','running','done','failed','omit','halt') ), ntest INT, -- Number of test cases run nerr INT, -- Number of errors reported svers TEXT, -- Reported SQLite version @@ -424,6 +425,19 @@ if {([llength $argv]==2 || [llength $argv]==1) } #-------------------------------------------------------------------------- +#-------------------------------------------------------------------------- +# Check if this is the "halt" command: +# +if {[llength $argv]==1 + && [string compare -nocase halt [lindex $argv 0]]==0 +} { + sqlite3 mydb $TRG(dbname) + mydb eval {UPDATE jobs SET state='halt' WHERE state IN ('ready','')} + mydb close + exit +} +#-------------------------------------------------------------------------- + #-------------------------------------------------------------------------- # Check if this is the "help" command: # @@ -1325,7 +1339,7 @@ proc mark_job_as_finished {jobid output state endtm} { SET output=$output, state=$state, endtime=$endtm, span=$endtm-starttime, ntest=$ntest, nerr=$nerr, svers=$svers, pltfm=$pltfm WHERE jobid=$jobid; - UPDATE jobs SET state=$childstate WHERE depid=$jobid; + UPDATE jobs SET state=$childstate WHERE depid=$jobid AND state!='halt'; UPDATE config SET value=value+$nerr WHERE name='nfail'; UPDATE config SET value=value+$ntest WHERE name='ntest'; } From 198b72cfe8c07214fe7a34a7802fe8895307f49f Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 01:18:16 +0000 Subject: [PATCH 097/522] Use pkg-config for readline detection, if available. Unrelated minor tcl cleanups. FossilOrigin-Name: 3a41ac08a443f96c3f34432f5034d2d12f03913f2a1db19d9f133b365b39ad20 --- auto.def | 36 +++++++++++++++++----------------- autosetup/hwaci-common.tcl | 40 +++++++++++++++++++++++++++++++------- manifest | 14 ++++++------- manifest.uuid | 2 +- 4 files changed, 59 insertions(+), 33 deletions(-) diff --git a/auto.def b/auto.def index 1a574ebc08..4d2f29264a 100644 --- a/auto.def +++ b/auto.def @@ -12,7 +12,9 @@ # # JimTCL: https://jim.tcl.tk # -use cc cc-db cc-shared cc-lib hwaci-common +use cc cc-db cc-shared cc-lib hwaci-common pkg-config +pkg-config-init 0; # ensure that it does not fail if pkg-config is unavailable + set DUMP_DEFINES_FILE ./defines.list # Are we cross-compiling? @@ -161,20 +163,20 @@ options [subst { # set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] -puts "srcdir = $srcdir" -puts "top_srcdir = $top_srcdir" +msg-result "srcdir = $srcdir" +msg-result "top_srcdir = $top_srcdir" set RELEASE [readfile $::autosetup(srcdir)/VERSION] regsub {([0-9]*\.*[0-9]*).*} $RELEASE {\1} VERSION define VERSION $VERSION define RELEASE $RELEASE -puts "RELEASE = $RELEASE" -puts "VERSION = $VERSION" +msg-result "RELEASE = $RELEASE" +msg-result "VERSION = $VERSION" define-append SQLITE_AUTOREMAKE cd $::autosetup(srcdir) && $top_srcdir/configure {*}$::autosetup(argv) set outOfTreeBuild 0 if {![file exists sqlite3.pc.in]} { - puts "This appears to be an out-of-tree build." + msg-result "This appears to be an out-of-tree build." set outOfTreeBuild 1 } @@ -313,7 +315,7 @@ if {1} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" if {$wasiSdkDir ne ""} { - puts "Checking WASI SDK directory \[$wasiSdkDir]... " + msg-result "Checking WASI SDK directory \[$wasiSdkDir]... " #puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" hwaci-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading" @@ -466,16 +468,16 @@ proc hwaci-check-tcl {} { hwaci-fatal "TCL shell $with_tclsh is not executable" } else { define TCLSH_CMD $with_tclsh - puts "Using tclsh: $with_tclsh" + msg-result "Using tclsh: $with_tclsh" } if {$use_tcl} { if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { set with_tcl $result } if {"" ne $with_tcl && [file isdir $with_tcl]} { - puts "$with_tclsh recommends the tclConfig.sh from $with_tcl" + msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl" } else { - puts "$with_tclsh is unable to recommand a tclConfig.sh" + hwaci-warn "$with_tclsh is unable to recommand a tclConfig.sh" set use_tcl 0 } } @@ -522,11 +524,11 @@ proc hwaci-check-tcl {} { } } } - puts "Using tclConfig.sh: $cfg" + msg-result "Using tclConfig.sh: $cfg" } elseif {!$optTcl} { - puts "Unable to run tests because of --disable-tcl" + hwaci-warn "Unable to run tests because of --disable-tcl" } else { - puts "Unable to run tests because no tclConfig.sh file could be located" + hwaci-warn "Unable to run tests because no tclConfig.sh file could be located" } define HAVE_TCL $use_tcl @@ -594,7 +596,7 @@ proc hwaci-check-tcl {} { if {"" eq $with_tclsh} { hwaci-warn "Cannot find a usable tclsh." } else { - puts "Using tclsh: $with_tclsh" + msg-result "Using tclsh: $with_tclsh" } }; # hwaci-check-tcl @@ -609,7 +611,7 @@ hwaci-check-tcl # accepts one arg unless JIM_COMPAT is defined. define CFLAGS_JIMSH {-DJIM_COMPAT} set useOwnJimsh 0 -puts "Which TCL to use for code generation... " +msg-result "Which TCL to use for code generation... " set cgtcl jimtcl if {[cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE_REALPATH @@ -1004,6 +1006,4 @@ hwaci-if-opt-truthy dump-defines { } } -puts { -Done! Now run "make". -} +msg-result "Done! Now run make." diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 30cce478be..b5894161b6 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -42,10 +42,10 @@ ######################################################################## proc hwaci-warn {msg} { - puts "WARNING: $msg" + puts stderr "WARNING: $msg" } proc hwaci-notice {msg} { - puts "NOTICE: $msg" + puts stderr "NOTICE: $msg" } proc hwaci-fatal {msg} { user-error "ERROR: $msg" @@ -320,11 +320,11 @@ proc hwaci-check-module-loader {} { if {[cc-check-includes ltdl.h] && [cc-check-function-in-lib lt_dlopen ltdl]} { set HAVE_LIBLTDL 1 set LDFLAGS_MODULE_LOADER "-lltdl -rdynamic" - puts " - Got libltdl." + msg-result " - Got libltdl." set rc 1 } elseif {[cc-with {-includes dlfcn.h} { cctest -link 1 -declare "extern char* dlerror(void);" -code "dlerror();"}]} { - puts " - This system can use dlopen() without -ldl." + msg-result " - This system can use dlopen() without -ldl." set HAVE_LIBDL 1 set LDFLAGS_MODULE_LOADER "" set rc 1 @@ -332,10 +332,10 @@ proc hwaci-check-module-loader {} { set HAVE_LIBDL 1 set rc 1 if {[cc-check-function-in-lib dlopen dl]} { - puts " - dlopen() needs libdl." + msg-result " - dlopen() needs libdl." set LDFLAGS_MODULE_LOADER "-ldl -rdynamic" } else { - puts " - dlopen() not found in libdl. Assuming dlopen() is built-in." + msg-result " - dlopen() not found in libdl. Assuming dlopen() is built-in." set LDFLAGS_MODULE_LOADER "-rdynamic" } } @@ -702,7 +702,10 @@ proc hwaci-check-rpath {} { } ######################################################################## -# Under construction - check for libreadline functionality. +# Under construction - check for libreadline functionality. Linking +# in readline varies wildly by platform and this check does not cover +# all known options. +# # Defines the following vars: # # - HAVE_READLINE: 0 or 1 @@ -720,6 +723,29 @@ proc hwaci-check-readline {} { msg-result "libreadline disabled via --disable-readline." return 0 } + + if {[pkg-config-init 0] && [pkg-config readline]} { + define HAVE_READLINE 1 + define LDFLAGS_READLINE [get-define PKG_READLINE_LDFLAGS] + define-append LDFLAGS_READLINE [get-define PKG_READLINE_LIBS] + define CFLAGS_READLINE [get-define PKG_READLINE_CFLAGS] + return 1 + } + + # On OpenBSD on a Raspberry pi 4: + # + # $ pkg-config readline; echo $? + # 0 + # $ pkg-config --cflags readline + # Package termcap was not found in the pkg-config search path + # $ echo $? + # 1 + # $ pkg-config --print-requires readline; echo $? + # 1 + # + # i.e. there's apparently no way to find out that readline + # requires termcap beyond parsing the error message. + set h "readline/readline.h" if {[cc-check-includes $h]} { define READLINE_H $h diff --git a/manifest b/manifest index 02c18db413..87b77c75cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sbuild\sdocs\sand\scleanups. -D 2024-10-22T17:57:22.975 +C Use\spkg-config\sfor\sreadline\sdetection,\sif\savailable.\sUnrelated\sminor\stcl\scleanups. +D 2024-10-23T01:18:16.765 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 3902f1d2f338750039b67e8b873635a6dc4127070d702f46d80010d71d9d81b8 +F auto.def 69277d3329dbd407d58d5f0fb84376df162e8d69eac81628c650eed296240729 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 7a033b0b799960363530abfdff156da8c74a8822cf4dfcab4c7c86c5e918c6e5 +F autosetup/hwaci-common.tcl e17ec263ffe52207be99604d0ee9c36ab866605b1881518ab814a47cacedff4d F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4484b4623684b09df018f85d95a2b2894a13f38013902831be20a263db605001 -R b34fe42beb3d9914cf9f463eff0df795 +P 0eb96ea2d153c0f7bd9743b759849c95b3e9f1e6e4a9cdb30c26aa2ca43c1e14 +R e0fcc1f673d98e8991070c55d66d6b02 U stephan -Z c63a701aa7d14ae8f70fde7cbc469898 +Z 0b0a67f959ecbfe154dceb336b7b1db7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ca07943c97..e16deab3c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0eb96ea2d153c0f7bd9743b759849c95b3e9f1e6e4a9cdb30c26aa2ca43c1e14 +3a41ac08a443f96c3f34432f5034d2d12f03913f2a1db19d9f133b365b39ad20 From 591123eea934c84fe7e4bd7d9145c9bb99a34c90 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 01:33:15 +0000 Subject: [PATCH 098/522] Fix /dev/null and stderr redirection ordering in autosetup/autosetup-find-tclsh so that the extraneous strlcpy()/snprintf()/rand() warning output from ld on OpenBSD does not break detection of jimsh0. FossilOrigin-Name: cd447e50d1b31e7539e4a8b5dc2a88c5a6a3814a28718b5829167b830dfd0edd --- autosetup/autosetup-find-tclsh | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/autosetup/autosetup-find-tclsh b/autosetup/autosetup-find-tclsh index f0fd98c8ed..2b2006241c 100755 --- a/autosetup/autosetup-find-tclsh +++ b/autosetup/autosetup-find-tclsh @@ -9,7 +9,7 @@ for tclsh in ./jimsh0 $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; d done echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" for cc in ${CC_FOR_BUILD:-cc} gcc; do - { $cc -o jimsh0 "$d/jimsh0.c"; } 2>&1 >/dev/null || continue + { $cc -o jimsh0 "$d/jimsh0.c"; } >/dev/null 2>&1 || continue ./jimsh0 "$d/${1-autosetup-test-tclsh}" && exit 0 done echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." diff --git a/manifest b/manifest index 87b77c75cf..fd1bde1e55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\spkg-config\sfor\sreadline\sdetection,\sif\savailable.\sUnrelated\sminor\stcl\scleanups. -D 2024-10-23T01:18:16.765 +C Fix\s/dev/null\sand\sstderr\sredirection\sordering\sin\sautosetup/autosetup-find-tclsh\sso\sthat\sthe\sextraneous\sstrlcpy()/snprintf()/rand()\swarning\soutput\sfrom\sld\son\sOpenBSD\sdoes\snot\sbreak\sdetection\sof\sjimsh0. +D 2024-10-23T01:33:15.729 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -41,7 +41,7 @@ F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a7 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x -F autosetup/autosetup-find-tclsh c5053419348cdd1aba824c3701bd97392d987b948c1bd748b32f11bbca2c0d8a x +F autosetup/autosetup-find-tclsh 25905f6c302959db80c2951aa267b4411c5645b598ce761cfc24a166141e2c4c x F autosetup/autosetup-test-tclsh 749d20defee533a3842139df47d700fc7a334a5da7bdbd444ae5331744b06c5f F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034b10a7b F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0eb96ea2d153c0f7bd9743b759849c95b3e9f1e6e4a9cdb30c26aa2ca43c1e14 -R e0fcc1f673d98e8991070c55d66d6b02 +P 3a41ac08a443f96c3f34432f5034d2d12f03913f2a1db19d9f133b365b39ad20 +R 800ba67376f69c50f3d861fe8a325e3a U stephan -Z 0b0a67f959ecbfe154dceb336b7b1db7 +Z e6425f1dee29bf6933ceda8b25c5f5cd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e16deab3c3..82b076b43e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a41ac08a443f96c3f34432f5034d2d12f03913f2a1db19d9f133b365b39ad20 +cd447e50d1b31e7539e4a8b5dc2a88c5a6a3814a28718b5829167b830dfd0edd From 54e1dff24b6ae42f3665efd8c0d7b5aa65c61a0d Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 01:59:34 +0000 Subject: [PATCH 099/522] Get auto.def handling the case that no tclsh is installed in a default location. If not, use jimsh if we can find realpath(), else bail out. FossilOrigin-Name: 359741bc7624006014d73c4cf5cdd29fa38c33a446ed04b46032e5d3ca18d13c --- auto.def | 99 +++++++++++++++++++++++++++------------------------ manifest | 12 +++---- manifest.uuid | 2 +- 3 files changed, 59 insertions(+), 54 deletions(-) diff --git a/auto.def b/auto.def index 4d2f29264a..6fc6ef27ec 100644 --- a/auto.def +++ b/auto.def @@ -123,7 +123,7 @@ options [subst { with-debug:=1 => {Enable debug build flags} with-tclsh:PATH => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} - tcl=1 => {Disable building accessory programs that require TCL-dev} + tcl=1 => {Disable components which require TCL-dev} test-status => {Enable status of tests} threadsafe=1 => {Disable mutexing} with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always.} @@ -310,6 +310,7 @@ define ENABLE_SHARED 1 # # It's unclear whether we can actually get away with making these # changes to the autosetup environment. +define HAVE_TCL 0 define HAVE_WASI_SDK 0 if {1} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] @@ -444,7 +445,6 @@ hwaci-if-opt-truthy with-debug { # be empty - this tree requires TCL to generated numerous # components. # -define HAVE_TCL 0 define TCLSH_CMD {exit 1} proc hwaci-check-tcl {} { global top_srcdir @@ -485,53 +485,57 @@ proc hwaci-check-tcl {} { set cfg "" set tclSubdirs {tcl9.0 tcl8.6 lib} - if {$use_tcl} { - if {"" ne $with_tcl} { - if {[file readable "${with_tcl}/tclConfig.sh"]} { - set cfg "${with_tcl}/tclConfig.sh" - } else { - foreach i $tclSubdirs { - if {[file readable "${with_tcl}/$i/tclConfig.sh"]} { - set cfg "${with_tcl}/$i/tclConfig.sh" - break + while {1} { + if {$use_tcl} { + if {"" ne $with_tcl} { + if {[file readable "${with_tcl}/tclConfig.sh"]} { + set cfg "${with_tcl}/tclConfig.sh" + } else { + foreach i $tclSubdirs { + if {[file readable "${with_tcl}/$i/tclConfig.sh"]} { + set cfg "${with_tcl}/$i/tclConfig.sh" + break + } } } - } - if {"" eq $cfg} { - hwaci-fatal "No tclConfig.sh found under ${with_tcl}" - } - } else { - # If we have not yet found a tclConfig.sh file, look in $libdir which is - # set automatically by autosetup or by the --prefix command-line option. - # See https://sqlite.org/forum/forumpost/e04e693439a22457 - set libdir [get-define libdir] - if {[file readable "${libdir}/tclConfig.sh"]} { - set cfg "${libdir}/tclConfig.sh" + if {"" eq $cfg} { + hwaci-fatal "No tclConfig.sh found under ${with_tcl}" + } } else { - foreach i $tclSubdirs { - if {[file readable "${libdir}/$i/tclConfig.sh"]} { - set cfg "${libdir}/$i/tclConfig.sh" - break + # If we have not yet found a tclConfig.sh file, look in $libdir which is + # set automatically by autosetup or by the --prefix command-line option. + # See https://sqlite.org/forum/forumpost/e04e693439a22457 + set libdir [get-define libdir] + if {[file readable "${libdir}/tclConfig.sh"]} { + set cfg "${libdir}/tclConfig.sh" + } else { + foreach i $tclSubdirs { + if {[file readable "${libdir}/$i/tclConfig.sh"]} { + set cfg "${libdir}/$i/tclConfig.sh" + break + } } } - } - if {![file readable $cfg]} { - hwaci-fatal { - Cannot find a usable tclConfig.sh file. - Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. - SQLite does not use TCL internally, but TCL is required to build SQLite - from canonical sources and TCL is required for testing. + if {![file readable $cfg]} { + hwaci-warn { + Cannot find a usable tclConfig.sh file. + Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. + SQLite does not use TCL internally, but TCL is required to build SQLite + from canonical sources and TCL is required for testing. + } + break } } + msg-result "Using tclConfig.sh: $cfg" + } elseif {!$optTcl} { + hwaci-warn "Unable to run tests because of --disable-tcl" + } else { + hwaci-warn "Unable to run tests because no tclConfig.sh file could be located" } - msg-result "Using tclConfig.sh: $cfg" - } elseif {!$optTcl} { - hwaci-warn "Unable to run tests because of --disable-tcl" - } else { - hwaci-warn "Unable to run tests because no tclConfig.sh file could be located" + break } - define HAVE_TCL $use_tcl + define HAVE_TCL 0 define TCL_CONFIG_SH $cfg # The historical configure.ac sources tclConfig.sh so that it can # use the several TCL_... env vars. We obviously cannot do that from @@ -550,7 +554,7 @@ proc hwaci-check-tcl {} { if {![file-isexec $with_tclsh]} { set with_tclsh2 [get-define TCL_EXEC_PREFIX]/bin/tclsh if {![file-isexec $with_tclsh2]} { - hwaci-warn "Cannot find a usable tclsh as $with_tclsh or $with_tclsh2" + hwaci-warn "Cannot find a usable tclsh (tried: $with_tclsh $with_tclsh2)" } else { set with_tclsh $with_tclsh2 } @@ -593,10 +597,11 @@ proc hwaci-check-tcl {} { define TCLLIB_RPATH "" } - if {"" eq $with_tclsh} { - hwaci-warn "Cannot find a usable tclsh." - } else { + if {[file exists $with_tclsh]} { msg-result "Using tclsh: $with_tclsh" + define HAVE_TCL 1 + } else { + hwaci-warn "Cannot find a usable tclsh, so cannot run tests." } }; # hwaci-check-tcl @@ -622,7 +627,7 @@ if {[cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE__FULLPATH define BTCLSH "\$(JIMSH)" set useOwnJimsh 1 -} elseif {"" ne [get-define TCLSH_CMD]} { +} elseif {[file exists [get-define TCLSH_CMD]]} { set cgtcl [get-define TCLSH_CMD] define BTCLSH "\$(TCLSH_CMD)" } else { @@ -640,11 +645,11 @@ if {[cc-check-functions realpath]} { unset tv } unset tpre - if {"" eq [get-define TCLSH_CMD]} { - hwaci-fatal "Cannot find a tclsh to use for code generation." - } } set cgtcl [get-define TCLSH_CMD] + if {![file exists $cgtcl]} { + hwaci-fatal "Cannot find a tclsh to use for code generation." + } define BTCLSH "\$(TCLSH_CMD)" } msg-result "TCL for code generation: $cgtcl" diff --git a/manifest b/manifest index fd1bde1e55..cd91dc8097 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\s/dev/null\sand\sstderr\sredirection\sordering\sin\sautosetup/autosetup-find-tclsh\sso\sthat\sthe\sextraneous\sstrlcpy()/snprintf()/rand()\swarning\soutput\sfrom\sld\son\sOpenBSD\sdoes\snot\sbreak\sdetection\sof\sjimsh0. -D 2024-10-23T01:33:15.729 +C Get\sauto.def\shandling\sthe\scase\sthat\sno\stclsh\sis\sinstalled\sin\sa\sdefault\slocation.\s\sIf\snot,\suse\sjimsh\sif\swe\scan\sfind\srealpath(),\selse\sbail\sout. +D 2024-10-23T01:59:34.375 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 69277d3329dbd407d58d5f0fb84376df162e8d69eac81628c650eed296240729 +F auto.def 1b677ab8ca5aaee8f6622ce0f9f1e3c07753c6ad15d258de22ea033b4abc5feb F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3a41ac08a443f96c3f34432f5034d2d12f03913f2a1db19d9f133b365b39ad20 -R 800ba67376f69c50f3d861fe8a325e3a +P cd447e50d1b31e7539e4a8b5dc2a88c5a6a3814a28718b5829167b830dfd0edd +R eb16726048dc406bfeeacf1897cc1534 U stephan -Z e6425f1dee29bf6933ceda8b25c5f5cd +Z f9b2797ed9043665e78aef0c31e48a93 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 82b076b43e..6fa56800fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd447e50d1b31e7539e4a8b5dc2a88c5a6a3814a28718b5829167b830dfd0edd +359741bc7624006014d73c4cf5cdd29fa38c33a446ed04b46032e5d3ca18d13c From fdcd599992ea10693f20669b0c5b9f2028d90b78 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 02:11:52 +0000 Subject: [PATCH 100/522] Minor cleanups in the --with-wasi-sdk bits. FossilOrigin-Name: d952c17981073cb0158b392edd9b0818dfba2456ab9997d360af56774c9f4216 --- auto.def | 83 +++++++++++++++++++------------------- autosetup/hwaci-common.tcl | 4 +- manifest | 14 +++---- manifest.uuid | 2 +- 4 files changed, 51 insertions(+), 52 deletions(-) diff --git a/auto.def b/auto.def index 6fc6ef27ec..32de7fd89e 100644 --- a/auto.def +++ b/auto.def @@ -301,54 +301,53 @@ if {"" eq [hwaci-bin-define install]} { define BUILD_CC [get-define CC_FOR_BUILD] define BUILD_CFLAGS [get-env CFLAGS {-g}] define ENABLE_SHARED 1 +define HAVE_TCL 0 ######################################################################## # Handle --with-wasi-sdk=DIR # -# This must be early because it may change the toolchain and several -# config options. -# -# It's unclear whether we can actually get away with making these -# changes to the autosetup environment. -define HAVE_TCL 0 -define HAVE_WASI_SDK 0 -if {1} { +# This must be early because it may change the toolchain and disable +# several config options. +proc hwaci-check-wasi-sdk {} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] + define HAVE_WASI_SDK 0 #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" - if {$wasiSdkDir ne ""} { - msg-result "Checking WASI SDK directory \[$wasiSdkDir]... " - #puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" - hwaci-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] - msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading" - define HAVE_WASI_SDK 1 - define WASI_SDK_DIR $wasiSdkDir - hwaci-opt-set load-extension 0; # ==> --disable-load-extension - hwaci-opt-set threadsafe 0; # ==> --threadsafe=0 - hwaci-opt-set tcl 0; # ==> --disable-tcl - define HAVE_TCL 0 - set cross_compiling 1 - # libtool is apparently hard-coded to use gcc for linking DLLs, so - # we disable the DLL build. - define ENABLE_SHARED 0 - - # Changing --host and --target have no effect here except to possibly - # cause confusion. autoconf has finished processing them by this - # point. - # - # host_alias=wasm32-wasi - # target=wasm32-wasi - # - # Merely changing CC and LD to the wasi-sdk's is enough to get - # sqlite3.o building in WASM format. - # XXX CC="${wasiSdkDir}/bin/clang" - # XXX LD="${wasiSdkDir}/bin/wasm-ld" - # XXX RANLIB="${wasiSdkDir}/bin/llvm-ranlib" - define CC "${wasiSdkDir}/bin/clang" - define LD "${wasiSdkDir}/bin/wasm-ld" - #define STRIP "${wasiSdkDir}/bin/strip" + if {$wasiSdkDir eq ""} { + return 0 + } elseif {$::cross_compiling} { + hwaci-fatal "Cannot combine --with-wasi-sdk with cross-compilation" } - unset wasiSdkDir -}; # --wasi-sdk-dir + msg-result "Checking WASI SDK directory \[$wasiSdkDir]... " + #puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" + hwaci-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] + msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading" + define HAVE_WASI_SDK 1 + define WASI_SDK_DIR $wasiSdkDir + hwaci-opt-set load-extension 0; # ==> --disable-load-extension + hwaci-opt-set threadsafe 0; # ==> --threadsafe=0 + hwaci-opt-set tcl 0; # ==> --disable-tcl + define HAVE_TCL 0 + set cross_compiling 1 + define ENABLE_SHARED 0 + + # Changing --host and --target have no effect here except to possibly + # cause confusion. autoconf has finished processing them by this + # point. + # + # host_alias=wasm32-wasi + # target=wasm32-wasi + # + # Merely changing CC and LD to the wasi-sdk's is enough to get + # sqlite3.o building in WASM format. + # XXX CC="${wasiSdkDir}/bin/clang" + # XXX LD="${wasiSdkDir}/bin/wasm-ld" + # XXX RANLIB="${wasiSdkDir}/bin/llvm-ranlib" + define CC "${wasiSdkDir}/bin/clang" + define LD "${wasiSdkDir}/bin/wasm-ld" + #define STRIP "${wasiSdkDir}/bin/strip" + return 1 +}; # hwaci-check-wasi-sdk +hwaci-check-wasi-sdk # # Enable large file support (if special flags are necessary) @@ -447,6 +446,7 @@ hwaci-if-opt-truthy with-debug { # define TCLSH_CMD {exit 1} proc hwaci-check-tcl {} { + # TODO: document the steps this is taking. global top_srcdir puts "Checking for a suitable tcl... " set optTcl [hwaci-opt-truthy tcl] @@ -535,7 +535,6 @@ proc hwaci-check-tcl {} { break } - define HAVE_TCL 0 define TCL_CONFIG_SH $cfg # The historical configure.ac sources tclConfig.sh so that it can # use the several TCL_... env vars. We obviously cannot do that from diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index b5894161b6..d2974591b0 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -610,11 +610,11 @@ proc hwaci-affirm-files-exist {args} { set args [lrange $args 1 end] } foreach f $args { - if {$verbose} { msg-checking "looking for file... " } + if {$verbose} { msg-checking "Looking for $f ... " } if {![file exists $f]} { user-error "not found: $f" } - if {$verbose} { msg-result "$f" } + if {$verbose} { msg-result "" } set rc $f } return rc diff --git a/manifest b/manifest index cd91dc8097..94b4aa4bfb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sauto.def\shandling\sthe\scase\sthat\sno\stclsh\sis\sinstalled\sin\sa\sdefault\slocation.\s\sIf\snot,\suse\sjimsh\sif\swe\scan\sfind\srealpath(),\selse\sbail\sout. -D 2024-10-23T01:59:34.375 +C Minor\scleanups\sin\sthe\s--with-wasi-sdk\sbits. +D 2024-10-23T02:11:52.441 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 1b677ab8ca5aaee8f6622ce0f9f1e3c07753c6ad15d258de22ea033b4abc5feb +F auto.def fdb4d96df5bc2ecb26aa4490b22ce0d4734828d6505574d1b22885a6cf2c6f1d F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl e17ec263ffe52207be99604d0ee9c36ab866605b1881518ab814a47cacedff4d +F autosetup/hwaci-common.tcl 3e9ae4dbdda198e5dea56e2bdf0a073f2acf60f76e83dc3ee25a00390d3f6bc7 F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cd447e50d1b31e7539e4a8b5dc2a88c5a6a3814a28718b5829167b830dfd0edd -R eb16726048dc406bfeeacf1897cc1534 +P 359741bc7624006014d73c4cf5cdd29fa38c33a446ed04b46032e5d3ca18d13c +R 6664e3de4f6cbfb5c6f691e38c508252 U stephan -Z f9b2797ed9043665e78aef0c31e48a93 +Z 3de5c5fa6fbeeee08097471cc1684856 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6fa56800fa..4e7d35cac8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -359741bc7624006014d73c4cf5cdd29fa38c33a446ed04b46032e5d3ca18d13c +d952c17981073cb0158b392edd9b0818dfba2456ab9997d360af56774c9f4216 From 55fca9585cea6a34211856879a27eb0c42dab387 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 02:17:46 +0000 Subject: [PATCH 101/522] Reorder some auto.def code to avoid breaking --help. FossilOrigin-Name: 151d7dfc8da64932f624528ed55764df6408a578bddc741b3dbf2f14567a0d71 --- auto.def | 14 ++++++-------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/auto.def b/auto.def index 32de7fd89e..d8185c90de 100644 --- a/auto.def +++ b/auto.def @@ -13,16 +13,8 @@ # JimTCL: https://jim.tcl.tk # use cc cc-db cc-shared cc-lib hwaci-common pkg-config -pkg-config-init 0; # ensure that it does not fail if pkg-config is unavailable - set DUMP_DEFINES_FILE ./defines.list -# Are we cross-compiling? -set cross_compiling 0 -if {[get-define host] ne [get-define build]} { - set cross_compiling 1 -} - ######################################################################## # Regarding flag compatibility with the historical autotool configure # script: @@ -155,6 +147,12 @@ options [subst { dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_FILE (for build debugging)} }] +# Are we cross-compiling? +set cross_compiling 0 +if {[get-define host] ne [get-define build]} { + set cross_compiling 1 +} + ######################################################################## # Notes about certain historical flags: # diff --git a/manifest b/manifest index 94b4aa4bfb..de553f757b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scleanups\sin\sthe\s--with-wasi-sdk\sbits. -D 2024-10-23T02:11:52.441 +C Reorder\ssome\sauto.def\scode\sto\savoid\sbreaking\s--help. +D 2024-10-23T02:17:46.419 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def fdb4d96df5bc2ecb26aa4490b22ce0d4734828d6505574d1b22885a6cf2c6f1d +F auto.def f18d3ac2c10f00e2dcb216e444180c1285b74fadc462107c44c45462d68fc2f5 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 359741bc7624006014d73c4cf5cdd29fa38c33a446ed04b46032e5d3ca18d13c -R 6664e3de4f6cbfb5c6f691e38c508252 +P d952c17981073cb0158b392edd9b0818dfba2456ab9997d360af56774c9f4216 +R bad9c6f29ee861dff55d3052a0704fc8 U stephan -Z 3de5c5fa6fbeeee08097471cc1684856 +Z b02a5594cbe7f4eba2097054c0a512dd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4e7d35cac8..c4c5e91250 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d952c17981073cb0158b392edd9b0818dfba2456ab9997d360af56774c9f4216 +151d7dfc8da64932f624528ed55764df6408a578bddc741b3dbf2f14567a0d71 From 5d6c11b7660854310738d69e9da2c5cb9f1ae88a Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 02:22:57 +0000 Subject: [PATCH 102/522] Latest autosetup/autosetup-find-tclsh from [https://github.com/msteveb/autosetup/issues/67 | autosetup ticket #67]. FossilOrigin-Name: 0e33f6cd48cb844331e66bfcfd93f83671380edef70b1e6684c09a7d4671eb17 --- autosetup/autosetup-find-tclsh | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/autosetup/autosetup-find-tclsh b/autosetup/autosetup-find-tclsh index 2b2006241c..0d0305125d 100755 --- a/autosetup/autosetup-find-tclsh +++ b/autosetup/autosetup-find-tclsh @@ -5,12 +5,12 @@ # If an argument is given, use that as the test instead of autosetup-test-tclsh d="`dirname "$0"`" for tclsh in ./jimsh0 $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; do - { $tclsh "$d/${1-autosetup-test-tclsh}"; } 2>/dev/null && exit 0 + { $tclsh "$d/${1-autosetup-test-tclsh}"; } >/dev/null 2>&1 && exit 0 done echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" for cc in ${CC_FOR_BUILD:-cc} gcc; do - { $cc -o jimsh0 "$d/jimsh0.c"; } >/dev/null 2>&1 || continue - ./jimsh0 "$d/${1-autosetup-test-tclsh}" && exit 0 + { $cc -o jimsh0 "$d/jimsh0.c"; } >/dev/null 2>&1 || continue + ./jimsh0 "$d/${1-autosetup-test-tclsh}" && exit 0 done echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." echo false diff --git a/manifest b/manifest index de553f757b..ed6f513a92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reorder\ssome\sauto.def\scode\sto\savoid\sbreaking\s--help. -D 2024-10-23T02:17:46.419 +C Latest\sautosetup/autosetup-find-tclsh\sfrom\s[https://github.com/msteveb/autosetup/issues/67\s|\sautosetup\sticket\s#67]. +D 2024-10-23T02:22:57.277 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -41,7 +41,7 @@ F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a7 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x -F autosetup/autosetup-find-tclsh 25905f6c302959db80c2951aa267b4411c5645b598ce761cfc24a166141e2c4c x +F autosetup/autosetup-find-tclsh c069d923d2011cba166279ba64b0bde7034fbf908d3a152f30a31a5109a9788e x F autosetup/autosetup-test-tclsh 749d20defee533a3842139df47d700fc7a334a5da7bdbd444ae5331744b06c5f F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034b10a7b F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d952c17981073cb0158b392edd9b0818dfba2456ab9997d360af56774c9f4216 -R bad9c6f29ee861dff55d3052a0704fc8 +P 151d7dfc8da64932f624528ed55764df6408a578bddc741b3dbf2f14567a0d71 +R fe90ed312938329808e1758de666366b U stephan -Z b02a5594cbe7f4eba2097054c0a512dd +Z 6cca0bc2add495ade6fe85a85eaad438 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c4c5e91250..bb3f063b65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -151d7dfc8da64932f624528ed55764df6408a578bddc741b3dbf2f14567a0d71 +0e33f6cd48cb844331e66bfcfd93f83671380edef70b1e6684c09a7d4671eb17 From 8a6ddc551e06c2c9371c8106eb378e120f775c96 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 02:36:50 +0000 Subject: [PATCH 103/522] Another fix for autosetup/autosetup-find-tclsh for the case where a tclsh is found on the system. FossilOrigin-Name: 19d78fcef469a15487953ce2d227746ad83c0360fdc42cd4b6df6a2bc5ebb8ae --- autosetup/autosetup-find-tclsh | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/autosetup/autosetup-find-tclsh b/autosetup/autosetup-find-tclsh index 0d0305125d..3b661d26ae 100755 --- a/autosetup/autosetup-find-tclsh +++ b/autosetup/autosetup-find-tclsh @@ -5,7 +5,7 @@ # If an argument is given, use that as the test instead of autosetup-test-tclsh d="`dirname "$0"`" for tclsh in ./jimsh0 $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; do - { $tclsh "$d/${1-autosetup-test-tclsh}"; } >/dev/null 2>&1 && exit 0 + { $tclsh "$d/${1-autosetup-test-tclsh}"; } 2>/dev/null && exit 0 done echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" for cc in ${CC_FOR_BUILD:-cc} gcc; do diff --git a/manifest b/manifest index ed6f513a92..215b0e0182 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Latest\sautosetup/autosetup-find-tclsh\sfrom\s[https://github.com/msteveb/autosetup/issues/67\s|\sautosetup\sticket\s#67]. -D 2024-10-23T02:22:57.277 +C Another\sfix\sfor\sautosetup/autosetup-find-tclsh\sfor\sthe\scase\swhere\sa\stclsh\sis\sfound\son\sthe\ssystem. +D 2024-10-23T02:36:50.580 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -41,7 +41,7 @@ F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a7 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x -F autosetup/autosetup-find-tclsh c069d923d2011cba166279ba64b0bde7034fbf908d3a152f30a31a5109a9788e x +F autosetup/autosetup-find-tclsh 38dc4ac03c061d5ee53ecd1ec2fc3d5f0bbf4e84a7123d3160e01d26b5858f36 x F autosetup/autosetup-test-tclsh 749d20defee533a3842139df47d700fc7a334a5da7bdbd444ae5331744b06c5f F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034b10a7b F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 151d7dfc8da64932f624528ed55764df6408a578bddc741b3dbf2f14567a0d71 -R fe90ed312938329808e1758de666366b +P 0e33f6cd48cb844331e66bfcfd93f83671380edef70b1e6684c09a7d4671eb17 +R 622e148ca442ba8131692c41eab1e194 U stephan -Z 6cca0bc2add495ade6fe85a85eaad438 +Z b8ce9feceacfd8aa8f9ced68df333f7b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bb3f063b65..1402daaa74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e33f6cd48cb844331e66bfcfd93f83671380edef70b1e6684c09a7d4671eb17 +19d78fcef469a15487953ce2d227746ad83c0360fdc42cd4b6df6a2bc5ebb8ae From 2c264ad060378a389b2fd0517bb0e7fe0b54ec79 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 23 Oct 2024 10:36:02 +0000 Subject: [PATCH 104/522] Add two new #include statements to the composite "fts5.c" file that is constructed as part of the build process. These #includes are no-ops in the SQLite amalgamation (and are commented out automatically by the amalgamation builder) but are needed if the FTS5 extension is built separately, it seems. [https://bugzilla.mozilla.org/show_bug.cgi?id=1926321#c3|Enhancement request]. FossilOrigin-Name: 1bf8daeb24142044e1b5d4b205317c42353004643fadb6b34f9ae6bfa4e3a6bc --- ext/fts5/tool/mkfts5c.tcl | 30 ++++++++++++++++++++++++++++-- manifest | 15 +++++++-------- manifest.uuid | 2 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/ext/fts5/tool/mkfts5c.tcl b/ext/fts5/tool/mkfts5c.tcl index b1a55fa4ae..9ea34a01e2 100644 --- a/ext/fts5/tool/mkfts5c.tcl +++ b/ext/fts5/tool/mkfts5c.tcl @@ -23,7 +23,27 @@ set G(src) [string map [list %dir% $srcdir] { }] set G(hdr) { - +/* +** This, the "fts5.c" source file, is a composite file that is itself +** assembled from the following files: +** +** fts5.h +** fts5Int.h +** fts5parse.h <--- Generated from fts5parse.y by Lemon +** fts5parse.c <--- Generated from fts5parse.y by Lemon +** fts5_aux.c +** fts5_buffer.c +** fts5_config.c +** fts5_expr.c +** fts5_hash.c +** fts5_index.c +** fts5_main.c +** fts5_storage.c +** fts5_tokenize.c +** fts5_unicode2.c +** fts5_varint.c +** fts5_vocab.c +*/ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) @@ -33,10 +53,16 @@ set G(hdr) { # undef NDEBUG #endif +#ifdef HAVE_STDINT_H +#include +#endif +#ifdef HAVE_INTTYPES_H +#include +#endif } set G(footer) { - +/* Here ends the fts5.c composite file. */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */ } diff --git a/manifest b/manifest index f5b9b0fcf2..b465f70eb3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sEXPLAIN\sQUERY\sPLAN\sto\sidentify\scovering\sindex\splan\sthat\suse\sindexes\son\sexpressions. -D 2024-10-22T20:16:41.027 +C Add\stwo\snew\s#include\sstatements\sto\sthe\scomposite\s"fts5.c"\sfile\sthat\nis\sconstructed\sas\spart\sof\sthe\sbuild\sprocess.\s\sThese\s#includes\sare\sno-ops\nin\sthe\sSQLite\samalgamation\s(and\sare\scommented\sout\sautomatically\sby\sthe\namalgamation\sbuilder)\sbut\sare\sneeded\sif\sthe\sFTS5\sextension\sis\sbuilt\nseparately,\sit\sseems.\n[https://bugzilla.mozilla.org/show_bug.cgi?id=1926321#c3|Enhancement\srequest]. +D 2024-10-23T10:36:02.768 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -258,7 +258,7 @@ F ext/fts5/test/fts5vocab2.test bbba149c254375d00055930c1a501c9a51e80b0d20bf7b98 F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc2870b45c0c82f9f F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 -F ext/fts5/tool/mkfts5c.tcl 3eba8e9bee4221ed165f3304b51b2a74a705f4ec5df3d044573a2be539534af8 +F ext/fts5/tool/mkfts5c.tcl 6649ed963a9135e36866f7cc9f8de5c8dcec85b5df089388274cee6381702cb7 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 F ext/icu/icu.c 3add8197e0a86c1761771a39500ebae749438bcf1836160b407a56b4eaa8721c @@ -2219,9 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2cc25d5dbbc729f3b6deb8c6a45b975c535b4d20ad240e4ec0c85b3733a170ed 3bb03a2891e30c58b66e3665a8877a8eab4a8bac57ee153d8d31358caeaf4b7c -R 15f28231c08df955e5429fb2ddbc37e9 -T +closed 3bb03a2891e30c58b66e3665a8877a8eab4a8bac57ee153d8d31358caeaf4b7c -U dan -Z ab6831b500df3a1cef4b8dd808d1b189 +P 29fb4919b6118b3b9ae411ec2ed5b59db7fae281909501c5fa238221ba635db5 +R 462eb90cd57fbab6c1cc9ab949c5cec7 +U drh +Z 54d605f0ae44fd417398f5aefbd89d12 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a0e2c25761..f962e87c6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29fb4919b6118b3b9ae411ec2ed5b59db7fae281909501c5fa238221ba635db5 +1bf8daeb24142044e1b5d4b205317c42353004643fadb6b34f9ae6bfa4e3a6bc From 98772d6e75f4033373c806e4e44f675971e55e38 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 23 Oct 2024 11:06:56 +0000 Subject: [PATCH 105/522] Fix harmless compiler warnings in wherecode.c. One such warning was identified by [forum:/forumpost/721675f007|forum post 721675f007] and the other was found by tool/warnings.sh. FossilOrigin-Name: 987b96aa636c1801f87d3e1c75d34d45c5b6f437bcc6d150298675447ed16b5d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b465f70eb3..fdd7df6e43 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stwo\snew\s#include\sstatements\sto\sthe\scomposite\s"fts5.c"\sfile\sthat\nis\sconstructed\sas\spart\sof\sthe\sbuild\sprocess.\s\sThese\s#includes\sare\sno-ops\nin\sthe\sSQLite\samalgamation\s(and\sare\scommented\sout\sautomatically\sby\sthe\namalgamation\sbuilder)\sbut\sare\sneeded\sif\sthe\sFTS5\sextension\sis\sbuilt\nseparately,\sit\sseems.\n[https://bugzilla.mozilla.org/show_bug.cgi?id=1926321#c3|Enhancement\srequest]. -D 2024-10-23T10:36:02.768 +C Fix\sharmless\scompiler\swarnings\sin\swherecode.c.\s\sOne\ssuch\swarning\swas\nidentified\sby\s[forum:/forumpost/721675f007|forum\spost\s721675f007]\sand\sthe\nother\swas\sfound\sby\stool/warnings.sh. +D 2024-10-23T11:06:56.384 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -859,7 +859,7 @@ F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 4de9e7ca5f49e4a21c1d733e2b2fbbc8b62b1a157a58a562c569da84cfcb005b F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca -F src/wherecode.c 8a260111af36d827d218118e36ccb8c359f9517f2743f5fe758e51dd9ae4acc7 +F src/wherecode.c 81b9af89f4f85c8097d0da6a31499f015eabc4d3584963d30ba7b7b782e26514 F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f F src/window.c 499d48f315a09242dc68f2fac635ed27dcf6bbb0d9ab9084857898c64489e975 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -2219,8 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 29fb4919b6118b3b9ae411ec2ed5b59db7fae281909501c5fa238221ba635db5 -R 462eb90cd57fbab6c1cc9ab949c5cec7 +P 1bf8daeb24142044e1b5d4b205317c42353004643fadb6b34f9ae6bfa4e3a6bc +R 8b3d6cd7e3f896ed28460cc14e806ffb U drh -Z 54d605f0ae44fd417398f5aefbd89d12 +Z 09e3d32bb2ddf741657be04c5623243d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f962e87c6b..226b1716d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1bf8daeb24142044e1b5d4b205317c42353004643fadb6b34f9ae6bfa4e3a6bc +987b96aa636c1801f87d3e1c75d34d45c5b6f437bcc6d150298675447ed16b5d diff --git a/src/wherecode.c b/src/wherecode.c index f1c6711af8..0bd1733b76 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -132,7 +132,9 @@ void sqlite3WhereAddExplainText( int isSearch; /* True for a SEARCH. False for SCAN. */ WhereLoop *pLoop; /* The controlling WhereLoop object */ u32 flags; /* Flags that describe this loop */ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) char *zMsg; /* Text to add to EQP output */ +#endif StrAccum str; /* EQP output string */ char zBuf[100]; /* Initial space for EQP output string */ @@ -215,8 +217,10 @@ void sqlite3WhereAddExplainText( sqlite3_str_append(&str, " (~1 row)", 9); } #endif +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) zMsg = sqlite3StrAccumFinish(&str); sqlite3ExplainBreakpoint("",zMsg); +#endif assert( pOp->opcode==OP_Explain ); assert( pOp->p4type==P4_DYNAMIC || pOp->p4.z==0 ); @@ -355,9 +359,10 @@ void sqlite3WhereAddScanStatus( } }else{ int addr; + VdbeOp *pOp; assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; - VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); + pOp = sqlite3VdbeGetOp(v, addr-1); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); From deb5ad6297490ddb910a1fcec61875b109d0a34e Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 23 Oct 2024 11:33:56 +0000 Subject: [PATCH 106/522] Reorder conditions in sqlite3PagerDirectReadOk() for coverage. FossilOrigin-Name: da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index fdd7df6e43..35446e6e5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\swherecode.c.\s\sOne\ssuch\swarning\swas\nidentified\sby\s[forum:/forumpost/721675f007|forum\spost\s721675f007]\sand\sthe\nother\swas\sfound\sby\stool/warnings.sh. -D 2024-10-23T11:06:56.384 +C Reorder\sconditions\sin\ssqlite3PagerDirectReadOk()\sfor\scoverage. +D 2024-10-23T11:33:56.073 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -759,7 +759,7 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210 F src/os_unix.c 0ad4e0885294b3a0e135a18533590ec9ad91ffe82f6a08e55b40babd51772928 F src/os_win.c 69fa1aaff68270423c85cff4327ba17ef99a1eb017e1a2bfb97416d9b8398b05 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c d57287cd0864c88740d20618e5e595b144b85bfdaefccafd353d596f254a7b35 +F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 @@ -2219,8 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1bf8daeb24142044e1b5d4b205317c42353004643fadb6b34f9ae6bfa4e3a6bc -R 8b3d6cd7e3f896ed28460cc14e806ffb +P 987b96aa636c1801f87d3e1c75d34d45c5b6f437bcc6d150298675447ed16b5d +R 83c78bc9e17ebe61e54351f39cf78374 U drh -Z 09e3d32bb2ddf741657be04c5623243d +Z cf7f2e26bfd189f11890320a8c9dc42f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 226b1716d4..612129bdfe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -987b96aa636c1801f87d3e1c75d34d45c5b6f437bcc6d150298675447ed16b5d +da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef diff --git a/src/pager.c b/src/pager.c index baaf4afbfe..4f616f0c7f 100644 --- a/src/pager.c +++ b/src/pager.c @@ -817,11 +817,6 @@ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ assert( pPager!=0 ); assert( pPager->fd!=0 ); if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ - assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); - if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) - & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ - return 0; /* Case (2) */ - } if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ @@ -830,6 +825,11 @@ int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ return iRead==0; /* Condition (4) */ } #endif + assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); + if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) + & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ + return 0; /* Case (2) */ + } return 1; } #endif From 284e70b3a1319805851ea306cfb60cbd23700c61 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 15:05:08 +0000 Subject: [PATCH 107/522] Add missing export of LDFLAGS_DLOPEN to Makefile.in. FossilOrigin-Name: d18af84bf76db16513791b43850c41dbb5a83c435b8d3e93afaa8c2920460ac7 --- Makefile.in | 1 + main.mk | 4 +++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index 46e9b70b2a..f7801f4e98 100644 --- a/Makefile.in +++ b/Makefile.in @@ -92,6 +92,7 @@ LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ LDFLAGS_MATH = @LDFLAGS_MATH@ LDFLAGS_RPATH = @LDFLAGS_RPATH@ LDFLAGS_PTHREAD = @LDFLAGS_PTHREAD@ +LDFLAGS_DLOPEN = @LDFLAGS_DLOPEN@ LDFLAGS_READLINE = @LDFLAGS_READLINE@ CFLAGS_READLINE = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ diff --git a/main.mk b/main.mk index 399c22fddf..a700538127 100644 --- a/main.mk +++ b/main.mk @@ -99,6 +99,7 @@ LDFLAGS_RPATH ?= -Wl,-rpath -Wl,$(prefix)/lib LDFLAGS_READLINE ?= -lreadline CFLAGS_READLINE ?= LDFLAGS_PTHREAD ?= -lpthread +LDFLAGS_DLOPEN ?= -ldl LDFLAGS_SHOBJ ?= -shared # # Various system-level directories, mostly needed for installation and @@ -247,7 +248,8 @@ CFLAGS_libsqlite3 ?= -DSQLITE_TEMP_STORE=1 # LDFLAGS_libsqlite3 = \ $(LDFLAGS_RPATH) $(LDFLAGS_PTHREAD) \ - $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) + $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) \ + $(LDFLAGS_DLOPEN) # # install-dir.XYZ = dirs for installation. diff --git a/manifest b/manifest index 215b0e0182..0d30aa1724 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Another\sfix\sfor\sautosetup/autosetup-find-tclsh\sfor\sthe\scase\swhere\sa\stclsh\sis\sfound\son\sthe\ssystem. -D 2024-10-23T02:36:50.580 +C Add\smissing\sexport\sof\sLDFLAGS_DLOPEN\sto\sMakefile.in. +D 2024-10-23T15:05:08.949 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 0997c8fc9c49bf2f4ac0df34575e3b502aa56255d86d2e3c66712296ee64fdf2 +F Makefile.in 2bee04a7f1a852d95deee05abed3ec5c7b57828fdfb1dd76208f64ababe05734 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -711,7 +711,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 420e9df512d6f7095392af26bc6bb1699c66251b8feb6cf848484378ea6f8980 +F main.mk 25ec1fb7641de775c2ebc89f25fbb0ad9910bdadaa623d0d0273a6802e3fde39 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0e33f6cd48cb844331e66bfcfd93f83671380edef70b1e6684c09a7d4671eb17 -R 622e148ca442ba8131692c41eab1e194 +P 19d78fcef469a15487953ce2d227746ad83c0360fdc42cd4b6df6a2bc5ebb8ae +R 1a61abf85307cb0889267743564ae1c2 U stephan -Z b8ce9feceacfd8aa8f9ced68df333f7b +Z 857140f1e561af28f97e4baf820cd93c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1402daaa74..4198fc7251 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19d78fcef469a15487953ce2d227746ad83c0360fdc42cd4b6df6a2bc5ebb8ae +d18af84bf76db16513791b43850c41dbb5a83c435b8d3e93afaa8c2920460ac7 From 264c6918630370ec1532f1640b22850710741244 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 15:13:43 +0000 Subject: [PATCH 108/522] Remove the configure-script VERSION check from tool/srctree-check.tcl, as it's not relevant in the autosetup build. FossilOrigin-Name: 6c5826d7522eade0f5682367637f45b0b64a7cced3cd7d643a30fb9ab0acd2a9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/srctree-check.tcl | 11 ----------- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 0d30aa1724..4fd665a940 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\sexport\sof\sLDFLAGS_DLOPEN\sto\sMakefile.in. -D 2024-10-23T15:05:08.949 +C Remove\sthe\sconfigure-script\sVERSION\scheck\sfrom\stool/srctree-check.tcl,\sas\sit's\snot\srelevant\sin\sthe\sautosetup\sbuild. +D 2024-10-23T15:13:43.582 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -2206,7 +2206,7 @@ F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaa F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c d00f93263aa2fa6ba0cba0106d95458e6effb94fdb5fc634f56834f90c05bbb4 F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f -F tool/srctree-check.tcl c15f860a3c97d5f7b4c14b60392d9466af29dd006c4ef18127f502641e2977a8 +F tool/srctree-check.tcl 1f1f505835a4beca64c1751a7ebec5c41a1ddf22b1e80481345b95059eef6583 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 19d78fcef469a15487953ce2d227746ad83c0360fdc42cd4b6df6a2bc5ebb8ae -R 1a61abf85307cb0889267743564ae1c2 +P d18af84bf76db16513791b43850c41dbb5a83c435b8d3e93afaa8c2920460ac7 +R fcf740736e0c66190eba26f9f4b8a254 U stephan -Z 857140f1e561af28f97e4baf820cd93c +Z f4e3e16667421c51bf77ba9ddc8d742f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4198fc7251..c9c68a10b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d18af84bf76db16513791b43850c41dbb5a83c435b8d3e93afaa8c2920460ac7 +6c5826d7522eade0f5682367637f45b0b64a7cced3cd7d643a30fb9ab0acd2a9 diff --git a/tool/srctree-check.tcl b/tool/srctree-check.tcl index 51226cda46..b65e223db9 100644 --- a/tool/srctree-check.tcl +++ b/tool/srctree-check.tcl @@ -36,17 +36,6 @@ set TCLSH [info nameofexe] # set NERR 0 -######################### configure ########################################### - -set conf [readfile $ROOT/configure] -set vers [readfile $ROOT/VERSION] -if {[string first $vers $conf]<=0} { - puts "ERROR: ./configure does not agree with ./VERSION" - puts "...... Fix: run autoconf" - incr NERR -} -unset conf - ######################### autoconf/tea/configure.ac ########################### set confac [readfile $ROOT/autoconf/tea/configure.ac] From 519fc4f8c26527bd6ce7ad87c16fcd4739100da1 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 16:03:51 +0000 Subject: [PATCH 109/522] Work around a minor JimTCL regexp incompatibility in tool/vdbe-compress.tcl. Summary: it thinks that backslash-escaped octal values are back-references, which it does not like. FossilOrigin-Name: aeac23359bb681c0c86c55c83ab9c16973822f6bc4e1a11959102b062333e358 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/vdbe-compress.tcl | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4fd665a940..79dace90bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sconfigure-script\sVERSION\scheck\sfrom\stool/srctree-check.tcl,\sas\sit's\snot\srelevant\sin\sthe\sautosetup\sbuild. -D 2024-10-23T15:13:43.582 +C Work\saround\sa\sminor\sJimTCL\sregexp\sincompatibility\sin\stool/vdbe-compress.tcl.\sSummary:\sit\sthinks\sthat\sbackslash-escaped\soctal\svalues\sare\sback-references,\swhich\sit\sdoes\snot\slike. +D 2024-10-23T16:03:51.991 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -2213,7 +2213,7 @@ F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9 F tool/tclConfigShToTcl.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 -F tool/vdbe-compress.tcl 1dcb7632e57cf57105248029e6e162fddaf6c0fccb3bb9e6215603752c5a2d4a +F tool/vdbe-compress.tcl fa2f37ab39b2a0087fafb6a7f3ce19503e25e624ffa8ed9951717ab72920c088 F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d18af84bf76db16513791b43850c41dbb5a83c435b8d3e93afaa8c2920460ac7 -R fcf740736e0c66190eba26f9f4b8a254 +P 6c5826d7522eade0f5682367637f45b0b64a7cced3cd7d643a30fb9ab0acd2a9 +R 4b2c513ad55674fcf9024d65f21597c1 U stephan -Z f4e3e16667421c51bf77ba9ddc8d742f +Z 4d628e9a2ca6d7aa1cdb129ebf537bbf # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c9c68a10b3..f883a5a4e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c5826d7522eade0f5682367637f45b0b64a7cced3cd7d643a30fb9ab0acd2a9 +aeac23359bb681c0c86c55c83ab9c16973822f6bc4e1a11959102b062333e358 diff --git a/tool/vdbe-compress.tcl b/tool/vdbe-compress.tcl index 5e63c96a9a..eaafc7a956 100644 --- a/tool/vdbe-compress.tcl +++ b/tool/vdbe-compress.tcl @@ -69,7 +69,7 @@ set namechars {abcefghjklmnopqrstuvwxyz} set nnc [string length $namechars] while {![eof stdin]} { set line [gets stdin] - if {[regexp "^case (OP_\\w+): \173" $line all operator]} { + if {[regexp "^case (OP_\\w+): \\x7B" $line all operator]} { append afterUnion $line\n set vlist {} while {![eof stdin]} { From a7d3d40e0611639e5f9c95e7b648f93c12376b7f Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 16:46:46 +0000 Subject: [PATCH 110/522] After compiling jimsh, run sanity tests on it to ensure that it is built with -DJIM_COMPAT and one of (-DHAVE_REALPATH, -DHAVE__FULLPATH). FossilOrigin-Name: ea6a14a6e64c0ed2306b9b3048132659094259b95b49a9572f7178c26b28f93a --- Makefile.in | 24 ++++++++++++++++++++++-- auto.def | 1 + manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Makefile.in b/Makefile.in index f7801f4e98..f284b242a9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -75,6 +75,7 @@ includedir ?= @includedir@ # # Just testing some default dir expansions... # srcdir = @srcdir@ +# builddir = @builddir@ # top_srcdir = @top_srcdir@ # abs_top_srcdir = @abs_top_srcdir@ # abs_top_builddir = @abs_top_builddir@ @@ -127,10 +128,29 @@ TCCX += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # to build it with another option enabled for use with the various # code generators. # -JIMSH = @srcdir@/jimsh +# After jimsh is compiled, we run some sanity checks to ensure that +# it was built in a way compatible with this project's scripts: +# +# 1) Ensure that it was built with realpath() or _fullpath() support. +# Without that flag the [file normalize] command will always resolve +# to an empty string. +# +# 2) Ensure that it is built with -DJIM_COMPAT (which may be +# hard-coded into jimsh0.c). Without this, the [expr] command +# accepts only a single argument. +# CFLAGS_JIMSH ?= @CFLAGS_JIMSH@ +JIMSH = @builddir@/jimsh$(TEXE) $(JIMSH): $(TOP)/autosetup/jimsh0.c - $(BCC) -o $(JIMSH) $(CFLAGS_JIMSH) $(TOP)/autosetup/jimsh0.c + $(BCC) -o $@ $(CFLAGS_JIMSH) $(TOP)/autosetup/jimsh0.c + @if [ x = "x$$($(JIMSH) -e 'file normalize $(JIMSH)' 2>/dev/null)" ]; then \ + echo "jimsh was built without -DHAVE_REALPATH or -DHAVE__FULLPATH." 1>&2; \ + exit 1; \ + fi + @if [ x3 != "x$$($(JIMSH) -e 'expr 1 + 2' 2>/dev/null)" ]; then \ + echo "jimsh was built without -DJIM_COMPAT." 1>&2; \ + exit 1; \ + fi # BTCLSH is the tclsh-compatible app used for running various code # generators and other in-tree tools, as opposed to the TCL-based diff --git a/auto.def b/auto.def index d8185c90de..2a298714d3 100644 --- a/auto.def +++ b/auto.def @@ -651,6 +651,7 @@ if {[cc-check-functions realpath]} { } msg-result "TCL for code generation: $cgtcl" unset cgtcl +#define CFLAGS_JIMSH {-DJUST_TESTING} # /TCL ######################################################################## diff --git a/manifest b/manifest index 79dace90bf..4c07bf7b92 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Work\saround\sa\sminor\sJimTCL\sregexp\sincompatibility\sin\stool/vdbe-compress.tcl.\sSummary:\sit\sthinks\sthat\sbackslash-escaped\soctal\svalues\sare\sback-references,\swhich\sit\sdoes\snot\slike. -D 2024-10-23T16:03:51.991 +C After\scompiling\sjimsh,\srun\ssanity\stests\son\sit\sto\sensure\sthat\sit\sis\sbuilt\swith\s-DJIM_COMPAT\sand\sone\sof\s(-DHAVE_REALPATH,\s-DHAVE__FULLPATH). +D 2024-10-23T16:46:46.669 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 2bee04a7f1a852d95deee05abed3ec5c7b57828fdfb1dd76208f64ababe05734 +F Makefile.in 2543a2bc53ef627ec0cf45a41ad14f571b5a3bff0049d84a390c5183455c6a09 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def f18d3ac2c10f00e2dcb216e444180c1285b74fadc462107c44c45462d68fc2f5 +F auto.def d29dde15497d1de443b4fb9aba96d084eeaa4ed08c18939af8bb2aabdada1328 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6c5826d7522eade0f5682367637f45b0b64a7cced3cd7d643a30fb9ab0acd2a9 -R 4b2c513ad55674fcf9024d65f21597c1 +P aeac23359bb681c0c86c55c83ab9c16973822f6bc4e1a11959102b062333e358 +R a7bc168b9304f807692f7a48ff3b1fd1 U stephan -Z 4d628e9a2ca6d7aa1cdb129ebf537bbf +Z e22ea7d251580efff9ff3789b0efb608 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f883a5a4e7..ef9eb68ae4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aeac23359bb681c0c86c55c83ab9c16973822f6bc4e1a11959102b062333e358 +ea6a14a6e64c0ed2306b9b3048132659094259b95b49a9572f7178c26b28f93a From 8d69bd2a20458ccecb4aefc23931042a72b2b38b Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 16:59:12 +0000 Subject: [PATCH 111/522] Fix a #define typo in jimsh0.c, eliminating the need to explicitly pass -DJIM_COMPAT when building it. This fix has since made its way upstream. FossilOrigin-Name: 9b105abf6fb6425d223ab9319f539b9d0cc2df488e0c23c5070853ba4778ebee --- auto.def | 6 ++++-- autosetup/jimsh0.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/auto.def b/auto.def index 2a298714d3..51c5490147 100644 --- a/auto.def +++ b/auto.def @@ -610,8 +610,10 @@ hwaci-check-tcl # # Building jimsh0.c with -DJIM_COMPAT changes certain behavior to be # compatible with canonical TCL. Specifically: jim's [expr] only -# accepts one arg unless JIM_COMPAT is defined. -define CFLAGS_JIMSH {-DJIM_COMPAT} +# accepts one arg unless JIM_COMPAT is defined. As of 2024-10-23, +# jimsh0.c defines JIM_COMPAT automatically (prior to that it intended +# to but a typo of JIM_TCL_COMPAT made it a no-op). +define CFLAGS_JIMSH {} set useOwnJimsh 0 msg-result "Which TCL to use for code generation... " set cgtcl jimtcl diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index 3c0e8b78a2..aa1e0bd9f2 100644 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -1,5 +1,5 @@ /* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ -#define JIM_TCL_COMPAT +#define JIM_COMPAT #define JIM_ANSIC #define JIM_REGEXP #define HAVE_NO_AUTOCONF diff --git a/manifest b/manifest index 4c07bf7b92..cd8eab4b02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C After\scompiling\sjimsh,\srun\ssanity\stests\son\sit\sto\sensure\sthat\sit\sis\sbuilt\swith\s-DJIM_COMPAT\sand\sone\sof\s(-DHAVE_REALPATH,\s-DHAVE__FULLPATH). -D 2024-10-23T16:46:46.669 +C Fix\sa\s#define\stypo\sin\sjimsh0.c,\seliminating\sthe\sneed\sto\sexplicitly\spass\s-DJIM_COMPAT\swhen\sbuilding\sit.\sThis\sfix\shas\ssince\smade\sits\sway\supstream. +D 2024-10-23T16:59:12.956 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d29dde15497d1de443b4fb9aba96d084eeaa4ed08c18939af8bb2aabdada1328 +F auto.def 1e8ae5762fc37fd33825879f177c78cde651946cfb0a41f274a677167cf16554 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/hwaci-common.tcl 3e9ae4dbdda198e5dea56e2bdf0a073f2acf60f76e83dc3ee25a00390d3f6bc7 -F autosetup/jimsh0.c 1b5fe91fffcddbc29f2b16acb80f1650632ea2edbe8336b8155ef7b4c66f6d8d +F autosetup/jimsh0.c 838968b1159a6061452d751a48df3646830b04b118e35790da97e998208bc5ae F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f @@ -2240,8 +2240,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aeac23359bb681c0c86c55c83ab9c16973822f6bc4e1a11959102b062333e358 -R a7bc168b9304f807692f7a48ff3b1fd1 +P ea6a14a6e64c0ed2306b9b3048132659094259b95b49a9572f7178c26b28f93a +R e5742b36efa53d07ed73d499dfe7e484 U stephan -Z e22ea7d251580efff9ff3789b0efb608 +Z ea44c0d193681b774d941092dfa1a741 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ef9eb68ae4..ccd143cf05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea6a14a6e64c0ed2306b9b3048132659094259b95b49a9572f7178c26b28f93a +9b105abf6fb6425d223ab9319f539b9d0cc2df488e0c23c5070853ba4778ebee From 18f6445aea9294db0a0cd70a329876da09c67ddb Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 17:17:16 +0000 Subject: [PATCH 112/522] Remove three autotools files which are not needed in the autosetup port. FossilOrigin-Name: fc20861443ea52a058f556fdf1ddf03a41c538e3b97ff663833e422a50e38d66 --- config.guess | 1659 --------------------------------------------- config.sub | 1798 ------------------------------------------------- configure.ac | 811 ---------------------- manifest | 13 +- manifest.uuid | 2 +- 5 files changed, 6 insertions(+), 4277 deletions(-) delete mode 100644 config.guess delete mode 100644 config.sub delete mode 100644 configure.ac diff --git a/config.guess b/config.guess deleted file mode 100644 index ae713942d8..0000000000 --- a/config.guess +++ /dev/null @@ -1,1659 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2019 Free Software Foundation, Inc. - -timestamp='2019-05-28' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. -# -# You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess -# -# Please send patches to . - - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Options: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright 1992-2019 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -tmp= -# shellcheck disable=SC2172 -trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 - -set_cc_for_build() { - : "${TMPDIR=/tmp}" - # shellcheck disable=SC2039 - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } - dummy=$tmp/dummy - case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in - ,,) echo "int x;" > "$dummy.c" - for driver in cc gcc c89 c99 ; do - if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD="$driver" - break - fi - done - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; - esac -} - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if test -f /.attbin/uname ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -case "$UNAME_SYSTEM" in -Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu - - set_cc_for_build - cat <<-EOF > "$dummy.c" - #include - #if defined(__UCLIBC__) - LIBC=uclibc - #elif defined(__dietlibc__) - LIBC=dietlibc - #else - LIBC=gnu - #endif - EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" - - # If ldd exists, use it to detect musl libc. - if command -v ldd >/dev/null && \ - ldd --version 2>&1 | grep -q ^musl - then - LIBC=musl - fi - ;; -esac - -# Note: order is significant - the case branches are not exclusive. - -case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - "/sbin/$sysctl" 2>/dev/null || \ - "/usr/sbin/$sysctl" 2>/dev/null || \ - echo unknown)` - case "$UNAME_MACHINE_ARCH" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - earmv*) - arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` - machine="${arch}${endian}"-unknown - ;; - *) machine="$UNAME_MACHINE_ARCH"-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently (or will in the future) and ABI. - case "$UNAME_MACHINE_ARCH" in - earm*) - os=netbsdelf - ;; - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # Determine ABI tags. - case "$UNAME_MACHINE_ARCH" in - earm*) - expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "$UNAME_VERSION" in - Debian*) - release='-gnu' - ;; - *) - release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "$machine-${os}${release}${abi-}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" - exit ;; - *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" - exit ;; - *:MidnightBSD:*:*) - echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" - exit ;; - *:ekkoBSD:*:*) - echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" - exit ;; - *:SolidBSD:*:*) - echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd"$UNAME_RELEASE" - exit ;; - *:MirBSD:*:*) - echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" - exit ;; - *:Sortix:*:*) - echo "$UNAME_MACHINE"-unknown-sortix - exit ;; - *:Redox:*:*) - echo "$UNAME_MACHINE"-unknown-redox - exit ;; - mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE=alpha ;; - "EV4.5 (21064)") - UNAME_MACHINE=alpha ;; - "LCA4 (21066/21068)") - UNAME_MACHINE=alpha ;; - "EV5 (21164)") - UNAME_MACHINE=alphaev5 ;; - "EV5.6 (21164A)") - UNAME_MACHINE=alphaev56 ;; - "EV5.6 (21164PC)") - UNAME_MACHINE=alphapca56 ;; - "EV5.7 (21164PC)") - UNAME_MACHINE=alphapca57 ;; - "EV6 (21264)") - UNAME_MACHINE=alphaev6 ;; - "EV6.7 (21264A)") - UNAME_MACHINE=alphaev67 ;; - "EV6.8CB (21264C)") - UNAME_MACHINE=alphaev68 ;; - "EV6.8AL (21264B)") - UNAME_MACHINE=alphaev68 ;; - "EV6.8CX (21264D)") - UNAME_MACHINE=alphaev68 ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE=alphaev69 ;; - "EV7 (21364)") - UNAME_MACHINE=alphaev7 ;; - "EV7.9 (21364A)") - UNAME_MACHINE=alphaev79 ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix"$UNAME_RELEASE" - exit ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux"$UNAME_RELEASE" - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - set_cc_for_build - SUN_ARCH=i386 - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH=x86_64 - fi - fi - echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos"$UNAME_RELEASE" - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos"$UNAME_RELEASE" - ;; - sun4) - echo sparc-sun-sunos"$UNAME_RELEASE" - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos"$UNAME_RELEASE" - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint"$UNAME_RELEASE" - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint"$UNAME_RELEASE" - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint"$UNAME_RELEASE" - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten"$UNAME_RELEASE" - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten"$UNAME_RELEASE" - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix"$UNAME_RELEASE" - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix"$UNAME_RELEASE" - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix"$UNAME_RELEASE" - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`"$dummy" "$dummyarg"` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos"$UNAME_RELEASE" - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] - then - if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ - [ "$TARGET_BINARY_INTERFACE"x = x ] - then - echo m88k-dg-dgux"$UNAME_RELEASE" - else - echo m88k-dg-dguxbcs"$UNAME_RELEASE" - fi - else - echo i586-dg-dgux"$UNAME_RELEASE" - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" - fi - echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` - else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" - fi - echo "$IBM_ARCH"-ibm-aix"$IBM_REV" - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` - case "$UNAME_MACHINE" in - 9000/31?) HP_ARCH=m68000 ;; - 9000/[34]??) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "$sc_cpu_version" in - 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 - 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "$sc_kernel_bits" in - 32) HP_ARCH=hppa2.0n ;; - 64) HP_ARCH=hppa2.0w ;; - '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "$HP_ARCH" = "" ]; then - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ "$HP_ARCH" = hppa2.0w ] - then - set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH=hppa2.0w - else - HP_ARCH=hppa64 - fi - fi - echo "$HP_ARCH"-hp-hpux"$HPUX_REV" - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux"$HPUX_REV" - exit ;; - 3050*:HI-UX:*:*) - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo "$UNAME_MACHINE"-unknown-osf1mk - else - echo "$UNAME_MACHINE"-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi"$UNAME_RELEASE" - exit ;; - *:BSD/OS:*:*) - echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" - exit ;; - arm:FreeBSD:*:*) - UNAME_PROCESSOR=`uname -p` - set_cc_for_build - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi - else - echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf - fi - exit ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case "$UNAME_PROCESSOR" in - amd64) - UNAME_PROCESSOR=x86_64 ;; - i386) - UNAME_PROCESSOR=i586 ;; - esac - echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" - exit ;; - i*:CYGWIN*:*) - echo "$UNAME_MACHINE"-pc-cygwin - exit ;; - *:MINGW64*:*) - echo "$UNAME_MACHINE"-pc-mingw64 - exit ;; - *:MINGW*:*) - echo "$UNAME_MACHINE"-pc-mingw32 - exit ;; - *:MSYS*:*) - echo "$UNAME_MACHINE"-pc-msys - exit ;; - i*:PW*:*) - echo "$UNAME_MACHINE"-pc-pw32 - exit ;; - *:Interix*:*) - case "$UNAME_MACHINE" in - x86) - echo i586-pc-interix"$UNAME_RELEASE" - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix"$UNAME_RELEASE" - exit ;; - IA64) - echo ia64-unknown-interix"$UNAME_RELEASE" - exit ;; - esac ;; - i*:UWIN*:*) - echo "$UNAME_MACHINE"-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-pc-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" - exit ;; - *:GNU:*:*) - # the GNU system - echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" - exit ;; - *:Minix:*:*) - echo "$UNAME_MACHINE"-unknown-minix - exit ;; - aarch64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - arm*:Linux:*:*) - set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi - else - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - cris:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; - crisv32:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; - e2k:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - frv:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - hexagon:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - i*86:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" - exit ;; - ia64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - k1om:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - m32r*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - m68*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - set_cc_for_build - IS_GLIBC=0 - test x"${LIBC}" = xgnu && IS_GLIBC=1 - sed 's/^ //' << EOF > "$dummy.c" - #undef CPU - #undef mips - #undef mipsel - #undef mips64 - #undef mips64el - #if ${IS_GLIBC} && defined(_ABI64) - LIBCABI=gnuabi64 - #else - #if ${IS_GLIBC} && defined(_ABIN32) - LIBCABI=gnuabin32 - #else - LIBCABI=${LIBC} - #endif - #endif - - #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 - CPU=mipsisa64r6 - #else - #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 - CPU=mipsisa32r6 - #else - #if defined(__mips64) - CPU=mips64 - #else - CPU=mips - #endif - #endif - #endif - - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - MIPS_ENDIAN=el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - MIPS_ENDIAN= - #else - MIPS_ENDIAN= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" - test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } - ;; - mips64el:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - openrisc*:Linux:*:*) - echo or1k-unknown-linux-"$LIBC" - exit ;; - or32:Linux:*:* | or1k*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-"$LIBC" - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-"$LIBC" - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; - PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; - *) echo hppa-unknown-linux-"$LIBC" ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-"$LIBC" - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-"$LIBC" - exit ;; - ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-"$LIBC" - exit ;; - ppcle:Linux:*:*) - echo powerpcle-unknown-linux-"$LIBC" - exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" - exit ;; - sh64*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - sh*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - tile*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - vax:Linux:*:*) - echo "$UNAME_MACHINE"-dec-linux-"$LIBC" - exit ;; - x86_64:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" - exit ;; - xtensa*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo "$UNAME_MACHINE"-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo "$UNAME_MACHINE"-unknown-stop - exit ;; - i*86:atheos:*:*) - echo "$UNAME_MACHINE"-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo "$UNAME_MACHINE"-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos"$UNAME_RELEASE" - exit ;; - i*86:*DOS:*:*) - echo "$UNAME_MACHINE"-pc-msdosdjgpp - exit ;; - i*86:*:4.*:*) - UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" - else - echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" - else - echo "$UNAME_MACHINE"-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configure will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos"$UNAME_RELEASE" - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos"$UNAME_RELEASE" - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos"$UNAME_RELEASE" - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos"$UNAME_RELEASE" - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv"$UNAME_RELEASE" - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo "$UNAME_MACHINE"-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo "$UNAME_MACHINE"-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux"$UNAME_RELEASE" - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv"$UNAME_RELEASE" - else - echo mips-unknown-sysv"$UNAME_RELEASE" - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux"$UNAME_RELEASE" - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux"$UNAME_RELEASE" - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux"$UNAME_RELEASE" - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux"$UNAME_RELEASE" - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux"$UNAME_RELEASE" - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux"$UNAME_RELEASE" - exit ;; - SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux"$UNAME_RELEASE" - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody"$UNAME_RELEASE" - exit ;; - *:Rhapsody:*:*) - echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - if command -v xcode-select > /dev/null 2> /dev/null && \ - ! xcode-select --print-path > /dev/null 2> /dev/null ; then - # Avoid executing cc if there is no toolchain installed as - # cc will be a stub that puts up a graphical alert - # prompting the user to install developer tools. - CC_FOR_BUILD=no_compiler_found - else - set_cc_for_build - fi - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi - elif test "$UNAME_PROCESSOR" = i386 ; then - # uname -m returns i386 or x86_64 - UNAME_PROCESSOR=$UNAME_MACHINE - fi - echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = x86; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-*:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk"$UNAME_RELEASE" - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk"$UNAME_RELEASE" - exit ;; - NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk"$UNAME_RELEASE" - exit ;; - NSV-*:NONSTOP_KERNEL:*:*) - echo nsv-tandem-nsk"$UNAME_RELEASE" - exit ;; - NSX-*:NONSTOP_KERNEL:*:*) - echo nsx-tandem-nsk"$UNAME_RELEASE" - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - # shellcheck disable=SC2154 - if test "$cputype" = 386; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo "$UNAME_MACHINE"-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux"$UNAME_RELEASE" - exit ;; - *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "$UNAME_MACHINE" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" - exit ;; - i*86:rdos:*:*) - echo "$UNAME_MACHINE"-pc-rdos - exit ;; - i*86:AROS:*:*) - echo "$UNAME_MACHINE"-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo "$UNAME_MACHINE"-unknown-esx - exit ;; - amd64:Isilon\ OneFS:*:*) - echo x86_64-unknown-onefs - exit ;; - *:Unleashed:*:*) - echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" - exit ;; -esac - -# No uname command or uname output not recognized. -set_cc_for_build -cat > "$dummy.c" < -#include -#endif -#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) -#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) -#include -#if defined(_SIZE_T_) || defined(SIGLOST) -#include -#endif -#endif -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); -#endif - -#if defined (vax) -#if !defined (ultrix) -#include -#if defined (BSD) -#if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -#else -#if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -#else - printf ("vax-dec-bsd\n"); exit (0); -#endif -#endif -#else - printf ("vax-dec-bsd\n"); exit (0); -#endif -#else -#if defined(_SIZE_T_) || defined(SIGLOST) - struct utsname un; - uname (&un); - printf ("vax-dec-ultrix%s\n", un.release); exit (0); -#else - printf ("vax-dec-ultrix\n"); exit (0); -#endif -#endif -#endif -#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) -#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) -#if defined(_SIZE_T_) || defined(SIGLOST) - struct utsname *un; - uname (&un); - printf ("mips-dec-ultrix%s\n", un.release); exit (0); -#else - printf ("mips-dec-ultrix\n"); exit (0); -#endif -#endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. -test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } - -echo "$0: unable to guess system type" >&2 - -case "$UNAME_MACHINE:$UNAME_SYSTEM" in - mips:Linux | mips64:Linux) - # If we got here on MIPS GNU/Linux, output extra information. - cat >&2 <&2 </dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = "$UNAME_MACHINE" -UNAME_RELEASE = "$UNAME_RELEASE" -UNAME_SYSTEM = "$UNAME_SYSTEM" -UNAME_VERSION = "$UNAME_VERSION" -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/config.sub b/config.sub deleted file mode 100644 index 5b158ac41c..0000000000 --- a/config.sub +++ /dev/null @@ -1,1798 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2019 Free Software Foundation, Inc. - -timestamp='2019-05-23' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches to . -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS - -Canonicalize a configuration name. - -Options: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright 1992-2019 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo "$1" - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Split fields of configuration type -# shellcheck disable=SC2162 -IFS="-" read field1 field2 field3 field4 <&2 - exit 1 - ;; - *-*-*-*) - basic_machine=$field1-$field2 - os=$field3-$field4 - ;; - *-*-*) - # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two - # parts - maybe_os=$field2-$field3 - case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ - | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ - | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ - | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) - basic_machine=$field1 - os=$maybe_os - ;; - android-linux) - basic_machine=$field1-unknown - os=linux-android - ;; - *) - basic_machine=$field1-$field2 - os=$field3 - ;; - esac - ;; - *-*) - # A lone config we happen to match not fitting any pattern - case $field1-$field2 in - decstation-3100) - basic_machine=mips-dec - os= - ;; - *-*) - # Second component is usually, but not always the OS - case $field2 in - # Prevent following clause from handling this valid os - sun*os*) - basic_machine=$field1 - os=$field2 - ;; - # Manufacturers - dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ - | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ - | unicom* | ibm* | next | hp | isi* | apollo | altos* \ - | convergent* | ncr* | news | 32* | 3600* | 3100* \ - | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ - | ultra | tti* | harris | dolphin | highlevel | gould \ - | cbm | ns | masscomp | apple | axis | knuth | cray \ - | microblaze* | sim | cisco \ - | oki | wec | wrs | winbond) - basic_machine=$field1-$field2 - os= - ;; - *) - basic_machine=$field1 - os=$field2 - ;; - esac - ;; - esac - ;; - *) - # Convert single-component short-hands not valid as part of - # multi-component configurations. - case $field1 in - 386bsd) - basic_machine=i386-pc - os=bsd - ;; - a29khif) - basic_machine=a29k-amd - os=udi - ;; - adobe68k) - basic_machine=m68010-adobe - os=scout - ;; - alliant) - basic_machine=fx80-alliant - os= - ;; - altos | altos3068) - basic_machine=m68k-altos - os= - ;; - am29k) - basic_machine=a29k-none - os=bsd - ;; - amdahl) - basic_machine=580-amdahl - os=sysv - ;; - amiga) - basic_machine=m68k-unknown - os= - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=bsd - ;; - aros) - basic_machine=i386-pc - os=aros - ;; - aux) - basic_machine=m68k-apple - os=aux - ;; - balance) - basic_machine=ns32k-sequent - os=dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=linux - ;; - cegcc) - basic_machine=arm-unknown - os=cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=bsd - ;; - convex-c2) - basic_machine=c2-convex - os=bsd - ;; - convex-c32) - basic_machine=c32-convex - os=bsd - ;; - convex-c34) - basic_machine=c34-convex - os=bsd - ;; - convex-c38) - basic_machine=c38-convex - os=bsd - ;; - cray) - basic_machine=j90-cray - os=unicos - ;; - crds | unos) - basic_machine=m68k-crds - os= - ;; - da30) - basic_machine=m68k-da30 - os= - ;; - decstation | pmax | pmin | dec3100 | decstatn) - basic_machine=mips-dec - os= - ;; - delta88) - basic_machine=m88k-motorola - os=sysv3 - ;; - dicos) - basic_machine=i686-pc - os=dicos - ;; - djgpp) - basic_machine=i586-pc - os=msdosdjgpp - ;; - ebmon29k) - basic_machine=a29k-amd - os=ebmon - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=ose - ;; - gmicro) - basic_machine=tron-gmicro - os=sysv - ;; - go32) - basic_machine=i386-pc - os=go32 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=hms - ;; - harris) - basic_machine=m88k-harris - os=sysv3 - ;; - hp300) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=hpux - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=proelf - ;; - i386mach) - basic_machine=i386-mach - os=mach - ;; - vsta) - basic_machine=i386-pc - os=vsta - ;; - isi68 | isi) - basic_machine=m68k-isi - os=sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=linux - ;; - magnum | m3230) - basic_machine=mips-mips - os=sysv - ;; - merlin) - basic_machine=ns32k-utek - os=sysv - ;; - mingw64) - basic_machine=x86_64-pc - os=mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=mingw32ce - ;; - monitor) - basic_machine=m68k-rom68k - os=coff - ;; - morphos) - basic_machine=powerpc-unknown - os=morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=moxiebox - ;; - msdos) - basic_machine=i386-pc - os=msdos - ;; - msys) - basic_machine=i686-pc - os=msys - ;; - mvs) - basic_machine=i370-ibm - os=mvs - ;; - nacl) - basic_machine=le32-unknown - os=nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=sysv4 - ;; - netbsd386) - basic_machine=i386-pc - os=netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=newsos - ;; - news1000) - basic_machine=m68030-sony - os=newsos - ;; - necv70) - basic_machine=v70-nec - os=sysv - ;; - nh3000) - basic_machine=m68k-harris - os=cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=cxux - ;; - nindy960) - basic_machine=i960-intel - os=nindy - ;; - mon960) - basic_machine=i960-intel - os=mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=nonstopux - ;; - os400) - basic_machine=powerpc-ibm - os=os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=ose - ;; - os68k) - basic_machine=m68k-none - os=os68k - ;; - paragon) - basic_machine=i860-intel - os=osf - ;; - parisc) - basic_machine=hppa-unknown - os=linux - ;; - pw32) - basic_machine=i586-unknown - os=pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=rdos - ;; - rdos32) - basic_machine=i386-pc - os=rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=coff - ;; - sa29200) - basic_machine=a29k-amd - os=udi - ;; - sei) - basic_machine=mips-sei - os=seiux - ;; - sequent) - basic_machine=i386-sequent - os= - ;; - sps7) - basic_machine=m68k-bull - os=sysv2 - ;; - st2000) - basic_machine=m68k-tandem - os= - ;; - stratus) - basic_machine=i860-stratus - os=sysv4 - ;; - sun2) - basic_machine=m68000-sun - os= - ;; - sun2os3) - basic_machine=m68000-sun - os=sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=sunos4 - ;; - sun3) - basic_machine=m68k-sun - os= - ;; - sun3os3) - basic_machine=m68k-sun - os=sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=sunos4 - ;; - sun4) - basic_machine=sparc-sun - os= - ;; - sun4os3) - basic_machine=sparc-sun - os=sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=solaris2 - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - os= - ;; - sv1) - basic_machine=sv1-cray - os=unicos - ;; - symmetry) - basic_machine=i386-sequent - os=dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=unicos - ;; - t90) - basic_machine=t90-cray - os=unicos - ;; - toad1) - basic_machine=pdp10-xkl - os=tops20 - ;; - tpf) - basic_machine=s390x-ibm - os=tpf - ;; - udi29k) - basic_machine=a29k-amd - os=udi - ;; - ultra3) - basic_machine=a29k-nyu - os=sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=none - ;; - vaxv) - basic_machine=vax-dec - os=sysv - ;; - vms) - basic_machine=vax-dec - os=vms - ;; - vxworks960) - basic_machine=i960-wrs - os=vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=vxworks - ;; - xbox) - basic_machine=i686-pc - os=mingw32 - ;; - ymp) - basic_machine=ymp-cray - os=unicos - ;; - *) - basic_machine=$1 - os= - ;; - esac - ;; -esac - -# Decode 1-component or ad-hoc basic machines -case $basic_machine in - # Here we handle the default manufacturer of certain CPU types. It is in - # some cases the only manufacturer, in others, it is the most popular. - w89k) - cpu=hppa1.1 - vendor=winbond - ;; - op50n) - cpu=hppa1.1 - vendor=oki - ;; - op60c) - cpu=hppa1.1 - vendor=oki - ;; - ibm*) - cpu=i370 - vendor=ibm - ;; - orion105) - cpu=clipper - vendor=highlevel - ;; - mac | mpw | mac-mpw) - cpu=m68k - vendor=apple - ;; - pmac | pmac-mpw) - cpu=powerpc - vendor=apple - ;; - - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - cpu=m68000 - vendor=att - ;; - 3b*) - cpu=we32k - vendor=att - ;; - bluegene*) - cpu=powerpc - vendor=ibm - os=cnk - ;; - decsystem10* | dec10*) - cpu=pdp10 - vendor=dec - os=tops10 - ;; - decsystem20* | dec20*) - cpu=pdp10 - vendor=dec - os=tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - cpu=m68k - vendor=motorola - ;; - dpx2*) - cpu=m68k - vendor=bull - os=sysv3 - ;; - encore | umax | mmax) - cpu=ns32k - vendor=encore - ;; - elxsi) - cpu=elxsi - vendor=elxsi - os=${os:-bsd} - ;; - fx2800) - cpu=i860 - vendor=alliant - ;; - genix) - cpu=ns32k - vendor=ns - ;; - h3050r* | hiux*) - cpu=hppa1.1 - vendor=hitachi - os=hiuxwe2 - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - cpu=m68000 - vendor=hp - ;; - hp9k3[2-9][0-9]) - cpu=m68k - vendor=hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - cpu=hppa1.1 - vendor=hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - i*86v32) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - os=sysv32 - ;; - i*86v4*) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - os=sysv4 - ;; - i*86v) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - os=sysv - ;; - i*86sol2) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - os=solaris2 - ;; - j90 | j90-cray) - cpu=j90 - vendor=cray - os=${os:-unicos} - ;; - iris | iris4d) - cpu=mips - vendor=sgi - case $os in - irix*) - ;; - *) - os=irix4 - ;; - esac - ;; - miniframe) - cpu=m68000 - vendor=convergent - ;; - *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) - cpu=m68k - vendor=atari - os=mint - ;; - news-3600 | risc-news) - cpu=mips - vendor=sony - os=newsos - ;; - next | m*-next) - cpu=m68k - vendor=next - case $os in - openstep*) - ;; - nextstep*) - ;; - ns2*) - os=nextstep2 - ;; - *) - os=nextstep3 - ;; - esac - ;; - np1) - cpu=np1 - vendor=gould - ;; - op50n-* | op60c-*) - cpu=hppa1.1 - vendor=oki - os=proelf - ;; - pa-hitachi) - cpu=hppa1.1 - vendor=hitachi - os=hiuxwe2 - ;; - pbd) - cpu=sparc - vendor=tti - ;; - pbb) - cpu=m68k - vendor=tti - ;; - pc532) - cpu=ns32k - vendor=pc532 - ;; - pn) - cpu=pn - vendor=gould - ;; - power) - cpu=power - vendor=ibm - ;; - ps2) - cpu=i386 - vendor=ibm - ;; - rm[46]00) - cpu=mips - vendor=siemens - ;; - rtpc | rtpc-*) - cpu=romp - vendor=ibm - ;; - sde) - cpu=mipsisa32 - vendor=sde - os=${os:-elf} - ;; - simso-wrs) - cpu=sparclite - vendor=wrs - os=vxworks - ;; - tower | tower-32) - cpu=m68k - vendor=ncr - ;; - vpp*|vx|vx-*) - cpu=f301 - vendor=fujitsu - ;; - w65) - cpu=w65 - vendor=wdc - ;; - w89k-*) - cpu=hppa1.1 - vendor=winbond - os=proelf - ;; - none) - cpu=none - vendor=none - ;; - leon|leon[3-9]) - cpu=sparc - vendor=$basic_machine - ;; - leon-*|leon[3-9]-*) - cpu=sparc - vendor=`echo "$basic_machine" | sed 's/-.*//'` - ;; - - *-*) - # shellcheck disable=SC2162 - IFS="-" read cpu vendor <&2 - exit 1 - ;; - esac - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $vendor in - digital*) - vendor=dec - ;; - commodore*) - vendor=cbm - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x$os != x ] -then -case $os in - # First match some system type aliases that might get confused - # with valid system types. - # solaris* is a basic system type, with this one exception. - auroraux) - os=auroraux - ;; - bluegene*) - os=cnk - ;; - solaris1 | solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - solaris) - os=solaris2 - ;; - unixware*) - os=sysv4.2uw - ;; - gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # es1800 is here to avoid being matched by es* (a different OS) - es1800*) - os=ose - ;; - # Some version numbers need modification - chorusos*) - os=chorusos - ;; - isc) - os=isc2.2 - ;; - sco6) - os=sco5v6 - ;; - sco5) - os=sco3.2v5 - ;; - sco4) - os=sco3.2v4 - ;; - sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - ;; - sco3.2v[4-9]* | sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - ;; - scout) - # Don't match below - ;; - sco*) - os=sco3.2v2 - ;; - psos*) - os=psos - ;; - # Now accept the basic system types. - # The portable systems comes first. - # Each alternative MUST end in a * to match a version number. - # sysv* is not here because it comes later, after sysvr4. - gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ - | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ - | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ - | sym* | kopensolaris* | plan9* \ - | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ - | aos* | aros* | cloudabi* | sortix* \ - | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ - | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ - | knetbsd* | mirbsd* | netbsd* \ - | bitrig* | openbsd* | solidbsd* | libertybsd* \ - | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ - | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ - | chorusrdb* | cegcc* | glidix* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ - | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ - | linux-newlib* | linux-musl* | linux-uclibc* \ - | uxpv* | beos* | mpeix* | udk* | moxiebox* \ - | interix* | uwin* | mks* | rhapsody* | darwin* \ - | openstep* | oskit* | conix* | pw32* | nonstopux* \ - | storm-chaos* | tops10* | tenex* | tops20* | its* \ - | os2* | vos* | palmos* | uclinux* | nucleus* \ - | morphos* | superux* | rtmk* | windiss* \ - | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ - | skyos* | haiku* | rdos* | toppers* | drops* | es* \ - | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - qnx*) - case $cpu in - x86 | i*86) - ;; - *) - os=nto-$os - ;; - esac - ;; - hiux*) - os=hiuxwe2 - ;; - nto-qnx*) - ;; - nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - sim | xray | os68k* | v88r* \ - | windows* | osx | abug | netware* | os9* \ - | macos* | mpw* | magic* | mmixware* | mon960* | lnews*) - ;; - linux-dietlibc) - os=linux-dietlibc - ;; - linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - lynx*178) - os=lynxos178 - ;; - lynx*5) - os=lynxos5 - ;; - lynx*) - os=lynxos - ;; - mac*) - os=`echo "$os" | sed -e 's|mac|macos|'` - ;; - opened*) - os=openedition - ;; - os400*) - os=os400 - ;; - sunos5*) - os=`echo "$os" | sed -e 's|sunos5|solaris2|'` - ;; - sunos6*) - os=`echo "$os" | sed -e 's|sunos6|solaris3|'` - ;; - wince*) - os=wince - ;; - utek*) - os=bsd - ;; - dynix*) - os=bsd - ;; - acis*) - os=aos - ;; - atheos*) - os=atheos - ;; - syllable*) - os=syllable - ;; - 386bsd) - os=bsd - ;; - ctix* | uts*) - os=sysv - ;; - nova*) - os=rtmk-nova - ;; - ns2) - os=nextstep2 - ;; - nsk*) - os=nsk - ;; - # Preserve the version number of sinix5. - sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - sinix*) - os=sysv4 - ;; - tpf*) - os=tpf - ;; - triton*) - os=sysv3 - ;; - oss*) - os=sysv3 - ;; - svr4*) - os=sysv4 - ;; - svr3) - os=sysv3 - ;; - sysvr4) - os=sysv4 - ;; - # This must come after sysvr4. - sysv*) - ;; - ose*) - os=ose - ;; - *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) - os=mint - ;; - zvmoe) - os=zvmoe - ;; - dicos*) - os=dicos - ;; - pikeos*) - # Until real need of OS specific support for - # particular features comes up, bare metal - # configurations are quite functional. - case $cpu in - arm*) - os=eabi - ;; - *) - os=elf - ;; - esac - ;; - nacl*) - ;; - ios) - ;; - none) - ;; - *-eabi) - ;; - *) - echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $cpu-$vendor in - score-*) - os=elf - ;; - spu-*) - os=elf - ;; - *-acorn) - os=riscix1.2 - ;; - arm*-rebel) - os=linux - ;; - arm*-semi) - os=aout - ;; - c4x-* | tic4x-*) - os=coff - ;; - c8051-*) - os=elf - ;; - clipper-intergraph) - os=clix - ;; - hexagon-*) - os=elf - ;; - tic54x-*) - os=coff - ;; - tic55x-*) - os=coff - ;; - tic6x-*) - os=coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=tops20 - ;; - pdp11-*) - os=none - ;; - *-dec | vax-*) - os=ultrix4.2 - ;; - m68*-apollo) - os=domain - ;; - i386-sun) - os=sunos4.0.2 - ;; - m68000-sun) - os=sunos3 - ;; - m68*-cisco) - os=aout - ;; - mep-*) - os=elf - ;; - mips*-cisco) - os=elf - ;; - mips*-*) - os=elf - ;; - or32-*) - os=coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=sysv3 - ;; - sparc-* | *-sun) - os=sunos4.1.1 - ;; - pru-*) - os=elf - ;; - *-be) - os=beos - ;; - *-ibm) - os=aix - ;; - *-knuth) - os=mmixware - ;; - *-wec) - os=proelf - ;; - *-winbond) - os=proelf - ;; - *-oki) - os=proelf - ;; - *-hp) - os=hpux - ;; - *-hitachi) - os=hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=sysv - ;; - *-cbm) - os=amigaos - ;; - *-dg) - os=dgux - ;; - *-dolphin) - os=sysv3 - ;; - m68k-ccur) - os=rtu - ;; - m88k-omron*) - os=luna - ;; - *-next) - os=nextstep - ;; - *-sequent) - os=ptx - ;; - *-crds) - os=unos - ;; - *-ns) - os=genix - ;; - i370-*) - os=mvs - ;; - *-gould) - os=sysv - ;; - *-highlevel) - os=bsd - ;; - *-encore) - os=bsd - ;; - *-sgi) - os=irix - ;; - *-siemens) - os=sysv4 - ;; - *-masscomp) - os=rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=uxpv - ;; - *-rom68k) - os=coff - ;; - *-*bug) - os=coff - ;; - *-apple) - os=macos - ;; - *-atari*) - os=mint - ;; - *-wrs) - os=vxworks - ;; - *) - os=none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -case $vendor in - unknown) - case $os in - riscix*) - vendor=acorn - ;; - sunos*) - vendor=sun - ;; - cnk*|-aix*) - vendor=ibm - ;; - beos*) - vendor=be - ;; - hpux*) - vendor=hp - ;; - mpeix*) - vendor=hp - ;; - hiux*) - vendor=hitachi - ;; - unos*) - vendor=crds - ;; - dgux*) - vendor=dg - ;; - luna*) - vendor=omron - ;; - genix*) - vendor=ns - ;; - clix*) - vendor=intergraph - ;; - mvs* | opened*) - vendor=ibm - ;; - os400*) - vendor=ibm - ;; - ptx*) - vendor=sequent - ;; - tpf*) - vendor=ibm - ;; - vxsim* | vxworks* | windiss*) - vendor=wrs - ;; - aux*) - vendor=apple - ;; - hms*) - vendor=hitachi - ;; - mpw* | macos*) - vendor=apple - ;; - *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) - vendor=atari - ;; - vos*) - vendor=stratus - ;; - esac - ;; -esac - -echo "$cpu-$vendor-$os" -exit - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/configure.ac b/configure.ac deleted file mode 100644 index cd5702a338..0000000000 --- a/configure.ac +++ /dev/null @@ -1,811 +0,0 @@ -# -# The build process allows for using a cross-compiler. But the default -# action is to target the same platform that we are running on. The -# configure script needs to discover the following properties of the -# build and target systems: -# -# srcdir -# -# The is the name of the directory that contains the -# "configure" shell script. All source files are -# located relative to this directory. -# -# bindir -# -# The name of the directory where executables should be -# written by the "install" target of the makefile. -# -# program_prefix -# -# Add this prefix to the names of all executables that run -# on the target machine. Default: "" -# -# ENABLE_SHARED -# -# True if shared libraries should be generated. -# -# BUILD_CC -# -# The name of a command that is used to convert C -# source files into executables that run on the build -# platform. -# -# BUILD_CFLAGS -# -# Switches that the build compiler needs in order to construct -# command-line programs. -# -# BUILD_LIBS -# -# Libraries that the build compiler needs in order to construct -# command-line programs. -# -# BUILD_EXEEXT -# -# The filename extension for executables on the build -# platform. "" for Unix and ".exe" for Windows. -# -# TCL_* -# -# Lots of values are read in from the tclConfig.sh script, -# if that script is available. This values are used for -# constructing and installing the TCL extension. -# -# TARGET_READLINE_LIBS -# -# This is the library directives passed to the target linker -# that cause the executable to link against the readline library. -# This might be a switch like "-lreadline" or pathnames of library -# file like "../../src/libreadline.a". -# -# TARGET_READLINE_INC -# -# This variables define the directory that contain header -# files for the readline library. If the compiler is able -# to find on its own, then this can be blank. -# -# TARGET_EXEEXT -# -# The filename extension for executables on the -# target platform. "" for Unix and ".exe" for windows. -# -# This configure.in file is easy to reuse on other projects. Just -# change the argument to AC_INIT. And disable any features that -# you don't need (for example BLT) by erasing or commenting out -# the corresponding code. -# -AC_INIT([sqlite],m4_esyscmd(cat VERSION | tr -d '\n')) - -dnl Make sure the local VERSION file matches this configure script -sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'` -if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then -AC_MSG_ERROR([configure script is out of date: - configure \$PACKAGE_VERSION = $PACKAGE_VERSION - top level VERSION file = $sqlite_version_sanity_check -please regen with autoconf]) -fi - -######### -# Programs needed -# -LT_INIT -AC_PROG_INSTALL - -######### -# Enable large file support (if special flags are necessary) -# -AC_SYS_LARGEFILE - -######### -# Check for needed/wanted data types -AC_CHECK_TYPES([int8_t, int16_t, int32_t, int64_t, intptr_t, uint8_t, - uint16_t, uint32_t, uint64_t, uintptr_t]) - -######### -# Check for needed/wanted headers -AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h malloc.h]) - -######### -# Figure out whether or not we have these functions -# -AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64]) - -######### -# By default, we use the amalgamation (this may be changed below...) -# -USE_AMALGAMATION=1 - -######### -# Figure out all the name of a working tclsh and parameters needed to compile against Tcl. -# The --with-tcl= and/or --with-tclsh= configuration arguments might be useful for this. -# -AC_ARG_WITH(tclsh, - AS_HELP_STRING([--with-tclsh=PATHNAME],[full pathname of a tclsh to use])) -AC_ARG_WITH(tcl, - AS_HELP_STRING([--with-tcl=DIR],[directory containing (tclConfig.sh)])) -AC_ARG_ENABLE(tcl, - AS_HELP_STRING([--disable-tcl],[omit building accessory programs that require TCL-dev]), - [use_tcl=$enableval],[use_tcl=yes]) -original_use_tcl=${use_tcl} -if test x"${with_tclsh}" == x -a x"${with_tcl}" == x; then - AC_CHECK_PROGS(TCLSH_CMD, [tclsh9.0 tclsh8.6 tclsh],none) - with_tclsh=${TCLSH_CMD} -fi -if test x"${with_tclsh}" != x -a x"${with_tclsh}" != xnone; then - TCLSH_CMD=${with_tclsh} - AC_MSG_RESULT([using tclsh at "$TCLSH_CMD"]) - if test x"${use_tcl}" = "xyes"; then - with_tcl=`${with_tclsh} <${srcdir}/tool/find_tclconfig.tcl` - if test x"${with_tcl}" != x; then - AC_MSG_RESULT([$TCLSH_CMD recommends the tclConfig.sh at ${with_tcl}]) - else - AC_MSG_WARN([$TCLSH_CMD is unable to recommend a tclConfig.sh]) - use_tcl=no - fi - fi -fi -if test x"${use_tcl}" = "xyes"; then - if test x"${with_tcl}" != x; then - if test -r ${with_tcl}/tclConfig.sh; then - tclconfig="${with_tcl}/tclConfig.sh" - else - for i in tcl8.6 tcl9.0 lib; do - if test -r ${with_tcl}/$i/tclConfig.sh; then - tclconfig=${with_tcl}/$i/tclConfig.sh - break - fi - done - fi - if test ! -r "${tclconfig}"; then - AC_MSG_ERROR([no tclConfig.sh file found under ${with_tcl}]) - fi - else - # If we have not yet found a tclConfig.sh file, look in $libdir whic is - # set automatically by autoconf or by the --prefix command-line option. - # See https://sqlite.org/forum/forumpost/e04e693439a22457 - libdir=${prefix}/lib - if test -r ${libdir}/tclConfig.sh; then - tclconfig=${libdir}/tclConfig.sh - else - for i in tcl8.6 tcl9.0 lib; do - if test -r ${libdir}/$i/tclConfig.sh; then - tclconfig=${libdir}/$i/tclConfig.sh - break - fi - done - fi - if test ! -r "${tclconfig}"; then - AC_MSG_ERROR([cannot find a usable tclConfig.sh file. - Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. - SQLite does not use TCL internally, but TCL is required to build SQLite - from canonical sources and TCL is required for testing.]) - fi - fi - AC_MSG_RESULT([loading TCL configuration from ${tclconfig}]) - . ${tclconfig} - AC_SUBST(TCL_INCLUDE_SPEC) - AC_SUBST(TCL_LIB_SPEC) - AC_SUBST(TCL_STUB_LIB_SPEC) - # There are lots of other configuration variables that are provided by the - # tclConfig.sh file and that could be included here. But as of right now, - # TCL_LIB_SPEC is the only what that the Makefile uses. - HAVE_TCL=1 -elif test x"${original_use_tcl}" = "xno"; then - AC_MSG_RESULT([unable to run tests because of --disable-tcl]) - HAVE_TCL=0 -else - AC_MSG_RESULT([unable to run tests because no tclConfig.sh file could be located]) - HAVE_TCL=0 -fi -AC_SUBST(HAVE_TCL) -if test x"$TCLSH_CMD" == x; then - TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION} - if test ! -x ${TCLSH_CMD}; then - TCLSH_CMD_2=${TCL_EXEC_PREFIX}/bin/tclsh - if test ! -x ${TCLSH_CMD_2}; then - AC_MSG_WARN([cannot find a usable tclsh at either ${TCLSH_CMD} or ${TCLSH_CMD_2}]) - TCLSH_CMD=none - else - TCLSH_CMD=${TCLSH_CMD_2} - fi - fi -fi -if test "$TCLSH_CMD" = "none"; then - # If we can't find a local tclsh, then building the amalgamation will fail. - # We act as though --disable-amalgamation has been used. - AC_MSG_WARN([Warning: can't find tclsh - defaulting to non-amalgamation build.]) - USE_AMALGAMATION=0 - TCLSH_CMD="tclsh" -fi -AC_SUBST(TCLSH_CMD) - -AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin]) -if test "x${TCLLIBDIR+set}" != "xset" ; then - for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do - if test -d $i ; then - TCLLIBDIR=$i - break - fi - done - TCLLIBDIR="${TCLLIBDIR}/sqlite3" -fi - -######### -# Set up options for running tests. -# -AC_ARG_ENABLE(test-status, AS_HELP_STRING([--enable-test-status],[Full-screen status of tests]), - [use_vt100=$enableval],[use_vt100=no]) -if test $use_vt100 != no; then - TSTRNNR_OPTS=--status -else - TSTRNNR_OPTS= -fi -AC_SUBST(TSTRNNR_OPTS) - - -######### -# Set up an appropriate program prefix -# -if test "$program_prefix" = "NONE"; then - program_prefix="" -fi -AC_SUBST(program_prefix) - -VERSION=[`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'`] -AC_MSG_NOTICE(Version set to $VERSION) -AC_SUBST(VERSION) -RELEASE=`cat $srcdir/VERSION` -AC_MSG_NOTICE(Release set to $RELEASE) -AC_SUBST(RELEASE) - -########## -# Handle --with-wasi-sdk=DIR -# -# This must be early because it changes the toolchain. -# -AC_ARG_WITH(wasi-sdk, - AS_HELP_STRING([--with-wasi-sdk=DIR], - [directory containing the WASI SDK. Triggers cross-compile to WASM.]), with_wasisdk=${withval}) - AC_MSG_CHECKING([for WASI SDK directory]) - AC_CACHE_VAL(ac_cv_c_wasi_sdk,[ - # First check to see if --with-tcl was specified. - if test x"${with_wasi_sdk}" != x ; then - if ! test -d "${with_wasi_sdk}" ; then - AC_MSG_ERROR([${with_wasi_sdk} directory doesn't exist]) - fi - AC_MSG_RESULT([${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL]) - use_wasi_sdk=yes - else - use_wasi_sdk=no - fi - ]) -if test "${use_wasi_sdk}" = "no" ; then - HAVE_WASI_SDK="" - AC_MSG_RESULT([no]) -else - HAVE_WASI_SDK=1 -# Changing --host and --target have no effect here except to possibly -# cause confusion. autoconf has finished processing them by this -# point. -# -# host_alias=wasm32-wasi -# target=wasm32-wasi -# -# Merely changing CC and LD to the wasi-sdk's is enough to get -# sqlite3.o building in WASM format. - CC="${with_wasi_sdk}/bin/clang" - LD="${with_wasi_sdk}/bin/wasm-ld" - RANLIB="${with_wasi_sdk}/bin/llvm-ranlib" - cross_compiling=yes - enable_threadsafe=no - use_tcl=no - enable_tcl=no - # libtool is apparently hard-coded to use gcc for linking DLLs, so - # we disable the DLL build... - enable_shared=no - AC_MSG_RESULT([yes]) -fi -AC_SUBST(HAVE_WASI_SDK) - - -######### -# Locate a compiler for the build machine. This compiler should -# generate command-line programs that run on the build machine. -# -if test x"$cross_compiling" = xno; then - BUILD_CC=$CC - BUILD_CFLAGS=$CFLAGS -else - if test "${BUILD_CC+set}" != set; then - AC_CHECK_PROGS(BUILD_CC, gcc cc cl) - fi - if test "${BUILD_CFLAGS+set}" != set; then - BUILD_CFLAGS="-g" - fi -fi -AC_SUBST(BUILD_CC) - -########## -# Do we want to support multithreaded use of sqlite -# -AC_ARG_ENABLE(threadsafe, - AS_HELP_STRING([--disable-threadsafe],[Disable mutexing])) - AC_MSG_CHECKING([whether to support threadsafe operation]) - if test "$enable_threadsafe" = "no"; then - SQLITE_THREADSAFE=0 - AC_MSG_RESULT([no]) - else - SQLITE_THREADSAFE=1 - AC_MSG_RESULT([yes]) - fi -AC_SUBST(SQLITE_THREADSAFE) - -if test "$SQLITE_THREADSAFE" = "1"; then - AC_SEARCH_LIBS(pthread_create, pthread) - AC_SEARCH_LIBS(pthread_mutexattr_init, pthread) -fi - -########## -# Do we want to support release -# -AC_ARG_ENABLE(releasemode, - AS_HELP_STRING([--enable-releasemode],[Support libtool link to release mode]),,enable_releasemode=no) - AC_MSG_CHECKING([whether to support shared library linked as release mode or not]) - if test "$enable_releasemode" = "no"; then - ALLOWRELEASE="" - AC_MSG_RESULT([no]) - else - ALLOWRELEASE="-release `cat $srcdir/VERSION`" - AC_MSG_RESULT([yes]) - fi -AC_SUBST(ALLOWRELEASE) - -########## -# Do we want temporary databases in memory -# -AC_ARG_ENABLE(tempstore, - AS_HELP_STRING([--enable-tempstore],[Use an in-ram database for temporary tables (never,no,yes,always)]),,enable_tempstore=no) - AC_MSG_CHECKING([whether to use an in-ram database for temporary tables]) - case "$enable_tempstore" in - never ) - TEMP_STORE=0 - AC_MSG_RESULT([never]) - ;; - no ) - TEMP_STORE=1 - AC_MSG_RESULT([no]) - ;; - yes ) - TEMP_STORE=2 - AC_MSG_RESULT([yes]) - ;; - always ) - TEMP_STORE=3 - AC_MSG_RESULT([always]) - ;; - * ) - TEMP_STORE=1 - AC_MSG_RESULT([no]) - ;; - esac - -AC_SUBST(TEMP_STORE) - -########### -# Lots of things are different if we are compiling for Windows using -# the CYGWIN environment. So check for that special case and handle -# things accordingly. -# -AC_MSG_CHECKING([if executables have the .exe suffix]) -if test "$config_BUILD_EXEEXT" = ".exe"; then - CYGWIN=yes - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(unknown) -fi -if test "$CYGWIN" != "yes"; then - m4_warn([obsolete], -[AC_CYGWIN is obsolete: use AC_CANONICAL_HOST and check if $host_os -matches *cygwin*])dnl -AC_CANONICAL_HOST -case $host_os in - *cygwin* ) CYGWIN=yes;; - * ) CYGWIN=no;; -esac - -fi -if test "$CYGWIN" = "yes"; then - BUILD_EXEEXT=.exe -else - BUILD_EXEEXT=$EXEEXT -fi -if test x"$cross_compiling" = xno; then - TARGET_EXEEXT=$BUILD_EXEEXT -else - TARGET_EXEEXT=$config_TARGET_EXEEXT -fi -if test "$TARGET_EXEEXT" = ".exe"; then - SQLITE_OS_UNIX=0 - SQLITE_OS_WIN=1 - CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1" -else - SQLITE_OS_UNIX=1 - SQLITE_OS_WIN=0 - CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1" -fi - -AC_SUBST(BUILD_EXEEXT) -AC_SUBST(SQLITE_OS_UNIX) -AC_SUBST(SQLITE_OS_WIN) -AC_SUBST(TARGET_EXEEXT) - -########## -# Figure out what C libraries are required to compile programs -# that use "readline()" library. -# -TARGET_READLINE_LIBS="" -TARGET_READLINE_INC="" -TARGET_HAVE_READLINE=0 -TARGET_HAVE_EDITLINE=0 -AC_ARG_ENABLE([editline], - [AS_HELP_STRING([--enable-editline],[enable BSD editline support])], - [with_editline=$enableval], - [with_editline=auto]) -AC_ARG_ENABLE([readline], - [AS_HELP_STRING([--disable-readline],[disable readline support])], - [with_readline=$enableval], - [with_readline=auto]) - -if test x"$with_editline" != xno; then - sLIBS=$LIBS - LIBS="" - TARGET_HAVE_EDITLINE=1 - AC_SEARCH_LIBS(readline,edit,[with_readline=no],[TARGET_HAVE_EDITLINE=0]) - TARGET_READLINE_LIBS=$LIBS - LIBS=$sLIBS -fi -if test x"$with_readline" != xno; then - found="yes" - - AC_ARG_WITH([readline-lib], - [AS_HELP_STRING([--with-readline-lib],[specify readline library])], - [with_readline_lib=$withval], - [with_readline_lib="auto"]) - if test "x$with_readline_lib" = xauto; then - save_LIBS="$LIBS" - LIBS="" - AC_SEARCH_LIBS(tgetent, [readline ncurses curses termcap], [term_LIBS="$LIBS"], [term_LIBS=""]) - AC_CHECK_LIB([readline], [readline], [TARGET_READLINE_LIBS="-lreadline"], [found="no"]) - TARGET_READLINE_LIBS="$TARGET_READLINE_LIBS $term_LIBS" - LIBS="$save_LIBS" - else - TARGET_READLINE_LIBS="$with_readline_lib" - fi - - AC_ARG_WITH([readline-inc], - [AS_HELP_STRING([--with-readline-inc],[specify readline include paths])], - [with_readline_inc=$withval], - [with_readline_inc="auto"]) - if test "x$with_readline_inc" = xauto; then - AC_CHECK_HEADER(readline.h, [found="yes"], [ - found="no" - if test "$cross_compiling" != yes; then - for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do - for subdir in include include/readline; do - AC_CHECK_FILE($dir/$subdir/readline.h, found=yes) - if test "$found" = "yes"; then - TARGET_READLINE_INC="-I$dir/$subdir" - break - fi - done - test "$found" = "yes" && break - done - fi - ]) - else - TARGET_READLINE_INC="$with_readline_inc" - fi - - if test x"$found" = xno; then - TARGET_READLINE_LIBS="" - TARGET_READLINE_INC="" - TARGET_HAVE_READLINE=0 - else - TARGET_HAVE_READLINE=1 - fi -fi -AC_ARG_WITH([linenoise], - [AS_HELP_STRING([--with-linenoise=DIR],[source directory for linenoise library])], - [with_linenoise=$withval], - [with_linenoise="no"]) -if test "x$with_linenoise" != "xno"; then - TARGET_HAVE_READLINE=0 - TARGET_HAVE_EDITLINE=0 - TARGET_HAVE_LINENOISE=1 - TARGET_READLINE_INC="-I${with_linenoise}" - TARGET_READLINE_LIBS="${with_linenoise}/linenoise.c" - echo "using linenoise source code at ${with_linenoise}" -else - TARGET_HAVE_LINENOISE=0 - echo "not using linenoise" -fi - -AC_SUBST(TARGET_READLINE_LIBS) -AC_SUBST(TARGET_READLINE_INC) -AC_SUBST(TARGET_HAVE_READLINE) -AC_SUBST(TARGET_HAVE_EDITLINE) -AC_SUBST(TARGET_HAVE_LINENOISE) - - -########## -# Figure out what C libraries are required to compile programs -# that use "fdatasync()" function. -# -AC_SEARCH_LIBS(fdatasync, [rt]) - -######### -# check for debug enabled -AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],[enable debugging & verbose explain])) -AC_MSG_CHECKING([build type]) -if test "${enable_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall" - AC_MSG_RESULT([debug]) -else - TARGET_DEBUG="-DNDEBUG" - AC_MSG_RESULT([release]) -fi -AC_SUBST(TARGET_DEBUG) - -######### -# See whether we should use the amalgamation to build - -AC_ARG_ENABLE(amalgamation, AS_HELP_STRING([--disable-amalgamation], - [Disable the amalgamation and instead build all files separately])) -if test "${enable_amalgamation}" = "no" ; then - USE_AMALGAMATION=0 -fi -AC_SUBST(USE_AMALGAMATION) - -######### -# Look for zlib. Only needed by extensions and by the sqlite3.exe shell -AC_CHECK_HEADERS(zlib.h) -AC_SEARCH_LIBS(deflate, z, [HAVE_ZLIB="-DSQLITE_HAVE_ZLIB=1"], [HAVE_ZLIB=""]) -AC_SUBST(HAVE_ZLIB) - -######### -# See whether we should allow loadable extensions -AC_ARG_ENABLE(load-extension, AS_HELP_STRING([--disable-load-extension], - [Disable loading of external extensions]),,[enable_load_extension=yes]) -if test "${enable_load_extension}" = "yes" ; then - OPT_FEATURE_FLAGS="" - AC_SEARCH_LIBS(dlopen, dl) -else - OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" -fi - -########## -# Do we want to support math functions -# -AC_ARG_ENABLE(math, - AS_HELP_STRING([--disable-math],[Disable math functions])) - AC_MSG_CHECKING([whether to support math functions]) - if test "$enable_math" = "no"; then - AC_MSG_RESULT([no]) - else - AC_MSG_RESULT([yes]) - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" - AC_SEARCH_LIBS(ceil, m) - fi - -########## -# Do we want to support JSON functions -# -AC_ARG_ENABLE(json, - AS_HELP_STRING([--disable-json],[Disable JSON functions])) - AC_MSG_CHECKING([whether to support JSON functions]) - if test "$enable_json" = "no"; then - AC_MSG_RESULT([no]) - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON" - else - AC_MSG_RESULT([yes]) - fi - -######## -# The --enable-all argument is short-hand to enable -# multiple extensions. -AC_ARG_ENABLE(all, AS_HELP_STRING([--enable-all], - [Enable FTS4, FTS5, Geopoly, RTree, Sessions])) - -########## -# Do we want to support memsys3 and/or memsys5 -# -AC_ARG_ENABLE(memsys5, - AS_HELP_STRING([--enable-memsys5],[Enable MEMSYS5])) -AC_MSG_CHECKING([whether to support MEMSYS5]) - if test "${enable_memsys5}" = "yes"; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi -AC_ARG_ENABLE(memsys3, - AS_HELP_STRING([--enable-memsys3],[Enable MEMSYS3])) -AC_MSG_CHECKING([whether to support MEMSYS3]) -if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -######### -# See whether we should enable Full Text Search extensions -AC_ARG_ENABLE(fts3, AS_HELP_STRING([--enable-fts3], - [Enable the FTS3 extension])) -AC_MSG_CHECKING([whether to support FTS3]) -if test "${enable_fts3}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi -AC_ARG_ENABLE(fts4, AS_HELP_STRING([--enable-fts4], - [Enable the FTS4 extension])) -AC_MSG_CHECKING([whether to support FTS4]) -if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then - AC_MSG_RESULT([yes]) - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" - AC_SEARCH_LIBS([log],[m]) -else - AC_MSG_RESULT([no]) -fi -AC_ARG_ENABLE(fts5, AS_HELP_STRING([--enable-fts5], - [Enable the FTS5 extension])) -AC_MSG_CHECKING([whether to support FTS5]) -if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then - AC_MSG_RESULT([yes]) - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" - AC_SEARCH_LIBS([log],[m]) -else - AC_MSG_RESULT([no]) -fi - -######### -# See whether we should enable the LIMIT clause on UPDATE and DELETE -# statements. -AC_ARG_ENABLE(update-limit, AS_HELP_STRING([--enable-update-limit], - [Enable the UPDATE/DELETE LIMIT clause])) -AC_MSG_CHECKING([whether to support LIMIT on UPDATE and DELETE statements]) -if test "${enable_update_limit}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -######### -# See whether we should enable GEOPOLY -AC_ARG_ENABLE(geopoly, AS_HELP_STRING([--enable-geopoly], - [Enable the GEOPOLY extension]), - [enable_geopoly=yes],[enable_geopoly=no]) -AC_MSG_CHECKING([whether to support GEOPOLY]) -if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" - enable_rtree=yes - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -######### -# See whether we should enable RTREE -AC_ARG_ENABLE(rtree, AS_HELP_STRING([--enable-rtree], - [Enable the RTREE extension])) -AC_MSG_CHECKING([whether to support RTREE]) -if test "${enable_rtree}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -######### -# See whether we should enable the SESSION extension -AC_ARG_ENABLE(session, AS_HELP_STRING([--enable-session], - [Enable the SESSION extension])) -AC_MSG_CHECKING([whether to support SESSION]) -if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -######### -# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter -for option in $CFLAGS $CPPFLAGS -do - case $option in - -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; - -DSQLITE_ENABLE*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; - esac -done -AC_SUBST(OPT_FEATURE_FLAGS) - - -# attempt to remove any OMITS and ENABLES from the $(CFLAGS) parameter -ac_temp_CFLAGS="" -for option in $CFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_CFLAGS="$ac_temp_CFLAGS $option";; - esac -done -CFLAGS=$ac_temp_CFLAGS - - -# attempt to remove any OMITS and ENABLES from the $(CPPFLAGS) parameter -ac_temp_CPPFLAGS="" -for option in $CPPFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_CPPFLAGS="$ac_temp_CPPFLAGS $option";; - esac -done -CPPFLAGS=$ac_temp_CPPFLAGS - - -# attempt to remove any OMITS and ENABLES from the $(BUILD_CFLAGS) parameter -ac_temp_BUILD_CFLAGS="" -for option in $BUILD_CFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_BUILD_CFLAGS="$ac_temp_BUILD_CFLAGS $option";; - esac -done -BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS - - -######### -# See whether we should use GCOV -AC_ARG_ENABLE(gcov, AS_HELP_STRING([--enable-gcov], - [Enable coverage testing using gcov])) -if test "${use_gcov}" = "yes" ; then - USE_GCOV=1 -else - USE_GCOV=0 -fi -AC_SUBST(USE_GCOV) - -######### -# Enable/disabled amalagamation line macros -######## -AMALGAMATION_LINE_MACROS=--linemacros=0 -if test "${amalgamation_line_macros}" = "yes" ; then - AMALGAMATION_LINE_MACROS=--linemacros=1 -fi -if test "${amalgamation_line_macros}" = "no" ; then - AMALGAMATION_LINE_MACROS=--linemacros=0 -fi -AC_SUBST(AMALGAMATION_LINE_MACROS) - -######### -# Output the config header -AC_CONFIG_HEADERS(sqlite_cfg.h) - -######### -# Generate the output files. -# -AC_SUBST(BUILD_CFLAGS) -AC_CONFIG_FILES([ -Makefile -sqlite3.pc -]) -AC_OUTPUT diff --git a/manifest b/manifest index cd8eab4b02..a00f72d778 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\s#define\stypo\sin\sjimsh0.c,\seliminating\sthe\sneed\sto\sexplicitly\spass\s-DJIM_COMPAT\swhen\sbuilding\sit.\sThis\sfix\shas\ssince\smade\sits\sway\supstream. -D 2024-10-23T16:59:12.956 +C Remove\sthree\sautotools\sfiles\swhich\sare\snot\sneeded\sin\sthe\sautosetup\sport. +D 2024-10-23T17:17:16.909 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -54,10 +54,7 @@ F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 -F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 -F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x -F configure.ac 6bb3470ed862e753a5e6754cc0eea16e1de7e8c6aac458de1ee7706a8da26f19 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/compile-for-unix.md 343fe9334260d8695c36b465f55221f0187c8e7abaaa4d5afb4d564ed1d22dc1 @@ -2240,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ea6a14a6e64c0ed2306b9b3048132659094259b95b49a9572f7178c26b28f93a -R e5742b36efa53d07ed73d499dfe7e484 +P 9b105abf6fb6425d223ab9319f539b9d0cc2df488e0c23c5070853ba4778ebee +R a4fc809c2b2c79c9ce8c978dd80c3daf U stephan -Z ea44c0d193681b774d941092dfa1a741 +Z e02bc7521f8e43dac7bd77ae0772d8d9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ccd143cf05..393cd47b78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b105abf6fb6425d223ab9319f539b9d0cc2df488e0c23c5070853ba4778ebee +fc20861443ea52a058f556fdf1ddf03a41c538e3b97ff663833e422a50e38d66 From 6d288e240873350b4b7152fe6691d854b63425bb Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 23 Oct 2024 17:40:07 +0000 Subject: [PATCH 113/522] Remove unused configure check for clang-18. FossilOrigin-Name: d73ac7286aba8e8f9d1236dd06f6055bc3026879ff15efb151cc54175d02e315 --- auto.def | 5 ----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/auto.def b/auto.def index 51c5490147..73fe821554 100644 --- a/auto.def +++ b/auto.def @@ -658,11 +658,6 @@ unset cgtcl # /TCL ######################################################################## -######################################################################## -# Some of the fuzzer bits require clang -define BIN_CLANG [hwaci-first-bin-of clang-18] - - ######################################################################## # Thread safety? msg-checking "Support threadsafe operation? " diff --git a/manifest b/manifest index a00f72d778..91629ba3d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthree\sautotools\sfiles\swhich\sare\snot\sneeded\sin\sthe\sautosetup\sport. -D 2024-10-23T17:17:16.909 +C Remove\sunused\sconfigure\scheck\sfor\sclang-18. +D 2024-10-23T17:40:07.588 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -14,7 +14,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 1e8ae5762fc37fd33825879f177c78cde651946cfb0a41f274a677167cf16554 +F auto.def 8de3a05ba31af07e8b691a5fc10059ed1380e0e578fc0e177ce66c6bb07bb564 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9b105abf6fb6425d223ab9319f539b9d0cc2df488e0c23c5070853ba4778ebee -R a4fc809c2b2c79c9ce8c978dd80c3daf +P fc20861443ea52a058f556fdf1ddf03a41c538e3b97ff663833e422a50e38d66 +R 0c9ab7e3cdd99104e706a198b9770bd9 U stephan -Z e02bc7521f8e43dac7bd77ae0772d8d9 +Z 9a55931e4c5b4461e8bf3c9a7ff6ad60 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 393cd47b78..3ada8e263a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc20861443ea52a058f556fdf1ddf03a41c538e3b97ff663833e422a50e38d66 +d73ac7286aba8e8f9d1236dd06f6055bc3026879ff15efb151cc54175d02e315 From e615b73040c10f29a225980e2506398a33876bbd Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 00:02:44 +0000 Subject: [PATCH 114/522] Fix out-of-tree builds configured with --disable-amalgamation. FossilOrigin-Name: 182dac1c46f8ada2e1f3abd4959ac72f0ecfd451b41fbe699f5077f338ae7d62 --- Makefile.in | 2 + main.mk | 213 ++++++++++++++++++++++++++------------------------ manifest | 14 ++-- manifest.uuid | 2 +- 4 files changed, 119 insertions(+), 112 deletions(-) diff --git a/Makefile.in b/Makefile.in index f284b242a9..529da336b3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -159,7 +159,9 @@ $(JIMSH): $(TOP)/autosetup/jimsh0.c BTCLSH = @BTCLSH@ $(BTCLSH): +# # $(CFLAGS_libsqlite3) is documented in main.mk. +# CFLAGS_libsqlite3 = -DSQLITE_TEMP_STORE=@TEMP_STORE@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) diff --git a/main.mk b/main.mk index a700538127..59db681c9e 100644 --- a/main.mk +++ b/main.mk @@ -226,6 +226,11 @@ CFLAGS_intree_includes = \ -I$(TOP)/ext/misc -I$(TOP)/ext/userauth TCCX += $(CFLAGS_intree_includes) +# +# $(TCC_EXT) = compiler invocation for loadable extensions. +# +TCC_EXT = $(TCOMPILE) -I. -I$(TOP)/src -DSQLITE_CORE + # # $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for # compiling the library's own sources, including (sometimes) when @@ -835,255 +840,255 @@ sqlite3ext.h: .target_source # opcodes.o # parse.o: parse.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c parse.c + $(TCCX) $(CFLAGS_libsqlite3) -c parse.c opcodes.o: opcodes.c - $(TCOMPILE) $(CFLAGS_libsqlite3) -c opcodes.c + $(TCCX) $(CFLAGS_libsqlite3) -c opcodes.c # Rules to build individual *.o files from files in the src directory. # alter.o: $(TOP)/src/alter.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/alter.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/alter.c analyze.o: $(TOP)/src/analyze.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/analyze.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/analyze.c attach.o: $(TOP)/src/attach.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/attach.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/attach.c auth.o: $(TOP)/src/auth.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/auth.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/auth.c backup.o: $(TOP)/src/backup.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/backup.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/backup.c bitvec.o: $(TOP)/src/bitvec.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/bitvec.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/bitvec.c btmutex.o: $(TOP)/src/btmutex.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/btmutex.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/btmutex.c btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/btree.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/btree.c build.o: $(TOP)/src/build.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/build.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/build.c callback.o: $(TOP)/src/callback.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/callback.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/callback.c complete.o: $(TOP)/src/complete.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/complete.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/complete.c ctime.o: $(TOP)/src/ctime.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/ctime.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/ctime.c date.o: $(TOP)/src/date.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/date.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/date.c dbpage.o: $(TOP)/src/dbpage.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbpage.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbpage.c dbstat.o: $(TOP)/src/dbstat.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbstat.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbstat.c delete.o: $(TOP)/src/delete.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/delete.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/delete.c expr.o: $(TOP)/src/expr.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/expr.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/expr.c fault.o: $(TOP)/src/fault.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/fault.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/fault.c fkey.o: $(TOP)/src/fkey.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/fkey.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/fkey.c func.o: $(TOP)/src/func.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/func.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/func.c global.o: $(TOP)/src/global.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/global.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/global.c hash.o: $(TOP)/src/hash.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/hash.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/insert.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/insert.c json.o: $(TOP)/src/json.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/json.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/json.c legacy.o: $(TOP)/src/legacy.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/legacy.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/legacy.c loadext.o: $(TOP)/src/loadext.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/loadext.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/loadext.c main.o: $(TOP)/src/main.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/main.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/main.c malloc.o: $(TOP)/src/malloc.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/malloc.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/malloc.c mem0.o: $(TOP)/src/mem0.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem0.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem0.c mem1.o: $(TOP)/src/mem1.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem1.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem1.c mem2.o: $(TOP)/src/mem2.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem2.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem2.c mem3.o: $(TOP)/src/mem3.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem3.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem3.c mem5.o: $(TOP)/src/mem5.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem5.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem5.c memdb.o: $(TOP)/src/memdb.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/memdb.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/memdb.c memjournal.o: $(TOP)/src/memjournal.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/memjournal.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/memjournal.c mutex.o: $(TOP)/src/mutex.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex.c mutex_noop.o: $(TOP)/src/mutex_noop.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_noop.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_noop.c mutex_unix.o: $(TOP)/src/mutex_unix.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_unix.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_unix.c mutex_w32.o: $(TOP)/src/mutex_w32.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_w32.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_w32.c notify.o: $(TOP)/src/notify.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/notify.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/notify.c pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/pager.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/pager.c pcache.o: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache.c pcache1.o: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache1.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache1.c os.o: $(TOP)/src/os.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/os.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/os.c os_kv.o: $(TOP)/src/os_kv.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_kv.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_kv.c os_unix.o: $(TOP)/src/os_unix.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_unix.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_unix.c os_win.o: $(TOP)/src/os_win.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_win.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_win.c pragma.o: $(TOP)/src/pragma.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/pragma.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/pragma.c prepare.o: $(TOP)/src/prepare.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/prepare.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/prepare.c printf.o: $(TOP)/src/printf.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/printf.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/printf.c random.o: $(TOP)/src/random.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/random.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/random.c resolve.o: $(TOP)/src/resolve.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/resolve.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/resolve.c rowset.o: $(TOP)/src/rowset.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/rowset.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/rowset.c select.o: $(TOP)/src/select.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/select.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/select.c status.o: $(TOP)/src/status.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/status.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/status.c sqlite3.o: sqlite3.h sqlite3.c - $(TCOMPILE) $(CFLAGS_libsqlite3) -c sqlite3.c + $(TCCX) $(CFLAGS_libsqlite3) -c sqlite3.c table.o: $(TOP)/src/table.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/table.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/table.c threads.o: $(TOP)/src/threads.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/threads.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/threads.c tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/tokenize.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/tokenize.c treeview.o: $(TOP)/src/treeview.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/treeview.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/treeview.c trigger.o: $(TOP)/src/trigger.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/trigger.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/trigger.c update.o: $(TOP)/src/update.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/update.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/update.c upsert.o: $(TOP)/src/upsert.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/upsert.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/upsert.c utf.o: $(TOP)/src/utf.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/utf.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/utf.c util.o: $(TOP)/src/util.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/util.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/util.c vacuum.o: $(TOP)/src/vacuum.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vacuum.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vacuum.c vdbe.o: $(TOP)/src/vdbe.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbe.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbe.c vdbeapi.o: $(TOP)/src/vdbeapi.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeapi.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeapi.c vdbeaux.o: $(TOP)/src/vdbeaux.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeaux.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeaux.c vdbeblob.o: $(TOP)/src/vdbeblob.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeblob.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeblob.c vdbemem.o: $(TOP)/src/vdbemem.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbemem.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbemem.c vdbesort.o: $(TOP)/src/vdbesort.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbesort.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbesort.c vdbetrace.o: $(TOP)/src/vdbetrace.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbetrace.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbetrace.c vdbevtab.o: $(TOP)/src/vdbevtab.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbevtab.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbevtab.c vtab.o: $(TOP)/src/vtab.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/vtab.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vtab.c wal.o: $(TOP)/src/wal.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/wal.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/wal.c walker.o: $(TOP)/src/walker.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/walker.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/walker.c where.o: $(TOP)/src/where.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/where.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/where.c wherecode.o: $(TOP)/src/wherecode.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/wherecode.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/wherecode.c whereexpr.o: $(TOP)/src/whereexpr.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/whereexpr.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/whereexpr.c window.o: $(TOP)/src/window.c $(HDR) - $(TCOMPILE) $(CFLAGS_libsqlite3) -c $(TOP)/src/window.c + $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/window.c tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS_intree_includes) \ @@ -1278,10 +1283,10 @@ fts5.c: $(FTS5_SRC) $(BTCLSH) # has_tclsh84 cp $(TOP)/ext/fts5/fts5.h . fts5.o: fts5.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c fts5.c + $(TCC_EXT) -c fts5.c sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c + $(TCC_EXT) -c $(TOP)/ext/rbu/sqlite3rbu.c # @@ -1808,58 +1813,58 @@ shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCLSH) # has_tclsh84 # Rules to build the extension objects. # icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c + $(TCC_EXT) -c $(TOP)/ext/icu/icu.c fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3.c fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_aux.c fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_expr.c fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_hash.c fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_icu.c fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_porter.c fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_snippet.c fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_tokenizer.c fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_tokenizer1.c fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_unicode.c fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_unicode2.c fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c + $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_write.c rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c + $(TCC_EXT) -c $(TOP)/ext/rtree/rtree.c userauth.o: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c + $(TCC_EXT) -c $(TOP)/ext/userauth/userauth.c sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c + $(TCC_EXT) -c $(TOP)/ext/session/sqlite3session.c stmt.o: $(TOP)/ext/misc/stmt.c - $(TCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c + $(TCC_EXT) -c $(TOP)/ext/misc/stmt.c # # tool/version-info: a utility for emitting sqlite3 version info @@ -1895,7 +1900,7 @@ tidy: rm -f lemon$(BEXE) sqlite*.tar.gz rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) rm -f parse.* fts5parse.* - rm -f $(libsqlite3.SO) $(libsqlite3.LIB) + rm -f $(libsqlite3.SO) $(libsqlite3.LIB) $(libtclsqlite3.SO) rm -f tclsqlite3$(TEXE) $(TESTPROGS) rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) diff --git a/manifest b/manifest index 91629ba3d1..f94d2c1c1b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Remove\sunused\sconfigure\scheck\sfor\sclang-18. -D 2024-10-23T17:40:07.588 +C Fix\sout-of-tree\sbuilds\sconfigured\swith\s--disable-amalgamation. +D 2024-10-24T00:02:44.736 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 2543a2bc53ef627ec0cf45a41ad14f571b5a3bff0049d84a390c5183455c6a09 +F Makefile.in c26ffc3c7ddc87640e5a511bf9bc327c8752638f505ce81cd2e8de4601c4b44c F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -708,7 +708,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 25ec1fb7641de775c2ebc89f25fbb0ad9910bdadaa623d0d0273a6802e3fde39 +F main.mk 2f1961b82b66dc53ade0745967e279d7afe88024a54981b066dd906ffb18dfb9 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fc20861443ea52a058f556fdf1ddf03a41c538e3b97ff663833e422a50e38d66 -R 0c9ab7e3cdd99104e706a198b9770bd9 +P d73ac7286aba8e8f9d1236dd06f6055bc3026879ff15efb151cc54175d02e315 +R bcb1899a7d5c22323efb7aa674de32c5 U stephan -Z 9a55931e4c5b4461e8bf3c9a7ff6ad60 +Z 732b1afd3b16514e16edefcfd886b58a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3ada8e263a..6e1282c617 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d73ac7286aba8e8f9d1236dd06f6055bc3026879ff15efb151cc54175d02e315 +182dac1c46f8ada2e1f3abd4959ac72f0ecfd451b41fbe699f5077f338ae7d62 From 4dadb531b0c726d98f86f8957061e1d92fb35455 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 01:26:50 +0000 Subject: [PATCH 115/522] Rename some build vars for legibility. Fix hwaci-make-from-dot-in when the input file list is multi-line. FossilOrigin-Name: fdb584421578cae825365d457cd533721839e3503f3744c77832c5925815b537 --- Makefile.in | 10 +- autosetup/hwaci-common.tcl | 1 + main.mk | 256 +++++++++++++++++++------------------ manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 146 insertions(+), 139 deletions(-) diff --git a/Makefile.in b/Makefile.in index 529da336b3..cd92c822ce 100644 --- a/Makefile.in +++ b/Makefile.in @@ -100,13 +100,15 @@ CFLAGS_READLINE = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ ENABLE_SHARED = @ENABLE_SHARED@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ -TCCX = $(TCC) @TARGET_DEBUG@ -# Define this for the autoconf-based build, so that the code knows it +TCC.sqlite = $(TCC) @TARGET_DEBUG@ + +# +# Define -D_HAVE_SQLITE_CONFIG_H so that the code knows it # can include the generated sqlite_cfg.h. # -TCCX += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite +TCC.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # -# main.mk will fill out TCCX with some flags common to all builds. +# main.mk will fill out TCC.sqlite with some flags common to all builds. #XX#CFLAGS_READLINE += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ #XX#CFLAGS_READLINE += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index d2974591b0..602c32660d 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -439,6 +439,7 @@ proc hwaci-make-from-dot-in {args} { set filename [lrange $args 1 end] } foreach f $filename { + set f [string trim $f] catch { exec chmod u+w $f } make-template $f.in $f if {$touch} { diff --git a/main.mk b/main.mk index 59db681c9e..630bb40b4f 100644 --- a/main.mk +++ b/main.mk @@ -5,10 +5,11 @@ # a higher-level makefile which configures any dynamic state needed by # this one. # -# Maintenance reminder: this file must remain devoid of GNU Make-isms. -# i.e. it must be POSIX Make compatible. "bmake" (BSD make) is -# available on most Linux systems, so compatibility is relatively easy -# to test. +# Maintenance reminders: +# +# - This file must remain devoid of GNU Make-isms. i.e. it must be +# POSIX Make compatible. "bmake" (BSD make) is available on most +# Linux systems, so compatibility is relatively easy to test. # #XX# Lines starting with #XX# are TODOs for the port to autosetup # @@ -198,23 +199,14 @@ INSTALL_noexec = $(INSTALL) -m 0644 # $(TCOMPILE_EXTRAS) = config-specific flags for $(TCOMPILE) # TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) -# -# $(TLINK) = compiler invocation for when the target will be an executable -# $(TLINK_EXTRAS) = config-specific flags for $(TLINK) -# -TLINK = $(TCCX) $(TLINK_EXTRAS) -# -# $(TLINK_shared) = $(TLINK) invocation specifically for shared libraries -# -TLINK_shared = $(TLINK) $(LDFLAGS_SHOBJ) # -# $(TCCX) is $(TCC) plus any flags which are desired for the library +# $(TCC.sqlite) is $(TCC) plus any flags which are desired for the library # as a whole, but not necessarily needed for every binary. It will # normally get initially populated by the configure-generated # makefile, so should not be overwritten here. # -TCCX ?= $(TCC) +TCC.sqlite ?= $(TCC) # # $(CFLAGS_intree_includes) = -I... flags relevant specifically to # this tree, including any subdirectories commonly needed for building @@ -224,12 +216,24 @@ CFLAGS_intree_includes = \ -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \ -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session \ -I$(TOP)/ext/misc -I$(TOP)/ext/userauth -TCCX += $(CFLAGS_intree_includes) +TCC.sqlite += $(CFLAGS_intree_includes) # -# $(TCC_EXT) = compiler invocation for loadable extensions. +# $(TCC.extension) = compiler invocation for loadable extensions. +# +TCC.extension = $(TCOMPILE) -I. -I$(TOP)/src -DSQLITE_CORE + +# +# $(TLINK) = compiler invocation for when the target will be an +# executable. +# +# $(TLINK_EXTRAS) = config-specific flags for $(TLINK) +# +TLINK = $(TCC.sqlite) $(TLINK_EXTRAS) +# +# $(TLINK.shared) = $(TLINK) invocation specifically for shared libraries # -TCC_EXT = $(TCOMPILE) -I. -I$(TOP)/src -DSQLITE_CORE +TLINK.shared = $(TLINK) $(LDFLAGS_SHOBJ) # # $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for @@ -249,7 +253,7 @@ CFLAGS_libsqlite3 ?= -DSQLITE_TEMP_STORE=1 # results in building libsqlite3.so, compiles sqlite3.c directly, or # links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these # flags are for the target build platform, not necessarily localhost. -# i.e. it should be used with $(TCCX) or $(TLINK) but not $(BCC). +# i.e. it should be used with $(TCC.sqlite) or $(TLINK) but not $(BCC). # LDFLAGS_libsqlite3 = \ $(LDFLAGS_RPATH) $(LDFLAGS_PTHREAD) \ @@ -840,255 +844,255 @@ sqlite3ext.h: .target_source # opcodes.o # parse.o: parse.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c parse.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c parse.c opcodes.o: opcodes.c - $(TCCX) $(CFLAGS_libsqlite3) -c opcodes.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c opcodes.c # Rules to build individual *.o files from files in the src directory. # alter.o: $(TOP)/src/alter.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/alter.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/alter.c analyze.o: $(TOP)/src/analyze.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/analyze.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/analyze.c attach.o: $(TOP)/src/attach.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/attach.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/attach.c auth.o: $(TOP)/src/auth.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/auth.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/auth.c backup.o: $(TOP)/src/backup.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/backup.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/backup.c bitvec.o: $(TOP)/src/bitvec.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/bitvec.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/bitvec.c btmutex.o: $(TOP)/src/btmutex.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/btmutex.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/btmutex.c btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/btree.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/btree.c build.o: $(TOP)/src/build.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/build.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/build.c callback.o: $(TOP)/src/callback.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/callback.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/callback.c complete.o: $(TOP)/src/complete.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/complete.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/complete.c ctime.o: $(TOP)/src/ctime.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/ctime.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/ctime.c date.o: $(TOP)/src/date.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/date.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/date.c dbpage.o: $(TOP)/src/dbpage.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbpage.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbpage.c dbstat.o: $(TOP)/src/dbstat.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbstat.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbstat.c delete.o: $(TOP)/src/delete.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/delete.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/delete.c expr.o: $(TOP)/src/expr.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/expr.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/expr.c fault.o: $(TOP)/src/fault.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/fault.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/fault.c fkey.o: $(TOP)/src/fkey.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/fkey.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/fkey.c func.o: $(TOP)/src/func.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/func.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/func.c global.o: $(TOP)/src/global.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/global.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/global.c hash.o: $(TOP)/src/hash.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/hash.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/insert.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/insert.c json.o: $(TOP)/src/json.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/json.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/json.c legacy.o: $(TOP)/src/legacy.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/legacy.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/legacy.c loadext.o: $(TOP)/src/loadext.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/loadext.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/loadext.c main.o: $(TOP)/src/main.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/main.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/main.c malloc.o: $(TOP)/src/malloc.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/malloc.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/malloc.c mem0.o: $(TOP)/src/mem0.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem0.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem0.c mem1.o: $(TOP)/src/mem1.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem1.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem1.c mem2.o: $(TOP)/src/mem2.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem2.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem2.c mem3.o: $(TOP)/src/mem3.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem3.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem3.c mem5.o: $(TOP)/src/mem5.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem5.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem5.c memdb.o: $(TOP)/src/memdb.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/memdb.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/memdb.c memjournal.o: $(TOP)/src/memjournal.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/memjournal.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/memjournal.c mutex.o: $(TOP)/src/mutex.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex.c mutex_noop.o: $(TOP)/src/mutex_noop.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_noop.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_noop.c mutex_unix.o: $(TOP)/src/mutex_unix.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_unix.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_unix.c mutex_w32.o: $(TOP)/src/mutex_w32.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_w32.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_w32.c notify.o: $(TOP)/src/notify.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/notify.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/notify.c pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/pager.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pager.c pcache.o: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache.c pcache1.o: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache1.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache1.c os.o: $(TOP)/src/os.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/os.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os.c os_kv.o: $(TOP)/src/os_kv.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_kv.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_kv.c os_unix.o: $(TOP)/src/os_unix.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_unix.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_unix.c os_win.o: $(TOP)/src/os_win.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_win.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_win.c pragma.o: $(TOP)/src/pragma.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/pragma.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pragma.c prepare.o: $(TOP)/src/prepare.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/prepare.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/prepare.c printf.o: $(TOP)/src/printf.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/printf.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/printf.c random.o: $(TOP)/src/random.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/random.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/random.c resolve.o: $(TOP)/src/resolve.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/resolve.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/resolve.c rowset.o: $(TOP)/src/rowset.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/rowset.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/rowset.c select.o: $(TOP)/src/select.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/select.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/select.c status.o: $(TOP)/src/status.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/status.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/status.c sqlite3.o: sqlite3.h sqlite3.c - $(TCCX) $(CFLAGS_libsqlite3) -c sqlite3.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c sqlite3.c table.o: $(TOP)/src/table.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/table.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/table.c threads.o: $(TOP)/src/threads.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/threads.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/threads.c tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/tokenize.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/tokenize.c treeview.o: $(TOP)/src/treeview.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/treeview.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/treeview.c trigger.o: $(TOP)/src/trigger.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/trigger.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/trigger.c update.o: $(TOP)/src/update.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/update.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/update.c upsert.o: $(TOP)/src/upsert.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/upsert.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/upsert.c utf.o: $(TOP)/src/utf.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/utf.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/utf.c util.o: $(TOP)/src/util.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/util.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/util.c vacuum.o: $(TOP)/src/vacuum.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vacuum.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vacuum.c vdbe.o: $(TOP)/src/vdbe.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbe.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbe.c vdbeapi.o: $(TOP)/src/vdbeapi.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeapi.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeapi.c vdbeaux.o: $(TOP)/src/vdbeaux.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeaux.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeaux.c vdbeblob.o: $(TOP)/src/vdbeblob.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeblob.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeblob.c vdbemem.o: $(TOP)/src/vdbemem.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbemem.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbemem.c vdbesort.o: $(TOP)/src/vdbesort.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbesort.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbesort.c vdbetrace.o: $(TOP)/src/vdbetrace.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbetrace.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbetrace.c vdbevtab.o: $(TOP)/src/vdbevtab.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbevtab.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbevtab.c vtab.o: $(TOP)/src/vtab.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/vtab.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vtab.c wal.o: $(TOP)/src/wal.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/wal.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/wal.c walker.o: $(TOP)/src/walker.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/walker.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/walker.c where.o: $(TOP)/src/where.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/where.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/where.c wherecode.o: $(TOP)/src/wherecode.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/wherecode.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/wherecode.c whereexpr.o: $(TOP)/src/whereexpr.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/whereexpr.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/whereexpr.c window.o: $(TOP)/src/window.c $(HDR) - $(TCCX) $(CFLAGS_libsqlite3) -c $(TOP)/src/window.c + $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/window.c tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS_intree_includes) \ @@ -1150,7 +1154,7 @@ all: lib # Dynamic libsqlite3 # $(libsqlite3.SO): $(LIBOBJ) - $(TLINK_shared) -o $@ $(LIBOBJ) $(LDFLAGS_libsqlite3) + $(TLINK.shared) -o $@ $(LIBOBJ) $(LDFLAGS_libsqlite3) $(libsqlite3.SO)-1: $(libsqlite3.SO) $(libsqlite3.SO)-0 $(libsqlite3.SO)-: so: $(libsqlite3.SO)-$(ENABLE_SHARED) @@ -1199,7 +1203,7 @@ pkgIndex.tcl: echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(TDLL) $(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) - $(TLINK_shared) -o $@ tclsqlite.o \ + $(TLINK.shared) -o $@ tclsqlite.o \ $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS_libsqlite3) \ $(libsqlite3.LIB) $(TCLLIB_RPATH) $(libtclsqlite3.SO)-1: $(libtclsqlite3.SO) @@ -1283,10 +1287,10 @@ fts5.c: $(FTS5_SRC) $(BTCLSH) # has_tclsh84 cp $(TOP)/ext/fts5/fts5.h . fts5.o: fts5.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c fts5.c + $(TCC.extension) -c fts5.c sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/rbu/sqlite3rbu.c + $(TCC.extension) -c $(TOP)/ext/rbu/sqlite3rbu.c # @@ -1646,7 +1650,7 @@ RSYNC_OPT = \ -DSQLITE_OMIT_DEPRECATED sqlite3_rsync$(TEXE): $(RSYNC_SRC) - $(TCCX) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) + $(TCC.sqlite) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) xbin: sqlite3_rsync$(TEXE) install-rsync: sqlite3_rsync$(TEXE) $(install-dir.bin) @@ -1813,58 +1817,58 @@ shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCLSH) # has_tclsh84 # Rules to build the extension objects. # icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/icu/icu.c + $(TCC.extension) -c $(TOP)/ext/icu/icu.c fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3.c fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_aux.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_aux.c fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_expr.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_expr.c fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_hash.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_hash.c fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_icu.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_icu.c fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_porter.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_porter.c fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_snippet.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_snippet.c fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_tokenizer.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenizer.c fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_tokenizer1.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenizer1.c fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_unicode.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_unicode.c fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_unicode2.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_unicode2.c fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/fts3/fts3_write.c + $(TCC.extension) -c $(TOP)/ext/fts3/fts3_write.c rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/rtree/rtree.c + $(TCC.extension) -c $(TOP)/ext/rtree/rtree.c userauth.o: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/userauth/userauth.c + $(TCC.extension) -c $(TOP)/ext/userauth/userauth.c sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) - $(TCC_EXT) -c $(TOP)/ext/session/sqlite3session.c + $(TCC.extension) -c $(TOP)/ext/session/sqlite3session.c stmt.o: $(TOP)/ext/misc/stmt.c - $(TCC_EXT) -c $(TOP)/ext/misc/stmt.c + $(TCC.extension) -c $(TOP)/ext/misc/stmt.c # # tool/version-info: a utility for emitting sqlite3 version info @@ -1883,7 +1887,7 @@ sqlite3.def: $(LIBOBJ) | sed 's/^.* _//' >>sqlite3.def sqlite3.dll: $(LIBOBJ) sqlite3.def - $(TCCX) $(LDFLAGS_SHOBJ) -o $@ sqlite3.def \ + $(TCC.sqlite) $(LDFLAGS_SHOBJ) -o $@ sqlite3.def \ -Wl,"--strip-all" $(LIBOBJ) diff --git a/manifest b/manifest index f94d2c1c1b..3653671844 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sout-of-tree\sbuilds\sconfigured\swith\s--disable-amalgamation. -D 2024-10-24T00:02:44.736 +C Rename\ssome\sbuild\svars\sfor\slegibility.\sFix\shwaci-make-from-dot-in\swhen\sthe\sinput\sfile\slist\sis\smulti-line. +D 2024-10-24T01:26:50.001 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in c26ffc3c7ddc87640e5a511bf9bc327c8752638f505ce81cd2e8de4601c4b44c +F Makefile.in 4b18845678335be6e56dbe6257a8a777d416ead26c72dd71a08b0bb1a0d59575 F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -48,7 +48,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 3e9ae4dbdda198e5dea56e2bdf0a073f2acf60f76e83dc3ee25a00390d3f6bc7 +F autosetup/hwaci-common.tcl 3513a7dbe685d4776e70d23fa41d6695098627ca063245cac163f8ed3dc696f9 F autosetup/jimsh0.c 838968b1159a6061452d751a48df3646830b04b118e35790da97e998208bc5ae F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -708,7 +708,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 2f1961b82b66dc53ade0745967e279d7afe88024a54981b066dd906ffb18dfb9 +F main.mk 244408dfbc1891f8a2dae883e07953218370007fcd20db49ec6f00cf6b3e3913 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d73ac7286aba8e8f9d1236dd06f6055bc3026879ff15efb151cc54175d02e315 -R bcb1899a7d5c22323efb7aa674de32c5 +P 182dac1c46f8ada2e1f3abd4959ac72f0ecfd451b41fbe699f5077f338ae7d62 +R 243b1b295b7d39496ee8f02f5822532a U stephan -Z 732b1afd3b16514e16edefcfd886b58a +Z 76aba5b639a66a5a98cbfb78d58f5288 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6e1282c617..6583cc4626 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -182dac1c46f8ada2e1f3abd4959ac72f0ecfd451b41fbe699f5077f338ae7d62 +fdb584421578cae825365d457cd533721839e3503f3744c77832c5925815b537 From 8c97ad883474a49375dea14b51397a143202a806 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 03:14:40 +0000 Subject: [PATCH 116/522] General make cleanups. Start adding a sanity-check mechanism to main.mk which does basic validation of the vars it expects to be set by the file which includes it. Get Makefile.linux-gcc working for the core-most rules. FossilOrigin-Name: 85b2c73ccb85d7f5830a6fac692b380c5c79e7a54ee3fc6fc37343fa23816ef8 --- Makefile.in | 9 +- Makefile.linux-gcc | 94 +- aclocal.m4 | 7972 -------------------------------------------- main.mk | 283 +- manifest | 17 +- manifest.uuid | 2 +- 6 files changed, 177 insertions(+), 8200 deletions(-) delete mode 100644 aclocal.m4 diff --git a/Makefile.in b/Makefile.in index cd92c822ce..2439480888 100644 --- a/Makefile.in +++ b/Makefile.in @@ -164,7 +164,7 @@ $(BTCLSH): # # $(CFLAGS_libsqlite3) is documented in main.mk. # -CFLAGS_libsqlite3 = -DSQLITE_TEMP_STORE=@TEMP_STORE@ +CFLAGS_libsqlite3 = $(CFLAGS) -DSQLITE_TEMP_STORE=@TEMP_STORE@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) @@ -332,4 +332,11 @@ distclean-autosetup: clean -gmake -C ext/wasm distclean 2>/dev/null; true distclean: distclean-autosetup +# +# tool/version-info: a utility for emitting sqlite3 version info +# in various forms. +# +version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h + $(TLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c + include $(TOP)/main.mk diff --git a/Makefile.linux-gcc b/Makefile.linux-gcc index fe7349ad46..b89f69efbe 100644 --- a/Makefile.linux-gcc +++ b/Makefile.linux-gcc @@ -10,100 +10,16 @@ # alternative. Create a copy of this file, edit the parameters # below and type "make". # - #### The toplevel directory of the source tree. This is the directory # that contains this "Makefile.in" and the "configure.in" script. # -TOP = ../sqlite - -#### C Compiler and options for use in building executables that -# will run on the platform that is doing the build. -# -BCC = gcc -g -O0 -#BCC = /opt/ancic/bin/c89 -0 - -#### If you want the SQLite library to be safe for use within a -# multi-threaded program, then define the following macro -# appropriately: -# -#THREADSAFE = -DTHREADSAFE=1 -THREADSAFE = -DTHREADSAFE=0 - -#### Specify any extra linker options needed to make the library -# thread safe -# -THREADLIB = -lpthread -lm -ldl -#THREADLIB = +TOP ?= . -#### Specify any extra libraries needed to access required functions. -# -#TLIBS = -lrt # fdatasync on Solaris 8 -TLIBS = - -#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1 -# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all -# malloc()s and free()s in order to track down memory leaks. -# -# SQLite uses some expensive assert() statements in the inner loop. -# You can make the library go almost twice as fast if you compile -# with -DNDEBUG=1 -# -OPTS += -DSQLITE_DEBUG=1 -OPTS += -DSQLITE_ENABLE_WHERETRACE -OPTS += -DSQLITE_ENABLE_SELECTTRACE - -#### The suffix to add to executable files. ".exe" for windows. -# Nothing for unix. -# -#EXE = .exe -EXE = - -#### C Compile and options for use in building executables that -# will run on the target platform. This is usually the same -# as BCC, unless you are cross-compiling. -# -TCC = gcc -O0 -#TCC = gcc -g -O0 -Wall -#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage -#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6 -#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive - -#### Tools used to build a static library. -# -AR = ar cr -#AR = /opt/mingw/bin/i386-mingw32-ar cr -RANLIB = ranlib -#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib - -MKSHLIB = gcc -shared -SO = so -SHPREFIX = lib -# SO = dll -# SHPREFIX = - -#### Extra compiler options needed for programs that use the TCL library. -# -TCL_FLAGS = -I/home/drh/tcl/include/tcl8.6 - -#### Linker options needed to link against the TCL library. -# -#LIBTCL = -ltcl -lm -ldl -LIBTCL = /home/drh/tcl/lib/libtcl8.6.a -lm -lpthread -ldl -lz - -#### Additional objects for SQLite library when TCL support is enabled. -#TCLOBJ = -TCLOBJ = tclsqlite.o - -#### Compiler options needed for programs that use the readline() library. -# -READLINE_FLAGS = -#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline - -#### Linker options needed by programs using readline() must link against. -# -LIBREADLINE = -#LIBREADLINE = -static -lreadline -ltermcap +CFLAGS += -fPIC # You should not have to change anything below this line ############################################################################### include $(TOP)/main.mk + +sqlite_cfg.h: + touch $@ diff --git a/aclocal.m4 b/aclocal.m4 deleted file mode 100644 index 8e5151ebad..0000000000 --- a/aclocal.m4 +++ /dev/null @@ -1,7972 +0,0 @@ -# generated automatically by aclocal 1.10.2 -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 56 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl -_LT_PROG_ECHO_BACKSLASH - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Fix-up fallback echo if it was mangled by the above quoting rules. -case \$lt_ECHO in -*'\\\[$]0 --fallback-echo"')dnl " - lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` - ;; -esac - -_LT_OUTPUT_LIBTOOL_INIT -]) - - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -cat >"$CONFIG_LT" <<_LTEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate a libtool stub with the current configuration. - -lt_cl_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AS_SHELL_SANITIZE -_AS_PREPARE - -exec AS_MESSAGE_FD>&1 -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2008 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -if test "$no_create" != yes; then - lt_cl_success=: - test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" - exec AS_MESSAGE_LOG_FD>/dev/null - $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false - exec AS_MESSAGE_LOG_FD>>config.log - $lt_cl_success || AS_EXIT(1) -fi -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_XSI_SHELLFNS - - sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES -# -------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=echo - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX -# ----------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi],[]) -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[ifdef([AC_DIVERSION_NOTICE], - [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -$1 -AC_DIVERT_POP -])# _LT_SHELL_INIT - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn't interpret backslashes. -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[_LT_SHELL_INIT([ -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$lt_ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -ECHO=${lt_ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then - # Yippee, $ECHO works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat <<_LT_EOF -[$]* -_LT_EOF - exit 0 -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test -z "$lt_ECHO"; then - if test "X${echo_test_string+set}" != Xset; then - # find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if { echo_test_string=`eval $cmd`; } 2>/dev/null && - { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null - then - break - fi - done - fi - - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : - else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$ECHO" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - ECHO='print -r' - elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - ECHO='printf %s\n' - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - ECHO="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - ECHO=echo - fi - fi - fi - fi - fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -lt_ECHO=$ECHO -if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(lt_ECHO) -]) -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], - [An echo program that does not interpret backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[AC_CHECK_TOOL(AR, ar, false) -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1]) - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ - = "XX$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line __oline__ "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` - else - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[123]]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - # Handle Gentoo/FreeBSD as it was Linux - case $host_vendor in - gentoo) - version_type=linux ;; - *) - version_type=freebsd-$objformat ;; - esac - - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - linux) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - need_lib_prefix=no - need_version=no - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -interix[[3-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # Some binutils ld are patched to set DT_RUNPATH - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method == "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -AC_MSG_CHECKING([for $compiler option to produce PIC]) -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC*) - # IBM XL 8.0 on PPC - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd*) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl*) - # IBM XL C 8.0/Fortran 10.1 on PPC - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Sun\ F*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac -AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag= - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE(int foo(void) {}, - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - ) - LDFLAGS="$save_LDFLAGS" - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], - [[If ld is used when linking, flag to hardcode $libdir into a binary - during linking. This must work even if $libdir does not exist]]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [fix_srcfile_path], [1], - [Fix the shell variable $srcfile for the compiler]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_PROG_CXX -# ------------ -# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ -# compiler, we have our own version here. -m4_defun([_LT_PROG_CXX], -[ -pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) -AC_PROG_CXX -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_CXX - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_CXX], []) - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[AC_REQUIRE([_LT_PROG_CXX])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd[[12]]*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 will use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - xl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=echo - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -]) -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case $p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - else - prev= - fi - - if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - ;; - - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_PROG_F77 -# ------------ -# Since AC_PROG_F77 is broken, in that it returns the empty string -# if there is no fortran compiler, we have our own version here. -m4_defun([_LT_PROG_F77], -[ -pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) -AC_PROG_F77 -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_F77 - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_F77], []) - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_REQUIRE([_LT_PROG_F77])dnl -AC_LANG_PUSH(Fortran 77) - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - CC=${F77-"f77"} - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_PROG_FC -# ----------- -# Since AC_PROG_FC is broken, in that it returns the empty string -# if there is no fortran compiler, we have our own version here. -m4_defun([_LT_PROG_FC], -[ -pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) -AC_PROG_FC -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_FC - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_FC], []) - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_REQUIRE([_LT_PROG_FC])dnl -AC_LANG_PUSH(Fortran) - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - CC=${FC-"f95"} - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC="$lt_save_CC" -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC="$lt_save_CC" -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_XSI_SHELLFNS -# --------------------- -# Bourne and XSI compatible variants of some useful shell functions. -m4_defun([_LT_PROG_XSI_SHELLFNS], -[case $xsi_shell in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac -} - -# func_basename file -func_basename () -{ - func_basename_result="${1##*/}" -} - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}" -} - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -func_stripname () -{ - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"} -} - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=${1%%=*} - func_opt_split_arg=${1#*=} -} - -# func_lo2o object -func_lo2o () -{ - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=${1%.*}.lo -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=$(( $[*] )) -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=${#1} -} - -_LT_EOF - ;; - *) # Bourne compatible functions. - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` -} - -dnl func_dirname_and_basename -dnl A portable version of this function is already defined in general.m4sh -dnl so there is no need for it here. - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; - esac -} - -# sed scripts: -my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' -my_sed_long_arg='1s/^-[[^=]]*=//' - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` - func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` -} - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "$[@]"` -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` -} - -_LT_EOF -esac - -case $lt_shell_append in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]+=\$[2]" -} -_LT_EOF - ;; - *) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]=\$$[1]\$[2]" -} - -_LT_EOF - ;; - esac -]) - -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - ]) -])# _LT_SET_OPTIONS - - - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [0], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' -# LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) - -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) - -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# Generated from ltversion.in. - -# serial 3012 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.2.6]) -m4_define([LT_PACKAGE_REVISION], [1.3012]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.2.6' -macro_revision='1.3012' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) - -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 4 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) - diff --git a/main.mk b/main.mk index 630bb40b4f..cd18b3cc3d 100644 --- a/main.mk +++ b/main.mk @@ -27,7 +27,8 @@ RELEASE ?= MAJOR.MINOR.PATCH # # The toplevel directory of the source tree. For canonical builds # this is the directory that contains this "Makefile.in" and the -# "configure.in" script. +# "configure.in" script. For out-of-tree builds, this will differ +# from $(PWD). TOP ?= $(PWD) # # $(BCC) = @@ -46,7 +47,8 @@ BCC ?= $(CC) TCC ?= $(BCC) # # $(AR) = -# Tool used to build a static library from object files. +# Tool used to build a static library from object files, including +# its arguments needed for doing so. # AR ?= ar # @@ -191,7 +193,7 @@ all: sqlite3.h sqlite3.c # # $(INSTALL) invocation for use with non-executable files. # -INSTALL_noexec = $(INSTALL) -m 0644 +INSTALL.noexec = $(INSTALL) -m 0644 # ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... # @@ -246,7 +248,7 @@ TLINK.shared = $(TLINK) $(LDFLAGS_SHOBJ) # to default to file, 2 to default to memory, and 3 to force temporary # tables to always be in memory. # -CFLAGS_libsqlite3 ?= -DSQLITE_TEMP_STORE=1 +CFLAGS_libsqlite3 ?= $(CFLAGS) -DSQLITE_TEMP_STORE=1 # # LDFLAGS_libsqlite3 should be used with any target which either @@ -261,7 +263,7 @@ LDFLAGS_libsqlite3 = \ $(LDFLAGS_DLOPEN) # -# install-dir.XYZ = dirs for installation. +# $(install-dir.XYZ) = dirs for installation. # # Design note: these should arguably all be defined with surrounding # double-quotes so that targets which have spaces in their paths will @@ -282,6 +284,28 @@ install-dir.all = $(install-dir.bin) $(install-dir.include) \ $(install-dir.all): $(INSTALL) -d $@ +# +# $(MAKE_SANITY_CHECK) = a set of checks for various make vars which +# must be provided to this file before including it. If any are +# missing, this target fails. It does (almost) no semantic validation, +# only checks to see that appropriate vars are not empty. +# +# Note that $(MAKEFILE_LIST) is a GNU-make-ism but its use is harmless +# in other flavors of Make. +# +MAKE_SANITY_CHECK = .main.mk.checks +$(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) + @if [ x = "x$(TOP)" ]; then echo "Missing TOP var" 1>&2; exit 1; fi + @if [ ! -d "$(TOP)" ]; then echo "TOP is not a directory" 1>&2; exit 1; fi + @if [ x = "x$(BCC)" ]; then echo "Missing BCC var" 1>&2; exit 1; fi + @if [ x = "x$(TCC)" ]; then echo "Missing TCC var" 1>&2; exit 1; fi + @if [ x = "x$(RELEASE)" ]; then echo "Missing RELEASE var" 1>&2; exit 1; fi + @if [ x = "x$(BTCLSH)" ]; then echo "Missing BTCLSH var" 1>&2; exit 1; fi + touch $@ +clean-sanity-check: + rm -f $(MAKE_SANITY_CHECK) +clean: clean-sanity-check + # # Object files for the SQLite library (non-amalgamation). # @@ -320,6 +344,8 @@ LIBOBJS1 = sqlite3.o # LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) +$(LIBOBJ): $(MAKE_SANITY_CHECK) + # All of the source code files. # SRC = \ @@ -769,7 +795,7 @@ FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c DBFUZZ_OPT = ST_OPT = -DSQLITE_OS_KV_OPTIONAL - +$(TCLSH_CMD): has_tclsh84: sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) touch has_tclsh84 @@ -791,7 +817,8 @@ has_tclconfig: # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c $(BTCLSH) # has_tclsh84 +.target_source: $(MAKE_SANITY_CHECK) $(SRC) $(TOP)/tool/vdbe-compress.tcl \ + fts5.c $(BTCLSH) # has_tclsh84 rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc @@ -806,16 +833,17 @@ libsqlite3.SO = libsqlite3$(TDLL) # Rules to build the LEMON compiler generator # -lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c +lemon$(BEXE): $(MAKE_SANITY_CHECK) $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o $@ $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . # Rules to build the program that generates the source-id # -mksourceid$(BEXE): $(TOP)/tool/mksourceid.c +mksourceid$(BEXE): $(MAKE_SANITY_CHECK) $(TOP)/tool/mksourceid.c $(BCC) -o $@ $(TOP)/tool/mksourceid.c -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) \ +sqlite3.h: $(MAKE_SANITY_CHECK) $(TOP)/src/sqlite.h.in \ + $(TOP)/manifest mksourceid$(BEXE) \ $(TOP)/VERSION $(BTCLSH) # has_tclsh84 $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h @@ -834,7 +862,7 @@ sqlite3r.c: sqlite3.c sqlite3r.h $(BTCLSH) # has_tclsh84 cp $(TOP)/ext/recover/dbdata.c tsrc/ $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) -sqlite3ext.h: .target_source +sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . # Rules to build individual *.o files from generated *.c files. This @@ -843,7 +871,8 @@ sqlite3ext.h: .target_source # parse.o # opcodes.o # -parse.o: parse.c $(HDR) +DEPS_OBJ_COMMON = $(MAKE_SANITY_CHECK) $(HDR) +parse.o: parse.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c parse.c opcodes.o: opcodes.c @@ -851,257 +880,257 @@ opcodes.o: opcodes.c # Rules to build individual *.o files from files in the src directory. # -alter.o: $(TOP)/src/alter.c $(HDR) +alter.o: $(TOP)/src/alter.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/alter.c -analyze.o: $(TOP)/src/analyze.c $(HDR) +analyze.o: $(TOP)/src/analyze.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/analyze.c -attach.o: $(TOP)/src/attach.c $(HDR) +attach.o: $(TOP)/src/attach.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/attach.c -auth.o: $(TOP)/src/auth.c $(HDR) +auth.o: $(TOP)/src/auth.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/auth.c -backup.o: $(TOP)/src/backup.c $(HDR) +backup.o: $(TOP)/src/backup.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/backup.c -bitvec.o: $(TOP)/src/bitvec.c $(HDR) +bitvec.o: $(TOP)/src/bitvec.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/bitvec.c -btmutex.o: $(TOP)/src/btmutex.c $(HDR) +btmutex.o: $(TOP)/src/btmutex.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/btmutex.c -btree.o: $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h +btree.o: $(TOP)/src/btree.c $(DEPS_OBJ_COMMON) $(TOP)/src/pager.h $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/btree.c -build.o: $(TOP)/src/build.c $(HDR) +build.o: $(TOP)/src/build.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/build.c -callback.o: $(TOP)/src/callback.c $(HDR) +callback.o: $(TOP)/src/callback.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/callback.c -complete.o: $(TOP)/src/complete.c $(HDR) +complete.o: $(TOP)/src/complete.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/complete.c -ctime.o: $(TOP)/src/ctime.c $(HDR) +ctime.o: $(TOP)/src/ctime.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/ctime.c -date.o: $(TOP)/src/date.c $(HDR) +date.o: $(TOP)/src/date.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/date.c -dbpage.o: $(TOP)/src/dbpage.c $(HDR) +dbpage.o: $(TOP)/src/dbpage.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbpage.c -dbstat.o: $(TOP)/src/dbstat.c $(HDR) +dbstat.o: $(TOP)/src/dbstat.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbstat.c -delete.o: $(TOP)/src/delete.c $(HDR) +delete.o: $(TOP)/src/delete.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/delete.c -expr.o: $(TOP)/src/expr.c $(HDR) +expr.o: $(TOP)/src/expr.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/expr.c -fault.o: $(TOP)/src/fault.c $(HDR) +fault.o: $(TOP)/src/fault.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/fault.c -fkey.o: $(TOP)/src/fkey.c $(HDR) +fkey.o: $(TOP)/src/fkey.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/fkey.c -func.o: $(TOP)/src/func.c $(HDR) +func.o: $(TOP)/src/func.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/func.c -global.o: $(TOP)/src/global.c $(HDR) +global.o: $(TOP)/src/global.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/global.c -hash.o: $(TOP)/src/hash.c $(HDR) +hash.o: $(TOP)/src/hash.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/hash.c -insert.o: $(TOP)/src/insert.c $(HDR) +insert.o: $(TOP)/src/insert.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/insert.c -json.o: $(TOP)/src/json.c $(HDR) +json.o: $(TOP)/src/json.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/json.c -legacy.o: $(TOP)/src/legacy.c $(HDR) +legacy.o: $(TOP)/src/legacy.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/legacy.c -loadext.o: $(TOP)/src/loadext.c $(HDR) +loadext.o: $(TOP)/src/loadext.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/loadext.c -main.o: $(TOP)/src/main.c $(HDR) +main.o: $(TOP)/src/main.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/main.c -malloc.o: $(TOP)/src/malloc.c $(HDR) +malloc.o: $(TOP)/src/malloc.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/malloc.c -mem0.o: $(TOP)/src/mem0.c $(HDR) +mem0.o: $(TOP)/src/mem0.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem0.c -mem1.o: $(TOP)/src/mem1.c $(HDR) +mem1.o: $(TOP)/src/mem1.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem1.c -mem2.o: $(TOP)/src/mem2.c $(HDR) +mem2.o: $(TOP)/src/mem2.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem2.c -mem3.o: $(TOP)/src/mem3.c $(HDR) +mem3.o: $(TOP)/src/mem3.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem3.c -mem5.o: $(TOP)/src/mem5.c $(HDR) +mem5.o: $(TOP)/src/mem5.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem5.c -memdb.o: $(TOP)/src/memdb.c $(HDR) +memdb.o: $(TOP)/src/memdb.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/memdb.c -memjournal.o: $(TOP)/src/memjournal.c $(HDR) +memjournal.o: $(TOP)/src/memjournal.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/memjournal.c -mutex.o: $(TOP)/src/mutex.c $(HDR) +mutex.o: $(TOP)/src/mutex.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex.c -mutex_noop.o: $(TOP)/src/mutex_noop.c $(HDR) +mutex_noop.o: $(TOP)/src/mutex_noop.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_noop.c -mutex_unix.o: $(TOP)/src/mutex_unix.c $(HDR) +mutex_unix.o: $(TOP)/src/mutex_unix.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_unix.c -mutex_w32.o: $(TOP)/src/mutex_w32.c $(HDR) +mutex_w32.o: $(TOP)/src/mutex_w32.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_w32.c -notify.o: $(TOP)/src/notify.c $(HDR) +notify.o: $(TOP)/src/notify.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/notify.c -pager.o: $(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h +pager.o: $(TOP)/src/pager.c $(DEPS_OBJ_COMMON) $(TOP)/src/pager.h $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pager.c -pcache.o: $(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h +pcache.o: $(TOP)/src/pcache.c $(DEPS_OBJ_COMMON) $(TOP)/src/pcache.h $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache.c -pcache1.o: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h +pcache1.o: $(TOP)/src/pcache1.c $(DEPS_OBJ_COMMON) $(TOP)/src/pcache.h $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache1.c -os.o: $(TOP)/src/os.c $(HDR) +os.o: $(TOP)/src/os.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os.c -os_kv.o: $(TOP)/src/os_kv.c $(HDR) +os_kv.o: $(TOP)/src/os_kv.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_kv.c -os_unix.o: $(TOP)/src/os_unix.c $(HDR) +os_unix.o: $(TOP)/src/os_unix.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_unix.c -os_win.o: $(TOP)/src/os_win.c $(HDR) +os_win.o: $(TOP)/src/os_win.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_win.c -pragma.o: $(TOP)/src/pragma.c $(HDR) +pragma.o: $(TOP)/src/pragma.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pragma.c -prepare.o: $(TOP)/src/prepare.c $(HDR) +prepare.o: $(TOP)/src/prepare.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/prepare.c -printf.o: $(TOP)/src/printf.c $(HDR) +printf.o: $(TOP)/src/printf.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/printf.c -random.o: $(TOP)/src/random.c $(HDR) +random.o: $(TOP)/src/random.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/random.c -resolve.o: $(TOP)/src/resolve.c $(HDR) +resolve.o: $(TOP)/src/resolve.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/resolve.c -rowset.o: $(TOP)/src/rowset.c $(HDR) +rowset.o: $(TOP)/src/rowset.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/rowset.c -select.o: $(TOP)/src/select.c $(HDR) +select.o: $(TOP)/src/select.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/select.c -status.o: $(TOP)/src/status.c $(HDR) +status.o: $(TOP)/src/status.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/status.c sqlite3.o: sqlite3.h sqlite3.c $(TCC.sqlite) $(CFLAGS_libsqlite3) -c sqlite3.c -table.o: $(TOP)/src/table.c $(HDR) +table.o: $(TOP)/src/table.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/table.c -threads.o: $(TOP)/src/threads.c $(HDR) +threads.o: $(TOP)/src/threads.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/threads.c -tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) +tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/tokenize.c -treeview.o: $(TOP)/src/treeview.c $(HDR) +treeview.o: $(TOP)/src/treeview.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/treeview.c -trigger.o: $(TOP)/src/trigger.c $(HDR) +trigger.o: $(TOP)/src/trigger.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/trigger.c -update.o: $(TOP)/src/update.c $(HDR) +update.o: $(TOP)/src/update.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/update.c -upsert.o: $(TOP)/src/upsert.c $(HDR) +upsert.o: $(TOP)/src/upsert.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/upsert.c -utf.o: $(TOP)/src/utf.c $(HDR) +utf.o: $(TOP)/src/utf.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/utf.c -util.o: $(TOP)/src/util.c $(HDR) +util.o: $(TOP)/src/util.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/util.c -vacuum.o: $(TOP)/src/vacuum.c $(HDR) +vacuum.o: $(TOP)/src/vacuum.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vacuum.c -vdbe.o: $(TOP)/src/vdbe.c $(HDR) +vdbe.o: $(TOP)/src/vdbe.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbe.c -vdbeapi.o: $(TOP)/src/vdbeapi.c $(HDR) +vdbeapi.o: $(TOP)/src/vdbeapi.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeapi.c -vdbeaux.o: $(TOP)/src/vdbeaux.c $(HDR) +vdbeaux.o: $(TOP)/src/vdbeaux.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeaux.c -vdbeblob.o: $(TOP)/src/vdbeblob.c $(HDR) +vdbeblob.o: $(TOP)/src/vdbeblob.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeblob.c -vdbemem.o: $(TOP)/src/vdbemem.c $(HDR) +vdbemem.o: $(TOP)/src/vdbemem.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbemem.c -vdbesort.o: $(TOP)/src/vdbesort.c $(HDR) +vdbesort.o: $(TOP)/src/vdbesort.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbesort.c -vdbetrace.o: $(TOP)/src/vdbetrace.c $(HDR) +vdbetrace.o: $(TOP)/src/vdbetrace.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbetrace.c -vdbevtab.o: $(TOP)/src/vdbevtab.c $(HDR) +vdbevtab.o: $(TOP)/src/vdbevtab.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbevtab.c -vtab.o: $(TOP)/src/vtab.c $(HDR) +vtab.o: $(TOP)/src/vtab.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vtab.c -wal.o: $(TOP)/src/wal.c $(HDR) +wal.o: $(TOP)/src/wal.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/wal.c -walker.o: $(TOP)/src/walker.c $(HDR) +walker.o: $(TOP)/src/walker.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/walker.c -where.o: $(TOP)/src/where.c $(HDR) +where.o: $(TOP)/src/where.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/where.c -wherecode.o: $(TOP)/src/wherecode.c $(HDR) +wherecode.o: $(TOP)/src/wherecode.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/wherecode.c -whereexpr.o: $(TOP)/src/whereexpr.c $(HDR) +whereexpr.o: $(TOP)/src/whereexpr.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/whereexpr.c -window.o: $(TOP)/src/window.c $(HDR) +window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON) $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/window.c -tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) +tclsqlite.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS_intree_includes) \ -c $(TOP)/src/tclsqlite.c -tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(HDR) +tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) $(TCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) -tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(HDR) +tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) $(TCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) @@ -1186,14 +1215,14 @@ install: install-so-$(ENABLE_SHARED) # Install $(libsqlite3.LIB) # install-lib: $(install-dir.lib) $(libsqlite3.LIB) - $(INSTALL_noexec) $(libsqlite3.LIB) $(install-dir.lib) + $(INSTALL.noexec) $(libsqlite3.LIB) $(install-dir.lib) install: install-lib # # Install C header files # install-includes: sqlite3.h $(install-dir.include) - $(INSTALL_noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install-dir.include) + $(INSTALL.noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install-dir.include) install: install-includes # @@ -1216,7 +1245,7 @@ install-tcl-1: install-lib $(libtclsqlite3.SO) pkgIndex.tcl @if [ "x$(DESTDIR)" = "x$(install.tcldir)" ]; then echo "TCLLIBDIR is not set." 1>&2; exit 1; fi $(INSTALL) -d $(install.tcldir) $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) - $(INSTALL_noexec) pkgIndex.tcl $(install.tcldir) + $(INSTALL.noexec) pkgIndex.tcl $(install.tcldir) install-tcl-0 install-tcl-: install: install-tcl-$(HAVE_TCL) @@ -1286,10 +1315,10 @@ fts5.c: $(FTS5_SRC) $(BTCLSH) # has_tclsh84 $(BTCLSH) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . -fts5.o: fts5.c $(HDR) $(EXTHDR) +fts5.o: fts5.c $(DEPS_OBJ_COMMON) $(EXTHDR) $(TCC.extension) -c fts5.c -sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR) +sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(DEPS_OBJ_COMMON) $(EXTHDR) $(TCC.extension) -c $(TOP)/ext/rbu/sqlite3rbu.c @@ -1658,14 +1687,14 @@ install-rsync: sqlite3_rsync$(TEXE) $(install-dir.bin) #install: install-rsync install-man1: $(install-dir.man1) - $(INSTALL_noexec) $(TOP)/sqlite3.1 $(install-dir.man1) + $(INSTALL.noexec) $(TOP)/sqlite3.1 $(install-dir.man1) install: install-man1 # # sqlite3.pc is typically generated by the configure script but could # conceivably be generated by hand. install-pc: sqlite3.pc $(install-dir.pkgconfig) - $(INSTALL_noexec) sqlite3.pc $(install-dir.pkgconfig) + $(INSTALL.noexec) sqlite3.pc $(install-dir.pkgconfig) scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ @@ -1816,67 +1845,61 @@ shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCLSH) # has_tclsh84 # # Rules to build the extension objects. # -icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR) +DEPS_EXT_COMMON = $(DEPS_OBJ_COMMON) $(EXTHDR) +icu.o: $(TOP)/ext/icu/icu.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/icu/icu.c -fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR) +fts3.o: $(TOP)/ext/fts3/fts3.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3.c -fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR) +fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_aux.c -fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR) +fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_expr.c -fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR) +fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_hash.c -fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR) +fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_icu.c -fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR) +fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_porter.c -fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR) +fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_snippet.c -fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR) +fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenizer.c -fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) +fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenizer1.c -fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR) +fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c -fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR) +fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_unicode.c -fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) +fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_unicode2.c -fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) +fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/fts3/fts3_write.c -rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) +rtree.o: $(TOP)/ext/rtree/rtree.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/rtree/rtree.c -userauth.o: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR) +userauth.o: $(TOP)/ext/userauth/userauth.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/userauth/userauth.c -sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) +sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/session/sqlite3session.c -stmt.o: $(TOP)/ext/misc/stmt.c +stmt.o: $(TOP)/ext/misc/stmt.c $(DEPS_EXT_COMMON) $(TCC.extension) -c $(TOP)/ext/misc/stmt.c -# -# tool/version-info: a utility for emitting sqlite3 version info -# in various forms. -# -version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h - $(TLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c - # # Windows section # @@ -1914,8 +1937,12 @@ tidy: rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) + rm -fr dbfuzz2-dir rm -f fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE) - rm -f sessionfuzz$(TEXE) + rm -f scrub$(TEXE) showshm$(TEXE) sqlite3_checker$(TEXE) loadfts$(EXE) + rm -f index_usage$(TEXE) kvtest$(TEXE) startup$(TEXE) threadtest3$(TEXE) + rm -f sessionfuzz$(TEXE) changesetfuzz$(TEXE) + rm -f dbdump$(TEXE) dbtotxt$(TEXE) atrc$(TEXX) rm -f threadtest5$(TEXE) rm -f src-verify$(BEXE) has_tclsh* has_tclconfig rm -f tclsqlite3.c diff --git a/manifest b/manifest index 3653671844..2cccee72ac 100644 --- a/manifest +++ b/manifest @@ -1,14 +1,13 @@ -C Rename\ssome\sbuild\svars\sfor\slegibility.\sFix\shwaci-make-from-dot-in\swhen\sthe\sinput\sfile\slist\sis\smulti-line. -D 2024-10-24T01:26:50.001 +C General\smake\scleanups.\sStart\sadding\sa\ssanity-check\smechanism\sto\smain.mk\swhich\sdoes\sbasic\svalidation\sof\sthe\svars\sit\sexpects\sto\sbe\sset\sby\sthe\sfile\swhich\sincludes\sit.\sGet\sMakefile.linux-gcc\sworking\sfor\sthe\score-most\srules. +D 2024-10-24T03:14:40.105 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 4b18845678335be6e56dbe6257a8a777d416ead26c72dd71a08b0bb1a0d59575 -F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 +F Makefile.in b59fc1da692960f2d4cb15fa05c5bafb5b289dda360f34562b5a97c6ddbdda7e +F Makefile.linux-gcc db3a57a7b34ebd24e1b18fc42c84339aeef7c4eced534db1817bc3c38895165e F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 -F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -708,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 244408dfbc1891f8a2dae883e07953218370007fcd20db49ec6f00cf6b3e3913 +F main.mk 1a29e60e6fa8dfec772d5a8b80e4a975692f7dd38f5bf72eeff45d46974ef561 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 182dac1c46f8ada2e1f3abd4959ac72f0ecfd451b41fbe699f5077f338ae7d62 -R 243b1b295b7d39496ee8f02f5822532a +P fdb584421578cae825365d457cd533721839e3503f3744c77832c5925815b537 +R 60a889aacfbf201fc2f3a1db7c7c07ee U stephan -Z 76aba5b639a66a5a98cbfb78d58f5288 +Z 88aaad170bee1bcadb1054f45af7ff25 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6583cc4626..b884b70814 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fdb584421578cae825365d457cd533721839e3503f3744c77832c5925815b537 +85b2c73ccb85d7f5830a6fac692b380c5c79e7a54ee3fc6fc37343fa23816ef8 From e74c738e55fc11d4fdfc46b3ee3b91d678044af4 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 03:50:40 +0000 Subject: [PATCH 117/522] Get Makefile.linux-generic (formerly Makefile.linux-gcc) working with jimsh in out-of-tree builds. Pass on -DHAVE_READLINE=1 to the sqlite3 shell if configure detects it. FossilOrigin-Name: a555ff6dbc2ded5a9c65c8ef483f3197298848a580dda25ba0b721ba13167ad4 --- Makefile.in | 37 ++--------- Makefile.linux-gcc => Makefile.linux-generic | 4 ++ auto.def | 2 +- main.mk | 70 +++++++++++++++++--- manifest | 18 ++--- manifest.uuid | 2 +- 6 files changed, 82 insertions(+), 51 deletions(-) rename Makefile.linux-gcc => Makefile.linux-generic (92%) diff --git a/Makefile.in b/Makefile.in index 2439480888..ac8fa6b925 100644 --- a/Makefile.in +++ b/Makefile.in @@ -122,37 +122,10 @@ TCC.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite #XX#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ # -# JimTCL is part of the autosetup suite and is suitable for all -# current in-tree code-generation TCL jobs, but it requires that we -# build it with non-default flags. Note that the build tree will, if -# no system-level tclsh is found, also have a ./jimsh0 binary. That -# one is a bare-bones build for the configure process, whereas we need -# to build it with another option enabled for use with the various -# code generators. -# -# After jimsh is compiled, we run some sanity checks to ensure that -# it was built in a way compatible with this project's scripts: -# -# 1) Ensure that it was built with realpath() or _fullpath() support. -# Without that flag the [file normalize] command will always resolve -# to an empty string. -# -# 2) Ensure that it is built with -DJIM_COMPAT (which may be -# hard-coded into jimsh0.c). Without this, the [expr] command -# accepts only a single argument. -# -CFLAGS_JIMSH ?= @CFLAGS_JIMSH@ -JIMSH = @builddir@/jimsh$(TEXE) -$(JIMSH): $(TOP)/autosetup/jimsh0.c - $(BCC) -o $@ $(CFLAGS_JIMSH) $(TOP)/autosetup/jimsh0.c - @if [ x = "x$$($(JIMSH) -e 'file normalize $(JIMSH)' 2>/dev/null)" ]; then \ - echo "jimsh was built without -DHAVE_REALPATH or -DHAVE__FULLPATH." 1>&2; \ - exit 1; \ - fi - @if [ x3 != "x$$($(JIMSH) -e 'expr 1 + 2' 2>/dev/null)" ]; then \ - echo "jimsh was built without -DJIM_COMPAT." 1>&2; \ - exit 1; \ - fi +# $(JIMSH) and $(CFLAGS_JIMSH) are documented in main.mk. +# +CFLAGS_JIMSH = @CFLAGS_JIMSH@ +JIMSH = $(TOP)/jimsh$(TEXE) # BTCLSH is the tclsh-compatible app used for running various code # generators and other in-tree tools, as opposed to the TCL-based @@ -327,7 +300,7 @@ clean-autosetup: clean: clean-autosetup distclean-autosetup: clean - rm -f sqlite_cfg.h config.log config.status $(JIMSH) Makefile sqlite3.pc + rm -f sqlite_cfg.h config.log config.status Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh -gmake -C ext/wasm distclean 2>/dev/null; true distclean: distclean-autosetup diff --git a/Makefile.linux-gcc b/Makefile.linux-generic similarity index 92% rename from Makefile.linux-gcc rename to Makefile.linux-generic index b89f69efbe..e019a3dc7c 100644 --- a/Makefile.linux-gcc +++ b/Makefile.linux-generic @@ -17,9 +17,13 @@ TOP ?= . CFLAGS += -fPIC +SHELL_OPT ?= -DHAVE_READLINE=1 + # You should not have to change anything below this line ############################################################################### include $(TOP)/main.mk sqlite_cfg.h: touch $@ +distclean-.: + rm -f sqlite_cfg.h diff --git a/auto.def b/auto.def index 73fe821554..5cd51f8994 100644 --- a/auto.def +++ b/auto.def @@ -701,7 +701,7 @@ if {1} { ########## # Figure out what C libraries are required to compile programs # that use "readline()" library. - hwaci-check-readline + add-shell-opt -DHAVE_READLINE=[hwaci-check-readline] } else { # Older impl solely for reference while porting... # diff --git a/main.mk b/main.mk index cd18b3cc3d..e53f259028 100644 --- a/main.mk +++ b/main.mk @@ -81,12 +81,26 @@ TLIB ?= .lib # The canonical tclsh. TCLSH_CMD ?= tclsh # +# JimTCL is part of the autosetup suite and is suitable for all +# current in-tree code-generation TCL jobs, but it requires that we +# build it with non-default flags. Note that the build tree will, if +# no system-level tclsh is found, also have a ./jimsh0 binary. That +# one is a bare-bones build for the configure process, whereas we need +# to build it with another option enabled for use with the various +# code generators. +# +CFLAGS_JIMSH ?= -DHAVE_REALPATH +JIMSH ?= ./jimsh$(TEXE) +# # $(BTCLSH) = # # The TCL interpreter for in-tree code generation. May be either the -# in-tree JimTCL or the canonical TCL. If it's JimTCL, it must be -# compiled with -DJIM_COMPAT and -DHAVE_REALPATH. -BTCLSH ?= $(TCLSH_CMD) +# in-tree JimTCL ($(JIMSH)) or the canonical TCL ($(TCLSH_CMD). If +# it's JimTCL, it must be compiled with -DHAVE_REALPATH or +# -DHAVE__FULLPATH. +# +BTCLSH ?= $(JIMSH) + # # $(LDFLAGS_{FEATURE}) and $(CFLAGS_{FEATURE}) = # @@ -96,6 +110,7 @@ BTCLSH ?= $(TCLSH_CMD) # Rather that stuffing all CFLAGS and LDFLAGS into a single set, we # break them down on a per-feature basis and expect the build targets # to use the one(s) it needs. +# LDFLAGS_ZLIB ?= -lz LDFLAGS_MATH ?= -lm LDFLAGS_RPATH ?= -Wl,-rpath -Wl,$(prefix)/lib @@ -107,6 +122,7 @@ LDFLAGS_SHOBJ ?= -shared # # Various system-level directories, mostly needed for installation and # for finding system-level dependencies. +# prefix ?= /usr/local exec_prefix ?= $(prefix) libdir ?= $(prefix)/lib @@ -121,22 +137,26 @@ includedir ?= $(prefix)/include # install-sh is _not_ compatible with this because it _moves_ targets # during installation, which may break the build of targets which are # built after others are installed. +# INSTALL ?= install # # $(ENABLE_SHARED) = # # 1 if libsqlite3.$(TDLL) should be built. +# ENABLE_SHARED ?= 1 # # $(USE_AMALGAMATION) # # 1 if the amalgamation (sqlite3.c/h) should be built/used, otherwise # the library is built from all of its original source files. +# USE_AMALGAMATION ?= 1 # # $(AMALGAMATION_GEN_FLAGS) = # # Optional flags for the amalgamation generator. +# AMALGAMATION_GEN_FLAGS ?= --linemacros=0 # # $(OPT_FEATURE_FLAGS) = @@ -150,6 +170,7 @@ AMALGAMATION_GEN_FLAGS ?= --linemacros=0 # the OPT_FEATURE_FLAGS. Note that some flags only work if the build # is specifically configured to account for them. Adding them later, # when compiling the amalgamation, may or may not work. +# OPT_FEATURE_FLAGS ?= # # $(SHELL_OPT) = @@ -163,6 +184,7 @@ SHELL_OPT ?= # Potential TODO: a shell script, similar tool/tclConfigShToTcl.sh, # which emits these vars in a format which we can include from this # makefile. +# TCL_INCLUDE_SPEC ?= TCL_LIB_SPEC ?= TCL_STUB_LIB_SPEC ?= @@ -176,7 +198,9 @@ TCLLIB_RPATH ?= # $(HAVE_WASI_SDK) = # # 1 when building with the WASI SDK. This disables certain build -# targets. +# targets. It is expected that the invoker assigns CC to the wasi-sdk +# CC. +# HAVE_WASI_SDK ?= 0 # # ... and many, many more. Sane defaults are selected where possible. @@ -284,6 +308,32 @@ install-dir.all = $(install-dir.bin) $(install-dir.include) \ $(install-dir.all): $(INSTALL) -d $@ +# +# After jimsh is compiled, we run some sanity checks to ensure that +# it was built in a way compatible with this project's scripts: +# +# 1) Ensure that it was built with realpath() or _fullpath() support. +# Without that flag the [file normalize] command will always resolve +# to an empty string. +# +# 2) Ensure that it is built with -DJIM_COMPAT (which may be +# hard-coded into jimsh0.c). Without this, the [expr] command +# accepts only a single argument. +# +$(JIMSH): $(TOP)/autosetup/jimsh0.c + $(BCC) -o $@ $(CFLAGS_JIMSH) $(TOP)/autosetup/jimsh0.c + @if [ x = "x$$($(JIMSH) -e 'file normalize $(JIMSH)' 2>/dev/null)" ]; then \ + echo "$(JIMSH) was built without -DHAVE_REALPATH or -DHAVE__FULLPATH." 1>&2; \ + exit 1; \ + fi + @if [ x3 != "x$$($(JIMSH) -e 'expr 1 + 2' 2>/dev/null)" ]; then \ + echo "$(JIMSH) was built without -DJIM_COMPAT." 1>&2; \ + exit 1; \ + fi +distclean-jimsh: + rm -f $(JIMSH) +distclean: distclean-jimsh + # # $(MAKE_SANITY_CHECK) = a set of checks for various make vars which # must be provided to this file before including it. If any are @@ -296,7 +346,8 @@ $(install-dir.all): MAKE_SANITY_CHECK = .main.mk.checks $(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) @if [ x = "x$(TOP)" ]; then echo "Missing TOP var" 1>&2; exit 1; fi - @if [ ! -d "$(TOP)" ]; then echo "TOP is not a directory" 1>&2; exit 1; fi + @if [ ! -d "$(TOP)" ]; then echo "$(TOP) is not a directory" 1>&2; exit 1; fi + @if [ ! -f "$(TOP)/auto.def" ]; then echo "$(TOP) does not appear to be the top-most source dir" 1>&2; exit 1; fi @if [ x = "x$(BCC)" ]; then echo "Missing BCC var" 1>&2; exit 1; fi @if [ x = "x$(TCC)" ]; then echo "Missing TCC var" 1>&2; exit 1; fi @if [ x = "x$(RELEASE)" ]; then echo "Missing RELEASE var" 1>&2; exit 1; fi @@ -1920,7 +1971,8 @@ sqlite3.dll: $(LIBOBJ) sqlite3.def # * test results and test logs # * output from ./configure # -tidy: +tidy-.: +tidy: tidy-. rm -f *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h rm -rf .libs .deps tsrc .target_source @@ -1951,8 +2003,10 @@ tidy: # # Removes build products and test logs. Retains ./configure outputs. # -clean: tidy +clean-.: +clean: clean-. tidy rm -rf omittest* testrunner* testdir* # Clean up everything. No exceptions. -distclean: clean +distclean-.: +distclean: distclean-. clean diff --git a/manifest b/manifest index 2cccee72ac..ed50768a13 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C General\smake\scleanups.\sStart\sadding\sa\ssanity-check\smechanism\sto\smain.mk\swhich\sdoes\sbasic\svalidation\sof\sthe\svars\sit\sexpects\sto\sbe\sset\sby\sthe\sfile\swhich\sincludes\sit.\sGet\sMakefile.linux-gcc\sworking\sfor\sthe\score-most\srules. -D 2024-10-24T03:14:40.105 +C Get\sMakefile.linux-generic\s(formerly\sMakefile.linux-gcc)\sworking\swith\sjimsh\sin\sout-of-tree\sbuilds.\sPass\son\s-DHAVE_READLINE=1\sto\sthe\ssqlite3\sshell\sif\sconfigure\sdetects\sit. +D 2024-10-24T03:50:40.281 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in b59fc1da692960f2d4cb15fa05c5bafb5b289dda360f34562b5a97c6ddbdda7e -F Makefile.linux-gcc db3a57a7b34ebd24e1b18fc42c84339aeef7c4eced534db1817bc3c38895165e +F Makefile.in 57258abc6688381871956cd35dcd3017f56b7161487845597971597ff0b36d6f +F Makefile.linux-generic c44f7d97a1289b218a41299e4e9d120599ae86d1c61dfff49f1040a111fdfb08 w Makefile.linux-gcc F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 8de3a05ba31af07e8b691a5fc10059ed1380e0e578fc0e177ce66c6bb07bb564 +F auto.def 4979dcf77888bf31ff52a22cbbd197d0ca708c3f7f4d8cc32ebc32948673d440 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 1a29e60e6fa8dfec772d5a8b80e4a975692f7dd38f5bf72eeff45d46974ef561 +F main.mk bed344fb2a0fc6f096d556db166b146582f814cdf3cb85042e7efd458acd1ec4 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fdb584421578cae825365d457cd533721839e3503f3744c77832c5925815b537 -R 60a889aacfbf201fc2f3a1db7c7c07ee +P 85b2c73ccb85d7f5830a6fac692b380c5c79e7a54ee3fc6fc37343fa23816ef8 +R 294cb6b174d7e2114f1ad6f2164ffdf3 U stephan -Z 88aaad170bee1bcadb1054f45af7ff25 +Z 2ba08cb783ad323f3f33b67e1c19037f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b884b70814..147cd3bf76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85b2c73ccb85d7f5830a6fac692b380c5c79e7a54ee3fc6fc37343fa23816ef8 +a555ff6dbc2ded5a9c65c8ef483f3197298848a580dda25ba0b721ba13167ad4 From ce236e031e04e0a4477cab2c83f66416f57f4517 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 04:34:39 +0000 Subject: [PATCH 118/522] Generic build cleanups. FossilOrigin-Name: be7b32a77f58ae3eb15cb828385035e63236b7e6c0669f90f2321f0509f0de1b --- Makefile.in | 38 +++++++++++---------- Makefile.linux-generic | 25 ++++++++++++-- main.mk | 76 +++++++++++++++++++++++------------------- manifest | 16 ++++----- manifest.uuid | 2 +- 5 files changed, 95 insertions(+), 62 deletions(-) diff --git a/Makefile.in b/Makefile.in index ac8fa6b925..6e1398a6e7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -127,10 +127,9 @@ TCC.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite CFLAGS_JIMSH = @CFLAGS_JIMSH@ JIMSH = $(TOP)/jimsh$(TEXE) -# BTCLSH is the tclsh-compatible app used for running various code -# generators and other in-tree tools, as opposed to the TCL-based -# tests, which must be built and run using the canonical TCL -# distribution. +# +# $(BTCLSH) is documented in main.mk. +# BTCLSH = @BTCLSH@ $(BTCLSH): @@ -151,11 +150,14 @@ TCC += $(OPT_FEATURE_FLAGS) #XX# serve different purposes. TCC += $(OPTS) -# Version numbers and release number for the SQLite being compiled. # -# VERSION = @VERSION@ +# Release (X.Y.Z) and version (X.Y) numbers for the SQLite being +# compiled. +# RELEASE = @RELEASE@ +# VERSION = @VERSION@ # we don't currently use this anywhere +# # Filename extensions for binaries and libraries # BEXE = @BUILD_EXEEXT@ @@ -165,21 +167,25 @@ TDLL = @TARGET_DLLEXT@ BLIB = @BUILD_LIBEXT@ TLIB = @TARGET_LIBEXT@ -# The following variable is "1" if the configure script was able to locate -# the tclConfig.sh file. It is an empty string otherwise. When this -# variable is "1", the TCL extension library (libtclsqlite3.so) is built -# and installed. +# +# $(HAVE_TCL) is 1 if the configure script was able to locate the +# tclConfig.sh file, else it is 0. When this variable is 1, the TCL +# extension library (libtclsqlite3.so) and related testing apps are +# built. # HAVE_TCL = @HAVE_TCL@ -# This is the command to use for tclsh - normally just "tclsh", but we may -# know the specific version we want to use. This must point to the canonical -# TCL interpreter, not JimTCL. +# +# $(TCLSH_CMD) is the command to use for tclsh - normally just +# "tclsh", but we may know the specific version we want to use. This +# must point to a canonical TCL interpreter, not JimTCL. # TCLSH_CMD = @TCLSH_CMD@ TCL_CONFIG_SH = @TCL_CONFIG_SH@ +# # TCL config info from tclConfig.sh +# TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ @@ -188,11 +194,13 @@ TCL_VERSION = @TCL_VERSION@ TCLLIB_RPATH = @TCLLIB_RPATH@ TCLLIBDIR = @TCLLIBDIR@ +# # Additional options when running tests using testrunner.tcl # This is usually either blank, or else --status # TSTRNNR_OPTS = @TSTRNNR_OPTS@ +# # Where do we want to install the tcl plugin # TCLLIBDIR = @TCLLIBDIR@ @@ -217,10 +225,6 @@ TCOMPILE_EXTRAS += $(CFLAGS_GCOV$(USE_GCOV)) TLINK_EXTRAS += $(LDFLAGS_GCOV$(USE_GCOV)) # -# You should not have to change anything below this line -################################################################################ -# - # Vars with the AS_ prefix are specifically related to AutoSetup. # # AS_AUTO_DEF is the main configure script. diff --git a/Makefile.linux-generic b/Makefile.linux-generic index e019a3dc7c..712a7392da 100644 --- a/Makefile.linux-generic +++ b/Makefile.linux-generic @@ -10,15 +10,36 @@ # alternative. Create a copy of this file, edit the parameters # below and type "make". # -#### The toplevel directory of the source tree. This is the directory -# that contains this "Makefile.in" and the "configure.in" script. +# Maintenance note: because this is the template for Linux systems, it +# is assumed that the platform has GNU make and this file takes +# advantage of that. +# +#### +# +# $(TOP) = The toplevel directory of the source tree. This is the +# directory that contains this "Makefile.in" and "auto.def". # TOP ?= . +# +# $(CFLAGS) will be used when compiling the library and most +# utilities. Generally speaking, it must contain -fPIC on Linux +# systems. +# CFLAGS += -fPIC +# +# $(SHELL_OPT) contains CFLAGS for building the sqlite3 CLI shell. +# See main.mk for other potentially-relevant vars which may need +# tweaking, like $(LDFLAGS_READLINE). +# SHELL_OPT ?= -DHAVE_READLINE=1 +# +# Library's version number. +# +RELEASE ?= $(shell cat $(TOP)/VERSION 2>/dev/null) + # You should not have to change anything below this line ############################################################################### include $(TOP)/main.mk diff --git a/main.mk b/main.mk index e53f259028..1acc62ce78 100644 --- a/main.mk +++ b/main.mk @@ -3,7 +3,7 @@ ############################################################################### # This is the main makefile for sqlite. It expects to be included from # a higher-level makefile which configures any dynamic state needed by -# this one. +# this one (as documented below). # # Maintenance reminders: # @@ -11,30 +11,31 @@ # POSIX Make compatible. "bmake" (BSD make) is available on most # Linux systems, so compatibility is relatively easy to test. # -#XX# Lines starting with #XX# are TODOs for the port to autosetup -# # The variables listed below must be defined before this script is # invoked. This file will use defaults, very possibly invalid, for any # which are not defined. ######################################################################## # -# $(RELEASE) = -# -# The MAJOR.MINOR.PATCH version number of this build. -RELEASE ?= MAJOR.MINOR.PATCH -# # $(TOP) = # # The toplevel directory of the source tree. For canonical builds # this is the directory that contains this "Makefile.in" and the # "configure.in" script. For out-of-tree builds, this will differ # from $(PWD). +# TOP ?= $(PWD) # +# $(RELEASE) = +# +# The MAJOR.MINOR.PATCH version number of this build. +# +RELEASE ?= +# # $(BCC) = # # C Compiler and options for use in building executables that will run # on the platform that is doing the build. +# BCC ?= $(CC) # # $(TCC) = @@ -43,12 +44,12 @@ BCC ?= $(CC) # on the target platform. This is usually the same as BCC, unless you # are cross-compiling. Note that it should only contain flags which # are used by _all_ build targets. Flags needed only by specific -# targets are defined elsewhere. +# targets are defined elsewhere and applied on a per-target basis. +# TCC ?= $(BCC) # # $(AR) = -# Tool used to build a static library from object files, including -# its arguments needed for doing so. +# Tool used to build a static library from object files. # AR ?= ar # @@ -56,11 +57,13 @@ AR ?= ar # # File extension for executables on the build platform. ".exe" for # Windows and "" everywhere else. +# BEXE ?= # # $(BDLL) and $(BLIB) = # # The DLL resp. static library counterparts of $(BEXE). +# BDLL ?= .so BLIB ?= .lib # @@ -68,17 +71,20 @@ BLIB ?= .lib # # File extension for executables on the target platform. ".exe" for # Windows and "" everywhere else. +# TEXE ?= # # $(TDLL) and $(TLIB) = # # The DLL resp. static library counterparts of $(TEXE). +# TDLL ?= .so TLIB ?= .lib # # $(TCLSH_CMD) = # # The canonical tclsh. +# TCLSH_CMD ?= tclsh # # JimTCL is part of the autosetup suite and is suitable for all @@ -89,6 +95,9 @@ TCLSH_CMD ?= tclsh # to build it with another option enabled for use with the various # code generators. # +# JIMSH requires a leading path component, even if it's ./, so that it +# can be used as a shell command. +# CFLAGS_JIMSH ?= -DHAVE_REALPATH JIMSH ?= ./jimsh$(TEXE) # @@ -114,7 +123,7 @@ BTCLSH ?= $(JIMSH) LDFLAGS_ZLIB ?= -lz LDFLAGS_MATH ?= -lm LDFLAGS_RPATH ?= -Wl,-rpath -Wl,$(prefix)/lib -LDFLAGS_READLINE ?= -lreadline +LDFLAGS_READLINE ?= -lreadline # these vary wildly across platforms CFLAGS_READLINE ?= LDFLAGS_PTHREAD ?= -lpthread LDFLAGS_DLOPEN ?= -ldl @@ -191,8 +200,10 @@ TCL_STUB_LIB_SPEC ?= TCL_EXEC_PREFIX ?= TCL_VERSION ?= TCLLIBDIR ?= +# # $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not # libsqlite3, and will usually differ from $(LDFLAGS_RPATH). +# TCLLIB_RPATH ?= # # $(HAVE_WASI_SDK) = @@ -203,6 +214,19 @@ TCLLIB_RPATH ?= # HAVE_WASI_SDK ?= 0 # +# $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for +# compiling the library's own sources, including (sometimes) when +# compiling sqlite3.c directly in to another app. +# +CFLAGS_libsqlite3 ?= $(CFLAGS) +# +# $(TCC.sqlite) is $(TCC) plus any flags which are desired for the +# library as a whole, but not necessarily needed for every binary. It +# will normally get initially populated with flags by the +# configure-generated makefile. +# +TCC.sqlite ?= $(TCC) +# # ... and many, many more. Sane defaults are selected where possible. # # With the above-described defined, the rest of this make script will @@ -211,7 +235,10 @@ HAVE_WASI_SDK ?= 0 all: sqlite3.h sqlite3.c ######################################################################## -# Modifying what follows should not be necessary for most builds. +######################################################################## +# Modifying anything after this point should not be necessary for most +# builds. +######################################################################## ######################################################################## # @@ -226,13 +253,6 @@ INSTALL.noexec = $(INSTALL) -m 0644 # TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) -# -# $(TCC.sqlite) is $(TCC) plus any flags which are desired for the library -# as a whole, but not necessarily needed for every binary. It will -# normally get initially populated by the configure-generated -# makefile, so should not be overwritten here. -# -TCC.sqlite ?= $(TCC) # # $(CFLAGS_intree_includes) = -I... flags relevant specifically to # this tree, including any subdirectories commonly needed for building @@ -253,7 +273,7 @@ TCC.extension = $(TCOMPILE) -I. -I$(TOP)/src -DSQLITE_CORE # $(TLINK) = compiler invocation for when the target will be an # executable. # -# $(TLINK_EXTRAS) = config-specific flags for $(TLINK) +# $(TLINK_EXTRAS) = optional config-specific flags for $(TLINK) # TLINK = $(TCC.sqlite) $(TLINK_EXTRAS) # @@ -261,19 +281,6 @@ TLINK = $(TCC.sqlite) $(TLINK_EXTRAS) # TLINK.shared = $(TLINK) $(LDFLAGS_SHOBJ) -# -# $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for -# compiling the library's own sources, including (sometimes) when -# compiling sqlite3.c directly in to another app. Most notably, it -# should always contain -DSQLITE_TEMP_STORE=N for the sake of -# historical build expecations. -# -# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 -# to default to file, 2 to default to memory, and 3 to force temporary -# tables to always be in memory. -# -CFLAGS_libsqlite3 ?= $(CFLAGS) -DSQLITE_TEMP_STORE=1 - # # LDFLAGS_libsqlite3 should be used with any target which either # results in building libsqlite3.so, compiles sqlite3.c directly, or @@ -348,6 +355,7 @@ $(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) @if [ x = "x$(TOP)" ]; then echo "Missing TOP var" 1>&2; exit 1; fi @if [ ! -d "$(TOP)" ]; then echo "$(TOP) is not a directory" 1>&2; exit 1; fi @if [ ! -f "$(TOP)/auto.def" ]; then echo "$(TOP) does not appear to be the top-most source dir" 1>&2; exit 1; fi + @if [ x = "x$(RELEASE)" ] then; then echo "RELEASE must be set to the library's X.Y.Z-format version number" 1>&2; exit 1; fi @if [ x = "x$(BCC)" ]; then echo "Missing BCC var" 1>&2; exit 1; fi @if [ x = "x$(TCC)" ]; then echo "Missing TCC var" 1>&2; exit 1; fi @if [ x = "x$(RELEASE)" ]; then echo "Missing RELEASE var" 1>&2; exit 1; fi diff --git a/manifest b/manifest index ed50768a13..40ee1c6bdf 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Get\sMakefile.linux-generic\s(formerly\sMakefile.linux-gcc)\sworking\swith\sjimsh\sin\sout-of-tree\sbuilds.\sPass\son\s-DHAVE_READLINE=1\sto\sthe\ssqlite3\sshell\sif\sconfigure\sdetects\sit. -D 2024-10-24T03:50:40.281 +C Generic\sbuild\scleanups. +D 2024-10-24T04:34:39.658 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 57258abc6688381871956cd35dcd3017f56b7161487845597971597ff0b36d6f -F Makefile.linux-generic c44f7d97a1289b218a41299e4e9d120599ae86d1c61dfff49f1040a111fdfb08 w Makefile.linux-gcc +F Makefile.in e5cd4b271a3ffbe4fd4c13ca8852d82352a4db9e9003b412d81437d0d4309f23 +F Makefile.linux-generic e79bf7b51f2cc7513f0f673070ad528f3311ba178599f257cb4d04bbd968f497 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk bed344fb2a0fc6f096d556db166b146582f814cdf3cb85042e7efd458acd1ec4 +F main.mk 803569231944f6221794d4df9bd2623547f093570b8f0538767eca1cfa4a6566 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 85b2c73ccb85d7f5830a6fac692b380c5c79e7a54ee3fc6fc37343fa23816ef8 -R 294cb6b174d7e2114f1ad6f2164ffdf3 +P a555ff6dbc2ded5a9c65c8ef483f3197298848a580dda25ba0b721ba13167ad4 +R 3e8eef5052286b2a46e0f9665a9d13cf U stephan -Z 2ba08cb783ad323f3f33b67e1c19037f +Z 75f0c66b04971012069339b49ca2dbc2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 147cd3bf76..2d335ed780 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a555ff6dbc2ded5a9c65c8ef483f3197298848a580dda25ba0b721ba13167ad4 +be7b32a77f58ae3eb15cb828385035e63236b7e6c0669f90f2321f0509f0de1b From caf8c28420e4e5bade50bea548cb72043fdc0da7 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 04:56:44 +0000 Subject: [PATCH 119/522] Potentially controversial/unconventional makefile symbol renamings and docs explaining them. FossilOrigin-Name: 7eceb7539dcce16104a93ad0ca1f755f23621751878cc4b01465e61333795b72 --- Makefile.in | 62 ++++---- Makefile.linux-generic | 3 +- main.mk | 334 ++++++++++++++++++++--------------------- manifest | 16 +- manifest.uuid | 2 +- 5 files changed, 214 insertions(+), 203 deletions(-) diff --git a/Makefile.in b/Makefile.in index 6e1398a6e7..5c0d9b667c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -50,12 +50,22 @@ clean: # SHELL_OPT out of the makefile. # # -# Maintenance reminder: When using the X?=Y variable assignment -# formulation, please test the build with both GNU make and a POSIX -# make (e.g. BSD make, a.k.a. bmake). On at least one occassion, that -# formulation has led to inconsistent behavior between the two major -# make flavors when used with variable names which might sensibly be -# in the developer's environment (namely CC). +# Maintenance reminders: +# +# - When using the X?=Y variable assignment formulation, please test +# the build with both GNU make and a POSIX make (e.g. BSD make, +# a.k.a. bmake). On at least one occassion, that formulation has led +# to inconsistent behavior between the two major make flavors when +# used with variable names which might sensibly be in the +# developer's environment (namely CC). +# +# - The naming convention of some vars, using periods instead of +# underscores, though unconventional, was selected for a couple of +# reasons: 1) Personal taste (for which there is no accounting). 2) +# It is thought to help defend against inadvertent injection of +# those vars via environment variables (because X.Y is not a legal +# environment variable name). "Feature or bug?" is debatable and +# this naming convention may be reverted if it causes any grief. # # @@ -88,14 +98,14 @@ BCC = @BUILD_CC@ @BUILD_CFLAGS@ TCC = $(CC) $(CFLAGS) CFLAGS = @CFLAGS@ @SH_CFLAGS@ -LDFLAGS_SHOBJ = @SHOBJ_LDFLAGS@ -LDFLAGS_ZLIB = @LDFLAGS_ZLIB@ -LDFLAGS_MATH = @LDFLAGS_MATH@ -LDFLAGS_RPATH = @LDFLAGS_RPATH@ -LDFLAGS_PTHREAD = @LDFLAGS_PTHREAD@ -LDFLAGS_DLOPEN = @LDFLAGS_DLOPEN@ -LDFLAGS_READLINE = @LDFLAGS_READLINE@ -CFLAGS_READLINE = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ +LDFLAGS.shobj = @SHOBJ_LDFLAGS@ +LDFLAGS.zlib = @LDFLAGS_ZLIB@ +LDFLAGS.math = @LDFLAGS_MATH@ +LDFLAGS.rpath = @LDFLAGS_RPATH@ +LDFLAGS.pthread = @LDFLAGS_PTHREAD@ +LDFLAGS.dlopen = @LDFLAGS_DLOPEN@ +LDFLAGS.readline = @LDFLAGS_READLINE@ +CFLAGS.readline = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ ENABLE_SHARED = @ENABLE_SHARED@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ @@ -110,8 +120,8 @@ TCC.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # # main.mk will fill out TCC.sqlite with some flags common to all builds. -#XX#CFLAGS_READLINE += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ -#XX#CFLAGS_READLINE += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ +#XX#CFLAGS.readline += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ +#XX#CFLAGS.readline += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ #XX# #XX## The library that programs using readline() must link against. #XX## @@ -122,9 +132,9 @@ TCC.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite #XX#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ # -# $(JIMSH) and $(CFLAGS_JIMSH) are documented in main.mk. +# $(JIMSH) and $(CFLAGS.JIMSH) are documented in main.mk. # -CFLAGS_JIMSH = @CFLAGS_JIMSH@ +CFLAGS.JIMSH = @CFLAGS_JIMSH@ JIMSH = $(TOP)/jimsh$(TEXE) # @@ -134,9 +144,9 @@ BTCLSH = @BTCLSH@ $(BTCLSH): # -# $(CFLAGS_libsqlite3) is documented in main.mk. +# $(CFLAGS.libsqlite3) is documented in main.mk. # -CFLAGS_libsqlite3 = $(CFLAGS) -DSQLITE_TEMP_STORE=@TEMP_STORE@ +CFLAGS.libsqlite3 = $(CFLAGS) -DSQLITE_TEMP_STORE=@TEMP_STORE@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) @@ -154,8 +164,8 @@ TCC += $(OPTS) # Release (X.Y.Z) and version (X.Y) numbers for the SQLite being # compiled. # -RELEASE = @RELEASE@ -# VERSION = @VERSION@ # we don't currently use this anywhere +VERSION.XYZ = @RELEASE@ +# VERSION.XY = @VERSION@ # we don't currently use this anywhere # # Filename extensions for binaries and libraries @@ -218,11 +228,11 @@ TCLLIBDIR = @TCLLIBDIR@ # for more info. # -CFLAGS_GCOV1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage -LDFLAGS_GCOV1 = -lgcov +CFLAGS.GCOV1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage +LDFLAGS.GCOV1 = -lgcov USE_GCOV = @USE_GCOV@ -TCOMPILE_EXTRAS += $(CFLAGS_GCOV$(USE_GCOV)) -TLINK_EXTRAS += $(LDFLAGS_GCOV$(USE_GCOV)) +TCOMPILE.EXTRAS += $(CFLAGS.GCOV$(USE_GCOV)) +TLINK.EXTRAS += $(LDFLAGS.GCOV$(USE_GCOV)) # # Vars with the AS_ prefix are specifically related to AutoSetup. diff --git a/Makefile.linux-generic b/Makefile.linux-generic index 712a7392da..50bd980b98 100644 --- a/Makefile.linux-generic +++ b/Makefile.linux-generic @@ -38,7 +38,8 @@ SHELL_OPT ?= -DHAVE_READLINE=1 # # Library's version number. # -RELEASE ?= $(shell cat $(TOP)/VERSION 2>/dev/null) +VERSION.XYZ ?= $(shell cat $(TOP)/VERSION 2>/dev/null) +$(info VERSION.XYZ=$(VERSION.XYZ)) # You should not have to change anything below this line ############################################################################### diff --git a/main.mk b/main.mk index 1acc62ce78..69ebeaa9bc 100644 --- a/main.mk +++ b/main.mk @@ -25,11 +25,11 @@ # TOP ?= $(PWD) # -# $(RELEASE) = +# $(VERSION.XYZ) = # # The MAJOR.MINOR.PATCH version number of this build. # -RELEASE ?= +VERSION.XYZ ?= # # $(BCC) = # @@ -98,7 +98,7 @@ TCLSH_CMD ?= tclsh # JIMSH requires a leading path component, even if it's ./, so that it # can be used as a shell command. # -CFLAGS_JIMSH ?= -DHAVE_REALPATH +CFLAGS.JIMSH ?= -DHAVE_REALPATH JIMSH ?= ./jimsh$(TEXE) # # $(BTCLSH) = @@ -111,23 +111,23 @@ JIMSH ?= ./jimsh$(TEXE) BTCLSH ?= $(JIMSH) # -# $(LDFLAGS_{FEATURE}) and $(CFLAGS_{FEATURE}) = +# $(LDFLAGS.{feature}) and $(CFLAGS.{feature}) = # # Linker resp. C/CPP flags required by a specific feature, e.g. -# $(LDFLAGS_PTHREAD) or $(CFLAGS_READLINE). +# $(LDFLAGS.pthread) or $(CFLAGS.readline). # # Rather that stuffing all CFLAGS and LDFLAGS into a single set, we # break them down on a per-feature basis and expect the build targets # to use the one(s) it needs. # -LDFLAGS_ZLIB ?= -lz -LDFLAGS_MATH ?= -lm -LDFLAGS_RPATH ?= -Wl,-rpath -Wl,$(prefix)/lib -LDFLAGS_READLINE ?= -lreadline # these vary wildly across platforms -CFLAGS_READLINE ?= -LDFLAGS_PTHREAD ?= -lpthread -LDFLAGS_DLOPEN ?= -ldl -LDFLAGS_SHOBJ ?= -shared +LDFLAGS.zlib ?= -lz +LDFLAGS.math ?= -lm +LDFLAGS.rpath ?= -Wl,-rpath -Wl,$(prefix)/lib +LDFLAGS.readline ?= -lreadline # these vary wildly across platforms +CFLAGS.readline ?= +LDFLAGS.pthread ?= -lpthread +LDFLAGS.dlopen ?= -ldl +LDFLAGS.shobj ?= -shared # # Various system-level directories, mostly needed for installation and # for finding system-level dependencies. @@ -202,7 +202,7 @@ TCL_VERSION ?= TCLLIBDIR ?= # # $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not -# libsqlite3, and will usually differ from $(LDFLAGS_RPATH). +# libsqlite3, and will usually differ from $(LDFLAGS.rpath). # TCLLIB_RPATH ?= # @@ -214,11 +214,11 @@ TCLLIB_RPATH ?= # HAVE_WASI_SDK ?= 0 # -# $(CFLAGS_libsqlite3) must contain any CFLAGS which are relevant for +# $(CFLAGS.libsqlite3) must contain any CFLAGS which are relevant for # compiling the library's own sources, including (sometimes) when # compiling sqlite3.c directly in to another app. # -CFLAGS_libsqlite3 ?= $(CFLAGS) +CFLAGS.libsqlite3 ?= $(CFLAGS) # # $(TCC.sqlite) is $(TCC) plus any flags which are desired for the # library as a whole, but not necessarily needed for every binary. It @@ -249,20 +249,20 @@ INSTALL.noexec = $(INSTALL) -m 0644 # # $(TCOMPILE) = generic target platform compiler invocation -# $(TCOMPILE_EXTRAS) = config-specific flags for $(TCOMPILE) +# $(TCOMPILE.EXTRAS) = config-specific flags for $(TCOMPILE) # -TCOMPILE = $(TCC) $(TCOMPILE_EXTRAS) +TCOMPILE = $(TCC) $(TCOMPILE.EXTRAS) # -# $(CFLAGS_intree_includes) = -I... flags relevant specifically to +# $(CFLAGS.intree_includes) = -I... flags relevant specifically to # this tree, including any subdirectories commonly needed for building # various tools. # -CFLAGS_intree_includes = \ +CFLAGS.intree_includes = \ -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \ -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session \ -I$(TOP)/ext/misc -I$(TOP)/ext/userauth -TCC.sqlite += $(CFLAGS_intree_includes) +TCC.sqlite += $(CFLAGS.intree_includes) # # $(TCC.extension) = compiler invocation for loadable extensions. @@ -273,25 +273,25 @@ TCC.extension = $(TCOMPILE) -I. -I$(TOP)/src -DSQLITE_CORE # $(TLINK) = compiler invocation for when the target will be an # executable. # -# $(TLINK_EXTRAS) = optional config-specific flags for $(TLINK) +# $(TLINK.EXTRAS) = optional config-specific flags for $(TLINK) # -TLINK = $(TCC.sqlite) $(TLINK_EXTRAS) +TLINK = $(TCC.sqlite) $(TLINK.EXTRAS) # # $(TLINK.shared) = $(TLINK) invocation specifically for shared libraries # -TLINK.shared = $(TLINK) $(LDFLAGS_SHOBJ) +TLINK.shared = $(TLINK) $(LDFLAGS.shobj) # -# LDFLAGS_libsqlite3 should be used with any target which either +# LDFLAGS.libsqlite3 should be used with any target which either # results in building libsqlite3.so, compiles sqlite3.c directly, or # links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these # flags are for the target build platform, not necessarily localhost. # i.e. it should be used with $(TCC.sqlite) or $(TLINK) but not $(BCC). # -LDFLAGS_libsqlite3 = \ - $(LDFLAGS_RPATH) $(LDFLAGS_PTHREAD) \ - $(LDFLAGS_MATH) $(LDFLAGS_ZLIB) \ - $(LDFLAGS_DLOPEN) +LDFLAGS.libsqlite3 = \ + $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ + $(LDFLAGS.math) $(LDFLAGS.zlib) \ + $(LDFLAGS.dlopen) # # $(install-dir.XYZ) = dirs for installation. @@ -328,7 +328,7 @@ $(install-dir.all): # accepts only a single argument. # $(JIMSH): $(TOP)/autosetup/jimsh0.c - $(BCC) -o $@ $(CFLAGS_JIMSH) $(TOP)/autosetup/jimsh0.c + $(BCC) -o $@ $(CFLAGS.JIMSH) $(TOP)/autosetup/jimsh0.c @if [ x = "x$$($(JIMSH) -e 'file normalize $(JIMSH)' 2>/dev/null)" ]; then \ echo "$(JIMSH) was built without -DHAVE_REALPATH or -DHAVE__FULLPATH." 1>&2; \ exit 1; \ @@ -355,10 +355,10 @@ $(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) @if [ x = "x$(TOP)" ]; then echo "Missing TOP var" 1>&2; exit 1; fi @if [ ! -d "$(TOP)" ]; then echo "$(TOP) is not a directory" 1>&2; exit 1; fi @if [ ! -f "$(TOP)/auto.def" ]; then echo "$(TOP) does not appear to be the top-most source dir" 1>&2; exit 1; fi - @if [ x = "x$(RELEASE)" ] then; then echo "RELEASE must be set to the library's X.Y.Z-format version number" 1>&2; exit 1; fi + @if [ x = "x$(VERSION.XYZ)" ]; then echo "VERSION.XYZ must be set to the library's X.Y.Z-format version number" 1>&2; exit 1; fi @if [ x = "x$(BCC)" ]; then echo "Missing BCC var" 1>&2; exit 1; fi @if [ x = "x$(TCC)" ]; then echo "Missing TCC var" 1>&2; exit 1; fi - @if [ x = "x$(RELEASE)" ]; then echo "Missing RELEASE var" 1>&2; exit 1; fi + @if [ x = "x$(VERSION.XYZ)" ]; then echo "Missing VERSION.XYZ var" 1>&2; exit 1; fi @if [ x = "x$(BTCLSH)" ]; then echo "Missing BTCLSH var" 1>&2; exit 1; fi touch $@ clean-sanity-check: @@ -932,258 +932,258 @@ sqlite3ext.h: .target_source # DEPS_OBJ_COMMON = $(MAKE_SANITY_CHECK) $(HDR) parse.o: parse.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c parse.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c parse.c opcodes.o: opcodes.c - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c opcodes.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c opcodes.c # Rules to build individual *.o files from files in the src directory. # alter.o: $(TOP)/src/alter.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/alter.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/alter.c analyze.o: $(TOP)/src/analyze.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/analyze.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/analyze.c attach.o: $(TOP)/src/attach.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/attach.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/attach.c auth.o: $(TOP)/src/auth.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/auth.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/auth.c backup.o: $(TOP)/src/backup.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/backup.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/backup.c bitvec.o: $(TOP)/src/bitvec.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/bitvec.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/bitvec.c btmutex.o: $(TOP)/src/btmutex.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/btmutex.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/btmutex.c btree.o: $(TOP)/src/btree.c $(DEPS_OBJ_COMMON) $(TOP)/src/pager.h - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/btree.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/btree.c build.o: $(TOP)/src/build.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/build.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/build.c callback.o: $(TOP)/src/callback.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/callback.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/callback.c complete.o: $(TOP)/src/complete.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/complete.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/complete.c ctime.o: $(TOP)/src/ctime.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/ctime.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/ctime.c date.o: $(TOP)/src/date.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/date.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/date.c dbpage.o: $(TOP)/src/dbpage.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbpage.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/dbpage.c dbstat.o: $(TOP)/src/dbstat.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/dbstat.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/dbstat.c delete.o: $(TOP)/src/delete.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/delete.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/delete.c expr.o: $(TOP)/src/expr.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/expr.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/expr.c fault.o: $(TOP)/src/fault.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/fault.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/fault.c fkey.o: $(TOP)/src/fkey.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/fkey.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/fkey.c func.o: $(TOP)/src/func.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/func.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/func.c global.o: $(TOP)/src/global.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/global.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/global.c hash.o: $(TOP)/src/hash.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/hash.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/insert.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/insert.c json.o: $(TOP)/src/json.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/json.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/json.c legacy.o: $(TOP)/src/legacy.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/legacy.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/legacy.c loadext.o: $(TOP)/src/loadext.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/loadext.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/loadext.c main.o: $(TOP)/src/main.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/main.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/main.c malloc.o: $(TOP)/src/malloc.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/malloc.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/malloc.c mem0.o: $(TOP)/src/mem0.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem0.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem0.c mem1.o: $(TOP)/src/mem1.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem1.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem1.c mem2.o: $(TOP)/src/mem2.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem2.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem2.c mem3.o: $(TOP)/src/mem3.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem3.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem3.c mem5.o: $(TOP)/src/mem5.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mem5.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem5.c memdb.o: $(TOP)/src/memdb.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/memdb.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/memdb.c memjournal.o: $(TOP)/src/memjournal.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/memjournal.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/memjournal.c mutex.o: $(TOP)/src/mutex.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex.c mutex_noop.o: $(TOP)/src/mutex_noop.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_noop.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_noop.c mutex_unix.o: $(TOP)/src/mutex_unix.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_unix.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_unix.c mutex_w32.o: $(TOP)/src/mutex_w32.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/mutex_w32.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_w32.c notify.o: $(TOP)/src/notify.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/notify.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/notify.c pager.o: $(TOP)/src/pager.c $(DEPS_OBJ_COMMON) $(TOP)/src/pager.h - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pager.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pager.c pcache.o: $(TOP)/src/pcache.c $(DEPS_OBJ_COMMON) $(TOP)/src/pcache.h - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pcache.c pcache1.o: $(TOP)/src/pcache1.c $(DEPS_OBJ_COMMON) $(TOP)/src/pcache.h - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pcache1.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pcache1.c os.o: $(TOP)/src/os.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os.c os_kv.o: $(TOP)/src/os_kv.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_kv.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_kv.c os_unix.o: $(TOP)/src/os_unix.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_unix.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_unix.c os_win.o: $(TOP)/src/os_win.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/os_win.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_win.c pragma.o: $(TOP)/src/pragma.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/pragma.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pragma.c prepare.o: $(TOP)/src/prepare.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/prepare.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/prepare.c printf.o: $(TOP)/src/printf.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/printf.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/printf.c random.o: $(TOP)/src/random.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/random.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/random.c resolve.o: $(TOP)/src/resolve.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/resolve.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/resolve.c rowset.o: $(TOP)/src/rowset.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/rowset.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/rowset.c select.o: $(TOP)/src/select.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/select.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/select.c status.o: $(TOP)/src/status.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/status.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/status.c sqlite3.o: sqlite3.h sqlite3.c - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c sqlite3.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c sqlite3.c table.o: $(TOP)/src/table.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/table.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/table.c threads.o: $(TOP)/src/threads.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/threads.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/threads.c tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/tokenize.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/tokenize.c treeview.o: $(TOP)/src/treeview.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/treeview.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/treeview.c trigger.o: $(TOP)/src/trigger.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/trigger.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/trigger.c update.o: $(TOP)/src/update.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/update.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/update.c upsert.o: $(TOP)/src/upsert.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/upsert.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/upsert.c utf.o: $(TOP)/src/utf.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/utf.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/utf.c util.o: $(TOP)/src/util.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/util.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/util.c vacuum.o: $(TOP)/src/vacuum.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vacuum.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vacuum.c vdbe.o: $(TOP)/src/vdbe.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbe.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbe.c vdbeapi.o: $(TOP)/src/vdbeapi.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeapi.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeapi.c vdbeaux.o: $(TOP)/src/vdbeaux.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeaux.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeaux.c vdbeblob.o: $(TOP)/src/vdbeblob.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbeblob.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeblob.c vdbemem.o: $(TOP)/src/vdbemem.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbemem.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbemem.c vdbesort.o: $(TOP)/src/vdbesort.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbesort.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbesort.c vdbetrace.o: $(TOP)/src/vdbetrace.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbetrace.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbetrace.c vdbevtab.o: $(TOP)/src/vdbevtab.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vdbevtab.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbevtab.c vtab.o: $(TOP)/src/vtab.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/vtab.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vtab.c wal.o: $(TOP)/src/wal.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/wal.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/wal.c walker.o: $(TOP)/src/walker.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/walker.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/walker.c where.o: $(TOP)/src/where.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/where.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/where.c wherecode.o: $(TOP)/src/wherecode.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/wherecode.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/wherecode.c whereexpr.o: $(TOP)/src/whereexpr.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/whereexpr.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/whereexpr.c window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS_libsqlite3) -c $(TOP)/src/window.c + $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/window.c tclsqlite.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS_intree_includes) \ + $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS.intree_includes) \ -c $(TOP)/src/tclsqlite.c tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) @@ -1194,7 +1194,7 @@ tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) $(TLINK) -o $@ tclsqlite-shell.o \ - $(libsqlite3.LIB) $(TCL_INCLUDE_SPEC) $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) + $(libsqlite3.LIB) $(TCL_INCLUDE_SPEC) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) # Rules to build opcodes.c and opcodes.h # @@ -1242,14 +1242,14 @@ all: lib # Dynamic libsqlite3 # $(libsqlite3.SO): $(LIBOBJ) - $(TLINK.shared) -o $@ $(LIBOBJ) $(LDFLAGS_libsqlite3) + $(TLINK.shared) -o $@ $(LIBOBJ) $(LDFLAGS.libsqlite3) $(libsqlite3.SO)-1: $(libsqlite3.SO) $(libsqlite3.SO)-0 $(libsqlite3.SO)-: so: $(libsqlite3.SO)-$(ENABLE_SHARED) all: so # -# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(RELEASE) and +# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(VERSION.XYZ) and # create symlinks which point to it. Do we really need all of this # hoop-jumping? Can we not simply install the .so as-is to # libsqlite3.so (without the versioned bits)? @@ -1262,11 +1262,11 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) $(install-dir.lib) @echo "Setting up SO symlinks..."; \ cd $(install-dir.lib) || exit $$?; \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(RELEASE) || exit $$?; \ - mv $(libsqlite3.SO) $(libsqlite3.SO).$(RELEASE) || exit $$?; \ - ln -s $(libsqlite3.SO).$(RELEASE) $(libsqlite3.SO).3 || exit $$?; \ + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(VERSION.XYZ) || exit $$?; \ + mv $(libsqlite3.SO) $(libsqlite3.SO).$(VERSION.XYZ) || exit $$?; \ + ln -s $(libsqlite3.SO).$(VERSION.XYZ) $(libsqlite3.SO).3 || exit $$?; \ ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ - ls -la $(libsqlite3.SO) $(libsqlite3.SO).3 $(libsqlite3.SO).$(RELEASE) + ls -la $(libsqlite3.SO) $(libsqlite3.SO).3 $(libsqlite3.SO).$(VERSION.XYZ) install-so-0 install-so-: install: install-so-$(ENABLE_SHARED) @@ -1288,11 +1288,11 @@ install: install-includes # libtclsqlite3... # pkgIndex.tcl: - echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ + echo 'package ifneeded sqlite3 $(VERSION.XYZ) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(TDLL) $(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) $(TLINK.shared) -o $@ tclsqlite.o \ - $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS_libsqlite3) \ + $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS.libsqlite3) \ $(libsqlite3.LIB) $(TCLLIB_RPATH) $(libtclsqlite3.SO)-1: $(libtclsqlite3.SO) $(libtclsqlite3.SO)-0 $(libtclsqlite3.SO)-: @@ -1314,21 +1314,21 @@ tclsqlite3.c: sqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c -CFLAGS_tclextension = $(CFLAGS_intree_includes) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) +CFLAGS.tclextension = $(CFLAGS.intree_includes) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) # # Build the SQLite TCL extension in a way that make it compatible # with whatever version of TCL is running as $TCLSH_CMD, possibly defined # by --with-tclsh= # tclextension: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS_tclextension) + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS.tclextension) # # Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD # to find it. # tclextension-install: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS_tclextension) + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS.tclextension) # # Install the SQLite TCL extension that is used by $TCLSH_CMD @@ -1411,7 +1411,7 @@ testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) $(TLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -o $@ $(TESTFIXTURE_SRC) \ $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) \ - $(CFLAGS_libsqlite3) $(LDFLAGS_libsqlite3) + $(CFLAGS.libsqlite3) $(LDFLAGS.libsqlite3) coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) @@ -1528,7 +1528,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c - $(TLINK) sqlite3_analyzer.c -o $@ $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) $(LDFLAGS_libsqlite3) + $(TLINK) sqlite3_analyzer.c -o $@ $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) $(LDFLAGS.libsqlite3) sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl \ @@ -1536,7 +1536,7 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(TEXE): has_tclconfig sqltclsh.c - $(TLINK) sqltclsh.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS_libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) + $(TLINK) sqltclsh.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS.libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. xbin: sqltclsh$(TEXE) @@ -1544,7 +1544,7 @@ xbin: sqltclsh$(TEXE) sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ - $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS_libsqlite3) + $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS.libsqlite3) xbin: sqlite3_expert$(TEXE) CHECKER_DEPS =\ @@ -1561,12 +1561,12 @@ sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c - $(TLINK) sqlite3_checker.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS_libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS_libsqlite3) + $(TLINK) sqlite3_checker.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS.libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) xbin: sqlite3_checker$(TEXE) dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.o $(TLINK) -DDBDUMP_STANDALONE -o $@ \ - $(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: dbdump$(TEXE) dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c @@ -1574,19 +1574,19 @@ dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c xbin: dbtotxt$(TEXE) showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: showdb$(TEXE) showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: showstat4$(TEXE) showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: showjournal$(TEXE) showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: showwal$(TEXE) showshm$(TEXE): $(TOP)/tool/showshm.c @@ -1594,24 +1594,24 @@ showshm$(TEXE): $(TOP)/tool/showshm.c xbin: showshm$(TEXE) index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.o - $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: index_usage$(TEXE) # Reminder: changeset does not build without -DSQLITE_ENABLE_SESSION changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.o - $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: changeset$(TEXE) changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.o - $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: changesetfuzz$(TEXE) rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: rollback-test$(TEXE) atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.o - $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: atrc$(TEXX) LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h @@ -1619,29 +1619,29 @@ LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h xbin: LogEst$(TEXE) wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.o - $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: wordcount$(TEXE) speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile - $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS_libsqlite3) + $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS.libsqlite3) xbin: speedtest1$(TEXE) startup$(TEXE): $(TOP)/test/startup.c sqlite3.c - $(TLINK) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS_libsqlite3) + $(TLINK) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3) xbin: startup$(TEXE) KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c - $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS_libsqlite3) + $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3) xbin: kvtest$(TEXE) #rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o -# $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS_libsqlite3) +# $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) #xbin: rbu$(EXE) loadfts$(EXE): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) - $(TLINK) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS_libsqlite3) + $(TLINK) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3) xbin: loadfts$(EXE) # This target will fail if the SQLite amalgamation contains any exported @@ -1688,20 +1688,20 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ $(TOP)/test/tt3_lookaside1.c threadtest3$(TEXE): sqlite3.o $(THREADTEST3_SRC) - $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(LDFLAGS_libsqlite3) + $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(LDFLAGS.libsqlite3) xbin: threadtest3$(TEXE) threadtest: threadtest3$(TEXE) ./threadtest3$(TEXE) threadtest5: sqlite3.c $(TOP)/test/threadtest5.c - $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS_libsqlite3) + $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3) xbin: threadtest5 sqlite3$(TEXE): shell.c sqlite3.c - $(TLINK) $(CFLAGS_READLINE) $(SHELL_OPT) -o $@ \ + $(TLINK) $(CFLAGS.readline) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ - $(LDFLAGS_libsqlite3) $(LDFLAGS_READLINE) + $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) # # Build sqlite3$(TEXE) by default except in wasi-sdk builds. Yes, the # semantics of 0 and 1 are confusingly swapped here. @@ -1716,14 +1716,14 @@ install-shell-1 install-shell-: install: install-shell-$(HAVE_WASI_SDK) sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h - $(TLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) install-diff: sqldiff$(TEXE) $(install-dir.bin) $(INSTALL) -s sqldiff$(TEXT) $(install-dir.bin) #install: install-diff dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h - $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: dbhash$(TEXE) RSYNC_SRC = \ @@ -1738,7 +1738,7 @@ RSYNC_OPT = \ -DSQLITE_OMIT_DEPRECATED sqlite3_rsync$(TEXE): $(RSYNC_SRC) - $(TCC.sqlite) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS_libsqlite3) + $(TCC.sqlite) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS.libsqlite3) xbin: sqlite3_rsync$(TEXE) install-rsync: sqlite3_rsync$(TEXE) $(install-dir.bin) @@ -1757,7 +1757,7 @@ install-pc: sqlite3.pc $(install-dir.pkgconfig) scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ - $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS_libsqlite3) + $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: scrub$(TEXE) srcck1$(BEXE): $(TOP)/tool/srcck1.c @@ -1776,24 +1776,24 @@ verify-source: ./src-verify$(BEXE) fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ - $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS_libsqlite3) + $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS.libsqlite3) fuzzy: fuzzershell$(TEXE) xbin: fuzzershell$(TEXE) fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(LDFLAGS.libsqlite3) fuzzy: fuzzcheck$(TEXE) xbin: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) $(TLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ - sqlite3.c $(LDFLAGS_libsqlite3) + sqlite3.c $(LDFLAGS.libsqlite3) fuzzy: fuzzcheck-asan$(TEXE) xbin: fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) $(TLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ - sqlite3.c $(LDFLAGS_libsqlite3) + sqlite3.c $(LDFLAGS.libsqlite3) fuzzy: fuzzcheck-ubsan$(TEXE) xbin: fuzzcheck-ubsan$(TEXE) @@ -1814,16 +1814,16 @@ run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(TLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ - $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) + $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS.libsqlite3) fuzzy: ossshell$(TEXE) xbin: ossshell$(TEXE) sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(LDFLAGS.libsqlite3) fuzzy: sessionfuzz$(TEXE) dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS_libsqlite3) + $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS.libsqlite3) fuzzy: dbfuzz$(TEXE) xbin: dbfuzz$(TEXE) @@ -1841,7 +1841,7 @@ DBFUZZ2_OPTS = \ dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h $(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ -DSTANDALONE -o dbfuzz2 \ - $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS_libsqlite3) + $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS.libsqlite3) mkdir -p dbfuzz2-dir cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir fuzzy: dbfuzz2$(TEXE) @@ -1849,7 +1849,7 @@ xbin: dbfuzz2$(TEXE) mptester$(TEXE): $(libsqlite3.LIB) $(TOP)/mptest/mptest.c $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c $(libsqlite3.LIB) \ - $(LDFLAGS_libsqlite3) + $(LDFLAGS.libsqlite3) xbin: mptester$(TEXE) MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 @@ -1969,7 +1969,7 @@ sqlite3.def: $(LIBOBJ) | sed 's/^.* _//' >>sqlite3.def sqlite3.dll: $(LIBOBJ) sqlite3.def - $(TCC.sqlite) $(LDFLAGS_SHOBJ) -o $@ sqlite3.def \ + $(TCC.sqlite) $(LDFLAGS.shobj) -o $@ sqlite3.def \ -Wl,"--strip-all" $(LIBOBJ) diff --git a/manifest b/manifest index 40ee1c6bdf..92a574f02e 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Generic\sbuild\scleanups. -D 2024-10-24T04:34:39.658 +C Potentially\scontroversial/unconventional\smakefile\ssymbol\srenamings\sand\sdocs\sexplaining\sthem. +D 2024-10-24T04:56:44.349 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in e5cd4b271a3ffbe4fd4c13ca8852d82352a4db9e9003b412d81437d0d4309f23 -F Makefile.linux-generic e79bf7b51f2cc7513f0f673070ad528f3311ba178599f257cb4d04bbd968f497 +F Makefile.in 46856434b39ebe5b4cbdaef96710895e37c78e171ea8855467b87ed12fd16d2c +F Makefile.linux-generic eb13e3e981a1950c99ce26c177fe2c2d2a268da4c0b1fcba85bfdf56142be298 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 803569231944f6221794d4df9bd2623547f093570b8f0538767eca1cfa4a6566 +F main.mk e083730779a0c9c0ee686c8bfd50f3b1920d6923cd1711f63a2a113fdd9342dc F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a555ff6dbc2ded5a9c65c8ef483f3197298848a580dda25ba0b721ba13167ad4 -R 3e8eef5052286b2a46e0f9665a9d13cf +P be7b32a77f58ae3eb15cb828385035e63236b7e6c0669f90f2321f0509f0de1b +R 557f37869a74501ca173c9da84c9952b U stephan -Z 75f0c66b04971012069339b49ca2dbc2 +Z 0b592963de7475918e5543e03cef7bf3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2d335ed780..b969078803 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be7b32a77f58ae3eb15cb828385035e63236b7e6c0669f90f2321f0509f0de1b +7eceb7539dcce16104a93ad0ca1f755f23621751878cc4b01465e61333795b72 From b3cff449f96e0e9b543e80bc33c5fb499e2add8f Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 05:03:20 +0000 Subject: [PATCH 120/522] Bump version number to 3.48.0 (in this branch only - in trunk, doing so requires a specific autoconf version) and rename the RELEASE and VERSION makefile symbols for clarity's sake. FossilOrigin-Name: 4193d90f2158e25fe25f9bcf579ae38a6e0ab6c26f52cd07a777d67b87107632 --- Makefile.in | 4 ++-- VERSION | 2 +- auto.def | 14 +++++++------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Makefile.in b/Makefile.in index 5c0d9b667c..436ab3941d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -164,8 +164,8 @@ TCC += $(OPTS) # Release (X.Y.Z) and version (X.Y) numbers for the SQLite being # compiled. # -VERSION.XYZ = @RELEASE@ -# VERSION.XY = @VERSION@ # we don't currently use this anywhere +VERSION.XYZ = @VERSION_XYZ@ +# VERSION.XY = @VERSION_XY@ # we don't currently use this anywhere # # Filename extensions for binaries and libraries diff --git a/VERSION b/VERSION index 5e895b2435..7dd5eda815 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.47.0 +3.48.0 diff --git a/auto.def b/auto.def index 5cd51f8994..9c6eccbf0c 100644 --- a/auto.def +++ b/auto.def @@ -163,12 +163,12 @@ set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] msg-result "srcdir = $srcdir" msg-result "top_srcdir = $top_srcdir" -set RELEASE [readfile $::autosetup(srcdir)/VERSION] -regsub {([0-9]*\.*[0-9]*).*} $RELEASE {\1} VERSION -define VERSION $VERSION -define RELEASE $RELEASE -msg-result "RELEASE = $RELEASE" -msg-result "VERSION = $VERSION" +set VERSION_XYZ [readfile $::autosetup(srcdir)/VERSION] +regsub {([0-9]*\.*[0-9]*).*} $VERSION_XYZ {\1} VERSION_XY +define VERSION_XY $VERSION_XY +define VERSION_XYZ $VERSION_XYZ +msg-result "RELEASE = $VERSION_XYZ" +msg-result "VERSION = $VERSION_XY" define-append SQLITE_AUTOREMAKE cd $::autosetup(srcdir) && $top_srcdir/configure {*}$::autosetup(argv) @@ -959,7 +959,7 @@ hwaci-check-rpath hwaci-make-from-dot-in -touch Makefile sqlite3.pc # for sqlite_cfg.h define PACKAGE_URL {https://sqlite.org} -define PACKAGE_VERSION [get-define VERSION] +define PACKAGE_VERSION [get-define VERSION_XYZ] if {0} { # Requires a hand-written sqlite_cfg.h.in... hwaci-make-from-dot-in sqlite_cfg.h diff --git a/manifest b/manifest index 92a574f02e..3523ba29b6 100644 --- a/manifest +++ b/manifest @@ -1,19 +1,19 @@ -C Potentially\scontroversial/unconventional\smakefile\ssymbol\srenamings\sand\sdocs\sexplaining\sthem. -D 2024-10-24T04:56:44.349 +C Bump\sversion\snumber\sto\s3.48.0\s(in\sthis\sbranch\sonly\s-\sin\strunk,\sdoing\sso\srequires\sa\sspecific\sautoconf\sversion)\sand\srename\sthe\sRELEASE\sand\sVERSION\smakefile\ssymbols\sfor\sclarity's\ssake. +D 2024-10-24T05:03:20.051 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 46856434b39ebe5b4cbdaef96710895e37c78e171ea8855467b87ed12fd16d2c +F Makefile.in bd9798f56bbdc342f8d563ef7f5da7a87eb3cd95e52bfe3f834c1c86e9862538 F Makefile.linux-generic eb13e3e981a1950c99ce26c177fe2c2d2a268da4c0b1fcba85bfdf56142be298 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 -F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6 +F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 4979dcf77888bf31ff52a22cbbd197d0ca708c3f7f4d8cc32ebc32948673d440 +F auto.def 610865aa878f3367977b5c4d74ffa9b74d097d1f0e76ffa4a8c286322e0d4e63 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P be7b32a77f58ae3eb15cb828385035e63236b7e6c0669f90f2321f0509f0de1b -R 557f37869a74501ca173c9da84c9952b +P 7eceb7539dcce16104a93ad0ca1f755f23621751878cc4b01465e61333795b72 +R 706f84b6afa1da7be99c001c09d178a8 U stephan -Z 0b592963de7475918e5543e03cef7bf3 +Z 9e7d56afc7541bc2579fecb7499ab27a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b969078803..737f06142b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7eceb7539dcce16104a93ad0ca1f755f23621751878cc4b01465e61333795b72 +4193d90f2158e25fe25f9bcf579ae38a6e0ab6c26f52cd07a777d67b87107632 From 30b20563e453759481548699b73e9a4f1cfc7b18 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 05:33:30 +0000 Subject: [PATCH 121/522] More potentially-controversial makefile symbol renaming. This is simply more readable to my eyes. FossilOrigin-Name: 6d4d1d5fefb82ec7458efc2e93c933d9dc415dfa06fa46ff4725c30fc920ca5a --- Makefile.in | 44 +-- main.mk | 766 +++++++++++++++++++++++++------------------------- manifest | 14 +- manifest.uuid | 2 +- 4 files changed, 413 insertions(+), 413 deletions(-) diff --git a/Makefile.in b/Makefile.in index 436ab3941d..31f715fe62 100644 --- a/Makefile.in +++ b/Makefile.in @@ -94,8 +94,8 @@ includedir ?= @includedir@ INSTALL = @BIN_INSTALL@ AR = @AR@ CC = @CC@ -BCC = @BUILD_CC@ @BUILD_CFLAGS@ -TCC = $(CC) $(CFLAGS) +B.cc = @BUILD_CC@ @BUILD_CFLAGS@ +T.cc = $(CC) $(CFLAGS) CFLAGS = @CFLAGS@ @SH_CFLAGS@ LDFLAGS.shobj = @SHOBJ_LDFLAGS@ @@ -110,15 +110,15 @@ CFLAGS.readline = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ ENABLE_SHARED = @ENABLE_SHARED@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ -TCC.sqlite = $(TCC) @TARGET_DEBUG@ +T.cc.sqlite = $(T.cc) @TARGET_DEBUG@ # # Define -D_HAVE_SQLITE_CONFIG_H so that the code knows it # can include the generated sqlite_cfg.h. # -TCC.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite +T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # -# main.mk will fill out TCC.sqlite with some flags common to all builds. +# main.mk will fill out T.cc.sqlite with some flags common to all builds. #XX#CFLAGS.readline += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ #XX#CFLAGS.readline += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ @@ -129,7 +129,7 @@ TCC.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite #XX# #XX## Should the database engine be compiled threadsafe #XX## -#XX#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ +#XX#T.cc += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ # # $(JIMSH) and $(CFLAGS.JIMSH) are documented in main.mk. @@ -138,10 +138,10 @@ CFLAGS.JIMSH = @CFLAGS_JIMSH@ JIMSH = $(TOP)/jimsh$(TEXE) # -# $(BTCLSH) is documented in main.mk. +# $(B.tclsh) is documented in main.mk. # -BTCLSH = @BTCLSH@ -$(BTCLSH): +B.tclsh = @BTCLSH@ +$(B.tclsh): # # $(CFLAGS.libsqlite3) is documented in main.mk. @@ -150,7 +150,7 @@ CFLAGS.libsqlite3 = $(CFLAGS) -DSQLITE_TEMP_STORE=@TEMP_STORE@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) -TCC += $(OPT_FEATURE_FLAGS) +T.cc += $(OPT_FEATURE_FLAGS) # # Add in any optional global compilation flags on the make commane @@ -158,7 +158,7 @@ TCC += $(OPT_FEATURE_FLAGS) # #XX# FIXME: rename one or the other of $(OPTS) and $(OPTIONS), as they #XX# serve different purposes. -TCC += $(OPTS) +T.cc += $(OPTS) # # Release (X.Y.Z) and version (X.Y) numbers for the SQLite being @@ -170,12 +170,12 @@ VERSION.XYZ = @VERSION_XYZ@ # # Filename extensions for binaries and libraries # -BEXE = @BUILD_EXEEXT@ -TEXE = @TARGET_EXEEXT@ -BDLL = @BUILD_DLLEXT@ -TDLL = @TARGET_DLLEXT@ -BLIB = @BUILD_LIBEXT@ -TLIB = @TARGET_LIBEXT@ +B.exe = @BUILD_EXEEXT@ +T.exe = @TARGET_EXEEXT@ +B.dll = @BUILD_DLLEXT@ +T.dll = @TARGET_DLLEXT@ +B.lib = @BUILD_LIBEXT@ +T.lib = @TARGET_LIBEXT@ # # $(HAVE_TCL) is 1 if the configure script was able to locate the @@ -231,8 +231,8 @@ TCLLIBDIR = @TCLLIBDIR@ CFLAGS.GCOV1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage LDFLAGS.GCOV1 = -lgcov USE_GCOV = @USE_GCOV@ -TCOMPILE.EXTRAS += $(CFLAGS.GCOV$(USE_GCOV)) -TLINK.EXTRAS += $(LDFLAGS.GCOV$(USE_GCOV)) +T.compile.extras += $(CFLAGS.GCOV$(USE_GCOV)) +T.link.extras += $(LDFLAGS.GCOV$(USE_GCOV)) # # Vars with the AS_ prefix are specifically related to AutoSetup. @@ -250,7 +250,7 @@ USE_AMALGAMATION ?= @USE_AMALGAMATION@ AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ # -# CFLAGS for sqlite3$(TEXE) +# CFLAGS for sqlite3$(T.exe) # SHELL_OPT ?= @OPT_SHELL@ @@ -323,7 +323,7 @@ distclean: distclean-autosetup # tool/version-info: a utility for emitting sqlite3 version info # in various forms. # -version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h - $(TLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c +version-info$(T.exe): $(TOP)/tool/version-info.c Makefile sqlite3.h + $(T.link) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c include $(TOP)/main.mk diff --git a/main.mk b/main.mk index 69ebeaa9bc..e8567d3694 100644 --- a/main.mk +++ b/main.mk @@ -31,55 +31,55 @@ TOP ?= $(PWD) # VERSION.XYZ ?= # -# $(BCC) = +# $(B.cc) = # # C Compiler and options for use in building executables that will run # on the platform that is doing the build. # -BCC ?= $(CC) +B.cc ?= $(CC) # -# $(TCC) = +# $(T.cc) = # # C Compiler and options for use in building executables that will run -# on the target platform. This is usually the same as BCC, unless you +# on the target platform. This is usually the same as B.cc, unless you # are cross-compiling. Note that it should only contain flags which # are used by _all_ build targets. Flags needed only by specific # targets are defined elsewhere and applied on a per-target basis. # -TCC ?= $(BCC) +T.cc ?= $(B.cc) # # $(AR) = # Tool used to build a static library from object files. # AR ?= ar # -# $(BEXE) = +# $(B.exe) = # # File extension for executables on the build platform. ".exe" for # Windows and "" everywhere else. # -BEXE ?= +B.exe ?= # -# $(BDLL) and $(BLIB) = +# $(B.dll) and $(B.lib) = # -# The DLL resp. static library counterparts of $(BEXE). +# The DLL resp. static library counterparts of $(B.exe). # -BDLL ?= .so -BLIB ?= .lib +B.dll ?= .so +B.lib ?= .lib # -# $(TEXE) = +# $(T.exe) = # # File extension for executables on the target platform. ".exe" for # Windows and "" everywhere else. # -TEXE ?= +T.exe ?= # -# $(TDLL) and $(TLIB) = +# $(T.dll) and $(T.lib) = # -# The DLL resp. static library counterparts of $(TEXE). +# The DLL resp. static library counterparts of $(T.exe). # -TDLL ?= .so -TLIB ?= .lib +T.dll ?= .so +T.lib ?= .lib # # $(TCLSH_CMD) = # @@ -99,16 +99,16 @@ TCLSH_CMD ?= tclsh # can be used as a shell command. # CFLAGS.JIMSH ?= -DHAVE_REALPATH -JIMSH ?= ./jimsh$(TEXE) +JIMSH ?= ./jimsh$(T.exe) # -# $(BTCLSH) = +# $(B.tclsh) = # # The TCL interpreter for in-tree code generation. May be either the # in-tree JimTCL ($(JIMSH)) or the canonical TCL ($(TCLSH_CMD). If # it's JimTCL, it must be compiled with -DHAVE_REALPATH or # -DHAVE__FULLPATH. # -BTCLSH ?= $(JIMSH) +B.tclsh ?= $(JIMSH) # # $(LDFLAGS.{feature}) and $(CFLAGS.{feature}) = @@ -151,7 +151,7 @@ INSTALL ?= install # # $(ENABLE_SHARED) = # -# 1 if libsqlite3.$(TDLL) should be built. +# 1 if libsqlite3.$(T.dll) should be built. # ENABLE_SHARED ?= 1 # @@ -220,12 +220,12 @@ HAVE_WASI_SDK ?= 0 # CFLAGS.libsqlite3 ?= $(CFLAGS) # -# $(TCC.sqlite) is $(TCC) plus any flags which are desired for the +# $(T.cc.sqlite) is $(T.cc) plus any flags which are desired for the # library as a whole, but not necessarily needed for every binary. It # will normally get initially populated with flags by the # configure-generated makefile. # -TCC.sqlite ?= $(TCC) +T.cc.sqlite ?= $(T.cc) # # ... and many, many more. Sane defaults are selected where possible. # @@ -248,10 +248,10 @@ INSTALL.noexec = $(INSTALL) -m 0644 # ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... # -# $(TCOMPILE) = generic target platform compiler invocation -# $(TCOMPILE.EXTRAS) = config-specific flags for $(TCOMPILE) +# $(T.compile) = generic target platform compiler invocation +# $(T.compile.extras) = config-specific flags for $(T.compile) # -TCOMPILE = $(TCC) $(TCOMPILE.EXTRAS) +T.compile = $(T.cc) $(T.compile.extras) # # $(CFLAGS.intree_includes) = -I... flags relevant specifically to @@ -262,31 +262,31 @@ CFLAGS.intree_includes = \ -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \ -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session \ -I$(TOP)/ext/misc -I$(TOP)/ext/userauth -TCC.sqlite += $(CFLAGS.intree_includes) +T.cc.sqlite += $(CFLAGS.intree_includes) # -# $(TCC.extension) = compiler invocation for loadable extensions. +# $(T.cc.extension) = compiler invocation for loadable extensions. # -TCC.extension = $(TCOMPILE) -I. -I$(TOP)/src -DSQLITE_CORE +T.cc.extension = $(T.compile) -I. -I$(TOP)/src -DSQLITE_CORE # -# $(TLINK) = compiler invocation for when the target will be an +# $(T.link) = compiler invocation for when the target will be an # executable. # -# $(TLINK.EXTRAS) = optional config-specific flags for $(TLINK) +# $(T.link.extras) = optional config-specific flags for $(T.link) # -TLINK = $(TCC.sqlite) $(TLINK.EXTRAS) +T.link = $(T.cc.sqlite) $(T.link.extras) # -# $(TLINK.shared) = $(TLINK) invocation specifically for shared libraries +# $(T.link.shared) = $(T.link) invocation specifically for shared libraries # -TLINK.shared = $(TLINK) $(LDFLAGS.shobj) +T.link.shared = $(T.link) $(LDFLAGS.shobj) # # LDFLAGS.libsqlite3 should be used with any target which either # results in building libsqlite3.so, compiles sqlite3.c directly, or # links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these # flags are for the target build platform, not necessarily localhost. -# i.e. it should be used with $(TCC.sqlite) or $(TLINK) but not $(BCC). +# i.e. it should be used with $(T.cc.sqlite) or $(T.link) but not $(B.cc). # LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ @@ -328,7 +328,7 @@ $(install-dir.all): # accepts only a single argument. # $(JIMSH): $(TOP)/autosetup/jimsh0.c - $(BCC) -o $@ $(CFLAGS.JIMSH) $(TOP)/autosetup/jimsh0.c + $(B.cc) -o $@ $(CFLAGS.JIMSH) $(TOP)/autosetup/jimsh0.c @if [ x = "x$$($(JIMSH) -e 'file normalize $(JIMSH)' 2>/dev/null)" ]; then \ echo "$(JIMSH) was built without -DHAVE_REALPATH or -DHAVE__FULLPATH." 1>&2; \ exit 1; \ @@ -356,10 +356,10 @@ $(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) @if [ ! -d "$(TOP)" ]; then echo "$(TOP) is not a directory" 1>&2; exit 1; fi @if [ ! -f "$(TOP)/auto.def" ]; then echo "$(TOP) does not appear to be the top-most source dir" 1>&2; exit 1; fi @if [ x = "x$(VERSION.XYZ)" ]; then echo "VERSION.XYZ must be set to the library's X.Y.Z-format version number" 1>&2; exit 1; fi - @if [ x = "x$(BCC)" ]; then echo "Missing BCC var" 1>&2; exit 1; fi - @if [ x = "x$(TCC)" ]; then echo "Missing TCC var" 1>&2; exit 1; fi + @if [ x = "x$(B.cc)" ]; then echo "Missing B.cc var" 1>&2; exit 1; fi + @if [ x = "x$(T.cc)" ]; then echo "Missing T.cc var" 1>&2; exit 1; fi @if [ x = "x$(VERSION.XYZ)" ]; then echo "Missing VERSION.XYZ var" 1>&2; exit 1; fi - @if [ x = "x$(BTCLSH)" ]; then echo "Missing BTCLSH var" 1>&2; exit 1; fi + @if [ x = "x$(B.tclsh)" ]; then echo "Missing B.tclsh var" 1>&2; exit 1; fi touch $@ clean-sanity-check: rm -f $(MAKE_SANITY_CHECK) @@ -770,12 +770,12 @@ EXTHDR += \ # Executables needed for testing # TESTPROGS = \ - testfixture$(TEXE) \ - sqlite3$(TEXE) \ - sqlite3_analyzer$(TEXE) \ - sqldiff$(TEXE) \ - dbhash$(TEXE) \ - sqltclsh$(TEXE) + testfixture$(T.exe) \ + sqlite3$(T.exe) \ + sqlite3_analyzer$(T.exe) \ + sqldiff$(T.exe) \ + dbhash$(T.exe) \ + sqltclsh$(T.exe) # Databases containing fuzzer test cases # @@ -877,49 +877,49 @@ has_tclconfig: # all that automatic generation. # .target_source: $(MAKE_SANITY_CHECK) $(SRC) $(TOP)/tool/vdbe-compress.tcl \ - fts5.c $(BTCLSH) # has_tclsh84 + fts5.c $(B.tclsh) # has_tclsh84 rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - $(BTCLSH) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new + $(B.tclsh) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new mv vdbe.new tsrc/vdbe.c cp fts5.c fts5.h tsrc touch .target_source -libsqlite3.LIB = libsqlite3$(TLIB) -libsqlite3.SO = libsqlite3$(TDLL) +libsqlite3.LIB = libsqlite3$(T.lib) +libsqlite3.SO = libsqlite3$(T.dll) # Rules to build the LEMON compiler generator # -lemon$(BEXE): $(MAKE_SANITY_CHECK) $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c - $(BCC) -o $@ $(TOP)/tool/lemon.c +lemon$(B.exe): $(MAKE_SANITY_CHECK) $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c + $(B.cc) -o $@ $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . # Rules to build the program that generates the source-id # -mksourceid$(BEXE): $(MAKE_SANITY_CHECK) $(TOP)/tool/mksourceid.c - $(BCC) -o $@ $(TOP)/tool/mksourceid.c +mksourceid$(B.exe): $(MAKE_SANITY_CHECK) $(TOP)/tool/mksourceid.c + $(B.cc) -o $@ $(TOP)/tool/mksourceid.c sqlite3.h: $(MAKE_SANITY_CHECK) $(TOP)/src/sqlite.h.in \ - $(TOP)/manifest mksourceid$(BEXE) \ - $(TOP)/VERSION $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h + $(TOP)/manifest mksourceid$(B.exe) \ + $(TOP)/VERSION $(B.tclsh) # has_tclsh84 + $(B.tclsh) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify \ - $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) + $(B.tclsh) # has_tclsh84 + $(B.tclsh) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . -sqlite3r.h: sqlite3.h $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h +sqlite3r.h: sqlite3.h $(B.tclsh) # has_tclsh84 + $(B.tclsh) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -sqlite3r.c: sqlite3.c sqlite3r.h $(BTCLSH) # has_tclsh84 +sqlite3r.c: sqlite3.c sqlite3r.h $(B.tclsh) # has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ - $(BTCLSH) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) + $(B.tclsh) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) sqlite3ext.h: .target_source cp tsrc/sqlite3ext.h . @@ -932,303 +932,303 @@ sqlite3ext.h: .target_source # DEPS_OBJ_COMMON = $(MAKE_SANITY_CHECK) $(HDR) parse.o: parse.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c parse.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c parse.c opcodes.o: opcodes.c - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c opcodes.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c opcodes.c # Rules to build individual *.o files from files in the src directory. # alter.o: $(TOP)/src/alter.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/alter.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/alter.c analyze.o: $(TOP)/src/analyze.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/analyze.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/analyze.c attach.o: $(TOP)/src/attach.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/attach.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/attach.c auth.o: $(TOP)/src/auth.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/auth.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/auth.c backup.o: $(TOP)/src/backup.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/backup.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/backup.c bitvec.o: $(TOP)/src/bitvec.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/bitvec.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/bitvec.c btmutex.o: $(TOP)/src/btmutex.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/btmutex.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/btmutex.c btree.o: $(TOP)/src/btree.c $(DEPS_OBJ_COMMON) $(TOP)/src/pager.h - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/btree.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/btree.c build.o: $(TOP)/src/build.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/build.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/build.c callback.o: $(TOP)/src/callback.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/callback.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/callback.c complete.o: $(TOP)/src/complete.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/complete.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/complete.c ctime.o: $(TOP)/src/ctime.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/ctime.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/ctime.c date.o: $(TOP)/src/date.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/date.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/date.c dbpage.o: $(TOP)/src/dbpage.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/dbpage.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/dbpage.c dbstat.o: $(TOP)/src/dbstat.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/dbstat.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/dbstat.c delete.o: $(TOP)/src/delete.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/delete.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/delete.c expr.o: $(TOP)/src/expr.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/expr.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/expr.c fault.o: $(TOP)/src/fault.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/fault.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/fault.c fkey.o: $(TOP)/src/fkey.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/fkey.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/fkey.c func.o: $(TOP)/src/func.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/func.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/func.c global.o: $(TOP)/src/global.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/global.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/global.c hash.o: $(TOP)/src/hash.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/hash.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/insert.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/insert.c json.o: $(TOP)/src/json.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/json.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/json.c legacy.o: $(TOP)/src/legacy.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/legacy.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/legacy.c loadext.o: $(TOP)/src/loadext.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/loadext.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/loadext.c main.o: $(TOP)/src/main.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/main.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/main.c malloc.o: $(TOP)/src/malloc.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/malloc.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/malloc.c mem0.o: $(TOP)/src/mem0.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem0.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem0.c mem1.o: $(TOP)/src/mem1.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem1.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem1.c mem2.o: $(TOP)/src/mem2.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem2.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem2.c mem3.o: $(TOP)/src/mem3.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem3.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem3.c mem5.o: $(TOP)/src/mem5.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem5.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem5.c memdb.o: $(TOP)/src/memdb.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/memdb.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/memdb.c memjournal.o: $(TOP)/src/memjournal.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/memjournal.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/memjournal.c mutex.o: $(TOP)/src/mutex.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex.c mutex_noop.o: $(TOP)/src/mutex_noop.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_noop.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_noop.c mutex_unix.o: $(TOP)/src/mutex_unix.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_unix.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_unix.c mutex_w32.o: $(TOP)/src/mutex_w32.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_w32.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_w32.c notify.o: $(TOP)/src/notify.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/notify.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/notify.c pager.o: $(TOP)/src/pager.c $(DEPS_OBJ_COMMON) $(TOP)/src/pager.h - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pager.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pager.c pcache.o: $(TOP)/src/pcache.c $(DEPS_OBJ_COMMON) $(TOP)/src/pcache.h - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pcache.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pcache.c pcache1.o: $(TOP)/src/pcache1.c $(DEPS_OBJ_COMMON) $(TOP)/src/pcache.h - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pcache1.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pcache1.c os.o: $(TOP)/src/os.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os.c os_kv.o: $(TOP)/src/os_kv.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_kv.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_kv.c os_unix.o: $(TOP)/src/os_unix.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_unix.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_unix.c os_win.o: $(TOP)/src/os_win.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_win.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_win.c pragma.o: $(TOP)/src/pragma.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pragma.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pragma.c prepare.o: $(TOP)/src/prepare.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/prepare.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/prepare.c printf.o: $(TOP)/src/printf.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/printf.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/printf.c random.o: $(TOP)/src/random.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/random.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/random.c resolve.o: $(TOP)/src/resolve.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/resolve.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/resolve.c rowset.o: $(TOP)/src/rowset.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/rowset.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/rowset.c select.o: $(TOP)/src/select.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/select.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/select.c status.o: $(TOP)/src/status.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/status.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/status.c sqlite3.o: sqlite3.h sqlite3.c - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c sqlite3.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c sqlite3.c table.o: $(TOP)/src/table.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/table.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/table.c threads.o: $(TOP)/src/threads.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/threads.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/threads.c tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/tokenize.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/tokenize.c treeview.o: $(TOP)/src/treeview.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/treeview.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/treeview.c trigger.o: $(TOP)/src/trigger.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/trigger.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/trigger.c update.o: $(TOP)/src/update.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/update.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/update.c upsert.o: $(TOP)/src/upsert.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/upsert.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/upsert.c utf.o: $(TOP)/src/utf.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/utf.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/utf.c util.o: $(TOP)/src/util.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/util.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/util.c vacuum.o: $(TOP)/src/vacuum.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vacuum.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vacuum.c vdbe.o: $(TOP)/src/vdbe.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbe.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbe.c vdbeapi.o: $(TOP)/src/vdbeapi.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeapi.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeapi.c vdbeaux.o: $(TOP)/src/vdbeaux.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeaux.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeaux.c vdbeblob.o: $(TOP)/src/vdbeblob.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeblob.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeblob.c vdbemem.o: $(TOP)/src/vdbemem.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbemem.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbemem.c vdbesort.o: $(TOP)/src/vdbesort.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbesort.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbesort.c vdbetrace.o: $(TOP)/src/vdbetrace.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbetrace.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbetrace.c vdbevtab.o: $(TOP)/src/vdbevtab.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbevtab.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbevtab.c vtab.o: $(TOP)/src/vtab.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vtab.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vtab.c wal.o: $(TOP)/src/wal.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/wal.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/wal.c walker.o: $(TOP)/src/walker.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/walker.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/walker.c where.o: $(TOP)/src/where.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/where.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/where.c wherecode.o: $(TOP)/src/wherecode.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/wherecode.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/wherecode.c whereexpr.o: $(TOP)/src/whereexpr.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/whereexpr.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/whereexpr.c window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON) - $(TCC.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/window.c + $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/window.c tclsqlite.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(TCOMPILE) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS.intree_includes) \ + $(T.compile) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS.intree_includes) \ -c $(TOP)/src/tclsqlite.c tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(TCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) + $(T.compile) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(TCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) + $(T.compile) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) -tclsqlite3$(TEXE): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) - $(TLINK) -o $@ tclsqlite-shell.o \ +tclsqlite3$(T.exe): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) + $(T.link) -o $@ tclsqlite-shell.o \ $(libsqlite3.LIB) $(TCL_INCLUDE_SPEC) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(B.tclsh) # has_tclsh84 + $(B.tclsh) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c opcodes.h: parse.h $(TOP)/src/vdbe.c \ - $(TOP)/tool/mkopcodeh.tcl $(BTCLSH) # has_tclsh84 - cat parse.h $(TOP)/src/vdbe.c | $(BTCLSH) $(TOP)/tool/mkopcodeh.tcl >opcodes.h + $(TOP)/tool/mkopcodeh.tcl $(B.tclsh) # has_tclsh84 + cat parse.h $(TOP)/src/vdbe.c | $(B.tclsh) $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. # parse.h: parse.c -parse.c: $(TOP)/src/parse.y lemon$(BEXE) +parse.c: $(TOP)/src/parse.y lemon$(B.exe) cp $(TOP)/src/parse.y . - ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y + ./lemon$(B.exe) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y -sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(BTCLSH) # has_tclsh84 +sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(B.tclsh) # has_tclsh84 echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ - cat $(TOP)/VERSION | $(BTCLSH) $(TOP)/tool/replace.tcl exact . , >>$@ + cat $(TOP)/VERSION | $(B.tclsh) $(TOP)/tool/replace.tcl exact . , >>$@ echo '#endif' >>sqlite3rc.h -mkkeywordhash$(BEXE): $(TOP)/tool/mkkeywordhash.c - $(BCC) -o $@ $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c -keywordhash.h: mkkeywordhash$(BEXE) - ./mkkeywordhash$(BEXE) > $@ +mkkeywordhash$(B.exe): $(TOP)/tool/mkkeywordhash.c + $(B.cc) -o $@ $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c +keywordhash.h: mkkeywordhash$(B.exe) + ./mkkeywordhash$(B.exe) > $@ # # sqlite3.c split into many smaller files. # -sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/split-sqlite3c.tcl +sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(B.tclsh) # has_tclsh84 + $(B.tclsh) $(TOP)/tool/split-sqlite3c.tcl # # Static libsqlite3 @@ -1242,7 +1242,7 @@ all: lib # Dynamic libsqlite3 # $(libsqlite3.SO): $(LIBOBJ) - $(TLINK.shared) -o $@ $(LIBOBJ) $(LDFLAGS.libsqlite3) + $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.libsqlite3) $(libsqlite3.SO)-1: $(libsqlite3.SO) $(libsqlite3.SO)-0 $(libsqlite3.SO)-: so: $(libsqlite3.SO)-$(ENABLE_SHARED) @@ -1289,9 +1289,9 @@ install: install-includes # pkgIndex.tcl: echo 'package ifneeded sqlite3 $(VERSION.XYZ) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ -libtclsqlite3.SO = libtclsqlite3$(TDLL) +libtclsqlite3.SO = libtclsqlite3$(T.dll) $(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) - $(TLINK.shared) -o $@ tclsqlite.o \ + $(T.link.shared) -o $@ tclsqlite.o \ $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS.libsqlite3) \ $(libsqlite3.LIB) $(TCLLIB_RPATH) $(libtclsqlite3.SO)-1: $(libtclsqlite3.SO) @@ -1363,22 +1363,22 @@ FTS5_SRC = \ $(TOP)/ext/fts5/fts5_varint.c \ $(TOP)/ext/fts5/fts5_vocab.c \ -fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE) +fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(B.exe) cp $(TOP)/ext/fts5/fts5parse.y . rm -f fts5parse.h - ./lemon$(BEXE) $(OPTS) -S fts5parse.y + ./lemon$(B.exe) $(OPTS) -S fts5parse.y fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/ext/fts5/tool/mkfts5c.tcl +fts5.c: $(FTS5_SRC) $(B.tclsh) # has_tclsh84 + $(B.tclsh) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . fts5.o: fts5.c $(DEPS_OBJ_COMMON) $(EXTHDR) - $(TCC.extension) -c fts5.c + $(T.cc.extension) -c fts5.c sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(DEPS_OBJ_COMMON) $(EXTHDR) - $(TCC.extension) -c $(TOP)/ext/rbu/sqlite3rbu.c + $(T.cc.extension) -c $(TOP)/ext/rbu/sqlite3rbu.c # @@ -1407,30 +1407,30 @@ TESTFIXTURE_SRC1 = sqlite3.c TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) -testfixture$(TEXE): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) - $(TLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ +testfixture$(T.exe): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) + $(T.link) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -o $@ $(TESTFIXTURE_SRC) \ $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) \ $(CFLAGS.libsqlite3) $(LDFLAGS.libsqlite3) -coretestprogs: testfixture$(BEXE) sqlite3$(BEXE) +coretestprogs: testfixture$(B.exe) sqlite3$(B.exe) -testprogs: $(TESTPROGS) srcck1$(BEXE) fuzzcheck$(TEXE) sessionfuzz$(TEXE) +testprogs: $(TESTPROGS) srcck1$(B.exe) fuzzcheck$(T.exe) sessionfuzz$(T.exe) # A very detailed test running most or all test cases fulltest: alltest fuzztest # Run most or all tcl test cases alltest: $(TESTPROGS) - ./testfixture$(TEXE) $(TOP)/test/all.test $(TESTOPTS) + ./testfixture$(T.exe) $(TOP)/test/all.test $(TESTOPTS) # Really really long testing soaktest: $(TESTPROGS) - ./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS) + ./testfixture$(T.exe) $(TOP)/test/all.test -soak=1 $(TESTOPTS) # Do extra testing but not everything. fulltestonly: $(TESTPROGS) fuzztest - ./testfixture$(TEXE) $(TOP)/test/full.test + ./testfixture$(T.exe) $(TOP)/test/full.test # # Fuzz testing @@ -1440,26 +1440,26 @@ fulltestonly: $(TESTPROGS) fuzztest # commands. Therefore, if this target is updated, then code in # testrunner_data.tcl (search for "trd_fuzztest_data") must also be updated. # -fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) - ./fuzzcheck$(TEXE) $(FUZZDATA) - ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db +fuzztest: fuzzcheck$(T.exe) $(FUZZDATA) sessionfuzz$(T.exe) + ./fuzzcheck$(T.exe) $(FUZZDATA) + ./sessionfuzz$(T.exe) run $(TOP)/test/sessionfuzz-data1.db -valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) - valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) - valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db +valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(T.exe) + valgrind ./fuzzcheck$(T.exe) --cell-size-check --limit-mem 10M $(FUZZDATA) + valgrind ./sessionfuzz$(T.exe) run $(TOP)/test/sessionfuzz-data1.db # # The veryquick.test TCL tests. # -tcltest: ./testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) +tcltest: ./testfixture$(T.exe) + ./testfixture$(T.exe) $(TOP)/test/veryquick.test $(TESTOPTS) # # Runs all the same tests cases as the "tcltest" target but uses # the testrunner.tcl script to run them in multiple cores # concurrently. -testrunner: testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl +testrunner: testfixture$(T.exe) + ./testfixture$(T.exe) $(TOP)/test/testrunner.tcl # # This is the testing target preferred by the core SQLite developers. @@ -1493,8 +1493,8 @@ releasetest: srctree-check has_tclsh85 verify-source # # Minimal testing that runs in less than 3 minutes # -quicktest: ./testfixture$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS) +quicktest: ./testfixture$(T.exe) + ./testfixture$(T.exe) $(TOP)/test/extraquick.test $(TESTOPTS) # # Try to run tests on whatever options are specified by the @@ -1510,42 +1510,42 @@ test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest # because valgrind is so much slower than a native machine. # valgrindtest: $(TESTPROGS) valgrindfuzz - OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind $(TESTOPTS) + OMIT_MISUSE=1 valgrind -v ./testfixture$(T.exe) $(TOP)/test/permutations.test valgrind $(TESTOPTS) # # A very fast test that checks basic sanity. The name comes from # the 60s-era electronics testing: "Turn it on and see if smoke # comes out." # -smoketest: $(TESTPROGS) fuzzcheck$(TEXE) - ./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS) +smoketest: $(TESTPROGS) fuzzcheck$(T.exe) + ./testfixture$(T.exe) $(TOP)/test/main.test $(TESTOPTS) shelltest: $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 - $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c + $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c -sqlite3_analyzer$(TEXE): has_tclconfig sqlite3_analyzer.c - $(TLINK) sqlite3_analyzer.c -o $@ $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) $(LDFLAGS.libsqlite3) +sqlite3_analyzer$(T.exe): has_tclconfig sqlite3_analyzer.c + $(T.link) sqlite3_analyzer.c -o $@ $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) $(LDFLAGS.libsqlite3) 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 has_tclsh85 - $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c + $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c -sqltclsh$(TEXE): has_tclconfig sqltclsh.c - $(TLINK) sqltclsh.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS.libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) +sqltclsh$(T.exe): has_tclconfig sqltclsh.c + $(T.link) sqltclsh.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS.libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. -xbin: sqltclsh$(TEXE) +xbin: sqltclsh$(T.exe) -sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ +sqlite3_expert$(T.exe): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c - $(TLINK) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ + $(T.link) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS.libsqlite3) -xbin: sqlite3_expert$(TEXE) +xbin: sqlite3_expert$(T.exe) CHECKER_DEPS =\ $(TOP)/tool/mkccode.tcl \ @@ -1558,91 +1558,91 @@ CHECKER_DEPS =\ $(TOP)/ext/repair/sqlite3_checker.c.in sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 - $(BTCLSH) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ + $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ -sqlite3_checker$(TEXE): has_tclconfig sqlite3_checker.c - $(TLINK) sqlite3_checker.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS.libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) -xbin: sqlite3_checker$(TEXE) +sqlite3_checker$(T.exe): has_tclconfig sqlite3_checker.c + $(T.link) sqlite3_checker.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS.libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) +xbin: sqlite3_checker$(T.exe) -dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.o - $(TLINK) -DDBDUMP_STANDALONE -o $@ \ +dbdump$(T.exe): $(TOP)/ext/misc/dbdump.c sqlite3.o + $(T.link) -DDBDUMP_STANDALONE -o $@ \ $(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: dbdump$(TEXE) +xbin: dbdump$(T.exe) -dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c - $(TLINK)-o $@ $(TOP)/tool/dbtotxt.c -xbin: dbtotxt$(TEXE) +dbtotxt$(T.exe): $(TOP)/tool/dbtotxt.c + $(T.link)-o $@ $(TOP)/tool/dbtotxt.c +xbin: dbtotxt$(T.exe) -showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: showdb$(TEXE) +showdb$(T.exe): $(TOP)/tool/showdb.c sqlite3.o + $(T.link) -o $@ $(TOP)/tool/showdb.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: showdb$(T.exe) -showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: showstat4$(TEXE) +showstat4$(T.exe): $(TOP)/tool/showstat4.c sqlite3.o + $(T.link) -o $@ $(TOP)/tool/showstat4.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: showstat4$(T.exe) -showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: showjournal$(TEXE) +showjournal$(T.exe): $(TOP)/tool/showjournal.c sqlite3.o + $(T.link) -o $@ $(TOP)/tool/showjournal.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: showjournal$(T.exe) -showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: showwal$(TEXE) +showwal$(T.exe): $(TOP)/tool/showwal.c sqlite3.o + $(T.link) -o $@ $(TOP)/tool/showwal.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: showwal$(T.exe) -showshm$(TEXE): $(TOP)/tool/showshm.c - $(TLINK) -o $@ $(TOP)/tool/showshm.c -xbin: showshm$(TEXE) +showshm$(T.exe): $(TOP)/tool/showshm.c + $(T.link) -o $@ $(TOP)/tool/showshm.c +xbin: showshm$(T.exe) -index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.o - $(TLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: index_usage$(TEXE) +index_usage$(T.exe): $(TOP)/tool/index_usage.c sqlite3.o + $(T.link) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: index_usage$(T.exe) # Reminder: changeset does not build without -DSQLITE_ENABLE_SESSION -changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.o - $(TLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: changeset$(TEXE) +changeset$(T.exe): $(TOP)/ext/session/changeset.c sqlite3.o + $(T.link) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: changeset$(T.exe) -changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.o - $(TLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: changesetfuzz$(TEXE) +changesetfuzz$(T.exe): $(TOP)/ext/session/changesetfuzz.c sqlite3.o + $(T.link) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: changesetfuzz$(T.exe) -rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.o - $(TLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: rollback-test$(TEXE) +rollback-test$(T.exe): $(TOP)/tool/rollback-test.c sqlite3.o + $(T.link) -o $@ $(TOP)/tool/rollback-test.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: rollback-test$(T.exe) atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.o - $(TLINK) -o $@ $(TOP)/test/atrc.c sqlite3.o $(LDFLAGS.libsqlite3) + $(T.link) -o $@ $(TOP)/test/atrc.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: atrc$(TEXX) -LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h - $(TLINK) -I. -o $@ $(TOP)/tool/logest.c -xbin: LogEst$(TEXE) +LogEst$(T.exe): $(TOP)/tool/logest.c sqlite3.h + $(T.link) -I. -o $@ $(TOP)/tool/logest.c +xbin: LogEst$(T.exe) -wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.o - $(TLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: wordcount$(TEXE) +wordcount$(T.exe): $(TOP)/test/wordcount.c sqlite3.o + $(T.link) -o $@ $(TOP)/test/wordcount.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: wordcount$(T.exe) -speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c Makefile - $(TLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS.libsqlite3) -xbin: speedtest1$(TEXE) +speedtest1$(T.exe): $(TOP)/test/speedtest1.c sqlite3.c Makefile + $(T.link) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS.libsqlite3) +xbin: speedtest1$(T.exe) -startup$(TEXE): $(TOP)/test/startup.c sqlite3.c - $(TLINK) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3) -xbin: startup$(TEXE) +startup$(T.exe): $(TOP)/test/startup.c sqlite3.c + $(T.link) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3) +xbin: startup$(T.exe) KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ -kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c - $(TLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3) -xbin: kvtest$(TEXE) +kvtest$(T.exe): $(TOP)/test/kvtest.c sqlite3.c + $(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3) +xbin: kvtest$(T.exe) -#rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o -# $(TLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) -#xbin: rbu$(EXE) +#rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o +# $(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) +#xbin: rbu$(T.exe) -loadfts$(EXE): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) - $(TLINK) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3) -xbin: loadfts$(EXE) +loadfts$(T.exe): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) + $(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3) +xbin: loadfts$(T.exe) # This target will fail if the SQLite amalgamation contains any exported # symbols that do not begin with "sqlite3_". It is run as part of the @@ -1656,10 +1656,10 @@ checksymbols: sqlite3.o # Build a ZIP archive containing various command-line tools. # -tool-zip: testfixture$(TEXE) sqlite3$(TEXE) sqldiff$(TEXE) \ - sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) $(TOP)/tool/mktoolzip.tcl - strip sqlite3$(TEXE) sqldiff$(TEXE) sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) - ./testfixture$(TEXE) $(TOP)/tool/mktoolzip.tcl +tool-zip: testfixture$(T.exe) sqlite3$(T.exe) sqldiff$(T.exe) \ + sqlite3_analyzer$(T.exe) sqlite3_rsync$(T.exe) $(TOP)/tool/mktoolzip.tcl + strip sqlite3$(T.exe) sqldiff$(T.exe) sqlite3_analyzer$(T.exe) sqlite3_rsync$(T.exe) + ./testfixture$(T.exe) $(TOP)/tool/mktoolzip.tcl clean-tool-zip: rm -f sqlite-tools-*.zip clean: clean-tool-zip @@ -1687,44 +1687,44 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ $(TOP)/test/tt3_stress.c \ $(TOP)/test/tt3_lookaside1.c -threadtest3$(TEXE): sqlite3.o $(THREADTEST3_SRC) - $(TLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(LDFLAGS.libsqlite3) -xbin: threadtest3$(TEXE) +threadtest3$(T.exe): sqlite3.o $(THREADTEST3_SRC) + $(T.link) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(LDFLAGS.libsqlite3) +xbin: threadtest3$(T.exe) -threadtest: threadtest3$(TEXE) - ./threadtest3$(TEXE) +threadtest: threadtest3$(T.exe) + ./threadtest3$(T.exe) threadtest5: sqlite3.c $(TOP)/test/threadtest5.c - $(TLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3) + $(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3) xbin: threadtest5 -sqlite3$(TEXE): shell.c sqlite3.c - $(TLINK) $(CFLAGS.readline) $(SHELL_OPT) -o $@ \ +sqlite3$(T.exe): shell.c sqlite3.c + $(T.link) $(CFLAGS.readline) $(SHELL_OPT) -o $@ \ shell.c sqlite3.c \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) # -# Build sqlite3$(TEXE) by default except in wasi-sdk builds. Yes, the +# Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the # semantics of 0 and 1 are confusingly swapped here. # -sqlite3$(TEXE)-1: -sqlite3$(TEXE)-0 sqlite3$(TEXE)-: sqlite3$(TEXE) -all: sqlite3$(TEXE)-$(HAVE_WASI_SDK) +sqlite3$(T.exe)-1: +sqlite3$(T.exe)-0 sqlite3$(T.exe)-: sqlite3$(T.exe) +all: sqlite3$(T.exe)-$(HAVE_WASI_SDK) install-shell-0: sqlite3$(TEXT) $(install-dir.bin) $(INSTALL) -s sqlite3$(TEXT) $(install-dir.bin) install-shell-1 install-shell-: install: install-shell-$(HAVE_WASI_SDK) -sqldiff$(TEXE): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h - $(TLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) +sqldiff$(T.exe): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h + $(T.link) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) -install-diff: sqldiff$(TEXE) $(install-dir.bin) +install-diff: sqldiff$(T.exe) $(install-dir.bin) $(INSTALL) -s sqldiff$(TEXT) $(install-dir.bin) #install: install-diff -dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h - $(TLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: dbhash$(TEXE) +dbhash$(T.exe): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h + $(T.link) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: dbhash$(T.exe) RSYNC_SRC = \ $(TOP)/tool/sqlite3_rsync.c \ @@ -1737,11 +1737,11 @@ RSYNC_OPT = \ -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_OMIT_DEPRECATED -sqlite3_rsync$(TEXE): $(RSYNC_SRC) - $(TCC.sqlite) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS.libsqlite3) -xbin: sqlite3_rsync$(TEXE) +sqlite3_rsync$(T.exe): $(RSYNC_SRC) + $(T.cc.sqlite) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(LDFLAGS.libsqlite3) +xbin: sqlite3_rsync$(T.exe) -install-rsync: sqlite3_rsync$(TEXE) $(install-dir.bin) +install-rsync: sqlite3_rsync$(T.exe) $(install-dir.bin) $(INSTALL) sqlite3_rsync$(TEXT) $(install-dir.bin) #install: install-rsync @@ -1755,47 +1755,47 @@ install: install-man1 install-pc: sqlite3.pc $(install-dir.pkgconfig) $(INSTALL.noexec) sqlite3.pc $(install-dir.pkgconfig) -scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o - $(TLINK) -o $@ -I. -DSCRUB_STANDALONE \ +scrub$(T.exe): $(TOP)/ext/misc/scrub.c sqlite3.o + $(T.link) -o $@ -I. -DSCRUB_STANDALONE \ $(TOP)/ext/misc/scrub.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: scrub$(TEXE) +xbin: scrub$(T.exe) -srcck1$(BEXE): $(TOP)/tool/srcck1.c - $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c -xbin: srcck1$(BEXE) +srcck1$(B.exe): $(TOP)/tool/srcck1.c + $(B.cc) -o srcck1$(B.exe) $(TOP)/tool/srcck1.c +xbin: srcck1$(B.exe) -sourcetest: srcck1$(BEXE) sqlite3.c - ./srcck1$(BEXE) sqlite3.c +sourcetest: srcck1$(B.exe) sqlite3.c + ./srcck1$(B.exe) sqlite3.c -src-verify$(BEXE): $(TOP)/tool/src-verify.c - $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c -xbin: src-verify$(BEXE) +src-verify$(B.exe): $(TOP)/tool/src-verify.c + $(B.cc) -o src-verify$(B.exe) $(TOP)/tool/src-verify.c +xbin: src-verify$(B.exe) -verify-source: ./src-verify$(BEXE) - ./src-verify$(BEXE) $(TOP) +verify-source: ./src-verify$(B.exe) + ./src-verify$(B.exe) $(TOP) -fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(FUZZERSHELL_OPT) \ +fuzzershell$(T.exe): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h + $(T.link) -o $@ $(FUZZERSHELL_OPT) \ $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS.libsqlite3) -fuzzy: fuzzershell$(TEXE) -xbin: fuzzershell$(TEXE) +fuzzy: fuzzershell$(T.exe) +xbin: fuzzershell$(T.exe) -fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(TLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(LDFLAGS.libsqlite3) -fuzzy: fuzzcheck$(TEXE) -xbin: fuzzcheck$(TEXE) +fuzzcheck$(T.exe): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(T.link) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(LDFLAGS.libsqlite3) +fuzzy: fuzzcheck$(T.exe) +xbin: fuzzcheck$(T.exe) -fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(TLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ +fuzzcheck-asan$(T.exe): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(T.link) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ sqlite3.c $(LDFLAGS.libsqlite3) -fuzzy: fuzzcheck-asan$(TEXE) -xbin: fuzzcheck-asan$(TEXE) +fuzzy: fuzzcheck-asan$(T.exe) +xbin: fuzzcheck-asan$(T.exe) -fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) - $(TLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ +fuzzcheck-ubsan$(T.exe): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(T.link) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) \ sqlite3.c $(LDFLAGS.libsqlite3) -fuzzy: fuzzcheck-ubsan$(TEXE) -xbin: fuzzcheck-ubsan$(TEXE) +fuzzy: fuzzcheck-ubsan$(T.exe) +xbin: fuzzcheck-ubsan$(T.exe) # Usage: FUZZDB=filename make run-fuzzcheck # @@ -1806,26 +1806,26 @@ xbin: fuzzcheck-ubsan$(TEXE) # # FUZZDB=test/fuzzdata*.db make run-fuzzcheck # -run-fuzzcheck: fuzzcheck$(TEXE) fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) +run-fuzzcheck: fuzzcheck$(T.exe) fuzzcheck-asan$(T.exe) fuzzcheck-ubsan$(T.exe) @if test "$(FUZZDB)" = ""; then echo 'ERROR: No FUZZDB specified. Rerun with FUZZDB=filename'; exit 1; fi - ./fuzzcheck$(TEXE) --spinner $(FUZZDB) - ./fuzzcheck-asan$(TEXE) --spinner $(FUZZDB) - ./fuzzcheck-ubsan$(TEXE) --spinner $(FUZZDB) + ./fuzzcheck$(T.exe) --spinner $(FUZZDB) + ./fuzzcheck-asan$(T.exe) --spinner $(FUZZDB) + ./fuzzcheck-ubsan$(T.exe) --spinner $(FUZZDB) -ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ +ossshell$(T.exe): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h + $(T.link) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS.libsqlite3) -fuzzy: ossshell$(TEXE) -xbin: ossshell$(TEXE) +fuzzy: ossshell$(T.exe) +xbin: ossshell$(T.exe) -sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(TOP)/test/sessionfuzz.c $(LDFLAGS.libsqlite3) -fuzzy: sessionfuzz$(TEXE) +sessionfuzz$(T.exe): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h + $(T.link) -o $@ $(TOP)/test/sessionfuzz.c $(LDFLAGS.libsqlite3) +fuzzy: sessionfuzz$(T.exe) -dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h - $(TLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS.libsqlite3) -fuzzy: dbfuzz$(TEXE) -xbin: dbfuzz$(TEXE) +dbfuzz$(T.exe): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h + $(T.link) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS.libsqlite3) +fuzzy: dbfuzz$(T.exe) +xbin: dbfuzz$(T.exe) DBFUZZ2_OPTS = \ -USQLITE_THREADSAFE \ @@ -1838,23 +1838,23 @@ DBFUZZ2_OPTS = \ -DSQLITE_ENABLE_FTS4 \ -DSQLITE_ENABLE_FTS5 -dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - $(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ +dbfuzz2$(T.exe): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h + $(T.cc) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ -DSTANDALONE -o dbfuzz2 \ $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS.libsqlite3) mkdir -p dbfuzz2-dir cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir -fuzzy: dbfuzz2$(TEXE) -xbin: dbfuzz2$(TEXE) +fuzzy: dbfuzz2$(T.exe) +xbin: dbfuzz2$(T.exe) -mptester$(TEXE): $(libsqlite3.LIB) $(TOP)/mptest/mptest.c - $(TLINK) -o $@ -I. $(TOP)/mptest/mptest.c $(libsqlite3.LIB) \ +mptester$(T.exe): $(libsqlite3.LIB) $(TOP)/mptest/mptest.c + $(T.link) -o $@ -I. $(TOP)/mptest/mptest.c $(libsqlite3.LIB) \ $(LDFLAGS.libsqlite3) -xbin: mptester$(TEXE) +xbin: mptester$(T.exe) -MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 -MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 -mptest: mptester$(TEXE) +MPTEST1=./mptester$(T.exe) mptest.db $(TOP)/mptest/crash01.test --repeat 20 +MPTEST2=./mptester$(T.exe) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20 +mptest: mptester$(T.exe) rm -f mptest.db $(MPTEST1) --journalmode DELETE $(MPTEST2) --journalmode WAL @@ -1898,66 +1898,66 @@ SHELL_DEP = \ $(TOP)/src/test_windirent.c \ $(TOP)/src/test_windirent.h -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(BTCLSH) # has_tclsh84 - $(BTCLSH) $(TOP)/tool/mkshellc.tcl >shell.c +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(B.tclsh) # has_tclsh84 + $(B.tclsh) $(TOP)/tool/mkshellc.tcl >shell.c # # Rules to build the extension objects. # DEPS_EXT_COMMON = $(DEPS_OBJ_COMMON) $(EXTHDR) icu.o: $(TOP)/ext/icu/icu.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/icu/icu.c + $(T.cc.extension) -c $(TOP)/ext/icu/icu.c fts3.o: $(TOP)/ext/fts3/fts3.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3.c fts3_aux.o: $(TOP)/ext/fts3/fts3_aux.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_aux.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_aux.c fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_expr.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_expr.c fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_hash.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_hash.c fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_icu.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_icu.c fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_porter.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_porter.c fts3_snippet.o: $(TOP)/ext/fts3/fts3_snippet.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_snippet.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_snippet.c fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenizer.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_tokenizer.c fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenizer1.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_tokenizer1.c fts3_tokenize_vtab.o: $(TOP)/ext/fts3/fts3_tokenize_vtab.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_unicode.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_unicode.c fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_unicode2.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_unicode2.c fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/fts3/fts3_write.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_write.c rtree.o: $(TOP)/ext/rtree/rtree.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/rtree/rtree.c + $(T.cc.extension) -c $(TOP)/ext/rtree/rtree.c userauth.o: $(TOP)/ext/userauth/userauth.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/userauth/userauth.c + $(T.cc.extension) -c $(TOP)/ext/userauth/userauth.c sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/session/sqlite3session.c + $(T.cc.extension) -c $(TOP)/ext/session/sqlite3session.c stmt.o: $(TOP)/ext/misc/stmt.c $(DEPS_EXT_COMMON) - $(TCC.extension) -c $(TOP)/ext/misc/stmt.c + $(T.cc.extension) -c $(TOP)/ext/misc/stmt.c # # Windows section @@ -1969,7 +1969,7 @@ sqlite3.def: $(LIBOBJ) | sed 's/^.* _//' >>sqlite3.def sqlite3.dll: $(LIBOBJ) sqlite3.def - $(TCC.sqlite) $(LDFLAGS.shobj) -o $@ sqlite3.def \ + $(T.cc.sqlite) $(LDFLAGS.shobj) -o $@ sqlite3.def \ -Wl,"--strip-all" $(LIBOBJ) @@ -1981,30 +1981,30 @@ sqlite3.dll: $(LIBOBJ) sqlite3.def # tidy-.: tidy: tidy-. - rm -f *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE) + rm -f *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(T.exe) rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h rm -rf .libs .deps tsrc .target_source - rm -f lemon$(BEXE) sqlite*.tar.gz - rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE) + rm -f lemon$(B.exe) sqlite*.tar.gz + rm -f mkkeywordhash$(B.exe) mksourceid$(B.exe) rm -f parse.* fts5parse.* rm -f $(libsqlite3.SO) $(libsqlite3.LIB) $(libtclsqlite3.SO) - rm -f tclsqlite3$(TEXE) $(TESTPROGS) - rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) - rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) - rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE) + rm -f tclsqlite3$(T.exe) $(TESTPROGS) + rm -f LogEst$(T.exe) fts3view$(T.exe) rollback-test$(T.exe) showdb$(T.exe) + rm -f showjournal$(T.exe) showstat4$(T.exe) showwal$(T.exe) speedtest1$(T.exe) + rm -f wordcount$(T.exe) changeset$(T.exe) version-info$(T.exe) rm -f *.exp *.vsix pkgIndex.tcl - rm -f sqlite3_analyzer$(TEXE) sqlite3_rsync$(TEXE) sqlite3_expert$(TEXE) - rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE) - rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE) - rm -f dbfuzz$(TEXE) dbfuzz2$(TEXE) + rm -f sqlite3_analyzer$(T.exe) sqlite3_rsync$(T.exe) sqlite3_expert$(T.exe) + rm -f mptester$(T.exe) rbu$(T.exe) srcck1$(T.exe) + rm -f fuzzershell$(T.exe) fuzzcheck$(T.exe) sqldiff$(T.exe) dbhash$(T.exe) + rm -f dbfuzz$(T.exe) dbfuzz2$(T.exe) rm -fr dbfuzz2-dir - rm -f fuzzcheck-asan$(TEXE) fuzzcheck-ubsan$(TEXE) ossshell$(TEXE) - rm -f scrub$(TEXE) showshm$(TEXE) sqlite3_checker$(TEXE) loadfts$(EXE) - rm -f index_usage$(TEXE) kvtest$(TEXE) startup$(TEXE) threadtest3$(TEXE) - rm -f sessionfuzz$(TEXE) changesetfuzz$(TEXE) - rm -f dbdump$(TEXE) dbtotxt$(TEXE) atrc$(TEXX) - rm -f threadtest5$(TEXE) - rm -f src-verify$(BEXE) has_tclsh* has_tclconfig + rm -f fuzzcheck-asan$(T.exe) fuzzcheck-ubsan$(T.exe) ossshell$(T.exe) + rm -f scrub$(T.exe) showshm$(T.exe) sqlite3_checker$(T.exe) loadfts$(T.exe) + rm -f index_usage$(T.exe) kvtest$(T.exe) startup$(T.exe) threadtest3$(T.exe) + rm -f sessionfuzz$(T.exe) changesetfuzz$(T.exe) + rm -f dbdump$(T.exe) dbtotxt$(T.exe) atrc$(T.exe) + rm -f threadtest5$(T.exe) + rm -f src-verify$(B.exe) has_tclsh* has_tclconfig rm -f tclsqlite3.c rm -f sqlite3rc.h sqlite3.def diff --git a/manifest b/manifest index 3523ba29b6..616a839251 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Bump\sversion\snumber\sto\s3.48.0\s(in\sthis\sbranch\sonly\s-\sin\strunk,\sdoing\sso\srequires\sa\sspecific\sautoconf\sversion)\sand\srename\sthe\sRELEASE\sand\sVERSION\smakefile\ssymbols\sfor\sclarity's\ssake. -D 2024-10-24T05:03:20.051 +C More\spotentially-controversial\smakefile\ssymbol\srenaming.\sThis\sis\ssimply\smore\sreadable\sto\smy\seyes. +D 2024-10-24T05:33:30.843 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in bd9798f56bbdc342f8d563ef7f5da7a87eb3cd95e52bfe3f834c1c86e9862538 +F Makefile.in 52f39f64dd0b5d925987adf433695db1a6bf7a5b009c8231303741a7620616d0 F Makefile.linux-generic eb13e3e981a1950c99ce26c177fe2c2d2a268da4c0b1fcba85bfdf56142be298 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk e083730779a0c9c0ee686c8bfd50f3b1920d6923cd1711f63a2a113fdd9342dc +F main.mk c75886e8126c083e85fabc287d9d4649305f8c90e8d98fde23e8e1f338884e0f F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7eceb7539dcce16104a93ad0ca1f755f23621751878cc4b01465e61333795b72 -R 706f84b6afa1da7be99c001c09d178a8 +P 4193d90f2158e25fe25f9bcf579ae38a6e0ab6c26f52cd07a777d67b87107632 +R 4feb62569d5755832ec6d50a1a994ac9 U stephan -Z 9e7d56afc7541bc2579fecb7499ab27a +Z fdd999fe051cb1883eb5d46f2f11b028 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 737f06142b..2b974d21a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4193d90f2158e25fe25f9bcf579ae38a6e0ab6c26f52cd07a777d67b87107632 +6d4d1d5fefb82ec7458efc2e93c933d9dc415dfa06fa46ff4725c30fc920ca5a From 4cd85bda4ae85893d5b5d0e3fec5e13f78f52935 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 07:31:39 +0000 Subject: [PATCH 122/522] Various build cleanups centered around straightening out various uses of CFLAGS and its cousins. Teach Makefile.linux-generic to figure out the TOP dir on its own (a GNU Make-ism, but it's a Linux-specific makefile). FossilOrigin-Name: 58a0f7e79ce913b432dfd4db018e5a92efa8a6bd8a50bd78ab705ceac0322e9c --- Makefile.in | 30 +++++++--------- Makefile.linux-generic | 30 ++++++++++------ auto.def | 9 +++-- main.mk | 79 +++++++++++++++++++++++++++++------------- manifest | 18 +++++----- manifest.uuid | 2 +- 6 files changed, 100 insertions(+), 68 deletions(-) diff --git a/Makefile.in b/Makefile.in index 31f715fe62..703511bc94 100644 --- a/Makefile.in +++ b/Makefile.in @@ -95,7 +95,7 @@ INSTALL = @BIN_INSTALL@ AR = @AR@ CC = @CC@ B.cc = @BUILD_CC@ @BUILD_CFLAGS@ -T.cc = $(CC) $(CFLAGS) +T.cc = $(CC) CFLAGS = @CFLAGS@ @SH_CFLAGS@ LDFLAGS.shobj = @SHOBJ_LDFLAGS@ @@ -105,7 +105,7 @@ LDFLAGS.rpath = @LDFLAGS_RPATH@ LDFLAGS.pthread = @LDFLAGS_PTHREAD@ LDFLAGS.dlopen = @LDFLAGS_DLOPEN@ LDFLAGS.readline = @LDFLAGS_READLINE@ -CFLAGS.readline = -DHAVE_READLINE=@HAVE_READLINE@ @CFLAGS_READLINE@ +CFLAGS.readline = @CFLAGS_READLINE@ ENABLE_SHARED = @ENABLE_SHARED@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ @@ -146,19 +146,16 @@ $(B.tclsh): # # $(CFLAGS.libsqlite3) is documented in main.mk. # -CFLAGS.libsqlite3 = $(CFLAGS) -DSQLITE_TEMP_STORE=@TEMP_STORE@ - -OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) - -T.cc += $(OPT_FEATURE_FLAGS) +CFLAGS.libsqlite3 = -DSQLITE_TEMP_STORE=@TEMP_STORE@ # -# Add in any optional global compilation flags on the make commane -# line ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". +# $(OPT_FEATURE_FLAGS) is documented in main.mk. # -#XX# FIXME: rename one or the other of $(OPTS) and $(OPTIONS), as they -#XX# serve different purposes. -T.cc += $(OPTS) +# The appending of $(OPTIONS) to $(OPT_FEATURE_FLAGS) is historical +# and somewhat confusing because there's another var, $(OPTS), which +# has a similar (but not identical) role. +# +OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) # # Release (X.Y.Z) and version (X.Y) numbers for the SQLite being @@ -227,12 +224,11 @@ TCLLIBDIR = @TCLLIBDIR@ # # for more info. # - -CFLAGS.GCOV1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage -LDFLAGS.GCOV1 = -lgcov +CFLAGS.gcov1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage +LDFLAGS.gcov1 = -lgcov USE_GCOV = @USE_GCOV@ -T.compile.extras += $(CFLAGS.GCOV$(USE_GCOV)) -T.link.extras += $(LDFLAGS.GCOV$(USE_GCOV)) +T.compile.extras = $(CFLAGS.gcov$(USE_GCOV)) +T.link.extras = $(LDFLAGS.gcov$(USE_GCOV)) # # Vars with the AS_ prefix are specifically related to AutoSetup. diff --git a/Makefile.linux-generic b/Makefile.linux-generic index 50bd980b98..b91861bbe7 100644 --- a/Makefile.linux-generic +++ b/Makefile.linux-generic @@ -1,4 +1,5 @@ #!/usr/make +all: # # Makefile for SQLITE # @@ -17,35 +18,42 @@ #### # # $(TOP) = The toplevel directory of the source tree. This is the -# directory that contains this "Makefile.in" and "auto.def". +# directory that contains "Makefile.in" and "auto.def". # -TOP ?= . +TOP ?= $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) # # $(CFLAGS) will be used when compiling the library and most -# utilities. Generally speaking, it must contain -fPIC on Linux -# systems. +# utilities. It must normally contain -fPIC on Linux systems. # -CFLAGS += -fPIC +CFLAGS = -fPIC # # $(SHELL_OPT) contains CFLAGS for building the sqlite3 CLI shell. # See main.mk for other potentially-relevant vars which may need # tweaking, like $(LDFLAGS_READLINE). # -SHELL_OPT ?= -DHAVE_READLINE=1 +SHELL_OPT += -DHAVE_READLINE=1 +SHELL_OPT += -DSQLITE_HAVE_ZLIB=1 +LDFLAGS.readline = -lreadline # may need -lcurses etc, depending on the system +CFLAGS.readline = # needs -I... if readline.h is in an unusual place. +LDFLAGS.zlib = -lz # # Library's version number. # VERSION.XYZ ?= $(shell cat $(TOP)/VERSION 2>/dev/null) -$(info VERSION.XYZ=$(VERSION.XYZ)) - -# You should not have to change anything below this line -############################################################################### -include $(TOP)/main.mk +# sqlite_cfg.h is typically created by the configure script. It's +# commonly not needed but main.mk does not know that so we have to +# create a dummy if we don't already have one. sqlite_cfg.h: touch $@ distclean-.: rm -f sqlite_cfg.h + +# +# With the above in place, we can now import the rules make use of +# it... +# +include $(TOP)/main.mk diff --git a/auto.def b/auto.def index 9c6eccbf0c..817a488db9 100644 --- a/auto.def +++ b/auto.def @@ -381,14 +381,13 @@ if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { # TODO: port over the more sophisticated zlib search from the fossil auto.def define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" define LDFLAGS_ZLIB -lz -# -DSQLITE_HAVE_ZLIB=1 is handled separately from the other feature -# flags in the autotools build -# add-feature-flag -DSQLITE_HAVE_ZLIB=1 - define CFLAGS_ZLIB -DSQLITE_HAVE_ZLIB=1 + # Note that -DSQLITE_HAVE_ZLIB=1 is handled separately from the + # other feature flags in the autotools build. Do we need to emulate + # that? + add-shell-opt -DSQLITE_HAVE_ZLIB=1 } else { define HAVE_ZLIB 0 define LDFLAGS_ZLIB "" - define CFLAGS_ZLIB "" } hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ diff --git a/main.mk b/main.mk index e8567d3694..8ed28d0bb6 100644 --- a/main.mk +++ b/main.mk @@ -98,7 +98,7 @@ TCLSH_CMD ?= tclsh # JIMSH requires a leading path component, even if it's ./, so that it # can be used as a shell command. # -CFLAGS.JIMSH ?= -DHAVE_REALPATH +CFLAGS.jimsh ?= -DHAVE_REALPATH JIMSH ?= ./jimsh$(T.exe) # # $(B.tclsh) = @@ -175,10 +175,14 @@ AMALGAMATION_GEN_FLAGS ?= --linemacros=0 # and ENABLE flags must be passed to the LEMON parser generator and # the mkkeywordhash tool as well. # -# Add OPTIONS=... on the command line to append additional options to -# the OPT_FEATURE_FLAGS. Note that some flags only work if the build -# is specifically configured to account for them. Adding them later, -# when compiling the amalgamation, may or may not work. +# Add OPTIONS=... on the make command line to append additional options +# to the OPT_FEATURE_FLAGS. Note that some flags only work if the +# build is specifically configured to account for them. Adding them +# later, when compiling the amalgamation, may or may not work. +# +# TO CLARIFY: OPTS=... has historically been expected in some +# contexts, and is distinctly different from OPTIONS and +# OPT_FEATURE_FLAGS, but its name is confusingly close to $(OPTIONS). # OPT_FEATURE_FLAGS ?= # @@ -214,19 +218,6 @@ TCLLIB_RPATH ?= # HAVE_WASI_SDK ?= 0 # -# $(CFLAGS.libsqlite3) must contain any CFLAGS which are relevant for -# compiling the library's own sources, including (sometimes) when -# compiling sqlite3.c directly in to another app. -# -CFLAGS.libsqlite3 ?= $(CFLAGS) -# -# $(T.cc.sqlite) is $(T.cc) plus any flags which are desired for the -# library as a whole, but not necessarily needed for every binary. It -# will normally get initially populated with flags by the -# configure-generated makefile. -# -T.cc.sqlite ?= $(T.cc) -# # ... and many, many more. Sane defaults are selected where possible. # # With the above-described defined, the rest of this make script will @@ -241,6 +232,26 @@ all: sqlite3.h sqlite3.c ######################################################################## ######################################################################## +# +# $(CFLAGS) should ideally only contain flags which are relevant for +# all binaries built for the target platform. +# +T.cc += $(CFLAGS) + +# +# The difference between $(OPT_FEATURE_FLAGS) and $(OPTS) is that the +# former is historically provided by the configure script, whereas the +# latter is intended to be provided as arguments to the make +# invocation. +# +T.cc += $(OPT_FEATURE_FLAGS) + +# +# Add in any optional global compilation flags on the make command +# line ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". +# +T.cc += $(OPTS) + # # $(INSTALL) invocation for use with non-executable files. # @@ -248,11 +259,26 @@ INSTALL.noexec = $(INSTALL) -m 0644 # ^^^ do not use GNU-specific flags to $(INSTALL), e.g. --mode=... # -# $(T.compile) = generic target platform compiler invocation -# $(T.compile.extras) = config-specific flags for $(T.compile) +# $(T.compile) = generic target platform compiler invocation, +# differing only from $(T.cc) in that it appends $(T.compile.extras), +# which are primarily intended for use with gcov-related flags. # T.compile = $(T.cc) $(T.compile.extras) +# +# $(CFLAGS.libsqlite3) must contain any CFLAGS which are relevant for +# compiling the library's own sources, including (sometimes) when +# compiling sqlite3.c directly in to another app. +# +CFLAGS.libsqlite3 ?= +# +# $(T.cc.sqlite) is $(T.cc) plus any flags which are desired for the +# library as a whole, but not necessarily needed for every binary. It +# will normally get initially populated with flags by the +# configure-generated makefile. +# +T.cc.sqlite ?= $(T.cc) + # # $(CFLAGS.intree_includes) = -I... flags relevant specifically to # this tree, including any subdirectories commonly needed for building @@ -273,7 +299,8 @@ T.cc.extension = $(T.compile) -I. -I$(TOP)/src -DSQLITE_CORE # $(T.link) = compiler invocation for when the target will be an # executable. # -# $(T.link.extras) = optional config-specific flags for $(T.link) +# $(T.link.extras) = optional config-specific flags for $(T.link), +# primarily intended for use with gcov-related flags. # T.link = $(T.cc.sqlite) $(T.link.extras) # @@ -328,7 +355,7 @@ $(install-dir.all): # accepts only a single argument. # $(JIMSH): $(TOP)/autosetup/jimsh0.c - $(B.cc) -o $@ $(CFLAGS.JIMSH) $(TOP)/autosetup/jimsh0.c + $(B.cc) -o $@ $(CFLAGS.jimsh) $(TOP)/autosetup/jimsh0.c @if [ x = "x$$($(JIMSH) -e 'file normalize $(JIMSH)' 2>/dev/null)" ]; then \ echo "$(JIMSH) was built without -DHAVE_REALPATH or -DHAVE__FULLPATH." 1>&2; \ exit 1; \ @@ -358,8 +385,8 @@ $(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) @if [ x = "x$(VERSION.XYZ)" ]; then echo "VERSION.XYZ must be set to the library's X.Y.Z-format version number" 1>&2; exit 1; fi @if [ x = "x$(B.cc)" ]; then echo "Missing B.cc var" 1>&2; exit 1; fi @if [ x = "x$(T.cc)" ]; then echo "Missing T.cc var" 1>&2; exit 1; fi - @if [ x = "x$(VERSION.XYZ)" ]; then echo "Missing VERSION.XYZ var" 1>&2; exit 1; fi @if [ x = "x$(B.tclsh)" ]; then echo "Missing B.tclsh var" 1>&2; exit 1; fi + @if [ x = "x$(AR)" ]; then echo "Missing AR var" 1>&2; exit 1; fi touch $@ clean-sanity-check: rm -f $(MAKE_SANITY_CHECK) @@ -1699,9 +1726,11 @@ threadtest5: sqlite3.c $(TOP)/test/threadtest5.c xbin: threadtest5 sqlite3$(T.exe): shell.c sqlite3.c - $(T.link) $(CFLAGS.readline) $(SHELL_OPT) -o $@ \ + $(T.link) -o $@ \ shell.c sqlite3.c \ + $(CFLAGS.readline) $(SHELL_OPT) \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) + # # Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the # semantics of 0 and 1 are confusingly swapped here. @@ -1839,7 +1868,7 @@ DBFUZZ2_OPTS = \ -DSQLITE_ENABLE_FTS5 dbfuzz2$(T.exe): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h - $(T.cc) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ + $(T.cc) -I. -g -O0 \ -DSTANDALONE -o dbfuzz2 \ $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(LDFLAGS.libsqlite3) mkdir -p dbfuzz2-dir diff --git a/manifest b/manifest index 616a839251..a2393aa657 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C More\spotentially-controversial\smakefile\ssymbol\srenaming.\sThis\sis\ssimply\smore\sreadable\sto\smy\seyes. -D 2024-10-24T05:33:30.843 +C Various\sbuild\scleanups\scentered\saround\sstraightening\sout\svarious\suses\sof\sCFLAGS\sand\sits\scousins.\sTeach\sMakefile.linux-generic\sto\sfigure\sout\sthe\sTOP\sdir\son\sits\sown\s(a\sGNU\sMake-ism,\sbut\sit's\sa\sLinux-specific\smakefile). +D 2024-10-24T07:31:39.328 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 52f39f64dd0b5d925987adf433695db1a6bf7a5b009c8231303741a7620616d0 -F Makefile.linux-generic eb13e3e981a1950c99ce26c177fe2c2d2a268da4c0b1fcba85bfdf56142be298 +F Makefile.in c9c7aa417b8f012f35ec3e4661f258f7fc415ddd75a55acc7f501a50ec39bb26 +F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 610865aa878f3367977b5c4d74ffa9b74d097d1f0e76ffa4a8c286322e0d4e63 +F auto.def d120d07a0fb42193224bcfb6b658804fdd609bb3b77196d436783b7536426394 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk c75886e8126c083e85fabc287d9d4649305f8c90e8d98fde23e8e1f338884e0f +F main.mk ece1eba12f6f0bba61a77a196abd88f665dd37124f767a28c2138d4860245059 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4193d90f2158e25fe25f9bcf579ae38a6e0ab6c26f52cd07a777d67b87107632 -R 4feb62569d5755832ec6d50a1a994ac9 +P 6d4d1d5fefb82ec7458efc2e93c933d9dc415dfa06fa46ff4725c30fc920ca5a +R bb709993bdd1e18592edf968cb2f2be0 U stephan -Z fdd999fe051cb1883eb5d46f2f11b028 +Z 980b41dc4221bf4da6aefdf6906d7934 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2b974d21a1..6a5cdb2722 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6d4d1d5fefb82ec7458efc2e93c933d9dc415dfa06fa46ff4725c30fc920ca5a +58a0f7e79ce913b432dfd4db018e5a92efa8a6bd8a50bd78ab705ceac0322e9c From 79d3714f2472f33b71db8ea8f58f201e7810d085 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 07:44:13 +0000 Subject: [PATCH 123/522] Beginnings of rephrasing #if SQLITE_CORE to #ifdef/ifndef for consistency, as discussed in [forum:cea40371c5e34b09 | forum post cea40371c5e34b09]. FossilOrigin-Name: 58d91abf0c5a7712f27783640ef628681de18be5007020d6d8b362dd5a392eda --- ext/icu/icu.c | 2 +- ext/rtree/rtree.c | 2 +- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 69867bfa83..50110072b5 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -571,7 +571,7 @@ int sqlite3IcuInit(sqlite3 *db){ return rc; } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 299b5b54b9..6efa20d162 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -4449,7 +4449,7 @@ int sqlite3_rtree_query_callback( ); } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif diff --git a/manifest b/manifest index 35446e6e5b..fdd326e3d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reorder\sconditions\sin\ssqlite3PagerDirectReadOk()\sfor\scoverage. -D 2024-10-23T11:33:56.073 +C Beginnings\sof\srephrasing\s#if\sSQLITE_CORE\sto\s#ifdef/ifndef\sfor\sconsistency,\sas\sdiscussed\sin\s[forum:cea40371c5e34b09\s|\sforum\spost\scea40371c5e34b09]. +D 2024-10-24T07:44:13.131 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -261,7 +261,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl 6649ed963a9135e36866f7cc9f8de5c8dcec85b5df089388274cee6381702cb7 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 -F ext/icu/icu.c 3add8197e0a86c1761771a39500ebae749438bcf1836160b407a56b4eaa8721c +F ext/icu/icu.c 9837f4611915baad1edbe38222f3ee7d1b5e118ab16fec9ba603720f72c78b2a F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 F ext/intck/intck1.test f3a3cba14b6aeff145ffa5515546dd22f7510dad91512e519f43b92b56514012 F ext/intck/intck2.test d2457c7e5e5b688046d15ebe08a1e1427cc5e7a6dc8d6af215f42e8bcaf67304 @@ -525,7 +525,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/geopoly.c 0dd4775e896cee6067979d67aff7c998e75c2c9d9cd8d62a1a790c09cde7adca -F ext/rtree/rtree.c b6133dba5ae331fa6c1fc34df6aa623eba951b05ac35116f954a0bf7ab550436 +F ext/rtree/rtree.c e002d8c58bf128d812db662ecc72b61c00ff14408ec807e103d5312a6d29817a F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d @@ -2219,8 +2219,11 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 987b96aa636c1801f87d3e1c75d34d45c5b6f437bcc6d150298675447ed16b5d -R 83c78bc9e17ebe61e54351f39cf78374 -U drh -Z cf7f2e26bfd189f11890320a8c9dc42f +P da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef +R 2ebdab3edb1350dc11d4104c859d9548 +T *branch * ifdef-SQLITE_CORE +T *sym-ifdef-SQLITE_CORE * +T -sym-trunk * Cancelled\sby\sbranch. +U stephan +Z b84db1ac2ea5639b2aff4682b7058a21 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 612129bdfe..34c437fa03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef +58d91abf0c5a7712f27783640ef628681de18be5007020d6d8b362dd5a392eda From 3db85bf0d31672ceb512d22c163cbb88d3dc590e Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 11:11:31 +0000 Subject: [PATCH 124/522] Update the version number for the TEA extension. FossilOrigin-Name: 56353bcffa1bad425b1645b09e7192aa418d6b989df5958e0a770226bfc2ce63 --- autoconf/tea/configure.ac | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/autoconf/tea/configure.ac b/autoconf/tea/configure.ac index a995cc2cff..8abf8ad02f 100644 --- a/autoconf/tea/configure.ac +++ b/autoconf/tea/configure.ac @@ -19,7 +19,7 @@ dnl to configure the system for the local environment. # so that we create the export library with the dll. #----------------------------------------------------------------------- -AC_INIT([sqlite],[3.47.0]) +AC_INIT([sqlite],[3.48.0]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. diff --git a/manifest b/manifest index a2393aa657..7b770e633b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Various\sbuild\scleanups\scentered\saround\sstraightening\sout\svarious\suses\sof\sCFLAGS\sand\sits\scousins.\sTeach\sMakefile.linux-generic\sto\sfigure\sout\sthe\sTOP\sdir\son\sits\sown\s(a\sGNU\sMake-ism,\sbut\sit's\sa\sLinux-specific\smakefile). -D 2024-10-24T07:31:39.328 +C Update\sthe\sversion\snumber\sfor\sthe\sTEA\sextension. +D 2024-10-24T11:11:31.638 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -24,7 +24,7 @@ F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d F autoconf/tea/Makefile.in ba0556fee8da09c066bad85a4457904e46ee2c2eabaa309c0e83a78f2f151a8e F autoconf/tea/README.txt 61e62e519579e4a112791354d6d440f8b51ea6db3b0bab58d59f29df42d2dfe3 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 -F autoconf/tea/configure.ac a73dff08c9aee25cb65bb5f83f511ac71760a7a288c59cfcea6504c1ac0f7ced +F autoconf/tea/configure.ac ff2d745f88e493080810b67958d88b4f7a7d79f19e2ee8e7f72ffd6fc04eabc7 F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in 55aec3c6d7e9a1de9b8d2fdc9c27fd055da3ac3a51b572195e2ae7300bcfd3a2 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6d4d1d5fefb82ec7458efc2e93c933d9dc415dfa06fa46ff4725c30fc920ca5a -R bb709993bdd1e18592edf968cb2f2be0 -U stephan -Z 980b41dc4221bf4da6aefdf6906d7934 +P 58a0f7e79ce913b432dfd4db018e5a92efa8a6bd8a50bd78ab705ceac0322e9c +R c66389447c3b7b2175096c4d28a4e3c7 +U drh +Z 8cb6d5a8498acf453471a00efb00ba92 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6a5cdb2722..4089841f69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58a0f7e79ce913b432dfd4db018e5a92efa8a6bd8a50bd78ab705ceac0322e9c +56353bcffa1bad425b1645b09e7192aa418d6b989df5958e0a770226bfc2ce63 From 2ba8b9566f0cc7f9054658538dae75d1bf65fd3a Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 12:03:02 +0000 Subject: [PATCH 125/522] Fix the sqlite3(.EXE) build to honor --disable-amalgamation. FossilOrigin-Name: bd66222721ad06e99c1b66a3a0fbde06532507aa067165f47fa5d6c41ba630e6 --- main.mk | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/main.mk b/main.mk index 8ed28d0bb6..aca8313f74 100644 --- a/main.mk +++ b/main.mk @@ -1725,9 +1725,9 @@ threadtest5: sqlite3.c $(TOP)/test/threadtest5.c $(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3) xbin: threadtest5 -sqlite3$(T.exe): shell.c sqlite3.c +sqlite3$(T.exe): shell.c sqlite3.c $(LIBOBJ) $(T.link) -o $@ \ - shell.c sqlite3.c \ + shell.c $(LIBOBJ) \ $(CFLAGS.readline) $(SHELL_OPT) \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) diff --git a/manifest b/manifest index 96fccfbf92..890f776221 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sall\sthe\slatest\strunk\senhancements\sinto\sthe\sautosetup\sbranch. -D 2024-10-24T11:20:25.409 +C Fix\sthe\ssqlite3(.EXE)\sbuild\sto\shonor\s--disable-amalgamation. +D 2024-10-24T12:03:02.198 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ece1eba12f6f0bba61a77a196abd88f665dd37124f767a28c2138d4860245059 +F main.mk 35a08d2d0c458205064f8b6ba453c540fcea21d6c389fba8ad8c5a71fb153082 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 56353bcffa1bad425b1645b09e7192aa418d6b989df5958e0a770226bfc2ce63 da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef -R cc1b154ed902ce297ea76c4a560a28a4 -U drh -Z 11c0afa471c73db054eb415d8e2d3805 +P d0554ac46866b5ad467b88de6fae06695fd81e7fdf38157702a395f7282cbe9d +R 2faf1c48d071a03a05d748b2f0e797c7 +U stephan +Z 0a7ea5c985771468eac3705a684f68b7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 54623038d2..5249bb4ead 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d0554ac46866b5ad467b88de6fae06695fd81e7fdf38157702a395f7282cbe9d +bd66222721ad06e99c1b66a3a0fbde06532507aa067165f47fa5d6c41ba630e6 From 8cfc6a7aedef811a11074ad74be1c3e9b4b75dac Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 24 Oct 2024 12:06:04 +0000 Subject: [PATCH 126/522] Fix an inconsistency in the way SQLITE_CORE is used in fts3.c. FossilOrigin-Name: d4816e534a22250bd18509b07edca205c7ad6a8b3ecbbf5336a517ac19f78f55 --- ext/fts3/fts3.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index f977aabfbc..6c583f4814 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -6169,7 +6169,7 @@ int sqlite3Fts3Corrupt(){ } #endif -#if !SQLITE_CORE +#if !defined(SQLITE_CORE) /* ** Initialize API pointer table, if required. */ diff --git a/manifest b/manifest index 35446e6e5b..afd64d8173 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reorder\sconditions\sin\ssqlite3PagerDirectReadOk()\sfor\scoverage. -D 2024-10-23T11:33:56.073 +C Fix\san\sinconsistency\sin\sthe\sway\sSQLITE_CORE\sis\sused\sin\sfts3.c. +D 2024-10-24T12:06:04.953 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -68,7 +68,7 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c c922380b62bd15bce953dae3350337acbd0fff07c10cdc805819409791eb480a +F ext/fts3/fts3.c 59ae8c42ed3c39478faa6d122687e467ac34c98a63282e834f7df9cb5076c450 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682 F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 @@ -2219,8 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 987b96aa636c1801f87d3e1c75d34d45c5b6f437bcc6d150298675447ed16b5d -R 83c78bc9e17ebe61e54351f39cf78374 -U drh -Z cf7f2e26bfd189f11890320a8c9dc42f +P da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef +R 2c588882a830faac9ec2abff1f03e469 +U dan +Z 74338cb9c56cdad446f65085f6db6d70 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 612129bdfe..7b931e2bdc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef +d4816e534a22250bd18509b07edca205c7ad6a8b3ecbbf5336a517ac19f78f55 From 936fa8340265a295d807f1d4380035e71dafa4a9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 12:18:53 +0000 Subject: [PATCH 127/522] Fix jimsh0.c so that it compiles using MSVC: "cl jimsh0.c" FossilOrigin-Name: f531825d4e16502ac8fa496fba51ea735232e2988aa9ddd0f232825f6ec2a9a2 --- autosetup/jimsh0.c | 40 ++++++++++++++++++++++++++++++++++------ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index aa1e0bd9f2..b7496de7b6 100644 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -109,11 +109,7 @@ char *dlerror(void); #define strtoull _strtoui64 #include - -struct timeval { - long tv_sec; - long tv_usec; -}; +#include int gettimeofday(struct timeval *tv, void *unused); @@ -1243,7 +1239,7 @@ int Jim_OpenForRead(const char *filename); #endif #endif -#ifndef O_TEXT +#if !defined(O_TEXT) && !defined(_WIN32) #define O_TEXT 0 #endif @@ -6721,9 +6717,11 @@ int Jim_arrayInit(Jim_Interp *interp) } #include +#ifndef _WIN32 #include #include #include +#endif #include #include @@ -23568,6 +23566,36 @@ void Jim_SetResultErrno(Jim_Interp *interp, const char *msg) Jim_SetResultFormatted(interp, "%s: %s", msg, strerror(Jim_Errno())); } +#if defined(_WIN32) +#include +int Jim_Errno(void){ return 0; } +int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file) +{ + char name[MAX_PATH]; + HANDLE handle; + + if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, filename_template ? filename_template : "JIM", 0, name)) { + return -1; + } + + handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | (unlink_file ? FILE_FLAG_DELETE_ON_CLOSE : 0), + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + goto error; + } + + Jim_SetResultString(interp, name, -1); + return _open_osfhandle((intptr_t)handle, _O_RDWR | _O_TEXT); + + error: + Jim_SetResultErrno(interp, name); + DeleteFile(name); + return -1; +} +#endif + #if defined(__MINGW32__) #include diff --git a/manifest b/manifest index 890f776221..819c6a9e6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3(.EXE)\sbuild\sto\shonor\s--disable-amalgamation. -D 2024-10-24T12:03:02.198 +C Fix\sjimsh0.c\sso\sthat\sit\scompiles\susing\sMSVC:\s\s"cl\sjimsh0.c" +D 2024-10-24T12:18:53.353 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -48,7 +48,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/hwaci-common.tcl 3513a7dbe685d4776e70d23fa41d6695098627ca063245cac163f8ed3dc696f9 -F autosetup/jimsh0.c 838968b1159a6061452d751a48df3646830b04b118e35790da97e998208bc5ae +F autosetup/jimsh0.c 0b29699d873c54127873b0906be501f63dacdd1abc76a209d59a6c7e30c579a0 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d0554ac46866b5ad467b88de6fae06695fd81e7fdf38157702a395f7282cbe9d -R 2faf1c48d071a03a05d748b2f0e797c7 -U stephan -Z 0a7ea5c985771468eac3705a684f68b7 +P bd66222721ad06e99c1b66a3a0fbde06532507aa067165f47fa5d6c41ba630e6 +R ee8b54ba756da77e4f583a1e09246d8d +U drh +Z 9fb2435d714bbd037899e6ca13239e09 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5249bb4ead..eb2b915fec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd66222721ad06e99c1b66a3a0fbde06532507aa067165f47fa5d6c41ba630e6 +f531825d4e16502ac8fa496fba51ea735232e2988aa9ddd0f232825f6ec2a9a2 From e3565d9424035f4a117a53c2d9da49a9885e7818 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 12:57:45 +0000 Subject: [PATCH 128/522] Minor makefile tweaks to account for customizations via a custom hand-built makefile. FossilOrigin-Name: 7f92e820e675ea5d54284c534d44ec4f7f242b30920a5f84c020b93f2e7e969d --- Makefile.in | 1 + main.mk | 48 ++++++++++++++++++++++++++++++------------------ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/Makefile.in b/Makefile.in index 703511bc94..52396a3e1a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -93,6 +93,7 @@ includedir ?= @includedir@ INSTALL = @BIN_INSTALL@ AR = @AR@ +AR.flags = cr # TODO? Add a configure test to determine this? CC = @CC@ B.cc = @BUILD_CC@ @BUILD_CFLAGS@ T.cc = $(CC) diff --git a/main.mk b/main.mk index aca8313f74..30273ba9d4 100644 --- a/main.mk +++ b/main.mk @@ -49,9 +49,12 @@ B.cc ?= $(CC) T.cc ?= $(B.cc) # # $(AR) = -# Tool used to build a static library from object files. # -AR ?= ar +# Tool used to build a static library from object files, without its +# arguments. $(AR.flags) are its flags for creating a lib. +# +AR ?= ar +AR.flags ?= cr # # $(B.exe) = # @@ -72,14 +75,14 @@ B.lib ?= .lib # File extension for executables on the target platform. ".exe" for # Windows and "" everywhere else. # -T.exe ?= +T.exe ?= $(B.exe) # # $(T.dll) and $(T.lib) = # # The DLL resp. static library counterparts of $(T.exe). # -T.dll ?= .so -T.lib ?= .lib +T.dll ?= $(B.dll) +T.lib ?= $(B.lib) # # $(TCLSH_CMD) = # @@ -110,6 +113,16 @@ JIMSH ?= ./jimsh$(T.exe) # B.tclsh ?= $(JIMSH) +# +# Various system-level directories, mostly needed for installation and +# for finding system-level dependencies. +# +prefix ?= /usr/local +exec_prefix ?= $(prefix) +libdir ?= $(prefix)/lib +pkgconfigdir ?= $(libdir)/pkgconfig +bindir ?= $(prefix)/bin +includedir ?= $(prefix)/include # # $(LDFLAGS.{feature}) and $(CFLAGS.{feature}) = # @@ -123,21 +136,20 @@ B.tclsh ?= $(JIMSH) LDFLAGS.zlib ?= -lz LDFLAGS.math ?= -lm LDFLAGS.rpath ?= -Wl,-rpath -Wl,$(prefix)/lib -LDFLAGS.readline ?= -lreadline # these vary wildly across platforms -CFLAGS.readline ?= LDFLAGS.pthread ?= -lpthread LDFLAGS.dlopen ?= -ldl LDFLAGS.shobj ?= -shared +LDFLAGS.icu ?= # -licui18n -licuuc -licudata +# libreadline (or a workalike): +# To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE +LDFLAGS.readline ?= -lreadline # these vary wildly across platforms +CFLAGS.readline ?= -I$(prefix)/include/readline +# ^^^ When using linenoise instead of readline, do something like: +# SHELL_OPT += -DHAVE_LINENOISE +# CFLAGS.readline = $(HOME)/linenoise $(HOME)/linenoise/linenoise.c +# LDFLAGS.readline = # empty + # -# Various system-level directories, mostly needed for installation and -# for finding system-level dependencies. -# -prefix ?= /usr/local -exec_prefix ?= $(prefix) -libdir ?= $(prefix)/lib -pkgconfigdir ?= $(libdir)/pkgconfig -bindir ?= $(prefix)/bin -includedir ?= $(prefix)/include # # $(INSTALL) = # @@ -1261,7 +1273,7 @@ sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(B.tclsh) # has_tclsh84 # Static libsqlite3 # $(libsqlite3.LIB): $(LIBOBJ) - $(AR) crs $@ $(LIBOBJ) + $(AR) $(AR.flags) $@ $(LIBOBJ) lib: $(libsqlite3.LIB) all: lib @@ -1729,7 +1741,7 @@ sqlite3$(T.exe): shell.c sqlite3.c $(LIBOBJ) $(T.link) -o $@ \ shell.c $(LIBOBJ) \ $(CFLAGS.readline) $(SHELL_OPT) \ - $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) + $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) $(LDFLAGS.icu) # # Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the diff --git a/manifest b/manifest index 819c6a9e6b..d37e48830f 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sjimsh0.c\sso\sthat\sit\scompiles\susing\sMSVC:\s\s"cl\sjimsh0.c" -D 2024-10-24T12:18:53.353 +C Minor\smakefile\stweaks\sto\saccount\sfor\scustomizations\svia\sa\scustom\shand-built\smakefile. +D 2024-10-24T12:57:45.989 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in c9c7aa417b8f012f35ec3e4661f258f7fc415ddd75a55acc7f501a50ec39bb26 +F Makefile.in 9b356be01524cdb771e35f7664e211bcdb397ab55c8d1ff61cf9adb5f80098b8 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 35a08d2d0c458205064f8b6ba453c540fcea21d6c389fba8ad8c5a71fb153082 +F main.mk 1b9915be842423224ace56f94ed0134ad1cfaefc28506954ad63cbcacf5ae353 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bd66222721ad06e99c1b66a3a0fbde06532507aa067165f47fa5d6c41ba630e6 -R ee8b54ba756da77e4f583a1e09246d8d -U drh -Z 9fb2435d714bbd037899e6ca13239e09 +P f531825d4e16502ac8fa496fba51ea735232e2988aa9ddd0f232825f6ec2a9a2 +R d9e4cf4cfcffbde09a24ab1ae9a0abb6 +U stephan +Z a8f41dea3dc5b35a3293ebbb60fab779 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eb2b915fec..7f7b5d73a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f531825d4e16502ac8fa496fba51ea735232e2988aa9ddd0f232825f6ec2a9a2 +7f92e820e675ea5d54284c534d44ec4f7f242b30920a5f84c020b93f2e7e969d From 542d1c923e540b7c3ade17cf23bc2f3fdbcbbb3a Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 13:27:25 +0000 Subject: [PATCH 129/522] Tweaks to help make jimsh0 usable to build using nmake. Does not quite work yet, but getting closer. FossilOrigin-Name: e911303b8d180897c256e5de6edaa6b99239f914b84de2d08b3410650cd52c6d --- Makefile.msc | 2 +- ext/fts5/tool/mkfts5c.tcl | 2 +- manifest | 18 +++++++++--------- manifest.uuid | 2 +- tool/mksqlite3h.tcl | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 1e20849107..65fcc5922f 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2330,7 +2330,7 @@ parse.c: $(TOP)\src\parse.y lemon.exe .\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S parse.y $(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION - $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS) + $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl "$(TOP:\=/)" > $(SQLITE3H) $(MKSQLITE3H_ARGS) sqlite3ext.h: .target_source !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 diff --git a/ext/fts5/tool/mkfts5c.tcl b/ext/fts5/tool/mkfts5c.tcl index 9ea34a01e2..6f20a0cd73 100644 --- a/ext/fts5/tool/mkfts5c.tcl +++ b/ext/fts5/tool/mkfts5c.tcl @@ -2,7 +2,7 @@ # restart with tclsh \ exec tclsh "$0" "$@" -set srcdir [file dirname [file dirname [info script]]] +set srcdir [file dirname [file dirname [file normalize [info script]]]] set G(src) [string map [list %dir% $srcdir] { %dir%/fts5.h %dir%/fts5Int.h diff --git a/manifest b/manifest index d37e48830f..6b5ab34f28 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Minor\smakefile\stweaks\sto\saccount\sfor\scustomizations\svia\sa\scustom\shand-built\smakefile. -D 2024-10-24T12:57:45.989 +C Tweaks\sto\shelp\smake\sjimsh0\susable\sto\sbuild\susing\snmake.\s\sDoes\snot\squite\swork\nyet,\sbut\sgetting\scloser. +D 2024-10-24T13:27:25.387 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 9b356be01524cdb771e35f7664e211bcdb397ab55c8d1ff61cf9adb5f80098b8 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 -F Makefile.msc 58b69eda1faad5d475092b8aeffab9156ee4901a82db089b166607f2ec907ee4 +F Makefile.msc 06444a62312be0dbb838f5192e596c3674da6776ff36ec0ccb9aa7ae1f8278fc F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -273,7 +273,7 @@ F ext/fts5/test/fts5vocab2.test bbba149c254375d00055930c1a501c9a51e80b0d20bf7b98 F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc2870b45c0c82f9f F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 -F ext/fts5/tool/mkfts5c.tcl 6649ed963a9135e36866f7cc9f8de5c8dcec85b5df089388274cee6381702cb7 +F ext/fts5/tool/mkfts5c.tcl 135b9e160f8e10211c10c5873d5e8c3eaebd3da9ec56a12ae4db157d4738ffe4 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 F ext/icu/icu.c 3add8197e0a86c1761771a39500ebae749438bcf1836160b407a56b4eaa8721c @@ -2166,7 +2166,7 @@ F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b0 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f F tool/mksqlite3c.tcl c6acfdf4e4ef93478ff3ce3cd593e17abb03f446036ce710c3156bcfa18665e0 -F tool/mksqlite3h.tcl d391cff7cad0a372ee1406faee9ccc7dad9cb80a0c95cae0f73d10dd26e06762 +F tool/mksqlite3h.tcl 1432a89bc62f4e7f25e0842ffec68374317abec8af80b650dd4149ffdd44be65 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c7a27c F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a @@ -2236,8 +2236,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f531825d4e16502ac8fa496fba51ea735232e2988aa9ddd0f232825f6ec2a9a2 -R d9e4cf4cfcffbde09a24ab1ae9a0abb6 -U stephan -Z a8f41dea3dc5b35a3293ebbb60fab779 +P 7f92e820e675ea5d54284c534d44ec4f7f242b30920a5f84c020b93f2e7e969d +R 2d13f98dd8c11ecd021f0f5a9e2cd77e +U drh +Z 24f28d9b3a4bdc2845ef3a07db70eab0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7f7b5d73a2..73c9a56f9b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f92e820e675ea5d54284c534d44ec4f7f242b30920a5f84c020b93f2e7e969d +e911303b8d180897c256e5de6edaa6b99239f914b84de2d08b3410650cd52c6d diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index bd579c28b0..07c4668463 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -53,7 +53,7 @@ if {[lsearch -regexp [lrange $argv 1 end] {^-+enable-recover}] != -1} { # Get the SQLite version number (ex: 3.6.18) from the $TOP/VERSION file. # -set in [open $TOP/VERSION] +set in [open [file normalize $TOP/VERSION]] set zVersion [string trim [read $in]] close $in set nVersion [eval format "%d%03d%03d" [split $zVersion .]] From 72ef5069254aacaf97d1b7e40f98682371f46a06 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 14:33:11 +0000 Subject: [PATCH 130/522] Back out [bd66222721] because it causes conflicts with test runs, apparently due to .o files being built with different flags. This means that the CLI shell currently does not honor --disable-amalgamation. FossilOrigin-Name: b063317352e1360293787909cafe46dbfda68a75a89c6559bac69ad160d5ec43 --- Makefile.in | 1 + main.mk | 8 +++++--- manifest | 17 +++++++++-------- manifest.uuid | 2 +- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Makefile.in b/Makefile.in index 52396a3e1a..653c728d0a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -313,6 +313,7 @@ clean: clean-autosetup distclean-autosetup: clean rm -f sqlite_cfg.h config.log config.status Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh + rm -f libsqlite3*.$(T.dll) -gmake -C ext/wasm distclean 2>/dev/null; true distclean: distclean-autosetup diff --git a/main.mk b/main.mk index 30273ba9d4..543ddbf752 100644 --- a/main.mk +++ b/main.mk @@ -441,7 +441,9 @@ LIBOBJS1 = sqlite3.o # Determine the real value of LIBOBJ based on the 'configure' script # LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) - +#LIBSRC0 = $(SRC) +#LIBSRC1 = sqlite3.c +#LIBSRC = $(LIBSRC$(USE_AMALGAMATION)) $(LIBOBJ): $(MAKE_SANITY_CHECK) # All of the source code files. @@ -1737,9 +1739,9 @@ threadtest5: sqlite3.c $(TOP)/test/threadtest5.c $(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3) xbin: threadtest5 -sqlite3$(T.exe): shell.c sqlite3.c $(LIBOBJ) +sqlite3$(T.exe): shell.c sqlite3.c $(T.link) -o $@ \ - shell.c $(LIBOBJ) \ + shell.c sqlite3.c \ $(CFLAGS.readline) $(SHELL_OPT) \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) $(LDFLAGS.icu) diff --git a/manifest b/manifest index 6b5ab34f28..5539db8918 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Tweaks\sto\shelp\smake\sjimsh0\susable\sto\sbuild\susing\snmake.\s\sDoes\snot\squite\swork\nyet,\sbut\sgetting\scloser. -D 2024-10-24T13:27:25.387 +C Back\sout\s[bd66222721]\sbecause\sit\scauses\sconflicts\swith\stest\sruns,\sapparently\sdue\sto\s.o\sfiles\sbeing\sbuilt\swith\sdifferent\sflags.\sThis\smeans\sthat\sthe\sCLI\sshell\scurrently\sdoes\snot\shonor\s--disable-amalgamation. +D 2024-10-24T14:33:11.835 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 9b356be01524cdb771e35f7664e211bcdb397ab55c8d1ff61cf9adb5f80098b8 +F Makefile.in a751c1d84222c389ff83dc9c7d2f4ef2ca29bf357609032bb4af3147f6f38b70 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 06444a62312be0dbb838f5192e596c3674da6776ff36ec0ccb9aa7ae1f8278fc F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 1b9915be842423224ace56f94ed0134ad1cfaefc28506954ad63cbcacf5ae353 +F main.mk 1cbc48b8316568be25d7d0720bcc80a0b3e4ef2701c418aaaa08e73b36b5bfc7 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2236,8 +2236,9 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7f92e820e675ea5d54284c534d44ec4f7f242b30920a5f84c020b93f2e7e969d -R 2d13f98dd8c11ecd021f0f5a9e2cd77e -U drh -Z 24f28d9b3a4bdc2845ef3a07db70eab0 +P e911303b8d180897c256e5de6edaa6b99239f914b84de2d08b3410650cd52c6d +Q -bd66222721ad06e99c1b66a3a0fbde06532507aa067165f47fa5d6c41ba630e6 +R 10a78d20a468d904200243ff7416a469 +U stephan +Z 8d3218807f194cbdcb2529b80d3d52e0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 73c9a56f9b..be4f6f515b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e911303b8d180897c256e5de6edaa6b99239f914b84de2d08b3410650cd52c6d +b063317352e1360293787909cafe46dbfda68a75a89c6559bac69ad160d5ec43 From ae07b98a3c992c4bc0621ce76d474714991cfa39 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 15:14:55 +0000 Subject: [PATCH 131/522] Add the tool/cp.tcl script and use it to simplify Makefile.msc. FossilOrigin-Name: b7db2146a89587075d268b524ffc83d147f1d9d3e428c6d72bb7f3b8717c7954 --- Makefile.msc | 13 +------------ manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/cp.tcl | 9 +++++++++ 4 files changed, 19 insertions(+), 21 deletions(-) create mode 100644 tool/cp.tcl diff --git a/Makefile.msc b/Makefile.msc index 65fcc5922f..203ca21fa3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1983,19 +1983,8 @@ mptest: mptester.exe .target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c $(SQLITE_TCL_DEP) -rmdir /Q/S tsrc 2>NUL -mkdir tsrc - for %i in ($(SRC00)) do copy /Y %i tsrc - for %i in ($(SRC01)) do copy /Y %i tsrc - for %i in ($(SRC03)) do copy /Y %i tsrc - for %i in ($(SRC04)) do copy /Y %i tsrc - for %i in ($(SRC05)) do copy /Y %i tsrc - for %i in ($(SRC07)) do copy /Y %i tsrc - for %i in ($(SRC09)) do copy /Y %i tsrc - for %i in ($(SRC10)) do copy /Y %i tsrc - for %i in ($(SRC11)) do copy /Y %i tsrc - for %i in ($(SRC12)) do copy /Y %i tsrc - copy /Y fts5.c tsrc + $(TCLSH_CMD) $(TOP)\tool\cp.tcl $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC07) $(SRC09) $(SRC10) $(SRC11) $(SRC12) fts5.c fts5.h tsrc copy /B tsrc\fts5.c +,, - copy /Y fts5.h tsrc copy /B tsrc\fts5.h +,, del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL $(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new diff --git a/manifest b/manifest index 5539db8918..575f9d925f 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Back\sout\s[bd66222721]\sbecause\sit\scauses\sconflicts\swith\stest\sruns,\sapparently\sdue\sto\s.o\sfiles\sbeing\sbuilt\swith\sdifferent\sflags.\sThis\smeans\sthat\sthe\sCLI\sshell\scurrently\sdoes\snot\shonor\s--disable-amalgamation. -D 2024-10-24T14:33:11.835 +C Add\sthe\stool/cp.tcl\sscript\sand\suse\sit\sto\ssimplify\sMakefile.msc. +D 2024-10-24T15:14:55.161 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in a751c1d84222c389ff83dc9c7d2f4ef2ca29bf357609032bb4af3147f6f38b70 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 -F Makefile.msc 06444a62312be0dbb838f5192e596c3674da6776ff36ec0ccb9aa7ae1f8278fc +F Makefile.msc ce5ba06254efafbc4794028f46a08a95c7772ff5a7949b2c36b34e9c26c19e1c F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -2128,6 +2128,7 @@ F tool/buildtclext.tcl b64d250517b148e644d26fcbc097851867a0df52cd4bafe9bcd94b842 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca +F tool/cp.tcl ea5b078f7558a8b28d0bc1017e95b543d671c5e1f308b5e14311b31e534f4ac4 F tool/custom.txt 24ed55e71c5edae0067ba159bbf09240d58b160331f7716e95816cd3aa0ba5c4 F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 @@ -2236,9 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e911303b8d180897c256e5de6edaa6b99239f914b84de2d08b3410650cd52c6d -Q -bd66222721ad06e99c1b66a3a0fbde06532507aa067165f47fa5d6c41ba630e6 -R 10a78d20a468d904200243ff7416a469 -U stephan -Z 8d3218807f194cbdcb2529b80d3d52e0 +P b063317352e1360293787909cafe46dbfda68a75a89c6559bac69ad160d5ec43 +R f818d9469282597cf5b67d7ff1e084ba +U drh +Z b1df376b6545b02e2f1bb8ecd957f9fc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index be4f6f515b..0749e44128 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b063317352e1360293787909cafe46dbfda68a75a89c6559bac69ad160d5ec43 +b7db2146a89587075d268b524ffc83d147f1d9d3e428c6d72bb7f3b8717c7954 diff --git a/tool/cp.tcl b/tool/cp.tcl new file mode 100644 index 0000000000..df512e6113 --- /dev/null +++ b/tool/cp.tcl @@ -0,0 +1,9 @@ +#/usr/bin/tclsh +# +# This is a TCL script that copies multiple files into a common directory. +# The "cp" command will do this on unix, but no such command is available +# by default on Windows, so we have to use this script. +# +# tclsh cp.tcl FILE1 FILE2 ... FILEN DIR +# +file copy -force -- {*}$argv From 4f237f8defe2c2031717835396f6b3f2017b8294 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 15:36:29 +0000 Subject: [PATCH 132/522] Fix harmless compiler warnings. One of the warnings was code that deliberately committed memory errors to test the systems ability to cope. But compilers don't allow that any more, so we'll have to leave that capability untested. FossilOrigin-Name: 7e7b3b2edbb580c9ac14f21e5caa8f2f6b171d9a7ce6cb336dc0c8db76da7e8c --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/test1.c | 61 +------------------------------------------------- test/main.test | 16 +------------ 4 files changed, 10 insertions(+), 83 deletions(-) diff --git a/manifest b/manifest index 575f9d925f..76d4ed7fe2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\stool/cp.tcl\sscript\sand\suse\sit\sto\ssimplify\sMakefile.msc. -D 2024-10-24T15:14:55.161 +C Fix\sharmless\scompiler\swarnings.\s\sOne\sof\sthe\swarnings\swas\scode\sthat\ndeliberately\scommitted\smemory\serrors\sto\stest\sthe\ssystems\sability\sto\scope.\nBut\scompilers\sdon't\sallow\sthat\sany\smore,\sso\swe'll\shave\sto\sleave\sthat\ncapability\suntested. +D 2024-10-24T15:36:29.408 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -798,7 +798,7 @@ F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 47d4bb6eb06aab48d643eeb8c4f65b5fa9529fa5526fdcbf223ea32277ed1b56 F src/tclsqlite.h 529047feec49e7f463374749147f64d3f17505b0ebd84b3477a364c6f46a9de1 -F src/test1.c 8bf8b74145b768f42386787f93f6d6dad7bc400a4ee2d50e4ad5a06a20a97ef1 +F src/test1.c 370668f1832dc7bc2ab0212d807d880b6cdb0d5949550489593ce0cdb4a61012 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d @@ -1428,7 +1428,7 @@ F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5 F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431 F test/lock_common.tcl 2f3f7f2e9637f93ccf609df48ef5b27a50278b6b1cd752b445d52262e5841413 F test/lookaside.test 5a828e7256f1ee4da8e1bdaa03373a3ccdb0f1ff98dfa82e9b76cb41a45b1083 -F test/main.test 6bbb3999fd461eb8fb335cbab97409a3d7f91bbb8da60635e8be3e4a04a77772 +F test/main.test 1b07447e484d3a3ca8c620c6551258fa51f9cc9fdd56648e8949ea8c836be961 F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/malloc.test 18dd1c4188c81ca79cf123527c71b19ee0c31feb9947fdffb0dc6ceb1436816a F test/malloc3.test 6e88bae6312854a4adb4ecc2a6a5ea8c59b4db778b724ba718e1c43fc8c3c136 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b063317352e1360293787909cafe46dbfda68a75a89c6559bac69ad160d5ec43 -R f818d9469282597cf5b67d7ff1e084ba +P b7db2146a89587075d268b524ffc83d147f1d9d3e428c6d72bb7f3b8717c7954 +R 4bbe74fe12db4071f3af07b47a271be6 U drh -Z b1df376b6545b02e2f1bb8ecd957f9fc +Z 0c6b003fa73be7dc330f07814972da1f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0749e44128..59139da933 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7db2146a89587075d268b524ffc83d147f1d9d3e428c6d72bb7f3b8717c7954 +7e7b3b2edbb580c9ac14f21e5caa8f2f6b171d9a7ce6cb336dc0c8db76da7e8c diff --git a/src/test1.c b/src/test1.c index 5af066c6b2..5d05667476 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5023,8 +5023,8 @@ static int SQLITE_TCLAPI test_prepare_v3( } pzTail = objc>=6 ? &zTail : 0; rc = sqlite3_prepare_v3(db, zCopy, bytes, (unsigned int)flags,&pStmt,pzTail); - free(zCopy); zTail = &zSql[(zTail - zCopy)]; + free(zCopy); assert(rc==SQLITE_OK || pStmt==0); Tcl_ResetResult(interp); @@ -8450,64 +8450,6 @@ static int SQLITE_TCLAPI test_user_delete( } #endif /* SQLITE_USER_AUTHENTICATION */ -/* -** tclcmd: bad_behavior TYPE -** -** Do some things that should trigger a valgrind or -fsanitize=undefined -** warning. This is used to verify that errors and warnings output by those -** tools are detected by the test scripts. -** -** TYPE BEHAVIOR -** 1 Overflow a signed integer -** 2 Jump based on an uninitialized variable -** 3 Read after free -** 4 Panic -*/ -static int SQLITE_TCLAPI test_bad_behavior( - ClientData clientData, /* Pointer to an integer containing zero */ - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[] /* Command arguments */ -){ - int iType; - int xyz; - int i = *(int*)clientData; - int j; - int w[10]; - int *a; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "TYPE"); - return TCL_ERROR; - } - if( Tcl_GetIntFromObj(interp, objv[1], &iType) ) return TCL_ERROR; - switch( iType ){ - case 1: { - xyz = 0x7fffff00 - i; - xyz += 0x100; - Tcl_SetObjResult(interp, Tcl_NewIntObj(xyz)); - break; - } - case 2: { - w[1] = 5; - if( w[i]>0 ) w[1]++; - Tcl_SetObjResult(interp, Tcl_NewIntObj(w[1])); - break; - } - case 3: { - a = malloc( sizeof(int)*10 ); - for(j=0; j<10; j++) a[j] = j; - free(a); - Tcl_SetObjResult(interp, Tcl_NewIntObj(a[i])); - break; - } - case 4: { - Tcl_Panic("Deliberate panic"); - break; - } - } - return TCL_OK; -} - /* ** tclcmd: register_dbstat_vtab DB ** @@ -9034,7 +8976,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ } aObjCmd[] = { { "sqlite3_db_config", test_sqlite3_db_config, 0 }, { "sqlite3_txn_state", test_sqlite3_txn_state, 0 }, - { "bad_behavior", test_bad_behavior, (void*)&iZero }, { "register_dbstat_vtab", test_register_dbstat_vtab }, { "sqlite3_connection_pointer", get_sqlite_pointer, 0 }, { "intarray_addr", test_intarray_addr, 0 }, diff --git a/test/main.test b/test/main.test index 13a385b7c4..cdf9fb99e0 100644 --- a/test/main.test +++ b/test/main.test @@ -520,19 +520,5 @@ if {$::tcl_platform(platform)=="unix" puts [db one {SELECT 'VERSION: ' || sqlite_version() || ' ' || sqlite_source_id();}] - -# Do deliberate failures if the TEST_FAILURE environment variable is set. -# This is done to verify that failure notifications are detected by the -# releasetest.tcl script, or possibly by other scripts involved in automatic -# testing. -# -if {[info exists ::env(TEST_FAILURE)]} { - set res 123 - if {$::env(TEST_FAILURE)==0} {set res 234} - do_test main-99.1 { - bad_behavior $::env(TEST_FAILURE) - set x 123 - } $res -} - + finish_test From ae5ef1e80fc0597a211cd14c2cc3ab715301111a Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 15:57:21 +0000 Subject: [PATCH 133/522] Fix the new tool/cp.tcl so that it works with older TCL versions, such as jimtcl. FossilOrigin-Name: 61f18c96183867fe9d0fb30b8b71c0253f40503e32c8a4202196fb6418f2f46e --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/cp.tcl | 21 ++++++++++++++++++++- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 76d4ed7fe2..79a7a534e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings.\s\sOne\sof\sthe\swarnings\swas\scode\sthat\ndeliberately\scommitted\smemory\serrors\sto\stest\sthe\ssystems\sability\sto\scope.\nBut\scompilers\sdon't\sallow\sthat\sany\smore,\sso\swe'll\shave\sto\sleave\sthat\ncapability\suntested. -D 2024-10-24T15:36:29.408 +C Fix\sthe\snew\stool/cp.tcl\sso\sthat\sit\sworks\swith\solder\sTCL\sversions,\ssuch\sas\njimtcl. +D 2024-10-24T15:57:21.801 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -2128,7 +2128,7 @@ F tool/buildtclext.tcl b64d250517b148e644d26fcbc097851867a0df52cd4bafe9bcd94b842 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca -F tool/cp.tcl ea5b078f7558a8b28d0bc1017e95b543d671c5e1f308b5e14311b31e534f4ac4 +F tool/cp.tcl 9a0d663ad45828de13763ee7ca0200f31f56c6d742cf104a56ae80e027c242d8 F tool/custom.txt 24ed55e71c5edae0067ba159bbf09240d58b160331f7716e95816cd3aa0ba5c4 F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b7db2146a89587075d268b524ffc83d147f1d9d3e428c6d72bb7f3b8717c7954 -R 4bbe74fe12db4071f3af07b47a271be6 +P 7e7b3b2edbb580c9ac14f21e5caa8f2f6b171d9a7ce6cb336dc0c8db76da7e8c +R 25a1f3ca2528827073938adc0aff88af U drh -Z 0c6b003fa73be7dc330f07814972da1f +Z 71442e5bb903956a92a03709a3f05ed9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 59139da933..378c0e325a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e7b3b2edbb580c9ac14f21e5caa8f2f6b171d9a7ce6cb336dc0c8db76da7e8c +61f18c96183867fe9d0fb30b8b71c0253f40503e32c8a4202196fb6418f2f46e diff --git a/tool/cp.tcl b/tool/cp.tcl index df512e6113..80e4adf107 100644 --- a/tool/cp.tcl +++ b/tool/cp.tcl @@ -6,4 +6,23 @@ # # tclsh cp.tcl FILE1 FILE2 ... FILEN DIR # -file copy -force -- {*}$argv + +# This should be as simple as +# +# file copy -force -- {*}$argv +# +# But jimtcl doesn't support that. So we have to do it the hard way. + +if {[llength $argv]<2} { + error "Usage: $argv0 SRC... DESTDIR" +} +set n [llength $argv] +set destdir [lindex $argv [expr {$n-1}]] +if {![file isdir $destdir]} { + error "$argv0: not a directory: \"$destdir\"" +} +for {set i 0} {$i<$n-1} {incr i} { + set fn [file normalize [lindex $argv $i]] + set tail [file tail $fn] + file copy -force $fn [file normalize $destdir/$tail] +} From ed959dba7df5b398ac8c576b123624db29fdb7f3 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 15:57:29 +0000 Subject: [PATCH 134/522] Add missing ZERO_ARGUMENT_GENERATE_SERIES checks to ext/misc/series.c, as reported via support mail. FossilOrigin-Name: cd82e4c0f5f8ff16468b909d84dd5545c0456f624db61a4d112467a7cafed2fc --- ext/misc/series.c | 6 ++++++ manifest | 15 ++++++--------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index faf8fd0306..64f3be2c05 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -667,7 +667,9 @@ static int seriesBestIndex( idxNum &= ~0x3300; aIdx[5] = i; aIdx[6] = -1; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES bStartSeen = 1; +#endif break; } case SQLITE_INDEX_CONSTRAINT_GE: { @@ -675,7 +677,9 @@ static int seriesBestIndex( idxNum |= 0x0100; idxNum &= ~0x0200; aIdx[5] = i; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES bStartSeen = 1; +#endif break; } case SQLITE_INDEX_CONSTRAINT_GT: { @@ -683,7 +687,9 @@ static int seriesBestIndex( idxNum |= 0x0200; idxNum &= ~0x0100; aIdx[5] = i; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES bStartSeen = 1; +#endif break; } case SQLITE_INDEX_CONSTRAINT_LE: { diff --git a/manifest b/manifest index fdd326e3d1..d87ba54555 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Beginnings\sof\srephrasing\s#if\sSQLITE_CORE\sto\s#ifdef/ifndef\sfor\sconsistency,\sas\sdiscussed\sin\s[forum:cea40371c5e34b09\s|\sforum\spost\scea40371c5e34b09]. -D 2024-10-24T07:44:13.131 +C Add\smissing\sZERO_ARGUMENT_GENERATE_SERIES\schecks\sto\sext/misc/series.c,\sas\sreported\svia\ssupport\smail. +D 2024-10-24T15:57:29.106 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -424,7 +424,7 @@ F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab840709636240 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c 596afbfbbc81ccf4ea6da11f016f7eed630ed195b5e9d548117e19f06d63f641 +F ext/misc/series.c ea604a16f9c5f7e09ccff3f18d94f2c3a6fa24ca08856156823d981873b8143c F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9 F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 @@ -2219,11 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef -R 2ebdab3edb1350dc11d4104c859d9548 -T *branch * ifdef-SQLITE_CORE -T *sym-ifdef-SQLITE_CORE * -T -sym-trunk * Cancelled\sby\sbranch. +P 58d91abf0c5a7712f27783640ef628681de18be5007020d6d8b362dd5a392eda +R 03696d3fcf9d4a87c6a7add90a199e32 U stephan -Z b84db1ac2ea5639b2aff4682b7058a21 +Z 544a28ed9fdb6c5e441dfb7f96432068 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 34c437fa03..13cd48faa5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58d91abf0c5a7712f27783640ef628681de18be5007020d6d8b362dd5a392eda +cd82e4c0f5f8ff16468b909d84dd5545c0456f624db61a4d112467a7cafed2fc From 7796ee07c42a3d290f2758fd2efb215c948ab698 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 24 Oct 2024 15:58:37 +0000 Subject: [PATCH 135/522] Add missing ZERO_ARGUMENT_GENERATE_SERIES checks to ext/misc/series.c, as reported via support mail. FossilOrigin-Name: 5a8e3915eec06dbec7e32d1b87c6a6d5eb618d9d1d9bac13f6e1e7f22bbf8180 --- ext/misc/series.c | 6 ++++++ manifest | 15 ++++++++------- manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index faf8fd0306..64f3be2c05 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -667,7 +667,9 @@ static int seriesBestIndex( idxNum &= ~0x3300; aIdx[5] = i; aIdx[6] = -1; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES bStartSeen = 1; +#endif break; } case SQLITE_INDEX_CONSTRAINT_GE: { @@ -675,7 +677,9 @@ static int seriesBestIndex( idxNum |= 0x0100; idxNum &= ~0x0200; aIdx[5] = i; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES bStartSeen = 1; +#endif break; } case SQLITE_INDEX_CONSTRAINT_GT: { @@ -683,7 +687,9 @@ static int seriesBestIndex( idxNum |= 0x0200; idxNum &= ~0x0100; aIdx[5] = i; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES bStartSeen = 1; +#endif break; } case SQLITE_INDEX_CONSTRAINT_LE: { diff --git a/manifest b/manifest index afd64d8173..f3a52e3c6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sinconsistency\sin\sthe\sway\sSQLITE_CORE\sis\sused\sin\sfts3.c. -D 2024-10-24T12:06:04.953 +C Add\smissing\sZERO_ARGUMENT_GENERATE_SERIES\schecks\sto\sext/misc/series.c,\sas\sreported\svia\ssupport\smail. +D 2024-10-24T15:58:37.345 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -424,7 +424,7 @@ F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab840709636240 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c 596afbfbbc81ccf4ea6da11f016f7eed630ed195b5e9d548117e19f06d63f641 +F ext/misc/series.c ea604a16f9c5f7e09ccff3f18d94f2c3a6fa24ca08856156823d981873b8143c F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9 F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 @@ -2219,8 +2219,9 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P da9124fee28c155c4d1cc0d3949eb7b588a7236c12883a010af7909ad8e534ef -R 2c588882a830faac9ec2abff1f03e469 -U dan -Z 74338cb9c56cdad446f65085f6db6d70 +P d4816e534a22250bd18509b07edca205c7ad6a8b3ecbbf5336a517ac19f78f55 +Q +cd82e4c0f5f8ff16468b909d84dd5545c0456f624db61a4d112467a7cafed2fc +R e4ca7fa81f6860fc5a04c1e28cee3a2a +U stephan +Z f070b9e19001ab8c0e2d4fe251a41b20 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7b931e2bdc..37dc626886 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4816e534a22250bd18509b07edca205c7ad6a8b3ecbbf5336a517ac19f78f55 +5a8e3915eec06dbec7e32d1b87c6a6d5eb618d9d1d9bac13f6e1e7f22bbf8180 From a734793b2f45a1fda96d96af51644256b0ada406 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 17:16:38 +0000 Subject: [PATCH 136/522] Fix a bug in jimsh0.c for when it is compiled using MSVC. FossilOrigin-Name: f7def0be742fad9863f1eba11d0c2f1fa739ad1262e67d24380698e3948cedb7 --- autosetup/jimsh0.c | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index b7496de7b6..ca4912f95a 100644 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -96,6 +96,7 @@ char *dlerror(void); #include #define jim_wide _int64 +#define HAVE_LONG_LONG 1 #ifndef LLONG_MAX #define LLONG_MAX 9223372036854775807I64 #endif diff --git a/manifest b/manifest index 79a7a534e8..102db05a8c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\snew\stool/cp.tcl\sso\sthat\sit\sworks\swith\solder\sTCL\sversions,\ssuch\sas\njimtcl. -D 2024-10-24T15:57:21.801 +C Fix\sa\sbug\sin\sjimsh0.c\sfor\swhen\sit\sis\scompiled\susing\sMSVC. +D 2024-10-24T17:16:38.986 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -48,7 +48,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/hwaci-common.tcl 3513a7dbe685d4776e70d23fa41d6695098627ca063245cac163f8ed3dc696f9 -F autosetup/jimsh0.c 0b29699d873c54127873b0906be501f63dacdd1abc76a209d59a6c7e30c579a0 +F autosetup/jimsh0.c eb49d62a5b28b4d3b2af10cdfa5dc972ed76e8474fd773cdc7266e768c746f6d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7e7b3b2edbb580c9ac14f21e5caa8f2f6b171d9a7ce6cb336dc0c8db76da7e8c -R 25a1f3ca2528827073938adc0aff88af +P 61f18c96183867fe9d0fb30b8b71c0253f40503e32c8a4202196fb6418f2f46e +R 3fcda85ce8cde0358524e6ceb13906f8 U drh -Z 71442e5bb903956a92a03709a3f05ed9 +Z 9f3b8d43e2772874f53939ba0a89ce88 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 378c0e325a..7f419644f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61f18c96183867fe9d0fb30b8b71c0253f40503e32c8a4202196fb6418f2f46e +f7def0be742fad9863f1eba11d0c2f1fa739ad1262e67d24380698e3948cedb7 From 9bcfb2b694d5cc98fa989a80289f6e79e9dac2d3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 19:17:25 +0000 Subject: [PATCH 137/522] Basic builds now appear to work using jimsh0 on Windows. FossilOrigin-Name: d8f5193970401b763a94a1d0403bed4337c9fb1f087772b72fb46b9e0bde1c0d --- Makefile.msc | 58 ++++++++++++++++++++++++++----------------- autoconf/Makefile.msc | 5 ++++ manifest | 18 +++++++------- manifest.uuid | 2 +- tool/mksqlite3c.tcl | 17 ++++++++----- tool/mksqlite3h.tcl | 11 +++++--- 6 files changed, 69 insertions(+), 42 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 203ca21fa3..979933926a 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1059,6 +1059,13 @@ TCLSH_CMD = $(TCLDIR)\bin\tclsh.exe TCLSH_CMD = tclsh !ENDIF !ENDIF + +# A light-weight TCLSH replacement that can be used for code generation +# but which is not adequate for testing. +# +!IFNDEF JIM_TCLSH +JIM_TCLSH = $(TOP)\jimsh0.exe +!ENDIF # <> # Compiler options needed for programs that use the readline() library. @@ -1849,6 +1856,11 @@ dll: $(SQLITE3DLL) # shell: $(SQLITE3EXE) +# jimsh0 - replacement for tclsh +# +jimsh0.exe: $(TOP)\autosetup\jimsh0.c + cl -DHAVE__FULLPATH=1 $(TOP)\autosetup\jimsh0.c + # <> libsqlite3.lib: $(LIBOBJ) $(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS) @@ -1889,10 +1901,10 @@ $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) # <> -sqlite3.def: libsqlite3.lib +sqlite3.def: libsqlite3.lib $(JIM_TCLSH) echo EXPORTS > sqlite3.def dumpbin /all libsqlite3.lib \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@]*)(?:@\d+)?$$" \1 \ + | $(JIM_TCLSH) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@]*)(?:@\d+)?$$" \1 \ | sort >> sqlite3.def # <> @@ -1980,22 +1992,22 @@ mptest: mptester.exe # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c $(SQLITE_TCL_DEP) +.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c $(SQLITE_TCL_DEP) $(JIM_TCLSH) -rmdir /Q/S tsrc 2>NUL -mkdir tsrc - $(TCLSH_CMD) $(TOP)\tool\cp.tcl $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC07) $(SRC09) $(SRC10) $(SRC11) $(SRC12) fts5.c fts5.h tsrc + $(JIM_TCLSH) $(TOP)\tool\cp.tcl $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC07) $(SRC09) $(SRC10) $(SRC11) $(SRC12) fts5.c fts5.h tsrc copy /B tsrc\fts5.c +,, copy /B tsrc\fts5.h +,, del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL - $(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new + $(JIM_TCLSH) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new move vdbe.new tsrc\vdbe.c echo > .target_source -sqlite3.c: .target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL) src-verify.exe - $(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS) $(EXTRA_SRC) +sqlite3.c: .target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL) src-verify.exe $(JIM_TCLSH) + $(JIM_TCLSH) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS) $(EXTRA_SRC) -sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl - $(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl +sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl $(JIM_TCLSH) + $(JIM_TCLSH) $(TOP)\tool\split-sqlite3c.tcl # <> # Rule to build the amalgamation @@ -2037,11 +2049,11 @@ opcodes.lo: opcodes.c # !IF $(USE_RC)!=0 # <> -$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H) $(TOP)\VERSION +$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H) $(TOP)\VERSION $(JIM_TCLSH) echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h for /F %%V in ('type "$(TOP)\VERSION"') do ( \ echo #define SQLITE_RESOURCE_VERSION %%V \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact . ^, >> sqlite3rc.h \ + | $(JIM_TCLSH) $(TOP)\tool\replace.tcl exact . ^, >> sqlite3rc.h \ ) echo #endif >> sqlite3rc.h $(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc @@ -2302,11 +2314,11 @@ tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)\tool\mkopcodec.tcl - $(TCLSH_CMD) $(TOP)\tool\mkopcodec.tcl opcodes.h > opcodes.c +opcodes.c: opcodes.h $(TOP)\tool\mkopcodec.tcl $(JIM_TCLSH) + $(JIM_TCLSH) $(TOP)\tool\mkopcodec.tcl opcodes.h > opcodes.c -opcodes.h: parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl - type parse.h $(TOP)\src\vdbe.c | $(TCLSH_CMD) $(TOP)\tool\mkopcodeh.tcl > opcodes.h +opcodes.h: parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl $(JIM_TCLSH) + type parse.h $(TOP)\src\vdbe.c | $(JIM_TCLSH) $(TOP)\tool\mkopcodeh.tcl > opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. # @@ -2318,8 +2330,8 @@ parse.c: $(TOP)\src\parse.y lemon.exe copy /B parse.y +,, .\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S parse.y -$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION - $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl "$(TOP:\=/)" > $(SQLITE3H) $(MKSQLITE3H_ARGS) +$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION $(JIM_TCLSH) + $(JIM_TCLSH) $(TOP)\tool\mksqlite3h.tcl "$(TOP:\=/)" > $(SQLITE3H) $(MKSQLITE3H_ARGS) sqlite3ext.h: .target_source !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 @@ -2382,8 +2394,8 @@ SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\sqlar.c SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\zipfile.c !ENDIF -shell.c: $(SHELL_DEP) $(TOP)\tool\mkshellc.tcl - $(TCLSH_CMD) $(TOP)\tool\mkshellc.tcl > shell.c +shell.c: $(SHELL_DEP) $(TOP)\tool\mkshellc.tcl $(JIM_TCLSH) + $(JIM_TCLSH) $(TOP)\tool\mkshellc.tcl > shell.c zlib: pushd $(ZLIBDIR) && $(MAKE) /f win32\Makefile.msc clean $(ZLIBLIB) && popd @@ -2486,13 +2498,13 @@ fts5parse.c: $(TOP)\ext\fts5\fts5parse.y lemon.exe fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) - $(TCLSH_CMD) $(TOP)\ext\fts5\tool\mkfts5c.tcl +fts5.c: $(FTS5_SRC) $(JIM_TCLSH) + $(JIM_TCLSH) $(TOP)\ext\fts5\tool\mkfts5c.tcl copy /Y $(TOP)\ext\fts5\fts5.h . copy /B fts5.h +,, -lsm1.c: $(LSM1_SRC) - $(TCLSH_CMD) $(TOP)\ext\lsm1\tool\mklsm1c.tcl +lsm1.c: $(LSM1_SRC) $(JIM_TCLSH) + $(JIM_TCLSH) $(TOP)\ext\lsm1\tool\mklsm1c.tcl copy /Y $(TOP)\ext\lsm1\lsm.h . copy /B lsm.h +,, diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index efebc9931a..29bb7174fb 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -1039,6 +1039,11 @@ dll: $(SQLITE3DLL) # shell: $(SQLITE3EXE) +# jimsh0 - replacement for tclsh +# +jimsh0.exe: $(TOP)\autosetup\jimsh0.c + cl -DHAVE__FULLPATH=1 $(TOP)\autosetup\jimsh0.c + $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) diff --git a/manifest b/manifest index 102db05a8c..bd4c87b6a1 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Fix\sa\sbug\sin\sjimsh0.c\sfor\swhen\sit\sis\scompiled\susing\sMSVC. -D 2024-10-24T17:16:38.986 +C Basic\sbuilds\snow\sappear\sto\swork\susing\sjimsh0\son\sWindows. +D 2024-10-24T19:17:25.207 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in a751c1d84222c389ff83dc9c7d2f4ef2ca29bf357609032bb4af3147f6f38b70 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 -F Makefile.msc ce5ba06254efafbc4794028f46a08a95c7772ff5a7949b2c36b34e9c26c19e1c +F Makefile.msc 46ac29ffb26ccd346353f22ed4c7d1a8589e93ee32997d63a63019e612cfe07e F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -17,7 +17,7 @@ F auto.def d120d07a0fb42193224bcfb6b658804fdd609bb3b77196d436783b7536426394 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.msc 0a1fdef1f2c618815cf7c82c817a7369c1e07b3cfed490803db16fb43326d506 +F autoconf/Makefile.msc 1162ef7b7937ba6927b038f824b050855784d417e785fe35ab71d20afd18022b F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 5e946ffb6fbdbb114c81e1bdc862df27fce8beab557d7b0421820b0fe8fc048f F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277 @@ -2166,8 +2166,8 @@ F tool/mkshellc.tcl 2bc29c201933ae72a16a79070fe80aded80c24ea487ecd2f8df20c2973c8 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f -F tool/mksqlite3c.tcl c6acfdf4e4ef93478ff3ce3cd593e17abb03f446036ce710c3156bcfa18665e0 -F tool/mksqlite3h.tcl 1432a89bc62f4e7f25e0842ffec68374317abec8af80b650dd4149ffdd44be65 +F tool/mksqlite3c.tcl 98a250d6f2ea60343268e32e2997790e678205ce128aa0d0a67a3f70811615af +F tool/mksqlite3h.tcl 1d996a99cda519e8519e9e514b564fa29b37a49d20263d57494903d685caf067 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c7a27c F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 61f18c96183867fe9d0fb30b8b71c0253f40503e32c8a4202196fb6418f2f46e -R 3fcda85ce8cde0358524e6ceb13906f8 +P f7def0be742fad9863f1eba11d0c2f1fa739ad1262e67d24380698e3948cedb7 +R f7d9ddba41062822bed325e6117a4ac3 U drh -Z 9f3b8d43e2772874f53939ba0a89ce88 +Z a8e6b0cd2247237e95c6b267e7597266 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7f419644f7..fb92e4e3ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f7def0be742fad9863f1eba11d0c2f1fa739ad1262e67d24380698e3948cedb7 +d8f5193970401b763a94a1d0403bed4337c9fb1f087772b72fb46b9e0bde1c0d diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index ef8353df4f..dd0ce380b4 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -70,7 +70,7 @@ for {set i 0} {$i<[llength $argv]} {incr i} { lappend extrasrc $x } } -set in [open $srcdir/sqlite3.h] +set in [open $srcdir/sqlite3.h rb] set cnt 0 set VERSION ????? while {![eof $in]} { @@ -86,7 +86,7 @@ close $in # set fname sqlite3.c if {$enable_recover} { set fname sqlite3r.c } -set out [open $fname w] +set out [open $fname wb] # Force the output to use unix line endings, even on Windows. fconfigure $out -translation lf set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1] @@ -117,7 +117,12 @@ if {$tcl_platform(platform)=="windows"} { set vsrcprog ./src-verify } if {[file executable $vsrcprog] && [file readable $srcroot/manifest]} { - set res [string trim [split [exec $vsrcprog -x $srcroot]] \n] + set tmpfile tmp-[clock millisec]-[expr {int(rand()*100000000000)}].txt + exec $vsrcprog -x $srcroot > $tmpfile + set fd [open $tmpfile rb] + set res [string trim [split [read $fd] \n]] + close $fd + file delete -force $tmpfile puts $out "** The content in this amalgamation comes from Fossil check-in" puts -nonewline $out "** [string range [lindex $res 0] 0 35]" if {[llength $res]==1} { @@ -148,7 +153,7 @@ if {$addstatic} { # # then set the SQLITE_UDL_CAPABLE_PARSER flag in the amalgamation. # -set in [open $srcdir/parse.c] +set in [open $srcdir/parse.c rb] if {[regexp {ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT} [read $in]]} { puts $out "#define SQLITE_UDL_CAPABLE_PARSER 1" } @@ -243,7 +248,7 @@ proc copy_file {filename} { set tail [file tail $filename] section_comment "Begin file $tail" if {$linemacros} {puts $out "#line 1 \"$filename\""} - set in [open $filename r] + set in [open $filename rb] set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)} set declpattern {([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3[_a-zA-Z0-9]+)(\(.*)} if {[file extension $filename]==".h"} { @@ -358,7 +363,7 @@ proc copy_file {filename} { # proc copy_file_verbatim {filename} { global out - set in [open $filename r] + set in [open $filename rb] set tail [file tail $filename] section_comment "Begin EXTRA_SRC file $tail" while {![eof $in]} { diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 07c4668463..8a723f01a6 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -53,7 +53,7 @@ if {[lsearch -regexp [lrange $argv 1 end] {^-+enable-recover}] != -1} { # Get the SQLite version number (ex: 3.6.18) from the $TOP/VERSION file. # -set in [open [file normalize $TOP/VERSION]] +set in [open [file normalize $TOP/VERSION] rb] set zVersion [string trim [read $in]] close $in set nVersion [eval format "%d%03d%03d" [split $zVersion .]] @@ -62,7 +62,12 @@ set nVersion [eval format "%d%03d%03d" [split $zVersion .]] # set PWD [pwd] cd $TOP -set zSourceId [exec $PWD/mksourceid manifest] +set tmpfile tmp-[clock millisec]-[expr {int(rand()*100000000000)}].txt +exec $PWD/mksourceid manifest > $tmpfile +set fd [open $tmpfile rb] +set zSourceId [string trim [read $fd]] +close $fd +#file delete -force $tmpfile cd $PWD # Set up patterns for recognizing API declarations. @@ -111,7 +116,7 @@ set cdecllist { # Process the source files. # foreach file $filelist { - set in [open $file] + set in [open $file rb] if {![regexp {sqlite\.h\.in} $file]} { puts "/******** Begin file [file tail $file] *********/" } From 8ce6d66986311f12983de2c72b5430c5a2d60f9e Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Oct 2024 19:56:42 +0000 Subject: [PATCH 138/522] The "WITHOUT_JIMSH=1" option on the nmake command-line forces the use of standard TCL for building, instead of jimsh0. FossilOrigin-Name: 9f861f66e238b62e04d640ee98bac86b9b532a55d62c92ae0154bd67ee01ec75 --- Makefile.msc | 7 ++++++- manifest | 14 +++++++------- manifest.uuid | 2 +- test/testrunner_data.tcl | 1 + 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 979933926a..4f50c300d8 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1061,8 +1061,13 @@ TCLSH_CMD = tclsh !ENDIF # A light-weight TCLSH replacement that can be used for code generation -# but which is not adequate for testing. +# but which is not adequate for testing. This is "jimsh0" by default, +# with source code in the repository. To force the whole build to use +# the full, official tclsh, add WITHOUT_JIMSH=1 to the nmake command line. # +!IFDEF WITHOUT_JIMSH +JIM_TCLSH = $(TCLSH_CMD) +!ENDIF !IFNDEF JIM_TCLSH JIM_TCLSH = $(TOP)\jimsh0.exe !ENDIF diff --git a/manifest b/manifest index bd4c87b6a1..67b4e76b25 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Basic\sbuilds\snow\sappear\sto\swork\susing\sjimsh0\son\sWindows. -D 2024-10-24T19:17:25.207 +C The\s"WITHOUT_JIMSH=1"\soption\son\sthe\snmake\scommand-line\sforces\sthe\suse\sof\nstandard\sTCL\sfor\sbuilding,\sinstead\sof\sjimsh0. +D 2024-10-24T19:56:42.026 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in a751c1d84222c389ff83dc9c7d2f4ef2ca29bf357609032bb4af3147f6f38b70 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 -F Makefile.msc 46ac29ffb26ccd346353f22ed4c7d1a8589e93ee32997d63a63019e612cfe07e +F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -1737,7 +1737,7 @@ F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 F test/testrunner.tcl bc1a8d21a1aa3a5cf7c4883cbee4b6748790fe960fad06ca5db74ec914bd6525 x -F test/testrunner_data.tcl c7b3b911e44f7e8c01cc6bc7571e16115cdc2e4db46630bd2acd7a931a46380e +F test/testrunner_data.tcl e3037f54cdb67479827cdfe8b8962a38811a496c1ad81956c085c64aa34e7a12 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f7def0be742fad9863f1eba11d0c2f1fa739ad1262e67d24380698e3948cedb7 -R f7d9ddba41062822bed325e6117a4ac3 +P d8f5193970401b763a94a1d0403bed4337c9fb1f087772b72fb46b9e0bde1c0d +R d6a2c119d2e2b5b78e997064a2e28dd5 U drh -Z a8e6b0cd2247237e95c6b267e7597266 +Z 501f1f77f82aa3cf9af5ab80f1dd5888 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fb92e4e3ee..018d4e174b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8f5193970401b763a94a1d0403bed4337c9fb1f087772b72fb46b9e0bde1c0d +9f861f66e238b62e04d640ee98bac86b9b532a55d62c92ae0154bd67ee01ec75 diff --git a/test/testrunner_data.tcl b/test/testrunner_data.tcl index 98b3669a33..eac3f69a99 100644 --- a/test/testrunner_data.tcl +++ b/test/testrunner_data.tcl @@ -116,6 +116,7 @@ namespace eval trd { --enable-all } set build(Stdcall) { + -DWITHOUT_JIMSH=1 -DUSE_STDCALL=1 -DSQLITE_USE_ONLY_WIN32=1 -O2 From 7db8d195c3da67cc4ad29f7f7ffb7f0b9f7c6c53 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 03:18:11 +0000 Subject: [PATCH 139/522] ./configure now emits config-defs.json, a JSON-formatted counterpart of the DEFS=... info which the pre-built autotools bundles emit. FossilOrigin-Name: 800b083c3a55a990bd5b7fd587e24144b0084a394f9cf8160c3aa0a6880f8053 --- Makefile.in | 2 +- auto.def | 11 +++++- autosetup/hwaci-common.tcl | 70 ++++++++++++++++++++++++++++++++++++++ manifest | 18 +++++----- manifest.uuid | 2 +- 5 files changed, 91 insertions(+), 12 deletions(-) diff --git a/Makefile.in b/Makefile.in index 653c728d0a..b39323f272 100644 --- a/Makefile.in +++ b/Makefile.in @@ -311,7 +311,7 @@ clean-autosetup: clean: clean-autosetup distclean-autosetup: clean - rm -f sqlite_cfg.h config.log config.status Makefile sqlite3.pc + rm -f sqlite_cfg.h config.log config.status config-defs.json Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh rm -f libsqlite3*.$(T.dll) -gmake -C ext/wasm distclean 2>/dev/null; true diff --git a/auto.def b/auto.def index 817a488db9..7f290905b4 100644 --- a/auto.def +++ b/auto.def @@ -956,9 +956,11 @@ hwaci-check-rpath # Generate the output files. # hwaci-make-from-dot-in -touch Makefile sqlite3.pc -# for sqlite_cfg.h +# for sqlite_cfg.h and config-defs.json define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION [get-define VERSION_XYZ] +define PACKAGE_STRING "sqlite [get-define VERSION_XYZ]" +define PACKAGE_BUGREPORT [get-define PACKAGE_URL] if {0} { # Requires a hand-written sqlite_cfg.h.in... hwaci-make-from-dot-in sqlite_cfg.h @@ -987,6 +989,13 @@ if {"" ne $oFF} { } unset oFF +hwaci-dump-defs-json config-defs.json \ + -bare {SIZEOF_* HAVE_DECL_*} \ + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} \ + -auto {OPT_* PACKAGE_* HAVE_*} \ + -none * + + ######################################################################## # Some build-dev/debug-only output hwaci-if-opt-truthy dump-defines { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 602c32660d..6f4faa3641 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -41,6 +41,8 @@ # updating global state via feature tests. ######################################################################## +array set hwaci {} + proc hwaci-warn {msg} { puts stderr "WARNING: $msg" } @@ -769,3 +771,71 @@ proc hwaci-check-readline {} { msg-result "libreadline not found." return 0 } + + +proc hwaci-defs-type- {name spec} { + foreach {type patterns} $spec { + foreach pattern $patterns { + if {[string match $pattern $name]} { + return $type + } + } + } + return "" +} + +######################################################################## +# An internal impl detail of hwaci-dump-defs-json. Requires a data +# type specifier, as used by make-config-header, and a value. Returns +# the formatted value or the value $::hwaci(defs-skip) if the +# caller should skip emitting that value. +set hwaci(defs-skip) "-hwaci-defs-format-skip-" +proc hwaci-defs-format- {type value} { + switch -exact -- $type { + -bare { + # Just output the value unchanged + } + -none { + set value $::hwaci(defs-skip) + } + -str { + #set value \"[string map [list \\ \\\\ \" \\\"] $value]\" + } + -auto { + # Automatically determine the type + if {![string is integer -strict $value]} { + set value \"[string map [list \\ \\\\ \" \\\"] $value]\" + } + } + "" { + set value $::hwaci(defs-skip) + } + default { + hwaci-fatal "Unknown type in hwaci-dump-defs-json: $type" + } + } + return $value +} + +######################################################################## +# This function works almost identically to autosetup's make-config-header +# but emits its output in JSON form. It is not a fully-functional JSON +# emitter, and emit broken JSON for complicated outputs, but should be +# sufficient for purposes of emitting most configure vars. +proc hwaci-dump-defs-json {file args} { + file mkdir [file dirname $file] + set lines {} + lappend args -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* + foreach n [lsort [dict keys [all-defines]]] { + set type [hwaci-defs-type- $n $args] + set value [hwaci-defs-format- $type [get-define $n]] + if {$::hwaci(defs-skip) ne $value} { + lappend lines "\"$n\": ${value}" + } + } + set buf {} + lappend buf [join $lines ",\n"] + write-if-changed $file $buf { + msg-result "Created $file" + } +} diff --git a/manifest b/manifest index 67b4e76b25..26017bed12 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C The\s"WITHOUT_JIMSH=1"\soption\son\sthe\snmake\scommand-line\sforces\sthe\suse\sof\nstandard\sTCL\sfor\sbuilding,\sinstead\sof\sjimsh0. -D 2024-10-24T19:56:42.026 +C ./configure\snow\semits\sconfig-defs.json,\sa\sJSON-formatted\scounterpart\sof\sthe\sDEFS=...\sinfo\swhich\sthe\spre-built\sautotools\sbundles\semit. +D 2024-10-25T03:18:11.374 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in a751c1d84222c389ff83dc9c7d2f4ef2ca29bf357609032bb4af3147f6f38b70 +F Makefile.in 1c73c6246b63579d583d6269afce7ac92dfe672521260eee30ca55d752d666b3 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d120d07a0fb42193224bcfb6b658804fdd609bb3b77196d436783b7536426394 +F auto.def f62fd9af4b7dbf53a51134edfef614bc16ec37b68787eb5e0c043efcbdb5a400 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 3513a7dbe685d4776e70d23fa41d6695098627ca063245cac163f8ed3dc696f9 +F autosetup/hwaci-common.tcl e68707f732d05df600a2b621c3c4c337edda0b00ee4216984b3db468da37b05c F autosetup/jimsh0.c eb49d62a5b28b4d3b2af10cdfa5dc972ed76e8474fd773cdc7266e768c746f6d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d8f5193970401b763a94a1d0403bed4337c9fb1f087772b72fb46b9e0bde1c0d -R d6a2c119d2e2b5b78e997064a2e28dd5 -U drh -Z 501f1f77f82aa3cf9af5ab80f1dd5888 +P 9f861f66e238b62e04d640ee98bac86b9b532a55d62c92ae0154bd67ee01ec75 +R bda6d69b215aa13feea0d2ce2c155327 +U stephan +Z 553db8e44b1988785785d92552d56c86 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 018d4e174b..dead31f245 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f861f66e238b62e04d640ee98bac86b9b532a55d62c92ae0154bd67ee01ec75 +800b083c3a55a990bd5b7fd587e24144b0084a394f9cf8160c3aa0a6880f8053 From aa7c9050fa01bcaf7d41d74702fb7c9d6f2f16d9 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 03:35:01 +0000 Subject: [PATCH 140/522] Experimentally add the -array formatting option to hwaci-dump-defs-json and emit OPT_FEATURE_FLAGS/OPT_SHELL in both flat string and array forms. FossilOrigin-Name: ce6bc4603c27952ca44ff55c81dd50a04b0f6ef8f198720ee0da3aff4c291449 --- auto.def | 4 ++++ autosetup/hwaci-common.tcl | 22 ++++++++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index 7f290905b4..84859575fe 100644 --- a/auto.def +++ b/auto.def @@ -989,9 +989,13 @@ if {"" ne $oFF} { } unset oFF +define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] +define OPT_SHELL.list [get-define OPT_SHELL] + hwaci-dump-defs-json config-defs.json \ -bare {SIZEOF_* HAVE_DECL_*} \ -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} \ + -array {*.list} \ -auto {OPT_* PACKAGE_* HAVE_*} \ -none * diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 6f4faa3641..deb94ed986 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -807,6 +807,16 @@ proc hwaci-defs-format- {type value} { set value \"[string map [list \\ \\\\ \" \\\"] $value]\" } } + -array { + set ar {} + foreach v $value { + set v [hwaci-defs-format- -auto $v] + if {$::hwaci(defs-skip) ne $v} { + lappend ar $v + } + } + set value "\[ [join $ar {, }] \]" + } "" { set value $::hwaci(defs-skip) } @@ -822,6 +832,18 @@ proc hwaci-defs-format- {type value} { # but emits its output in JSON form. It is not a fully-functional JSON # emitter, and emit broken JSON for complicated outputs, but should be # sufficient for purposes of emitting most configure vars. +# +# In addition to the formatting flags supported by make-config-header, +# it also supports: +# +# -array {patterns...} +# +# Any defines matching the given patterns will be treated as a list of +# values, each of which will be formatted as if it were in an -auto {...} +# set, and the define will be emitted to JSON in the form: +# +# "ITS_NAME": [ "value1", ...valueN ] +# proc hwaci-dump-defs-json {file args} { file mkdir [file dirname $file] set lines {} diff --git a/manifest b/manifest index 26017bed12..585a47ebe5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C ./configure\snow\semits\sconfig-defs.json,\sa\sJSON-formatted\scounterpart\sof\sthe\sDEFS=...\sinfo\swhich\sthe\spre-built\sautotools\sbundles\semit. -D 2024-10-25T03:18:11.374 +C Experimentally\sadd\sthe\s-array\sformatting\soption\sto\shwaci-dump-defs-json\sand\semit\sOPT_FEATURE_FLAGS/OPT_SHELL\sin\sboth\sflat\sstring\sand\sarray\sforms. +D 2024-10-25T03:35:01.759 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def f62fd9af4b7dbf53a51134edfef614bc16ec37b68787eb5e0c043efcbdb5a400 +F auto.def d84cacf36daca7f56099b5ea525cf0ce20ab2e635d73517fec87cd46340d7a5e F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl e68707f732d05df600a2b621c3c4c337edda0b00ee4216984b3db468da37b05c +F autosetup/hwaci-common.tcl 8575c29133e3bec015915965940812fe07196b67a88a47f3f5473dace4dab43f F autosetup/jimsh0.c eb49d62a5b28b4d3b2af10cdfa5dc972ed76e8474fd773cdc7266e768c746f6d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9f861f66e238b62e04d640ee98bac86b9b532a55d62c92ae0154bd67ee01ec75 -R bda6d69b215aa13feea0d2ce2c155327 +P 800b083c3a55a990bd5b7fd587e24144b0084a394f9cf8160c3aa0a6880f8053 +R f436110a36bf2e585da07552c226e8eb U stephan -Z 553db8e44b1988785785d92552d56c86 +Z 22976a2d67fb47f3aec5f8d0ffbf3d71 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dead31f245..73963d7ab3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -800b083c3a55a990bd5b7fd587e24144b0084a394f9cf8160c3aa0a6880f8053 +ce6bc4603c27952ca44ff55c81dd50a04b0f6ef8f198720ee0da3aff4c291449 From a1bc2ad6ce1cfea9e36855ba4766d1b62f57e2ba Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 03:56:09 +0000 Subject: [PATCH 141/522] Docs related to the -array defs-dump option. Rename some internal-use hwaci-common.tcl APIs after discovering that a - as a symbol suffix fails for var derefs (but works for procs calls). FossilOrigin-Name: 0d5da3888e79166fec560554a921e2ef4290558e988144465f1ea7138ca263a3 --- auto.def | 6 ++++-- autosetup/hwaci-common.tcl | 38 +++++++++++++++++++++++++++----------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/auto.def b/auto.def index 84859575fe..c403ee1ad7 100644 --- a/auto.def +++ b/auto.def @@ -989,16 +989,18 @@ if {"" ne $oFF} { } unset oFF +# Demonstrate (mis?)handling of spaces in JSON-export array values: +# define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] define OPT_SHELL.list [get-define OPT_SHELL] - hwaci-dump-defs-json config-defs.json \ -bare {SIZEOF_* HAVE_DECL_*} \ -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} \ -array {*.list} \ -auto {OPT_* PACKAGE_* HAVE_*} \ -none * - +undefine OPT_FEATURE_FLAGS.list +undefine OPT_SHELL.list ######################################################################## # Some build-dev/debug-only output diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index deb94ed986..bab05264f3 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -12,7 +12,7 @@ # Routines for Steve Bennett's autosetup which are common to trees # managed in and around the umbrella of the SQLite project. # -# Routines with a suffix of - are intended for internal use, +# Routines with a suffix of _ are intended for internal use, # within this file, and are not part of the API which auto.def files # should rely on. # @@ -41,7 +41,10 @@ # updating global state via feature tests. ######################################################################## -array set hwaci {} +######################################################################## +# $hwaci is an internal-use-only array for storing whatever generic +# internal stuff we need stored. +array set hwaci_ {} proc hwaci-warn {msg} { puts stderr "WARNING: $msg" @@ -54,13 +57,13 @@ proc hwaci-fatal {msg} { } ######################################################################## -# hwaci-lshift- shifts $count elements from the list named $listVar and +# hwaci-lshift_ shifts $count elements from the list named $listVar and # returns them. # # Modified slightly from: https://wiki.tcl-lang.org/page/lshift # # On an empty list, returns "". -proc hwaci-lshift- {listVar {count 1}} { +proc hwaci-lshift_ {listVar {count 1}} { upvar 1 $listVar l if {![info exists l]} { # make the error message show the real variable name @@ -262,9 +265,9 @@ proc hwaci-opt-define-bool {args} { set invert 1 set args [lrange $args 1 end] } - set optName [hwaci-lshift- args] - set defName [hwaci-lshift- args] - set descr [hwaci-lshift- args] + set optName [hwaci-lshift_ args] + set defName [hwaci-lshift_ args] + set descr [hwaci-lshift_ args] if {"" eq $descr} { set descr $defName } @@ -828,10 +831,11 @@ proc hwaci-defs-format- {type value} { } ######################################################################## -# This function works almost identically to autosetup's make-config-header -# but emits its output in JSON form. It is not a fully-functional JSON -# emitter, and emit broken JSON for complicated outputs, but should be -# sufficient for purposes of emitting most configure vars. +# This function works almost identically to autosetup's +# make-config-header but emits its output in JSON form. It is not a +# fully-functional JSON emitter, and will emit broken JSON for +# complicated outputs, but should be sufficient for purposes of +# emitting most configure vars (numbers and simple strings). # # In addition to the formatting flags supported by make-config-header, # it also supports: @@ -844,6 +848,18 @@ proc hwaci-defs-format- {type value} { # # "ITS_NAME": [ "value1", ...valueN ] # +# Achtung: if a given -array pattern contains values which themselves +# contains spaces... +# +# define-append foo {"-DFOO=bar baz" -DBAR="baz barre"} +# +# will lead to: +# +# ["-DFOO=bar baz", "-DBAR=\"baz", "barre\""] +# +# Neither is especially satisfactory (and the second is useless), and +# handling of such values is subject to change if any such values ever +# _really_ need to be processed by our source trees. proc hwaci-dump-defs-json {file args} { file mkdir [file dirname $file] set lines {} diff --git a/manifest b/manifest index 585a47ebe5..a40fd468aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimentally\sadd\sthe\s-array\sformatting\soption\sto\shwaci-dump-defs-json\sand\semit\sOPT_FEATURE_FLAGS/OPT_SHELL\sin\sboth\sflat\sstring\sand\sarray\sforms. -D 2024-10-25T03:35:01.759 +C Docs\srelated\sto\sthe\s-array\sdefs-dump\soption.\sRename\ssome\sinternal-use\shwaci-common.tcl\sAPIs\safter\sdiscovering\sthat\sa\s-\sas\sa\ssymbol\ssuffix\sfails\sfor\svar\sderefs\s(but\sworks\sfor\sprocs\scalls). +D 2024-10-25T03:56:09.158 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d84cacf36daca7f56099b5ea525cf0ce20ab2e635d73517fec87cd46340d7a5e +F auto.def 48411cc3e6b140d4af7ab51ce309bf1dc0d4eaace628befb261f6915994bb3c7 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 8575c29133e3bec015915965940812fe07196b67a88a47f3f5473dace4dab43f +F autosetup/hwaci-common.tcl 3f1653580ed9256c186c14264e50f8d7fb03e5a21b1790fccad173515d162b2a F autosetup/jimsh0.c eb49d62a5b28b4d3b2af10cdfa5dc972ed76e8474fd773cdc7266e768c746f6d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 800b083c3a55a990bd5b7fd587e24144b0084a394f9cf8160c3aa0a6880f8053 -R f436110a36bf2e585da07552c226e8eb +P ce6bc4603c27952ca44ff55c81dd50a04b0f6ef8f198720ee0da3aff4c291449 +R 38a7ffa837a034a8e4135985ac058125 U stephan -Z 22976a2d67fb47f3aec5f8d0ffbf3d71 +Z 7fac80295cd944d4b161bf97831f53d2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 73963d7ab3..f8dd8bc4e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ce6bc4603c27952ca44ff55c81dd50a04b0f6ef8f198720ee0da3aff4c291449 +0d5da3888e79166fec560554a921e2ef4290558e988144465f1ea7138ca263a3 From 7ad582ad5a10f068dc6ed21da1b991241d6400c7 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 04:16:36 +0000 Subject: [PATCH 142/522] Internal cleanups and docs in hwaci-common.tcl. FossilOrigin-Name: 30699b57d21f70dd42ec61f5157859358c6be5e3e14bb2989f8874ceeda5dae6 --- autosetup/hwaci-common.tcl | 41 +++++++++++++++++++++++++------------- manifest | 12 +++++------ manifest.uuid | 2 +- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index bab05264f3..06f3b11645 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -776,7 +776,13 @@ proc hwaci-check-readline {} { } -proc hwaci-defs-type- {name spec} { +######################################################################## +# Internal helper for hwaci-dump-defs-json. Expects to be passed a +# [define] name and the variadic $args which are passed to +# hwaci-dump-defs-json. If it finds a pattern match for the given +# $name in the various $args, it returns the type flag for that $name, +# e.g. "-str" or "-bare", else returns an empty string. +proc hwaci-defs-type_ {name spec} { foreach {type patterns} $spec { foreach pattern $patterns { if {[string match $pattern $name]} { @@ -787,41 +793,48 @@ proc hwaci-defs-type- {name spec} { return "" } +######################################################################## +# Internal helper for hwaci-defs-format_: returns a JSON-ish quoted +# form of the given (JSON) string-type values. +proc hwaci-quote-str_ {value} { + return \"[string map [list \\ \\\\ \" \\\"] $value]\" +} + ######################################################################## # An internal impl detail of hwaci-dump-defs-json. Requires a data # type specifier, as used by make-config-header, and a value. Returns -# the formatted value or the value $::hwaci(defs-skip) if the -# caller should skip emitting that value. -set hwaci(defs-skip) "-hwaci-defs-format-skip-" -proc hwaci-defs-format- {type value} { +# the formatted value or the value $::hwaci_(defs-skip) if the caller +# should skip emitting that value. +set hwaci_(defs-skip) "-hwaci-defs-format_ sentinel" +proc hwaci-defs-format_ {type value} { switch -exact -- $type { -bare { # Just output the value unchanged } -none { - set value $::hwaci(defs-skip) + set value $::hwaci_(defs-skip) } -str { - #set value \"[string map [list \\ \\\\ \" \\\"] $value]\" + set value [hwaci-quote-str_ $value] } -auto { # Automatically determine the type if {![string is integer -strict $value]} { - set value \"[string map [list \\ \\\\ \" \\\"] $value]\" + set value [hwaci-quote-str_ $value] } } -array { set ar {} foreach v $value { - set v [hwaci-defs-format- -auto $v] - if {$::hwaci(defs-skip) ne $v} { + set v [hwaci-defs-format_ -auto $v] + if {$::hwaci_(defs-skip) ne $v} { lappend ar $v } } set value "\[ [join $ar {, }] \]" } "" { - set value $::hwaci(defs-skip) + set value $::hwaci_(defs-skip) } default { hwaci-fatal "Unknown type in hwaci-dump-defs-json: $type" @@ -865,9 +878,9 @@ proc hwaci-dump-defs-json {file args} { set lines {} lappend args -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* foreach n [lsort [dict keys [all-defines]]] { - set type [hwaci-defs-type- $n $args] - set value [hwaci-defs-format- $type [get-define $n]] - if {$::hwaci(defs-skip) ne $value} { + set type [hwaci-defs-type_ $n $args] + set value [hwaci-defs-format_ $type [get-define $n]] + if {$::hwaci_(defs-skip) ne $value} { lappend lines "\"$n\": ${value}" } } diff --git a/manifest b/manifest index a40fd468aa..5e84a206cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Docs\srelated\sto\sthe\s-array\sdefs-dump\soption.\sRename\ssome\sinternal-use\shwaci-common.tcl\sAPIs\safter\sdiscovering\sthat\sa\s-\sas\sa\ssymbol\ssuffix\sfails\sfor\svar\sderefs\s(but\sworks\sfor\sprocs\scalls). -D 2024-10-25T03:56:09.158 +C Internal\scleanups\sand\sdocs\sin\shwaci-common.tcl. +D 2024-10-25T04:16:36.966 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 3f1653580ed9256c186c14264e50f8d7fb03e5a21b1790fccad173515d162b2a +F autosetup/hwaci-common.tcl 97b55f68dd190e624340ced9c2de16286edad9db95fede4a184af4249561b4bb F autosetup/jimsh0.c eb49d62a5b28b4d3b2af10cdfa5dc972ed76e8474fd773cdc7266e768c746f6d F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ce6bc4603c27952ca44ff55c81dd50a04b0f6ef8f198720ee0da3aff4c291449 -R 38a7ffa837a034a8e4135985ac058125 +P 0d5da3888e79166fec560554a921e2ef4290558e988144465f1ea7138ca263a3 +R 3df9a97de38801cc8ea2ce03eb6935ab U stephan -Z 7fac80295cd944d4b161bf97831f53d2 +Z c1a5ed21a5f202d16f8c6f337f6da0c7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f8dd8bc4e7..0016dc7576 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d5da3888e79166fec560554a921e2ef4290558e988144465f1ea7138ca263a3 +30699b57d21f70dd42ec61f5157859358c6be5e3e14bb2989f8874ceeda5dae6 From 957209e7ac7425381e4bb35c06e23bd97baa6f8c Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 04:39:14 +0000 Subject: [PATCH 143/522] Add --defs-json-include-lowercase configure flag to cause config-defs.json to include lower-case defines, which are primarily the various build-related system paths. FossilOrigin-Name: 0f2555ea3c7c1950566182c8f5a4d98049461e9db305e892c8434ba3fbf3497a --- Makefile.in | 2 +- auto.def | 22 +++++++++++++++------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Makefile.in b/Makefile.in index b39323f272..8ea809e672 100644 --- a/Makefile.in +++ b/Makefile.in @@ -313,7 +313,7 @@ clean: clean-autosetup distclean-autosetup: clean rm -f sqlite_cfg.h config.log config.status config-defs.json Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh - rm -f libsqlite3*.$(T.dll) + rm -f libsqlite3*$(T.dll) -gmake -C ext/wasm distclean 2>/dev/null; true distclean: distclean-autosetup diff --git a/auto.def b/auto.def index c403ee1ad7..31cb336abb 100644 --- a/auto.def +++ b/auto.def @@ -144,6 +144,7 @@ options [subst { with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build.} with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} + defs-json-include-lowercase=0 => {Include lower-case defines in config-defs.json, which are primarily system paths.} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_FILE (for build debugging)} }] @@ -957,9 +958,10 @@ hwaci-check-rpath # hwaci-make-from-dot-in -touch Makefile sqlite3.pc # for sqlite_cfg.h and config-defs.json +define PACKAGE_NAME "sqlite" define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION [get-define VERSION_XYZ] -define PACKAGE_STRING "sqlite [get-define VERSION_XYZ]" +define PACKAGE_STRING "[get-define PACKAGE_NAME] [get-define VERSION_XYZ]" define PACKAGE_BUGREPORT [get-define PACKAGE_URL] if {0} { # Requires a hand-written sqlite_cfg.h.in... @@ -993,12 +995,18 @@ unset oFF # define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] define OPT_SHELL.list [get-define OPT_SHELL] -hwaci-dump-defs-json config-defs.json \ - -bare {SIZEOF_* HAVE_DECL_*} \ - -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} \ - -array {*.list} \ - -auto {OPT_* PACKAGE_* HAVE_*} \ - -none * +set dumpDefsOpt { + -bare {SIZEOF_* HAVE_DECL_*} + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} + -array {*.list} + -auto {OPT_* PACKAGE_* HAVE_*} +} +if {[opt-bool defs-json-include-lowercase]} { + lappend dumpDefsOpt -none {lib_*} ; # remnants from hwaci-check-function-in-lib and friends + lappend dumpDefsOpt -auto {[a-z]*} +} +lappend dumpDefsOpt -none * +hwaci-dump-defs-json config-defs.json {*}$dumpDefsOpt undefine OPT_FEATURE_FLAGS.list undefine OPT_SHELL.list diff --git a/manifest b/manifest index 5e84a206cf..bffcdf0b88 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Internal\scleanups\sand\sdocs\sin\shwaci-common.tcl. -D 2024-10-25T04:16:36.966 +C Add\s--defs-json-include-lowercase\sconfigure\sflag\sto\scause\sconfig-defs.json\sto\sinclude\slower-case\sdefines,\swhich\sare\sprimarily\sthe\svarious\sbuild-related\ssystem\spaths. +D 2024-10-25T04:39:14.952 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 1c73c6246b63579d583d6269afce7ac92dfe672521260eee30ca55d752d666b3 +F Makefile.in f62cd6d36461d462cccc80ecd2b43a53e21467d67250555570644e616ca5b18d F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 48411cc3e6b140d4af7ab51ce309bf1dc0d4eaace628befb261f6915994bb3c7 +F auto.def dc9e9da56ef6b99f79fe51e9c6b7510f33fd4d4b44e00779642ea237a0768b76 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0d5da3888e79166fec560554a921e2ef4290558e988144465f1ea7138ca263a3 -R 3df9a97de38801cc8ea2ce03eb6935ab +P 30699b57d21f70dd42ec61f5157859358c6be5e3e14bb2989f8874ceeda5dae6 +R 072d902d5f60f416f41fd709fc58d6b0 U stephan -Z c1a5ed21a5f202d16f8c6f337f6da0c7 +Z b79df6907aab089767fcfcfc7c508bc3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0016dc7576..192bb16f99 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -30699b57d21f70dd42ec61f5157859358c6be5e3e14bb2989f8874ceeda5dae6 +0f2555ea3c7c1950566182c8f5a4d98049461e9db305e892c8434ba3fbf3497a From 14e4d9ad306dc6647b57fb503e8dc1f607280fb3 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 04:48:40 +0000 Subject: [PATCH 144/522] Rename config-defines.json to config.defines.json for consistent with other generated config.* files. Rename --defs-json-include-lowercase to the even less wieldy --defines-json-include-lowercase. FossilOrigin-Name: 131a2a7ef87b65527d03b3c838de9d34eaca94992a973283ad6eeb296250db92 --- Makefile.in | 2 +- auto.def | 10 ++++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 8ea809e672..705489fcfe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -311,7 +311,7 @@ clean-autosetup: clean: clean-autosetup distclean-autosetup: clean - rm -f sqlite_cfg.h config.log config.status config-defs.json Makefile sqlite3.pc + rm -f sqlite_cfg.h config.log config.status config.defines.json Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh rm -f libsqlite3*$(T.dll) -gmake -C ext/wasm distclean 2>/dev/null; true diff --git a/auto.def b/auto.def index 31cb336abb..66c9b978b7 100644 --- a/auto.def +++ b/auto.def @@ -144,7 +144,7 @@ options [subst { with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build.} with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} - defs-json-include-lowercase=0 => {Include lower-case defines in config-defs.json, which are primarily system paths.} + defines-json-include-lowercase=0 => {Include lower-case defines in config.defines.json, which are primarily system paths.} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_FILE (for build debugging)} }] @@ -957,7 +957,7 @@ hwaci-check-rpath # Generate the output files. # hwaci-make-from-dot-in -touch Makefile sqlite3.pc -# for sqlite_cfg.h and config-defs.json +# for sqlite_cfg.h and config.defines.json define PACKAGE_NAME "sqlite" define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION [get-define VERSION_XYZ] @@ -991,6 +991,8 @@ if {"" ne $oFF} { } unset oFF +######################################################################## +# Dump config-defines.json... # Demonstrate (mis?)handling of spaces in JSON-export array values: # define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] @@ -1001,12 +1003,12 @@ set dumpDefsOpt { -array {*.list} -auto {OPT_* PACKAGE_* HAVE_*} } -if {[opt-bool defs-json-include-lowercase]} { +if {[opt-bool defines-json-include-lowercase]} { lappend dumpDefsOpt -none {lib_*} ; # remnants from hwaci-check-function-in-lib and friends lappend dumpDefsOpt -auto {[a-z]*} } lappend dumpDefsOpt -none * -hwaci-dump-defs-json config-defs.json {*}$dumpDefsOpt +hwaci-dump-defs-json config.defines.json {*}$dumpDefsOpt undefine OPT_FEATURE_FLAGS.list undefine OPT_SHELL.list diff --git a/manifest b/manifest index bffcdf0b88..2ea3d82ecf 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\s--defs-json-include-lowercase\sconfigure\sflag\sto\scause\sconfig-defs.json\sto\sinclude\slower-case\sdefines,\swhich\sare\sprimarily\sthe\svarious\sbuild-related\ssystem\spaths. -D 2024-10-25T04:39:14.952 +C Rename\sconfig-defines.json\sto\sconfig.defines.json\sfor\sconsistent\swith\sother\sgenerated\sconfig.*\sfiles.\sRename\s--defs-json-include-lowercase\sto\sthe\seven\sless\swieldy\s--defines-json-include-lowercase. +D 2024-10-25T04:48:40.197 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in f62cd6d36461d462cccc80ecd2b43a53e21467d67250555570644e616ca5b18d +F Makefile.in 594067da2bde9defc6ff79d15db35f6433ff972ad585461ba5f13d110a095af2 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def dc9e9da56ef6b99f79fe51e9c6b7510f33fd4d4b44e00779642ea237a0768b76 +F auto.def 79da787fe2e011ca43a571147dd68f737a565a57c814b51c5b7b1f7a0f587b24 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 30699b57d21f70dd42ec61f5157859358c6be5e3e14bb2989f8874ceeda5dae6 -R 072d902d5f60f416f41fd709fc58d6b0 +P 0f2555ea3c7c1950566182c8f5a4d98049461e9db305e892c8434ba3fbf3497a +R 001a56dd108f5cc3c7d24adb5c49ea93 U stephan -Z b79df6907aab089767fcfcfc7c508bc3 +Z a5be42358d441efdb62f852f6106323d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 192bb16f99..1f320d0f69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f2555ea3c7c1950566182c8f5a4d98049461e9db305e892c8434ba3fbf3497a +131a2a7ef87b65527d03b3c838de9d34eaca94992a973283ad6eeb296250db92 From f84060f2f8b505f94b21dc4c38dc616912d27758 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 05:53:50 +0000 Subject: [PATCH 145/522] Ensure that jimsh is built in the proper dir in an out-of-tree build and that jimsh0 is cleaned up by distclean. FossilOrigin-Name: e0286e258b17e7812387f5e661910ddd3c015bd5ac62dcbd7e02b69379dc9277 --- Makefile.in | 7 +++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index 705489fcfe..6ca1f3ac10 100644 --- a/Makefile.in +++ b/Makefile.in @@ -133,10 +133,12 @@ T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite #XX#T.cc += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ # -# $(JIMSH) and $(CFLAGS.JIMSH) are documented in main.mk. +# $(JIMSH) and $(CFLAGS.JIMSH) are documented in main.mk. $(JIMSH) +# must start with a path component so that it can be invoked as a +# shell command. # CFLAGS.JIMSH = @CFLAGS_JIMSH@ -JIMSH = $(TOP)/jimsh$(TEXE) +JIMSH = ./jimsh$(TEXE) # # $(B.tclsh) is documented in main.mk. @@ -314,6 +316,7 @@ distclean-autosetup: clean rm -f sqlite_cfg.h config.log config.status config.defines.json Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh rm -f libsqlite3*$(T.dll) + rm -f jimsh0* -gmake -C ext/wasm distclean 2>/dev/null; true distclean: distclean-autosetup diff --git a/manifest b/manifest index 2ea3d82ecf..23a8792add 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Rename\sconfig-defines.json\sto\sconfig.defines.json\sfor\sconsistent\swith\sother\sgenerated\sconfig.*\sfiles.\sRename\s--defs-json-include-lowercase\sto\sthe\seven\sless\swieldy\s--defines-json-include-lowercase. -D 2024-10-25T04:48:40.197 +C Ensure\sthat\sjimsh\sis\sbuilt\sin\sthe\sproper\sdir\sin\san\sout-of-tree\sbuild\sand\sthat\sjimsh0\sis\scleaned\sup\sby\sdistclean. +D 2024-10-25T05:53:50.786 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 594067da2bde9defc6ff79d15db35f6433ff972ad585461ba5f13d110a095af2 +F Makefile.in 5a95c68b70be1448a6f226c09c1df5e338cc496e70987173fcfdca9ad94cb5a4 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0f2555ea3c7c1950566182c8f5a4d98049461e9db305e892c8434ba3fbf3497a -R 001a56dd108f5cc3c7d24adb5c49ea93 +P 131a2a7ef87b65527d03b3c838de9d34eaca94992a973283ad6eeb296250db92 +R 489a8b201a3bc8d75b578c157a68a0fc U stephan -Z a5be42358d441efdb62f852f6106323d +Z 2e64ff42f6eac2a825d81033399cb4f4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1f320d0f69..e0add573ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -131a2a7ef87b65527d03b3c838de9d34eaca94992a973283ad6eeb296250db92 +e0286e258b17e7812387f5e661910ddd3c015bd5ac62dcbd7e02b69379dc9277 From 4de88eb13e72b0a7056996adaea860888eae4a44 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 25 Oct 2024 12:06:40 +0000 Subject: [PATCH 146/522] Update the LICENSE.md file to describe BSD-licensed code that is included in the repository as a convenience to developers but which is not itself actually a part of SQLite. FossilOrigin-Name: deb5994bb1c7295099939f9c88a97ecfe6d21087cfc9c98384e91993ce85f5e6 --- LICENSE.md | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ manifest | 14 ++++----- manifest.uuid | 2 +- 3 files changed, 93 insertions(+), 8 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index f68a6c175f..6a1f19246a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,91 @@ +License Information +=================== + +SQLite Is Public Domain +----------------------- + +The SQLite source code, including all of the files in the directories +listed in the bullets below are +[Public Domain](https://sqlite.org/copyright.html). +The authors have submitted written affidavits releasing their work to +the public for any use. Every byte of the public-domain code can be +traced back to the original authors. The files of this repository +that are public domain include the following: + + * All of the primary SQLite source code files found in the + [src/ directory](https://sqlite.org/src/tree/src?type=tree&expand) + * All of the test cases and testing code in the + [test/ directory](https://sqlite.org/src/tree/test?type=tree&expand) + * All of the SQLite extension source code and test cases in the + [ext/ directory](https://sqlite.org/src/tree/ext?type=tree&expand) + * All code that ends up in the "sqlite3.c" and "sqlite3.h" build products + that actually implements the SQLite RDBMS. + * All of the code used to compile the + [command-line interface](https://sqlite.org/cli.html) + * All of the code used to build various utility programs such as + "sqldiff", "sqlite3_rsync", and "sqlite3_analyzer". + + +The public domain source files usually contain a header comment +similar to the following to make it clear that the software is +public domain. + +> ~~~ The author disclaims copyright to this source code. In place of a legal notice, here is a blessing: * May you do good and not evil. * May you find forgiveness for yourself and forgive others. * May you share freely, never taking more than you give. +~~~ + +Almost every file you find in this source repository will be +public domain. But there are a small number of exceptions: + +Non-Public-Domain Code Included With This Source Repository AS A Convenience +---------------------------------------------------------------------------- + +This repository contains a (relatively) small amount of non-public-domain +code used to help implement the configuration and build logic. In other +words, there are some non-public-domain files used to implement: + +> ~~~ +./configure && make +~~~ + +In all cases, the non-public-domain files included with this +repository have generous BSD-style licenses. So anyone is free to +use any of the code in this source repository for any purpose, though +attribution my be required to reuse or republish the configure and +build scripts. None of the non-public-domain code ever actually reaches +the build products, such as "sqlite3.c", however, so no attribution is +required to use SQLite itself. The non-public-domain code consists of +scripts used to help compile SQLite. The non-public-domain code is +technically not part of SQLite. The non-public-domain code is +included in this repository as a convenience to developers, so that those +who want to build SQLite do not need to go download a bunch of +third-party build scripts in order to compile SQLite. + +Non-public-domain code included in this respository includes: + + * The ["autosetup"](http://msteveb.github.io/autosetup/) configuration + system that is contained (mostly) the autosetup/ directory, but also + includes the "./configure" script at the top-level of this archive. + Autosetup has a separate BSD-style license. See the + [autosetup/LICENSE](http://msteveb.github.io/autosetup/license/) + for details. + + * There are BSD-style licenses on some of the configuration + software found in the legacy autoconf/ directory and its + subdirectories. + +The following unix shell command is can be run from the top-level +of this source repository in order to remove all non-public-domain +code: + +> ~~~ +rm -rf configure autosetup autoconf +~~~ + +If you unpack this source repository and then run the command above, what +is left will be 100% public domain. diff --git a/manifest b/manifest index 23a8792add..508860e7cf 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Ensure\sthat\sjimsh\sis\sbuilt\sin\sthe\sproper\sdir\sin\san\sout-of-tree\sbuild\sand\sthat\sjimsh0\sis\scleaned\sup\sby\sdistclean. -D 2024-10-25T05:53:50.786 +C Update\sthe\sLICENSE.md\sfile\sto\sdescribe\sBSD-licensed\scode\sthat\sis\sincluded\nin\sthe\srepository\sas\sa\sconvenience\sto\sdevelopers\sbut\swhich\sis\snot\sitself\nactually\sa\spart\sof\sSQLite. +D 2024-10-25T12:06:40.881 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea -F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 +F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 F Makefile.in 5a95c68b70be1448a6f226c09c1df5e338cc496e70987173fcfdca9ad94cb5a4 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 131a2a7ef87b65527d03b3c838de9d34eaca94992a973283ad6eeb296250db92 -R 489a8b201a3bc8d75b578c157a68a0fc -U stephan -Z 2e64ff42f6eac2a825d81033399cb4f4 +P e0286e258b17e7812387f5e661910ddd3c015bd5ac62dcbd7e02b69379dc9277 +R 56a923b21a8d871154262a2cbdd151d9 +U drh +Z 3da269bef7fc6d4935caf8524fa95e19 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e0add573ac..b05d58414e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0286e258b17e7812387f5e661910ddd3c015bd5ac62dcbd7e02b69379dc9277 +deb5994bb1c7295099939f9c88a97ecfe6d21087cfc9c98384e91993ce85f5e6 From 4ccc5de98fce5009b93bb63e553dcae0600151f9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 25 Oct 2024 12:22:29 +0000 Subject: [PATCH 147/522] New jimsh0.c file for autosetup. FossilOrigin-Name: cfacf864119170365fb21a09d2cca5f2a16354837ef0c3c726b00a886ea8e7e2 --- autosetup/jimsh0.c | 312 ++++++++++++++++++++++----------------------- manifest | 12 +- manifest.uuid | 2 +- 3 files changed, 160 insertions(+), 166 deletions(-) diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index ca4912f95a..fb4e8b806d 100644 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -13,7 +13,6 @@ #define jim_ext_file #define jim_ext_glob #define jim_ext_exec -#define jim_ext_posix #define jim_ext_clock #define jim_ext_array #define jim_ext_stdlib @@ -63,7 +62,7 @@ #define HAVE_PIPE #define _FILE_OFFSET_BITS 64 #endif -#define JIM_VERSION 83 +#define JIM_VERSION 84 #ifndef JIM_WIN32COMPAT_H #define JIM_WIN32COMPAT_H @@ -96,7 +95,9 @@ char *dlerror(void); #include #define jim_wide _int64 -#define HAVE_LONG_LONG 1 +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG +#endif #ifndef LLONG_MAX #define LLONG_MAX 9223372036854775807I64 #endif @@ -110,8 +111,8 @@ char *dlerror(void); #define strtoull _strtoui64 #include -#include +#include int gettimeofday(struct timeval *tv, void *unused); #define HAVE_OPENDIR @@ -1161,7 +1162,7 @@ int Jim_OpenForWrite(const char *filename, int append); int Jim_OpenForRead(const char *filename); -#if defined(__MINGW32__) +#if defined(__MINGW32__) || defined(_WIN32) #ifndef STRICT #define STRICT #endif @@ -1196,6 +1197,7 @@ int Jim_OpenForRead(const char *filename); #define Jim_Stat _stat64 #define Jim_FileStat _fstat64 #define Jim_Lseek _lseeki64 + #define O_TEXT _O_TEXT #else #if defined(HAVE_STAT64) @@ -1238,10 +1240,11 @@ int Jim_OpenForRead(const char *filename); #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV) #endif #endif -#endif -#if !defined(O_TEXT) && !defined(_WIN32) -#define O_TEXT 0 + #ifndef O_TEXT + #define O_TEXT 0 + #endif + #endif @@ -1944,9 +1947,6 @@ int Jim_tclcompatInit(Jim_Interp *interp) " if {$cmd eq \"pid\"} {\n" " return $pids\n" " }\n" -" if {$cmd eq \"getfd\"} {\n" -" $f getfd\n" -" }\n" " if {$cmd eq \"close\"} {\n" " $f close\n" "\n" @@ -2046,8 +2046,8 @@ int Jim_tclcompatInit(Jim_Interp *interp) #define AIO_CMD_LEN 32 -#define AIO_BUF_LEN 256 -#define AIO_WBUF_FULL_SIZE (64 * 1024) +#define AIO_DEFAULT_RBUF_LEN 256 +#define AIO_DEFAULT_WBUF_LIMIT (64 * 1024) #define AIO_KEEPOPEN 1 #define AIO_NODELETE 2 @@ -2055,6 +2055,8 @@ int Jim_tclcompatInit(Jim_Interp *interp) #define AIO_WBUF_NONE 8 #define AIO_NONBLOCK 16 +#define AIO_ONEREAD 32 + enum wbuftype { WBUF_OPT_NONE, WBUF_OPT_LINE, @@ -2129,11 +2131,20 @@ typedef struct AioFile const JimAioFopsType *fops; Jim_Obj *readbuf; Jim_Obj *writebuf; + char *rbuf; + size_t rbuf_len; + size_t wbuf_limit; } AioFile; +static void aio_consume(Jim_Obj *objPtr, int n); + static int stdio_writer(struct AioFile *af, const char *buf, int len) { - return write(af->fd, buf, len); + int ret = write(af->fd, buf, len); + if (ret < 0 && errno == EPIPE) { + aio_consume(af->writebuf, Jim_Length(af->writebuf)); + } + return ret; } static int stdio_reader(struct AioFile *af, char *buf, int len, int nb) @@ -2270,7 +2281,22 @@ static void aio_consume(Jim_Obj *objPtr, int n) } -static int aio_autoflush(Jim_Interp *interp, void *clientData, int mask); +static int aio_flush(Jim_Interp *interp, AioFile *af); + +#ifdef jim_ext_eventloop +static int aio_autoflush(Jim_Interp *interp, void *clientData, int mask) +{ + AioFile *af = clientData; + + aio_flush(interp, af); + if (Jim_Length(af->writebuf) == 0) { + + return -1; + } + return 0; +} +#endif + static int aio_flush(Jim_Interp *interp, AioFile *af) { @@ -2305,19 +2331,7 @@ static int aio_flush(Jim_Interp *interp, AioFile *af) return JIM_OK; } -static int aio_autoflush(Jim_Interp *interp, void *clientData, int mask) -{ - AioFile *af = clientData; - - aio_flush(interp, af); - if (Jim_Length(af->writebuf) == 0) { - - return -1; - } - return 0; -} - -static int aio_read_len(Jim_Interp *interp, AioFile *af, int nb, char *buf, size_t buflen, int neededLen) +static int aio_read_len(Jim_Interp *interp, AioFile *af, unsigned flags, int neededLen) { if (!af->readbuf) { af->readbuf = Jim_NewStringObj(interp, NULL, 0); @@ -2335,20 +2349,29 @@ static int aio_read_len(Jim_Interp *interp, AioFile *af, int nb, char *buf, size int readlen; if (neededLen == -1) { - readlen = AIO_BUF_LEN; + readlen = af->rbuf_len; } else { - readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen); + readlen = (neededLen > af->rbuf_len ? af->rbuf_len : neededLen); + } + + if (!af->rbuf) { + af->rbuf = Jim_Alloc(af->rbuf_len); } - retval = af->fops->reader(af, buf, readlen, nb); + retval = af->fops->reader(af, af->rbuf, readlen, flags & AIO_NONBLOCK); if (retval > 0) { - Jim_AppendString(interp, af->readbuf, buf, retval); + if (retval) { + Jim_AppendString(interp, af->readbuf, af->rbuf, retval); + } if (neededLen != -1) { neededLen -= retval; } + if (flags & AIO_ONEREAD) { + return JIM_OK; + } continue; } - if (JimCheckStreamError(interp, af)) { + if ((flags & AIO_ONEREAD) || JimCheckStreamError(interp, af)) { return JIM_ERR; } break; @@ -2419,6 +2442,7 @@ static void JimAioDelProc(Jim_Interp *interp, void *privData) Jim_FreeNewObj(interp, af->readbuf); } + Jim_Free(af->rbuf); Jim_Free(af); } @@ -2432,7 +2456,6 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int option; int nb; Jim_Obj *objPtr; - char buf[AIO_BUF_LEN]; if (argc) { if (*Jim_String(argv[0]) == '-') { @@ -2466,7 +2489,7 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) nb = aio_start_nonblocking(af); - if (aio_read_len(interp, af, nb, buf, sizeof(buf), neededLen) != JIM_OK) { + if (aio_read_len(interp, af, nb ? AIO_NONBLOCK : 0, neededLen) != JIM_OK) { aio_set_nonblocking(af, nb); return JIM_ERR; } @@ -2521,11 +2544,6 @@ static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) AioFile *af = Jim_CmdPrivData(interp); jim_wide count = 0; jim_wide maxlen = JIM_WIDE_MAX; - - char buf[AIO_BUF_LEN]; - - char *bufp = buf; - int buflen = sizeof(buf); int ok = 1; Jim_Obj *objv[4]; @@ -2551,10 +2569,10 @@ static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) while (count < maxlen) { jim_wide len = maxlen - count; - if (len > buflen) { - len = buflen; + if (len > af->rbuf_len) { + len = af->rbuf_len; } - if (aio_read_len(interp, af, 0, bufp, buflen, len) != JIM_OK) { + if (aio_read_len(interp, af, 0, len) != JIM_OK) { ok = 0; break; } @@ -2567,17 +2585,13 @@ static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (aio_eof(af)) { break; } - if (count >= 16384 && bufp == buf) { + if (count >= 16384 && af->rbuf_len < 65536) { - buflen = 65536; - bufp = Jim_Alloc(buflen); + af->rbuf_len = 65536; + af->rbuf = Jim_Realloc(af->rbuf, af->rbuf_len); } } - if (bufp != buf) { - Jim_Free(bufp); - } - Jim_DecrRefCount(interp, objv[1]); Jim_DecrRefCount(interp, objv[2]); @@ -2593,10 +2607,10 @@ static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); - char buf[AIO_BUF_LEN]; Jim_Obj *objPtr = NULL; int len; int nb; + unsigned flags = AIO_ONEREAD; char *nl = NULL; int offset = 0; @@ -2604,33 +2618,33 @@ static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv) nb = aio_start_nonblocking(af); - - if (!af->readbuf) { - af->readbuf = Jim_NewStringObj(interp, NULL, 0); + if (nb) { + flags |= AIO_NONBLOCK; } while (!aio_eof(af)) { - const char *pt = Jim_GetString(af->readbuf, &len); - nl = memchr(pt + offset, '\n', len - offset); - if (nl) { + if (af->readbuf) { + const char *pt = Jim_GetString(af->readbuf, &len); + nl = memchr(pt + offset, '\n', len - offset); + if (nl) { - objPtr = Jim_NewStringObj(interp, pt, nl - pt); + objPtr = Jim_NewStringObj(interp, pt, nl - pt); - aio_consume(af->readbuf, nl - pt + 1); - break; + aio_consume(af->readbuf, nl - pt + 1); + break; + } + offset = len; } - offset = len; - len = af->fops->reader(af, buf, AIO_BUF_LEN, nb); - if (len <= 0) { + + if (aio_read_len(interp, af, flags, -1) != JIM_OK) { break; } - Jim_AppendString(interp, af->readbuf, buf, len); } aio_set_nonblocking(af, nb); - if (!nl && aio_eof(af)) { + if (!nl && aio_eof(af) && af->readbuf) { objPtr = af->readbuf; af->readbuf = NULL; @@ -2679,6 +2693,13 @@ static int aio_cmd_puts(Jim_Interp *interp, int argc, Jim_Obj *const *argv) strObj = argv[0]; } +#ifdef JIM_MAINTAINER + if (Jim_IsShared(af->writebuf)) { + Jim_DecrRefCount(interp, af->writebuf); + af->writebuf = Jim_DuplicateObj(interp, af->writebuf); + Jim_IncrRefCount(af->writebuf); + } +#endif Jim_AppendObj(interp, af->writebuf, strObj); if (nl) { Jim_AppendString(interp, af->writebuf, "\n", 1); @@ -2700,7 +2721,7 @@ static int aio_cmd_puts(Jim_Interp *interp, int argc, Jim_Obj *const *argv) break; case WBUF_OPT_FULL: - if (wlen >= AIO_WBUF_FULL_SIZE) { + if (wlen >= af->wbuf_limit) { wnow = 1; } break; @@ -2869,6 +2890,7 @@ static int aio_cmd_sync(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); + Jim_Obj *resultObj; static const char * const options[] = { "none", @@ -2877,17 +2899,57 @@ static int aio_cmd_buffering(Jim_Interp *interp, int argc, Jim_Obj *const *argv) NULL }; - if (Jim_GetEnum(interp, argv[0], options, &af->wbuft, NULL, JIM_ERRMSG) != JIM_OK) { - return JIM_ERR; + if (argc) { + if (Jim_GetEnum(interp, argv[0], options, &af->wbuft, NULL, JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + + if (af->wbuft == WBUF_OPT_FULL && argc == 2) { + long l; + if (Jim_GetLong(interp, argv[1], &l) != JIM_OK || l <= 0) { + return JIM_ERR; + } + af->wbuf_limit = l; + } + + if (af->wbuft == WBUF_OPT_NONE) { + if (aio_flush(interp, af) != JIM_OK) { + return JIM_ERR; + } + } + } - if (af->wbuft == WBUF_OPT_NONE) { - return aio_flush(interp, af); + resultObj = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, resultObj, Jim_NewStringObj(interp, options[af->wbuft], -1)); + if (af->wbuft == WBUF_OPT_FULL) { + Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, af->wbuf_limit)); + } + Jim_SetResult(interp, resultObj); + + return JIM_OK; +} + +static int aio_cmd_readsize(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + AioFile *af = Jim_CmdPrivData(interp); + + if (argc) { + long l; + if (Jim_GetLong(interp, argv[0], &l) != JIM_OK || l <= 0) { + return JIM_ERR; + } + af->rbuf_len = l; + if (af->rbuf) { + af->rbuf = Jim_Realloc(af->rbuf, af->rbuf_len); + } } + Jim_SetResultInt(interp, af->rbuf_len); return JIM_OK; } +#ifdef jim_ext_eventloop static int aio_cmd_timeout(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { #ifdef HAVE_SELECT @@ -2905,7 +2967,6 @@ static int aio_cmd_timeout(Jim_Interp *interp, int argc, Jim_Obj *const *argv) #endif } -#ifdef jim_ext_eventloop static int aio_eventinfo(Jim_Interp *interp, AioFile * af, unsigned mask, int argc, Jim_Obj * const *argv) { @@ -3073,9 +3134,16 @@ static const jim_subcmd_type aio_command_table[] = { }, #endif { "buffering", - "none|line|full", + "?none|line|full? ?size?", aio_cmd_buffering, - 1, + 0, + 2, + + }, + { "readsize", + "?size?", + aio_cmd_readsize, + 0, 1, }, @@ -3318,6 +3386,9 @@ static AioFile *JimMakeChannel(Jim_Interp *interp, int fd, Jim_Obj *filename, af->writebuf = Jim_NewStringObj(interp, NULL, 0); Jim_IncrRefCount(af->writebuf); + af->wbuf_limit = AIO_DEFAULT_WBUF_LIMIT; + af->rbuf_len = AIO_DEFAULT_RBUF_LEN; + Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc); @@ -6716,55 +6787,6 @@ int Jim_arrayInit(Jim_Interp *interp) Jim_CreateCommand(interp, "array", Jim_SubCmdProc, (void *)array_command_table, NULL); return JIM_OK; } - -#include -#ifndef _WIN32 -#include -#include -#include -#endif -#include -#include - - -#ifdef HAVE_SYS_SYSINFO_H -#include -#endif - -static void Jim_PosixSetError(Jim_Interp *interp) -{ - Jim_SetResultString(interp, strerror(errno), -1); -} - -#if defined(HAVE_FORK) -static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - pid_t pid; - - JIM_NOTUSED(argv); - - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } - if ((pid = fork()) == -1) { - Jim_PosixSetError(interp); - return JIM_ERR; - } - Jim_SetResultInt(interp, (jim_wide) pid); - return JIM_OK; -} -#endif - - -int Jim_posixInit(Jim_Interp *interp) -{ - Jim_PackageProvideCheck(interp, "posix"); -#ifdef HAVE_FORK - Jim_CreateCommand(interp, "os.fork", Jim_PosixForkCommand, NULL, NULL); -#endif - return JIM_OK; -} int Jim_InitStaticExtensions(Jim_Interp *interp) { extern int Jim_bootstrapInit(Jim_Interp *); @@ -6774,7 +6796,6 @@ extern int Jim_regexpInit(Jim_Interp *); extern int Jim_fileInit(Jim_Interp *); extern int Jim_globInit(Jim_Interp *); extern int Jim_execInit(Jim_Interp *); -extern int Jim_posixInit(Jim_Interp *); extern int Jim_clockInit(Jim_Interp *); extern int Jim_arrayInit(Jim_Interp *); extern int Jim_stdlibInit(Jim_Interp *); @@ -6786,7 +6807,6 @@ Jim_regexpInit(interp); Jim_fileInit(interp); Jim_globInit(interp); Jim_execInit(interp); -Jim_posixInit(interp); Jim_clockInit(interp); Jim_arrayInit(interp); Jim_stdlibInit(interp); @@ -11457,6 +11477,9 @@ void Jim_FreeInterp(Jim_Interp *i) JimFreeCallFrame(i, cf, JIM_FCF_FULL); } + + Jim_FreeHashTable(&i->commands); + Jim_DecrRefCount(i, i->emptyObj); Jim_DecrRefCount(i, i->trueObj); Jim_DecrRefCount(i, i->falseObj); @@ -11468,8 +11491,6 @@ void Jim_FreeInterp(Jim_Interp *i) Jim_DecrRefCount(i, i->nullScriptObj); Jim_DecrRefCount(i, i->currentFilenameObj); - Jim_FreeHashTable(&i->commands); - Jim_InterpIncrProcEpoch(i); @@ -17624,7 +17645,7 @@ static int Jim_LoopCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg { int retval; jim_wide i; - jim_wide limit; + jim_wide limit = 0; jim_wide incr = 1; Jim_Obj *bodyObjPtr; @@ -20936,11 +20957,12 @@ char **Jim_GetEnviron(void) { #if defined(HAVE__NSGETENVIRON) return *_NSGetEnviron(); +#elif defined(_environ) + return _environ; #else #if !defined(NO_ENVIRON_EXTERN) extern char **environ; #endif - return environ; #endif } @@ -20949,6 +20971,8 @@ void Jim_SetEnviron(char **env) { #if defined(HAVE__NSGETENVIRON) *_NSGetEnviron() = env; +#elif defined(_environ) + _environ = env; #else #if !defined(NO_ENVIRON_EXTERN) extern char **environ; @@ -23567,37 +23591,7 @@ void Jim_SetResultErrno(Jim_Interp *interp, const char *msg) Jim_SetResultFormatted(interp, "%s: %s", msg, strerror(Jim_Errno())); } -#if defined(_WIN32) -#include -int Jim_Errno(void){ return 0; } -int Jim_MakeTempFile(Jim_Interp *interp, const char *filename_template, int unlink_file) -{ - char name[MAX_PATH]; - HANDLE handle; - - if (!GetTempPath(MAX_PATH, name) || !GetTempFileName(name, filename_template ? filename_template : "JIM", 0, name)) { - return -1; - } - - handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | (unlink_file ? FILE_FLAG_DELETE_ON_CLOSE : 0), - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - goto error; - } - - Jim_SetResultString(interp, name, -1); - return _open_osfhandle((intptr_t)handle, _O_RDWR | _O_TEXT); - - error: - Jim_SetResultErrno(interp, name); - DeleteFile(name); - return -1; -} -#endif - -#if defined(__MINGW32__) +#if defined(_WIN32) || defined(WIN32) #include int Jim_Errno(void) diff --git a/manifest b/manifest index 508860e7cf..be62ab5d99 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sLICENSE.md\sfile\sto\sdescribe\sBSD-licensed\scode\sthat\sis\sincluded\nin\sthe\srepository\sas\sa\sconvenience\sto\sdevelopers\sbut\swhich\sis\snot\sitself\nactually\sa\spart\sof\sSQLite. -D 2024-10-25T12:06:40.881 +C New\sjimsh0.c\sfile\sfor\sautosetup. +D 2024-10-25T12:22:29.583 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -48,7 +48,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/hwaci-common.tcl 97b55f68dd190e624340ced9c2de16286edad9db95fede4a184af4249561b4bb -F autosetup/jimsh0.c eb49d62a5b28b4d3b2af10cdfa5dc972ed76e8474fd773cdc7266e768c746f6d +F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e0286e258b17e7812387f5e661910ddd3c015bd5ac62dcbd7e02b69379dc9277 -R 56a923b21a8d871154262a2cbdd151d9 +P deb5994bb1c7295099939f9c88a97ecfe6d21087cfc9c98384e91993ce85f5e6 +R f837aa238c2e72caaf3c9df33a6b2a82 U drh -Z 3da269bef7fc6d4935caf8524fa95e19 +Z 11aaa30a777227b0b808d0d134efd59b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b05d58414e..04f9332735 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -deb5994bb1c7295099939f9c88a97ecfe6d21087cfc9c98384e91993ce85f5e6 +cfacf864119170365fb21a09d2cca5f2a16354837ef0c3c726b00a886ea8e7e2 From d2cbc22dd50164dee875b066e4e992e0b415e92a Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 13:56:13 +0000 Subject: [PATCH 148/522] Minor auto.def cleanups and doc addtions. FossilOrigin-Name: ea53aba82b1083bd59262e768b9331bfdc5c4ca6c4121b98aeedcbeb5af01b07 --- auto.def | 30 ++++++++++++++++++++---------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/auto.def b/auto.def index 66c9b978b7..b5bde98e25 100644 --- a/auto.def +++ b/auto.def @@ -13,7 +13,16 @@ # JimTCL: https://jim.tcl.tk # use cc cc-db cc-shared cc-lib hwaci-common pkg-config -set DUMP_DEFINES_FILE ./defines.list +# $DUMP_DEFINES_TXT is the file emitted by --dump-defines, intended +# only for build debugging and not part of the public build interface. +set DUMP_DEFINES_TXT ./config.defines.txt +# $DUMP_DEFINES_JSON is the autosetup counterpart of the historical +# "DEFS" var which was generated by the autotools in the pre-processed +# autotools builds (but not in the canonical tree). This is used by at +# least one high-profile client to extract build config info for use +# in compiling a scripting-language binding, so its name should not be +# arbitrarily changed. +set DUMP_DEFINES_JSON ./config.defines.json ######################################################################## # Regarding flag compatibility with the historical autotool configure @@ -118,7 +127,7 @@ options [subst { tcl=1 => {Disable components which require TCL-dev} test-status => {Enable status of tests} threadsafe=1 => {Disable mutexing} - with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always.} + with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always} editline=0 => {BSD editline support} readline=1 => {Disable readline support} largefile=1 => {Disable large file support} @@ -142,10 +151,11 @@ options [subst { gcov=0 => {Enable coverage testing using gcov} linemacros => {Enable #line macros in the amalgamation.} with-wasi-sdk:=/opt/wasi-sdk - => {Top-most dir of the wasi-sdk for a WASI build.} + => {Top-most dir of the wasi-sdk for a WASI build} with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} - defines-json-include-lowercase=0 => {Include lower-case defines in config.defines.json, which are primarily system paths.} - dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_FILE (for build debugging)} + defines-json-include-lowercase=0 + => {Include lower-case defines (primarily system paths) in $DUMP_DEFINES_JSON} + dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} }] # Are we cross-compiling? @@ -957,7 +967,7 @@ hwaci-check-rpath # Generate the output files. # hwaci-make-from-dot-in -touch Makefile sqlite3.pc -# for sqlite_cfg.h and config.defines.json +# for sqlite_cfg.h and $DUMP_DEFINES_JSON define PACKAGE_NAME "sqlite" define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION [get-define VERSION_XYZ] @@ -1008,16 +1018,16 @@ if {[opt-bool defines-json-include-lowercase]} { lappend dumpDefsOpt -auto {[a-z]*} } lappend dumpDefsOpt -none * -hwaci-dump-defs-json config.defines.json {*}$dumpDefsOpt +hwaci-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt undefine OPT_FEATURE_FLAGS.list undefine OPT_SHELL.list ######################################################################## # Some build-dev/debug-only output hwaci-if-opt-truthy dump-defines { - global DUMP_DEFINES_FILE - msg-result "--dump-defines is creating file: $DUMP_DEFINES_FILE" - make-config-header $DUMP_DEFINES_FILE \ + global DUMP_DEFINES_TXT + msg-result "--dump-defines is creating $DUMP_DEFINES_TXT" + make-config-header $DUMP_DEFINES_TXT \ -bare {SQLITE_OS* SQLITE_DEBUG USE_*} \ -str {BIN_* CC LD AR LDFLAG* OPT_*} \ -auto {*} diff --git a/manifest b/manifest index be62ab5d99..a5866e1812 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sjimsh0.c\sfile\sfor\sautosetup. -D 2024-10-25T12:22:29.583 +C Minor\sauto.def\scleanups\sand\sdoc\saddtions. +D 2024-10-25T13:56:13.425 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 79da787fe2e011ca43a571147dd68f737a565a57c814b51c5b7b1f7a0f587b24 +F auto.def 44bfd6a96800a552736e2b1c482d2be818aa1e8156c63fb877cbab480d974af0 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P deb5994bb1c7295099939f9c88a97ecfe6d21087cfc9c98384e91993ce85f5e6 -R f837aa238c2e72caaf3c9df33a6b2a82 -U drh -Z 11aaa30a777227b0b808d0d134efd59b +P cfacf864119170365fb21a09d2cca5f2a16354837ef0c3c726b00a886ea8e7e2 +R d15a924070482fb08222da31d4f184cf +U stephan +Z 096fb849e2442f5f30570cc0621e9986 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 04f9332735..2ab51de6de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cfacf864119170365fb21a09d2cca5f2a16354837ef0c3c726b00a886ea8e7e2 +ea53aba82b1083bd59262e768b9331bfdc5c4ca6c4121b98aeedcbeb5af01b07 From 35660cb5a63ae34857ff88ae68f4021dacfdf967 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 25 Oct 2024 14:36:23 +0000 Subject: [PATCH 149/522] Restore the amalgamation-tarball and snapshot-tarball targets, at least for now. FossilOrigin-Name: 1baf4b948854cb4f7c509395df4520a04c16c10cf9e4b67e73e26118636b3204 --- main.mk | 10 ++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/main.mk b/main.mk index 543ddbf752..bbf4fd5c66 100644 --- a/main.mk +++ b/main.mk @@ -1695,6 +1695,16 @@ checksymbols: sqlite3.o nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 echo '0 errors out of 1 tests' +# Build the amalgamation-autoconf package. The amalamgation-tarball target builds +# a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. +# The snapshot-tarball target builds a tarball named by the SHA3 hash +# +amalgamation-tarball: sqlite3.c sqlite3rc.h + TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal + +snapshot-tarball: sqlite3.c sqlite3rc.h + TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot + # Build a ZIP archive containing various command-line tools. # tool-zip: testfixture$(T.exe) sqlite3$(T.exe) sqldiff$(T.exe) \ diff --git a/manifest b/manifest index a5866e1812..8a4fea3690 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sauto.def\scleanups\sand\sdoc\saddtions. -D 2024-10-25T13:56:13.425 +C Restore\sthe\samalgamation-tarball\sand\ssnapshot-tarball\stargets,\sat\sleast\sfor\nnow. +D 2024-10-25T14:36:23.503 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 1cbc48b8316568be25d7d0720bcc80a0b3e4ef2701c418aaaa08e73b36b5bfc7 +F main.mk a26d970036f31c538426ff12d7bb99384402bec16aeef63ac6f795531143fabc F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cfacf864119170365fb21a09d2cca5f2a16354837ef0c3c726b00a886ea8e7e2 -R d15a924070482fb08222da31d4f184cf -U stephan -Z 096fb849e2442f5f30570cc0621e9986 +P ea53aba82b1083bd59262e768b9331bfdc5c4ca6c4121b98aeedcbeb5af01b07 +R 6f6982c8032b18efbaee10e03ad0df13 +U drh +Z 3cb455301c8d8421f7f1dd35401b828f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2ab51de6de..189cbbdf17 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea53aba82b1083bd59262e768b9331bfdc5c4ca6c4121b98aeedcbeb5af01b07 +1baf4b948854cb4f7c509395df4520a04c16c10cf9e4b67e73e26118636b3204 From 5460d5da8e4cba519f18cda2400b4b88320a246f Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 25 Oct 2024 15:28:00 +0000 Subject: [PATCH 150/522] Update the compile-for-*.md documents. FossilOrigin-Name: c4da7fa279274e5a6fe214b5c22f17bcf9b40299aeeab5bfbdae2ba0b2de6af0 --- doc/compile-for-unix.md | 23 ++++++++++++++++------- doc/compile-for-windows.md | 32 +++++++++++++++++--------------- manifest | 17 ++++++++--------- manifest.uuid | 2 +- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/doc/compile-for-unix.md b/doc/compile-for-unix.md index a5caa8b1a1..7e3784d695 100644 --- a/doc/compile-for-unix.md +++ b/doc/compile-for-unix.md @@ -8,11 +8,10 @@ are general and should work on most any modern unix platform. 1. Install a C-compiler. GCC or Clang both work fine. If you are reading this document, you've probably already done that. - 2. Install TCL9 development libraries. In this note, we'll do a - private install in the $HOME/local directory, but you can make - adjustments to install TCL9 wherever you like. -

    - This document assumes you are working with TCL version 9.0. + 2. *(Optional):* Install TCL development libraries. In this note, + we'll do a private install in the $HOME/local directory, + but you can make adjustments to install TCL wherever you like. + This document assumes you are working with TCL version 9.0.

    1. Get the TCL source archive, perhaps from @@ -23,6 +22,12 @@ are general and should work on most any modern unix platform.
    2. Run: `./configure --prefix=$HOME/local`
    3. Run: `make install`
    +

    + As of 2024-10-25, TCL is not longer required for many + common build targets, such as "sqlite3.c" or the "sqlite3" + command-line tool. So you can skip this step if that is all + you want to build. TCL is still required to run "make test" + and similar, or to build the TCL extension, of course. 4. Download the SQLite source tree and unpack it. CD into the toplevel directory of the source tree. @@ -30,7 +35,7 @@ are general and should work on most any modern unix platform. 5. Run: `./configure --enable-all --with-tclsh=$HOME/local/bin/tclsh9.0` You do not need to use --with-tclsh if the tclsh you want to use is the - first one on your PATH. + first one on your PATH or if you are building without TCL. 6. Run the "`Makefile`" makefile with an appropriate target. Examples: @@ -39,6 +44,10 @@ are general and should work on most any modern unix platform.

  • `make sqlite3`
  • `make sqldiff`
  • `make sqlite3_rsync` + +

    None of the targets above require TCL. TCL is only needed + for the following targets: +

    • `make tclextension-install`
    • `make devtest`
    • `make releasetest` @@ -54,4 +63,4 @@ are general and should work on most any modern unix platform. 7. For a debugging build of the CLI, where the ".treetrace" and ".wheretrace" - commands work, add the the --enable-debug argument to configure. + commands work, add the the --with-debug argument to configure. diff --git a/doc/compile-for-windows.md b/doc/compile-for-windows.md index 05893b56c8..b3a48549a6 100644 --- a/doc/compile-for-windows.md +++ b/doc/compile-for-windows.md @@ -16,13 +16,14 @@ canonical source on a new Windows 11 PC, as of 2024-10-09: a 32-bit build.) The subsequent steps will not work in a vanilla DOS prompt. Nor will they work in PowerShell. - 3. Install TCL development libraries. This note assumes that you will + 3. *(Optional):* Install TCL development libraries. + This note assumes that you will install the TCL development libraries in the "`c:\Tcl`" directory. Make adjustments if you want TCL installed somewhere else. SQLite needs both the "tclsh90.exe" command-line tool as part of the build process, and the "tcl90.lib" and "tclstub.lib" libraries in order to run tests. - This document assumes you are working with TCL version 9.0. + This document assumes you are working with TCL version 9.0. See versions of this document from prior to 2024-10-10 for instructions on how to build using TCL version 8.6.
        @@ -43,22 +44,16 @@ canonical source on a new Windows 11 PC, as of 2024-10-09: making this change.
      + As of 2024-10-25, TCL is not longer required for many + common build targets, such as "sqlite3.c" or the "sqlite3.exe" + command-line tool. So you can skip this step if that is all + you want to build. TCL is still required to run "make test" + and similar, or to build the TCL extension, of course. + 4. Download the SQLite source tree and unpack it. CD into the toplevel directory of the source tree. - 5. Set the TCLDIR environment variable to point to your TCL installation. - Like this: -
        -
      • `set TCLDIR=c:\Tcl` -
      - - If you install TCL in the "`c:\Tcl`" directory (as recommended - in step 3 above), then this step is optional because - "`c:\Tcl`" is the default value for TCLDIR. You can also skip this - step by specifying "`TCLDIR=c:\Tcl`" as an argument to the nmake - commands in step 6 below. - - 6. Run the "`Makefile.msc`" makefile with an appropriate target. + 5. Run the "`Makefile.msc`" makefile with an appropriate target. Examples:
      • `nmake /f makefile.msc` @@ -66,6 +61,13 @@ canonical source on a new Windows 11 PC, as of 2024-10-09:
      • `nmake /f makefile.msc sqlite3.exe`
      • `nmake /f makefile.msc sqldiff.exe`
      • `nmake /f makefile.msc sqlite3_rsync.exe` +
      +

      No TCL is required for the nmake targets above. But for the ones + that follow, you will need a TCL installation, as described in step 3 + above. If you install TCL in some directory other than C:\\Tcl, then + you will also need to add the "TCLDIR=<dir>" option on the + nmake command line to tell nmake where your TCL is installed. +

      • `nmake /f makefile.msc tclextension-install`
      • `nmake /f makefile.msc devtest`
      • `nmake /f makefile.msc releasetest` diff --git a/manifest b/manifest index f96aae8202..80a37707aa 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Rework\sthe\sconfigure+make\ssystem\sto\suse\sautosetup\srather\sthan\sautoconf.\nAutosetup\sruns\sfaster\sand\sis\seasier\sto\smaintain,\sand\sit\sallows\sfor\scommon\ntargets\s(such\sas\s"sqlite3"\sand\s"sqlite3.c")\sto\sbe\sbuilt\swithin\shaving\sto\ninstall\s"tclsh". -D 2024-10-25T14:39:26.067 +C Update\sthe\scompile-for-*.md\sdocuments. +D 2024-10-25T15:28:00.541 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 F Makefile.in 5a95c68b70be1448a6f226c09c1df5e338cc496e70987173fcfdca9ad94cb5a4 -F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 w Makefile.linux-gcc +F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 @@ -56,8 +56,8 @@ F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d7 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd -F doc/compile-for-unix.md 343fe9334260d8695c36b465f55221f0187c8e7abaaa4d5afb4d564ed1d22dc1 -F doc/compile-for-windows.md 90f97b9e6bbf27470e825711064bca409d26355f8f31416631a1722bcddf0612 +F doc/compile-for-unix.md 7d6a5770611ea0643de456b385581923dac7c0a7c3758825dda810d12fc3e5b2 +F doc/compile-for-windows.md 17e1491897a117ff0247531a61671b26d487bc1dad25c3894c04ad4fca936a7f F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 @@ -2237,9 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5a8e3915eec06dbec7e32d1b87c6a6d5eb618d9d1d9bac13f6e1e7f22bbf8180 1baf4b948854cb4f7c509395df4520a04c16c10cf9e4b67e73e26118636b3204 -R cfabe0d6dd87d1c992c8a8166f7db7ca -T +closed 1baf4b948854cb4f7c509395df4520a04c16c10cf9e4b67e73e26118636b3204 +P d8c0e0184226bdae9785199d486200e49db7973d78502d09db7a7e34ab0af941 +R 4d14b0cf75d6af0603108fd77389184c U drh -Z 0cfc0d1870ba6f8facd3d6e724075303 +Z 668ae18c27501de00efe113f6d944d91 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b0b3351053..a469e5098d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8c0e0184226bdae9785199d486200e49db7973d78502d09db7a7e34ab0af941 +c4da7fa279274e5a6fe214b5c22f17bcf9b40299aeeab5bfbdae2ba0b2de6af0 From 895ad5f4af52b7058d94a49ba802988aa9c33aaa Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 22:44:58 +0000 Subject: [PATCH 151/522] Rename VERSION_XYZ to the more conventional PACKAGE_VERSION and remove the unused VERSION_XY. FossilOrigin-Name: 2d2f6dfdebbaba181d0ac16b5b0fa63490fb4c4bdb5ee2e8bf70f06ec862a77f --- Makefile.in | 8 +++----- auto.def | 20 ++++++++------------ main.mk | 22 +++++++++++----------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 5 files changed, 32 insertions(+), 38 deletions(-) diff --git a/Makefile.in b/Makefile.in index 6ca1f3ac10..2556c8c709 100644 --- a/Makefile.in +++ b/Makefile.in @@ -96,7 +96,7 @@ AR = @AR@ AR.flags = cr # TODO? Add a configure test to determine this? CC = @CC@ B.cc = @BUILD_CC@ @BUILD_CFLAGS@ -T.cc = $(CC) +T.cc = @CC@ CFLAGS = @CFLAGS@ @SH_CFLAGS@ LDFLAGS.shobj = @SHOBJ_LDFLAGS@ @@ -161,11 +161,9 @@ CFLAGS.libsqlite3 = -DSQLITE_TEMP_STORE=@TEMP_STORE@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS) # -# Release (X.Y.Z) and version (X.Y) numbers for the SQLite being -# compiled. +# Version (X.Y.Z) number for the SQLite being compiled. # -VERSION.XYZ = @VERSION_XYZ@ -# VERSION.XY = @VERSION_XY@ # we don't currently use this anywhere +PACKAGE_VERSION = @PACKAGE_VERSION@ # # Filename extensions for binaries and libraries diff --git a/auto.def b/auto.def index b5bde98e25..dc1a7aedae 100644 --- a/auto.def +++ b/auto.def @@ -174,12 +174,14 @@ set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] msg-result "srcdir = $srcdir" msg-result "top_srcdir = $top_srcdir" -set VERSION_XYZ [readfile $::autosetup(srcdir)/VERSION] -regsub {([0-9]*\.*[0-9]*).*} $VERSION_XYZ {\1} VERSION_XY -define VERSION_XY $VERSION_XY -define VERSION_XYZ $VERSION_XYZ -msg-result "RELEASE = $VERSION_XYZ" -msg-result "VERSION = $VERSION_XY" +set PACKAGE_VERSION [readfile $::autosetup(srcdir)/VERSION] +msg-result "VERSION = $PACKAGE_VERSION" + +define PACKAGE_NAME "sqlite" +define PACKAGE_URL {https://sqlite.org} +define PACKAGE_VERSION $PACKAGE_VERSION +define PACKAGE_STRING "[get-define PACKAGE_NAME] $PACKAGE_VERSION" +define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum define-append SQLITE_AUTOREMAKE cd $::autosetup(srcdir) && $top_srcdir/configure {*}$::autosetup(argv) @@ -967,12 +969,6 @@ hwaci-check-rpath # Generate the output files. # hwaci-make-from-dot-in -touch Makefile sqlite3.pc -# for sqlite_cfg.h and $DUMP_DEFINES_JSON -define PACKAGE_NAME "sqlite" -define PACKAGE_URL {https://sqlite.org} -define PACKAGE_VERSION [get-define VERSION_XYZ] -define PACKAGE_STRING "[get-define PACKAGE_NAME] [get-define VERSION_XYZ]" -define PACKAGE_BUGREPORT [get-define PACKAGE_URL] if {0} { # Requires a hand-written sqlite_cfg.h.in... hwaci-make-from-dot-in sqlite_cfg.h diff --git a/main.mk b/main.mk index bbf4fd5c66..b5866aa1b2 100644 --- a/main.mk +++ b/main.mk @@ -25,11 +25,11 @@ # TOP ?= $(PWD) # -# $(VERSION.XYZ) = +# $(PACKAGE_VERSION) = # # The MAJOR.MINOR.PATCH version number of this build. # -VERSION.XYZ ?= +PACKAGE_VERSION ?= # # $(B.cc) = # @@ -394,7 +394,7 @@ $(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) @if [ x = "x$(TOP)" ]; then echo "Missing TOP var" 1>&2; exit 1; fi @if [ ! -d "$(TOP)" ]; then echo "$(TOP) is not a directory" 1>&2; exit 1; fi @if [ ! -f "$(TOP)/auto.def" ]; then echo "$(TOP) does not appear to be the top-most source dir" 1>&2; exit 1; fi - @if [ x = "x$(VERSION.XYZ)" ]; then echo "VERSION.XYZ must be set to the library's X.Y.Z-format version number" 1>&2; exit 1; fi + @if [ x = "x$(PACKAGE_VERSION)" ]; then echo "PACKAGE_VERSION must be set to the library's X.Y.Z-format version number" 1>&2; exit 1; fi @if [ x = "x$(B.cc)" ]; then echo "Missing B.cc var" 1>&2; exit 1; fi @if [ x = "x$(T.cc)" ]; then echo "Missing T.cc var" 1>&2; exit 1; fi @if [ x = "x$(B.tclsh)" ]; then echo "Missing B.tclsh var" 1>&2; exit 1; fi @@ -1290,7 +1290,7 @@ so: $(libsqlite3.SO)-$(ENABLE_SHARED) all: so # -# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(VERSION.XYZ) and +# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(PACKAGE_VERSION) and # create symlinks which point to it. Do we really need all of this # hoop-jumping? Can we not simply install the .so as-is to # libsqlite3.so (without the versioned bits)? @@ -1303,11 +1303,11 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) $(install-dir.lib) @echo "Setting up SO symlinks..."; \ cd $(install-dir.lib) || exit $$?; \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(VERSION.XYZ) || exit $$?; \ - mv $(libsqlite3.SO) $(libsqlite3.SO).$(VERSION.XYZ) || exit $$?; \ - ln -s $(libsqlite3.SO).$(VERSION.XYZ) $(libsqlite3.SO).3 || exit $$?; \ + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ + mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).3 || exit $$?; \ ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ - ls -la $(libsqlite3.SO) $(libsqlite3.SO).3 $(libsqlite3.SO).$(VERSION.XYZ) + ls -la $(libsqlite3.SO) $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) install-so-0 install-so-: install: install-so-$(ENABLE_SHARED) @@ -1329,7 +1329,7 @@ install: install-includes # libtclsqlite3... # pkgIndex.tcl: - echo 'package ifneeded sqlite3 $(VERSION.XYZ) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ + echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(T.dll) $(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) $(T.link.shared) -o $@ tclsqlite.o \ @@ -1362,14 +1362,14 @@ CFLAGS.tclextension = $(CFLAGS.intree_includes) $(CFLAGS) $(OPT_FEATURE_FLAGS) $ # by --with-tclsh= # tclextension: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(CC)" $(CFLAGS.tclextension) + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --build-only --cc "$(T.cc)" $(CFLAGS.tclextension) # # Install the SQLite TCL extension in a way that is appropriate for $TCLSH_CMD # to find it. # tclextension-install: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(CC)" $(CFLAGS.tclextension) + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(T.cc)" $(CFLAGS.tclextension) # # Install the SQLite TCL extension that is used by $TCLSH_CMD diff --git a/manifest b/manifest index 80a37707aa..696d18d26a 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Update\sthe\scompile-for-*.md\sdocuments. -D 2024-10-25T15:28:00.541 +C Rename\sVERSION_XYZ\sto\sthe\smore\sconventional\sPACKAGE_VERSION\sand\sremove\sthe\sunused\sVERSION_XY. +D 2024-10-25T22:44:58.901 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 -F Makefile.in 5a95c68b70be1448a6f226c09c1df5e338cc496e70987173fcfdca9ad94cb5a4 +F Makefile.in e880d287a3233a5352b3e260ff9b44baa9388070ba033ec842bc46e2cebdd11e F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 44bfd6a96800a552736e2b1c482d2be818aa1e8156c63fb877cbab480d974af0 +F auto.def a9b6bbe2bd8433a79113253550b27e01ace2194b59412244b0c0ac7b38ccaec3 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk a26d970036f31c538426ff12d7bb99384402bec16aeef63ac6f795531143fabc +F main.mk af346a94426e107f4140f841a2875af97c025ae54fd00cd67a67f8672e90306c F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d8c0e0184226bdae9785199d486200e49db7973d78502d09db7a7e34ab0af941 -R 4d14b0cf75d6af0603108fd77389184c -U drh -Z 668ae18c27501de00efe113f6d944d91 +P c4da7fa279274e5a6fe214b5c22f17bcf9b40299aeeab5bfbdae2ba0b2de6af0 +R 5aa1eb68c22173fd339cc6da207da603 +U stephan +Z c513b9b62fc4b0a4b0fc3bf321e7bc3a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a469e5098d..c3d7f539ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4da7fa279274e5a6fe214b5c22f17bcf9b40299aeeab5bfbdae2ba0b2de6af0 +2d2f6dfdebbaba181d0ac16b5b0fa63490fb4c4bdb5ee2e8bf70f06ec862a77f From a2a875e3b8fa0bed189d6c585fb3096ac4a0e172 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 23:03:33 +0000 Subject: [PATCH 152/522] Experimentally: when ./configure CC=foo is used in a non-cross-compilation build and CC_FOR_BUILD is not explicitly provided, force CC_FOR_BUILD to default to CC. This is debatable - see the code comments for the justification. FossilOrigin-Name: a49bee68418f9e8c3813a60f76de265b8e6a98a15ab9b246aa42d9e9558a03eb --- auto.def | 35 +++++++++++++++++++++++++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/auto.def b/auto.def index dc1a7aedae..b520cfb1e4 100644 --- a/auto.def +++ b/auto.def @@ -12,7 +12,36 @@ # # JimTCL: https://jim.tcl.tk # + + use cc cc-db cc-shared cc-lib hwaci-common pkg-config + +# Are we cross-compiling? +set cross_compiling 0 +if {[get-define host] ne [get-define build]} { + set cross_compiling 1 +} elseif {1 + && "nope" eq [get-env CC_FOR_BUILD "nope"] + && [get-define CC] ne [get-define CC_FOR_BUILD]} { + # Arguable/debatable... + # + # When _not_ cross-compiling and CC_FOR_BUILD is _not_ explcitely + # specified, force CC_FOR_BUILD to be the same as CC, so that: + # + # ./configure CC=clang + # + # will use CC_FOR_BUILD=clang, instead of cc, for building in-tree + # tools. This is based off of an email discussion and is thought to + # be likely to cause less confusion than seeing 'cc' invocations + # will when the user passes CC=clang. + # + # Sidebar: if we do this before the cc package is installed, it gets + # reverted by that package. Ergo, the cc package init will tell the + # user "Build C compiler...cc" shortly before we tell them: + msg-result "Re-defining CC_FOR_BUILD to CC=[get-define CC]. To avoid this, explicitly pass CC_FOR_BUILD=..." + define CC_FOR_BUILD [get-define CC] +} + # $DUMP_DEFINES_TXT is the file emitted by --dump-defines, intended # only for build debugging and not part of the public build interface. set DUMP_DEFINES_TXT ./config.defines.txt @@ -158,12 +187,6 @@ options [subst { dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} }] -# Are we cross-compiling? -set cross_compiling 0 -if {[get-define host] ne [get-define build]} { - set cross_compiling 1 -} - ######################################################################## # Notes about certain historical flags: # diff --git a/manifest b/manifest index 696d18d26a..edbf21d6eb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sVERSION_XYZ\sto\sthe\smore\sconventional\sPACKAGE_VERSION\sand\sremove\sthe\sunused\sVERSION_XY. -D 2024-10-25T22:44:58.901 +C Experimentally:\swhen\s./configure\sCC=foo\sis\sused\sin\sa\snon-cross-compilation\sbuild\sand\sCC_FOR_BUILD\sis\snot\sexplicitly\sprovided,\sforce\sCC_FOR_BUILD\sto\sdefault\sto\sCC.\sThis\sis\sdebatable\s-\ssee\sthe\scode\scomments\sfor\sthe\sjustification. +D 2024-10-25T23:03:33.136 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a9b6bbe2bd8433a79113253550b27e01ace2194b59412244b0c0ac7b38ccaec3 +F auto.def 1671569c94900178ab4683928ccf408992a3e512fdd582cb1e52c80b6b05fa07 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c4da7fa279274e5a6fe214b5c22f17bcf9b40299aeeab5bfbdae2ba0b2de6af0 -R 5aa1eb68c22173fd339cc6da207da603 +P 2d2f6dfdebbaba181d0ac16b5b0fa63490fb4c4bdb5ee2e8bf70f06ec862a77f +R 030d93b69f9a5aa6b2998a65b82a419a U stephan -Z c513b9b62fc4b0a4b0fc3bf321e7bc3a +Z 328d6e2939a83c73df030dc650be2125 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c3d7f539ac..185b16ef2f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d2f6dfdebbaba181d0ac16b5b0fa63490fb4c4bdb5ee2e8bf70f06ec862a77f +a49bee68418f9e8c3813a60f76de265b8e6a98a15ab9b246aa42d9e9558a03eb From 70188a66e0dbf072572d69f96dcdb4114e7ddba8 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 23:04:50 +0000 Subject: [PATCH 153/522] Fix BUILD_CFLAGS (for B.cc) to not inherent CFLAGS (which are only for T.cc). FossilOrigin-Name: ffdce13deb8a1fbce717da9ca44fd34409bedad4db805722100647372c06f4f5 --- auto.def | 2 +- autosetup/hwaci-common.tcl | 6 ++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/auto.def b/auto.def index b520cfb1e4..8b429f18a2 100644 --- a/auto.def +++ b/auto.def @@ -333,7 +333,7 @@ if {"" eq [hwaci-bin-define install]} { # a.k.a. TCC). Normally they're the same, but they will differ when # cross-compiling. define BUILD_CC [get-define CC_FOR_BUILD] -define BUILD_CFLAGS [get-env CFLAGS {-g}] +define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] define ENABLE_SHARED 1 define HAVE_TCL 0 diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 06f3b11645..a09dedffea 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -57,12 +57,10 @@ proc hwaci-fatal {msg} { } ######################################################################## -# hwaci-lshift_ shifts $count elements from the list named $listVar and -# returns them. +# hwaci-lshift_ shifts $count elements from the list named $listVar +# and returns them as a new list. On empty input, returns "". # # Modified slightly from: https://wiki.tcl-lang.org/page/lshift -# -# On an empty list, returns "". proc hwaci-lshift_ {listVar {count 1}} { upvar 1 $listVar l if {![info exists l]} { diff --git a/manifest b/manifest index edbf21d6eb..40bf020b12 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimentally:\swhen\s./configure\sCC=foo\sis\sused\sin\sa\snon-cross-compilation\sbuild\sand\sCC_FOR_BUILD\sis\snot\sexplicitly\sprovided,\sforce\sCC_FOR_BUILD\sto\sdefault\sto\sCC.\sThis\sis\sdebatable\s-\ssee\sthe\scode\scomments\sfor\sthe\sjustification. -D 2024-10-25T23:03:33.136 +C Fix\sBUILD_CFLAGS\s(for\sB.cc)\sto\snot\sinherent\sCFLAGS\s(which\sare\sonly\sfor\sT.cc). +D 2024-10-25T23:04:50.934 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 1671569c94900178ab4683928ccf408992a3e512fdd582cb1e52c80b6b05fa07 +F auto.def 91a723897b2f2230fe200e9cbda9e7b4063bc0af42768d6fe0f376b813c80b9b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 97b55f68dd190e624340ced9c2de16286edad9db95fede4a184af4249561b4bb +F autosetup/hwaci-common.tcl ed34d81dc51e8acc934d2101d9da5ded27ae7ae55a01a00896150bbfc7ca52da F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2d2f6dfdebbaba181d0ac16b5b0fa63490fb4c4bdb5ee2e8bf70f06ec862a77f -R 030d93b69f9a5aa6b2998a65b82a419a +P a49bee68418f9e8c3813a60f76de265b8e6a98a15ab9b246aa42d9e9558a03eb +R c14c5d9afdf9f83be57f58112a477cbb U stephan -Z 328d6e2939a83c73df030dc650be2125 +Z fa7cc103b1950703dd62a0222c63e168 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 185b16ef2f..f3078dd72f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a49bee68418f9e8c3813a60f76de265b8e6a98a15ab9b246aa42d9e9558a03eb +ffdce13deb8a1fbce717da9ca44fd34409bedad4db805722100647372c06f4f5 From cbb182fef291aa36a6fa90e19a78f77506d11439 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 23:13:12 +0000 Subject: [PATCH 154/522] When --with-tclsh=X is used, use X for all TCL purposes, including in-tree code generation, per developer request. FossilOrigin-Name: 12498e55c0c689f43c78002fb850a58dda337feae51194b9cade7f5dff15e833 --- auto.def | 63 +++++++++++++++++++++++++++------------------------ manifest | 12 +++++----- manifest.uuid | 2 +- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/auto.def b/auto.def index 8b429f18a2..acc5d476d2 100644 --- a/auto.def +++ b/auto.def @@ -649,42 +649,45 @@ hwaci-check-tcl # jimsh0.c defines JIM_COMPAT automatically (prior to that it intended # to but a typo of JIM_TCL_COMPAT made it a no-op). define CFLAGS_JIMSH {} -set useOwnJimsh 0 msg-result "Which TCL to use for code generation... " -set cgtcl jimtcl -if {[cc-check-functions realpath]} { - define-append CFLAGS_JIMSH -DHAVE_REALPATH - define BTCLSH "\$(JIMSH)" - set useOwnJimsh 1 -} elseif {[cc-check-functions _fullpath]} { - # _fullpath() is a Windows API - define-append CFLAGS_JIMSH -DHAVE__FULLPATH - define BTCLSH "\$(JIMSH)" - set useOwnJimsh 1 -} elseif {[file exists [get-define TCLSH_CMD]]} { - set cgtcl [get-define TCLSH_CMD] +set cgtcl [opt-val with-tclsh jimsh] +if {"jimsh" ne $cgtcl} { + # When --with-tclsh=X is used, use that for all TCL purposes, + # including in-tree code generation, per developer request. define BTCLSH "\$(TCLSH_CMD)" } else { - # One last-ditch effort to find TCLSH_CMD: use info from - # tclConfig.sh to try to find a tclsh - if {"" eq [get-define TCLSH_CMD]} { - set tpre [get-define TCL_EXEC_PREFIX] - if {"" ne $tpre} { - set tv [get-define TCL_VERSION] - if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { - define TCLSH_CMD "${tpre}/bin/tclsh${tv}" - } elseif {[file-isexec "${tpre}/bin/tclsh"]} { - define TCLSH_CMD "${tpre}/bin/tclsh" + if {[cc-check-functions realpath]} { + define-append CFLAGS_JIMSH -DHAVE_REALPATH + define BTCLSH "\$(JIMSH)" + } elseif {[cc-check-functions _fullpath]} { + # _fullpath() is a Windows API + define-append CFLAGS_JIMSH -DHAVE__FULLPATH + define BTCLSH "\$(JIMSH)" + } elseif {[file exists [get-define TCLSH_CMD]]} { + set cgtcl [get-define TCLSH_CMD] + define BTCLSH "\$(TCLSH_CMD)" + } else { + # One last-ditch effort to find TCLSH_CMD: use info from + # tclConfig.sh to try to find a tclsh + if {"" eq [get-define TCLSH_CMD]} { + set tpre [get-define TCL_EXEC_PREFIX] + if {"" ne $tpre} { + set tv [get-define TCL_VERSION] + if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { + define TCLSH_CMD "${tpre}/bin/tclsh${tv}" + } elseif {[file-isexec "${tpre}/bin/tclsh"]} { + define TCLSH_CMD "${tpre}/bin/tclsh" + } + unset tv } - unset tv + unset tpre } - unset tpre - } - set cgtcl [get-define TCLSH_CMD] - if {![file exists $cgtcl]} { - hwaci-fatal "Cannot find a tclsh to use for code generation." + set cgtcl [get-define TCLSH_CMD] + if {![file exists $cgtcl]} { + hwaci-fatal "Cannot find a tclsh to use for code generation." + } + define BTCLSH "\$(TCLSH_CMD)" } - define BTCLSH "\$(TCLSH_CMD)" } msg-result "TCL for code generation: $cgtcl" unset cgtcl diff --git a/manifest b/manifest index 40bf020b12..e0298815fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sBUILD_CFLAGS\s(for\sB.cc)\sto\snot\sinherent\sCFLAGS\s(which\sare\sonly\sfor\sT.cc). -D 2024-10-25T23:04:50.934 +C When\s--with-tclsh=X\sis\sused,\suse\sX\sfor\sall\sTCL\spurposes,\sincluding\sin-tree\scode\sgeneration,\sper\sdeveloper\srequest. +D 2024-10-25T23:13:12.897 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 91a723897b2f2230fe200e9cbda9e7b4063bc0af42768d6fe0f376b813c80b9b +F auto.def 6f81ce2f8d9dfa59d4fa9ea423e9e3228be41e23a63f457472d28b7e267d99cd F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a49bee68418f9e8c3813a60f76de265b8e6a98a15ab9b246aa42d9e9558a03eb -R c14c5d9afdf9f83be57f58112a477cbb +P ffdce13deb8a1fbce717da9ca44fd34409bedad4db805722100647372c06f4f5 +R 547a5fbc8c084efef7911861f5f974f8 U stephan -Z fa7cc103b1950703dd62a0222c63e168 +Z ecd9048bff7dc4b2fb9935c4a4daef26 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f3078dd72f..1f50f34e30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ffdce13deb8a1fbce717da9ca44fd34409bedad4db805722100647372c06f4f5 +12498e55c0c689f43c78002fb850a58dda337feae51194b9cade7f5dff15e833 From d045b428542379b8f27052f89784e5228f4c204b Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 23:25:49 +0000 Subject: [PATCH 155/522] Use (cc-with {-includes stdint.h}) when checking for the various int types because, despite it being C99, it turns out that we do indeed use it if it's available. FossilOrigin-Name: 51a9278134b5b9093c92c7036cc91b823f30dd36f677f2335927854744225024 --- auto.def | 7 ++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/auto.def b/auto.def index acc5d476d2..03af30e47b 100644 --- a/auto.def +++ b/auto.def @@ -389,8 +389,9 @@ cc-check-lfs # # Check for needed/wanted data types -cc-check-types int8_t int16_t int32_t int64_t intptr_t \ - uint8_t uint16_t uint32_t uint64_t uintptr_t +cc-with {-includes stdint.h} \ + {cc-check-types int8_t int16_t int32_t int64_t intptr_t \ + uint8_t uint16_t uint32_t uint64_t uintptr_t} # # Check for needed/wanted functions @@ -407,7 +408,7 @@ cc-check-includes \ sys/types.h sys/stat.h dlfcn.h unistd.h \ stdlib.h malloc.h memory.h \ string.h strings.h \ - stdint.h inttypes.h + inttypes.h # These are optional for JimTCL but necessary if we want to use it for # code generation: diff --git a/manifest b/manifest index e0298815fd..a76a4a24fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\s--with-tclsh=X\sis\sused,\suse\sX\sfor\sall\sTCL\spurposes,\sincluding\sin-tree\scode\sgeneration,\sper\sdeveloper\srequest. -D 2024-10-25T23:13:12.897 +C Use\s(cc-with\s{-includes\sstdint.h})\swhen\schecking\sfor\sthe\svarious\sint\stypes\sbecause,\sdespite\sit\sbeing\sC99,\sit\sturns\sout\sthat\swe\sdo\sindeed\suse\sit\sif\sit's\savailable. +D 2024-10-25T23:25:49.980 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 6f81ce2f8d9dfa59d4fa9ea423e9e3228be41e23a63f457472d28b7e267d99cd +F auto.def d7401a7cec04aa6a71c3a7c1faa89494f091917307a4b1b7a6d423e81a348010 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ffdce13deb8a1fbce717da9ca44fd34409bedad4db805722100647372c06f4f5 -R 547a5fbc8c084efef7911861f5f974f8 +P 12498e55c0c689f43c78002fb850a58dda337feae51194b9cade7f5dff15e833 +R f62edb16995e026ea7ba97df69933436 U stephan -Z ecd9048bff7dc4b2fb9935c4a4daef26 +Z 76068fe3afa72145f92179b17b78663b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1f50f34e30..07b0c351f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12498e55c0c689f43c78002fb850a58dda337feae51194b9cade7f5dff15e833 +51a9278134b5b9093c92c7036cc91b823f30dd36f677f2335927854744225024 From a2d88f6a03c9ebde3d037b0e297f47216c685381 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 25 Oct 2024 23:45:05 +0000 Subject: [PATCH 156/522] Correct unresolved @LIBS@ placeholder in sqlite3.pc.in. FossilOrigin-Name: 63218898ed0a6d466a282f10819d51a7f480d8f12316b74ee8a3f402fcc4e927 --- main.mk | 6 +++--- manifest | 14 +++++++------- manifest.uuid | 2 +- sqlite3.pc.in | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/main.mk b/main.mk index b5866aa1b2..f60abb18ce 100644 --- a/main.mk +++ b/main.mk @@ -329,8 +329,8 @@ T.link.shared = $(T.link) $(LDFLAGS.shobj) # LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ - $(LDFLAGS.math) $(LDFLAGS.zlib) \ - $(LDFLAGS.dlopen) + $(LDFLAGS.math)$(LDFLAGS.dlopen) +# $(LDFLAGS.zlib) # # $(install-dir.XYZ) = dirs for installation. @@ -1753,7 +1753,7 @@ sqlite3$(T.exe): shell.c sqlite3.c $(T.link) -o $@ \ shell.c sqlite3.c \ $(CFLAGS.readline) $(SHELL_OPT) \ - $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) $(LDFLAGS.icu) + $(LDFLAGS.libsqlite3) $(LDFLAGS.zlib) $(LDFLAGS.readline) $(LDFLAGS.icu) # # Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the diff --git a/manifest b/manifest index a76a4a24fc..dc1fe7a4d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\s(cc-with\s{-includes\sstdint.h})\swhen\schecking\sfor\sthe\svarious\sint\stypes\sbecause,\sdespite\sit\sbeing\sC99,\sit\sturns\sout\sthat\swe\sdo\sindeed\suse\sit\sif\sit's\savailable. -D 2024-10-25T23:25:49.980 +C Correct\sunresolved\s@LIBS@\splaceholder\sin\ssqlite3.pc.in. +D 2024-10-25T23:45:05.569 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk af346a94426e107f4140f841a2875af97c025ae54fd00cd67a67f8672e90306c +F main.mk ad39030eeac4f0b775ed458c484211c7519ddbe29375a88eea88c0c719af3bf5 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -717,7 +717,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc -F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a +F sqlite3.pc.in b8b551878b9bdca1ff148f6e943d0e06206864c757eb07eef030343c27bb10bd F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 12498e55c0c689f43c78002fb850a58dda337feae51194b9cade7f5dff15e833 -R f62edb16995e026ea7ba97df69933436 +P 51a9278134b5b9093c92c7036cc91b823f30dd36f677f2335927854744225024 +R a314c5e68fb037432cac9fe3ae63e4a5 U stephan -Z 76068fe3afa72145f92179b17b78663b +Z 16d047a5bb3a50c8e6fef3840bc7d061 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 07b0c351f9..69b3352667 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -51a9278134b5b9093c92c7036cc91b823f30dd36f677f2335927854744225024 +63218898ed0a6d466a282f10819d51a7f480d8f12316b74ee8a3f402fcc4e927 diff --git a/sqlite3.pc.in b/sqlite3.pc.in index 3799671e61..52cda3065d 100644 --- a/sqlite3.pc.in +++ b/sqlite3.pc.in @@ -9,5 +9,5 @@ Name: SQLite Description: SQL database engine Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lsqlite3 -Libs.private: @LIBS@ +Libs.private: @LDFLAGS_ZLIB@ @LDFLAGS_READLINE@ Cflags: -I${includedir} From 65d83fa22110da101c3ac21b5dd9174efb147c66 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 03:05:20 +0000 Subject: [PATCH 157/522] Disable generation of config.defines.json until/unless it proves interesting. Honor the --disable-largefile flag. When installing libsqlite3.so and an older-style libtool installation is found, re-link the libtool-generated files to the newly-installed ones to retain their historical names. FossilOrigin-Name: 0a50e33051fbdd5b7b7f0ab7eb2b2561d259098075fa8847868017041d789484 --- auto.def | 69 ++++++++++++++++++++++++++++++++------------------- main.mk | 25 ++++++++++++++++--- manifest | 14 +++++------ manifest.uuid | 2 +- 4 files changed, 74 insertions(+), 36 deletions(-) diff --git a/auto.def b/auto.def index 03af30e47b..dffe733bbc 100644 --- a/auto.def +++ b/auto.def @@ -51,7 +51,11 @@ set DUMP_DEFINES_TXT ./config.defines.txt # least one high-profile client to extract build config info for use # in compiling a scripting-language binding, so its name should not be # arbitrarily changed. -set DUMP_DEFINES_JSON ./config.defines.json +# +# 2024-10-26: generation of this file is disabled (via an empty file +# name) until/unless someone voices a specific interest in it. The +# original motivating use case is handled fine by sqlite_cfg.h. +set DUMP_DEFINES_JSON ""; #./config.defines.json ######################################################################## # Regarding flag compatibility with the historical autotool configure @@ -149,7 +153,7 @@ set DUMP_DEFINES_JSON ./config.defines.json # - [opt-val FLAG] # ######################################################################## -options [subst { +set flags { with-debug:=1 => {Enable debug build flags} with-tclsh:PATH => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} @@ -182,10 +186,15 @@ options [subst { with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build} with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} - defines-json-include-lowercase=0 - => {Include lower-case defines (primarily system paths) in $DUMP_DEFINES_JSON} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} -}] +} +if {"" ne $DUMP_DEFINES_JSON} { + lappend flags \ + defines-json-include-lowercase=0 \ + => {Include lower-case defines (primarily system paths) in $DUMP_DEFINES_JSON} +} +options [subst $flags] +unset flags ######################################################################## # Notes about certain historical flags: @@ -385,7 +394,10 @@ hwaci-check-wasi-sdk # # Enable large file support (if special flags are necessary) -cc-check-lfs +define HAVE_LFS 0 +if {[opt-bool largefile]} { + cc-check-lfs +} # # Check for needed/wanted data types @@ -741,6 +753,11 @@ if {1} { # Figure out what C libraries are required to compile programs # that use "readline()" library. add-shell-opt -DHAVE_READLINE=[hwaci-check-readline] + # TODO: reimplement: + # --enable-editline + # --with-readline-lib specify readline library + # --with-readline-inc specify readline include paths + # --with-linenoise=DIR source directory for linenoise library } else { # Older impl solely for reference while porting... # @@ -1024,26 +1041,28 @@ if {"" ne $oFF} { } unset oFF -######################################################################## -# Dump config-defines.json... -# Demonstrate (mis?)handling of spaces in JSON-export array values: -# define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} -define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] -define OPT_SHELL.list [get-define OPT_SHELL] -set dumpDefsOpt { - -bare {SIZEOF_* HAVE_DECL_*} - -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} - -array {*.list} - -auto {OPT_* PACKAGE_* HAVE_*} -} -if {[opt-bool defines-json-include-lowercase]} { - lappend dumpDefsOpt -none {lib_*} ; # remnants from hwaci-check-function-in-lib and friends - lappend dumpDefsOpt -auto {[a-z]*} +if {"" ne $DUMP_DEFINES_JSON} { + ######################################################################## + # Dump config-defines.json... + # Demonstrate (mis?)handling of spaces in JSON-export array values: + # define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} + define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] + define OPT_SHELL.list [get-define OPT_SHELL] + set dumpDefsOpt { + -bare {SIZEOF_* HAVE_DECL_*} + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} + -array {*.list} + -auto {OPT_* PACKAGE_* HAVE_*} + } + if {[opt-bool defines-json-include-lowercase]} { + lappend dumpDefsOpt -none {lib_*} ; # remnants from hwaci-check-function-in-lib and friends + lappend dumpDefsOpt -auto {[a-z]*} + } + lappend dumpDefsOpt -none * + hwaci-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt + undefine OPT_FEATURE_FLAGS.list + undefine OPT_SHELL.list } -lappend dumpDefsOpt -none * -hwaci-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt -undefine OPT_FEATURE_FLAGS.list -undefine OPT_SHELL.list ######################################################################## # Some build-dev/debug-only output diff --git a/main.mk b/main.mk index f60abb18ce..f2ebad4754 100644 --- a/main.mk +++ b/main.mk @@ -1297,7 +1297,19 @@ all: so # # The historical SQLite build always used a version number of 0.8.6 # for reasons lost to history but having something to do with libtool -# (which is not longer used in this tree). +# (which is not longer used in this tree). In order to retain filename +# compatibility for systems which have libraries installed using those +# conventions, if libsqlite3.so.0.8.6 is found on then it is re-linked +# to point to the new names. libsqlite3.so.0 historically symlinks to +# libsqlite3.so.0.8.6, and that link is left in place. We cannot +# retain both the old and new installation because they both share the +# high-level name $(libsqlite3.SO). The down-side of this is that it +# may well upset packaging tools when we replace libsqlite3.so (from a +# legacy package) with a new symlink. In this case we also delete +# libsqlite3.la because it cannot work with the non-libtool library +# this installation replaces. Since two versions of such a package +# cannot coexist anyway (they share identical file names), that +# conflict is believed to be an imaginary problem. # install-so-1: $(install-dir.lib) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) $(install-dir.lib) @@ -1307,9 +1319,16 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).3 || exit $$?; \ ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ - ls -la $(libsqlite3.SO) $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) + ls -la $(libsqlite3.SO) $(libsqlite3.SO).3*; \ + if [ -e $(libsqlite3.SO).0.8.6 ]; then \ + echo "ACHTUNG: older libtool-compatible install found. Re-linking it..."; \ + rm -f $(libsqlite3.SO).0.8.6 libsqlite3.la; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ + ls -la $(libsqlite3.SO).0*; \ + fi install-so-0 install-so-: -install: install-so-$(ENABLE_SHARED) +install-so: install-so-$(ENABLE_SHARED) +install: install-so # # Install $(libsqlite3.LIB) diff --git a/manifest b/manifest index dc1fe7a4d3..115acf38b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sunresolved\s@LIBS@\splaceholder\sin\ssqlite3.pc.in. -D 2024-10-25T23:45:05.569 +C Disable\sgeneration\sof\sconfig.defines.json\suntil/unless\sit\sproves\sinteresting.\sHonor\sthe\s--disable-largefile\sflag.\sWhen\sinstalling\slibsqlite3.so\sand\san\solder-style\slibtool\sinstallation\sis\sfound,\sre-link\sthe\slibtool-generated\sfiles\sto\sthe\snewly-installed\sones\sto\sretain\stheir\shistorical\snames. +D 2024-10-26T03:05:20.205 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d7401a7cec04aa6a71c3a7c1faa89494f091917307a4b1b7a6d423e81a348010 +F auto.def f3c94971e3559636a89276adaa9cfe949b1d83f72c300a21226f28377c56ec74 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ad39030eeac4f0b775ed458c484211c7519ddbe29375a88eea88c0c719af3bf5 +F main.mk 2a1e41234197e59df10160408ca221815f6fecb7de6ad60231b03944c5cd8a8f F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 51a9278134b5b9093c92c7036cc91b823f30dd36f677f2335927854744225024 -R a314c5e68fb037432cac9fe3ae63e4a5 +P 63218898ed0a6d466a282f10819d51a7f480d8f12316b74ee8a3f402fcc4e927 +R 7933f107530fbfe42f5cc26d7f7899b9 U stephan -Z 16d047a5bb3a50c8e6fef3840bc7d061 +Z fb78edb2f2fc1c6af37f2783aae577ac # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 69b3352667..069bd27f12 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63218898ed0a6d466a282f10819d51a7f480d8f12316b74ee8a3f402fcc4e927 +0a50e33051fbdd5b7b7f0ab7eb2b2561d259098075fa8847868017041d789484 From 56d46d9d386674aac97329360c596aebac719053 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 03:19:29 +0000 Subject: [PATCH 158/522] Expand the libtool-style link support from [0a50e33051] such that if INSTALL_SO_086_LINKS=1 is passed to 'make install' then the libtool-style names are always linked in, regardless of whether they already existed or not. In either case, we unconditionally remove libsqlite3.la because it cannot work with the newly-installed non-libtool .so file. FossilOrigin-Name: 2b2ca7dec18d6b53ba7810a2ecf3937d98b5b08232d4f82d16fa2ad5f9fd83b2 --- main.mk | 44 ++++++++++++++++++++++++++++++-------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/main.mk b/main.mk index f2ebad4754..fd789d0270 100644 --- a/main.mk +++ b/main.mk @@ -1295,34 +1295,50 @@ all: so # hoop-jumping? Can we not simply install the .so as-is to # libsqlite3.so (without the versioned bits)? # +# Regarding the historcal installation name of libsqlite3.so.0.8.6: +# # The historical SQLite build always used a version number of 0.8.6 # for reasons lost to history but having something to do with libtool # (which is not longer used in this tree). In order to retain filename # compatibility for systems which have libraries installed using those -# conventions, if libsqlite3.so.0.8.6 is found on then it is re-linked -# to point to the new names. libsqlite3.so.0 historically symlinks to -# libsqlite3.so.0.8.6, and that link is left in place. We cannot -# retain both the old and new installation because they both share the -# high-level name $(libsqlite3.SO). The down-side of this is that it -# may well upset packaging tools when we replace libsqlite3.so (from a -# legacy package) with a new symlink. In this case we also delete -# libsqlite3.la because it cannot work with the non-libtool library -# this installation replaces. Since two versions of such a package -# cannot coexist anyway (they share identical file names), that -# conflict is believed to be an imaginary problem. +# conventions: +# +# 1) If libsqlite3.so.0.8.6 is found on then it is re-linked to point +# to the new names. libsqlite3.so.0 historically symlinks to +# libsqlite3.so.0.8.6, and that link is left in place. We cannot +# retain both the old and new installation because they both share +# the high-level name $(libsqlite3.SO). The down-side of this is +# that it may well upset packaging tools when we replace +# libsqlite3.so (from a legacy package) with a new symlink. +# +# 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links +# to the older-style names are created. The primary intent of this +# is to enable chains of operations such as the hypothetical (apt +# remove sqlite3-3.47.0 && apt install sqlite3-3.48.0). In such +# cases, condition (1) would never trigger but applications might +# still expect to see the legacy file names. +# +# In either case we also delete libsqlite3.la because it cannot work +# with the non-libtool library this installation installs. # install-so-1: $(install-dir.lib) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) $(install-dir.lib) @echo "Setting up SO symlinks..."; \ cd $(install-dir.lib) || exit $$?; \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) libsqlite3.la || exit $$?; \ mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).3 || exit $$?; \ ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ - ls -la $(libsqlite3.SO) $(libsqlite3.SO).3*; \ + ls -la $(libsqlite3.SO) $(libsqlite3.SO).3* || exit $$?; \ if [ -e $(libsqlite3.SO).0.8.6 ]; then \ echo "ACHTUNG: older libtool-compatible install found. Re-linking it..."; \ - rm -f $(libsqlite3.SO).0.8.6 libsqlite3.la; \ + rm -f $(libsqlite3.SO).0.8.6 || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ + ls -la $(libsqlite3.SO).0*; \ + elif [ x1 = "x$(INSTALL_SO_086_LINKS)" ]; then \ + echo "ACHTUNG: installing older libtool-style links because INSTALL_SO_086_LINKS=1"; \ + rm -f $(libsqlite3.SO).0.8.6 $(libsqlite3.SO).0 || exit $$?; \ + ln -s $(libsqlite3.SO).0.8.6 $(libsqlite3.SO).0 || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ ls -la $(libsqlite3.SO).0*; \ fi diff --git a/manifest b/manifest index 115acf38b9..314ec4dd34 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sgeneration\sof\sconfig.defines.json\suntil/unless\sit\sproves\sinteresting.\sHonor\sthe\s--disable-largefile\sflag.\sWhen\sinstalling\slibsqlite3.so\sand\san\solder-style\slibtool\sinstallation\sis\sfound,\sre-link\sthe\slibtool-generated\sfiles\sto\sthe\snewly-installed\sones\sto\sretain\stheir\shistorical\snames. -D 2024-10-26T03:05:20.205 +C Expand\sthe\slibtool-style\slink\ssupport\sfrom\s[0a50e33051]\ssuch\sthat\sif\sINSTALL_SO_086_LINKS=1\sis\spassed\sto\s'make\sinstall'\sthen\sthe\slibtool-style\snames\sare\salways\slinked\sin,\sregardless\sof\swhether\sthey\salready\sexisted\sor\snot.\sIn\seither\scase,\swe\sunconditionally\sremove\slibsqlite3.la\sbecause\sit\scannot\swork\swith\sthe\snewly-installed\snon-libtool\s.so\sfile. +D 2024-10-26T03:19:29.450 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 2a1e41234197e59df10160408ca221815f6fecb7de6ad60231b03944c5cd8a8f +F main.mk 551a9af3801b7d801e02663ccba8f2002fd5e0309a5a6b8acacea688baba7f7c F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 63218898ed0a6d466a282f10819d51a7f480d8f12316b74ee8a3f402fcc4e927 -R 7933f107530fbfe42f5cc26d7f7899b9 +P 0a50e33051fbdd5b7b7f0ab7eb2b2561d259098075fa8847868017041d789484 +R e48329e2a4923b776177fca5669845be U stephan -Z fb78edb2f2fc1c6af37f2783aae577ac +Z b7378c5e10b74962b82afd4525f8ef5f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 069bd27f12..2198d3671a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a50e33051fbdd5b7b7f0ab7eb2b2561d259098075fa8847868017041d789484 +2b2ca7dec18d6b53ba7810a2ecf3937d98b5b08232d4f82d16fa2ad5f9fd83b2 From bf441f7575975b4059dc671bc4771a0548b8326b Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 03:22:44 +0000 Subject: [PATCH 159/522] Rephrase 'older' as 'legacy' in the docs from [0a50e33051] and [2b2ca7dec18d]. FossilOrigin-Name: d212cc36824acd490a0afd8bc393159612075438b9f3fab992deec9d78d8a366 --- main.mk | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/main.mk b/main.mk index fd789d0270..3d7ab54813 100644 --- a/main.mk +++ b/main.mk @@ -1312,7 +1312,7 @@ all: so # libsqlite3.so (from a legacy package) with a new symlink. # # 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links -# to the older-style names are created. The primary intent of this +# to the legacy-style names are created. The primary intent of this # is to enable chains of operations such as the hypothetical (apt # remove sqlite3-3.47.0 && apt install sqlite3-3.48.0). In such # cases, condition (1) would never trigger but applications might @@ -1331,12 +1331,12 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ ls -la $(libsqlite3.SO) $(libsqlite3.SO).3* || exit $$?; \ if [ -e $(libsqlite3.SO).0.8.6 ]; then \ - echo "ACHTUNG: older libtool-compatible install found. Re-linking it..."; \ + echo "ACHTUNG: legacy libtool-compatible install found. Re-linking it..."; \ rm -f $(libsqlite3.SO).0.8.6 || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ ls -la $(libsqlite3.SO).0*; \ elif [ x1 = "x$(INSTALL_SO_086_LINKS)" ]; then \ - echo "ACHTUNG: installing older libtool-style links because INSTALL_SO_086_LINKS=1"; \ + echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINKS=1"; \ rm -f $(libsqlite3.SO).0.8.6 $(libsqlite3.SO).0 || exit $$?; \ ln -s $(libsqlite3.SO).0.8.6 $(libsqlite3.SO).0 || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ diff --git a/manifest b/manifest index 314ec4dd34..40df759152 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\sthe\slibtool-style\slink\ssupport\sfrom\s[0a50e33051]\ssuch\sthat\sif\sINSTALL_SO_086_LINKS=1\sis\spassed\sto\s'make\sinstall'\sthen\sthe\slibtool-style\snames\sare\salways\slinked\sin,\sregardless\sof\swhether\sthey\salready\sexisted\sor\snot.\sIn\seither\scase,\swe\sunconditionally\sremove\slibsqlite3.la\sbecause\sit\scannot\swork\swith\sthe\snewly-installed\snon-libtool\s.so\sfile. -D 2024-10-26T03:19:29.450 +C Rephrase\s'older'\sas\s'legacy'\sin\sthe\sdocs\sfrom\s[0a50e33051]\sand\s[2b2ca7dec18d]. +D 2024-10-26T03:22:44.440 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 551a9af3801b7d801e02663ccba8f2002fd5e0309a5a6b8acacea688baba7f7c +F main.mk 7ece71aa7e4a53622b5b81d208161b3bad16f63bbcb3bafa49d94af9736c615c F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0a50e33051fbdd5b7b7f0ab7eb2b2561d259098075fa8847868017041d789484 -R e48329e2a4923b776177fca5669845be +P 2b2ca7dec18d6b53ba7810a2ecf3937d98b5b08232d4f82d16fa2ad5f9fd83b2 +R 7d10bfe43f15ccc57604c6190d35f1e5 U stephan -Z b7378c5e10b74962b82afd4525f8ef5f +Z 6b4ebd6c45c2e1821bbd12a50e70f61a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2198d3671a..84337de3b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b2ca7dec18d6b53ba7810a2ecf3937d98b5b08232d4f82d16fa2ad5f9fd83b2 +d212cc36824acd490a0afd8bc393159612075438b9f3fab992deec9d78d8a366 From dac467890e1276c2b81b66ab1b91342089033ff2 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 03:30:18 +0000 Subject: [PATCH 160/522] Doc typo fix. FossilOrigin-Name: da50e85d9a2020f4c59a72d6ae775fa32c275f0d5086c3caf9b13ab0a937fe1f --- main.mk | 5 +++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index 3d7ab54813..f330b43e22 100644 --- a/main.mk +++ b/main.mk @@ -1303,8 +1303,9 @@ all: so # compatibility for systems which have libraries installed using those # conventions: # -# 1) If libsqlite3.so.0.8.6 is found on then it is re-linked to point -# to the new names. libsqlite3.so.0 historically symlinks to +# 1) If libsqlite3.so.0.8.6 is found in the target installation +# directory then it is re-linked to point to the new +# names. libsqlite3.so.0 historically symlinks to # libsqlite3.so.0.8.6, and that link is left in place. We cannot # retain both the old and new installation because they both share # the high-level name $(libsqlite3.SO). The down-side of this is diff --git a/manifest b/manifest index 40df759152..7549d55321 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rephrase\s'older'\sas\s'legacy'\sin\sthe\sdocs\sfrom\s[0a50e33051]\sand\s[2b2ca7dec18d]. -D 2024-10-26T03:22:44.440 +C Doc\stypo\sfix. +D 2024-10-26T03:30:18.979 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 7ece71aa7e4a53622b5b81d208161b3bad16f63bbcb3bafa49d94af9736c615c +F main.mk cad572855eeff7329613154ce1a6562739db9b85abfdaa4ee8e0ca89bf5c8ef0 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2b2ca7dec18d6b53ba7810a2ecf3937d98b5b08232d4f82d16fa2ad5f9fd83b2 -R 7d10bfe43f15ccc57604c6190d35f1e5 +P d212cc36824acd490a0afd8bc393159612075438b9f3fab992deec9d78d8a366 +R 4ffe7a9aa88108e45b75beeee9d17cd2 U stephan -Z 6b4ebd6c45c2e1821bbd12a50e70f61a +Z 791f15b119b9e59df140430c050f6eff # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 84337de3b2..bbb33472c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d212cc36824acd490a0afd8bc393159612075438b9f3fab992deec9d78d8a366 +da50e85d9a2020f4c59a72d6ae775fa32c275f0d5086c3caf9b13ab0a937fe1f From 8ee82c6202df2bd619a8249c5ad451fec91a3904 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 04:31:04 +0000 Subject: [PATCH 161/522] Add missing B.exe extension to src-verify, as reported in the forum. FossilOrigin-Name: 2801fb6507fc98730449168f3cf49495690e634c004c7074b4d45a0bd7513d41 --- main.mk | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/main.mk b/main.mk index f330b43e22..78db375f91 100644 --- a/main.mk +++ b/main.mk @@ -947,7 +947,7 @@ sqlite3.h: $(MAKE_SANITY_CHECK) $(TOP)/src/sqlite.h.in \ $(TOP)/VERSION $(B.tclsh) # has_tclsh84 $(B.tclsh) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h -sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify \ +sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify$(B.exe) \ $(B.tclsh) # has_tclsh84 $(B.tclsh) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . diff --git a/manifest b/manifest index 7549d55321..7fd3955db3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Doc\stypo\sfix. -D 2024-10-26T03:30:18.979 +C Add\smissing\sB.exe\sextension\sto\ssrc-verify,\sas\sreported\sin\sthe\sforum. +D 2024-10-26T04:31:04.564 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk cad572855eeff7329613154ce1a6562739db9b85abfdaa4ee8e0ca89bf5c8ef0 +F main.mk 6bf2b3be4e37d5c8ee533573d5950c26ca039daaabded9de238643ac201837a3 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d212cc36824acd490a0afd8bc393159612075438b9f3fab992deec9d78d8a366 -R 4ffe7a9aa88108e45b75beeee9d17cd2 +P da50e85d9a2020f4c59a72d6ae775fa32c275f0d5086c3caf9b13ab0a937fe1f +R 061755f9f91986fade258a58345280b1 U stephan -Z 791f15b119b9e59df140430c050f6eff +Z d2486cdcf7233fbb225e9c04aca5fb61 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bbb33472c5..266c44444c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da50e85d9a2020f4c59a72d6ae775fa32c275f0d5086c3caf9b13ab0a937fe1f +2801fb6507fc98730449168f3cf49495690e634c004c7074b4d45a0bd7513d41 From 26d5652b56e75353414afbc4d25709ea7d087abd Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 26 Oct 2024 11:18:29 +0000 Subject: [PATCH 162/522] Fix a bug in the computation of LDFLAGS.libsqlite3 introduced by [63218898ed0a6d46]. FossilOrigin-Name: 58373d523cece0b39a29edcccecf93cfdc7ac68f9f12130ee8e487675d3f6a4d --- main.mk | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index 78db375f91..f87c48434c 100644 --- a/main.mk +++ b/main.mk @@ -329,7 +329,7 @@ T.link.shared = $(T.link) $(LDFLAGS.shobj) # LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ - $(LDFLAGS.math)$(LDFLAGS.dlopen) + $(LDFLAGS.math) $(LDFLAGS.dlopen) # $(LDFLAGS.zlib) # diff --git a/manifest b/manifest index 7fd3955db3..3bc880cc53 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\sB.exe\sextension\sto\ssrc-verify,\sas\sreported\sin\sthe\sforum. -D 2024-10-26T04:31:04.564 +C Fix\sa\sbug\sin\sthe\scomputation\sof\sLDFLAGS.libsqlite3\sintroduced\sby\s[63218898ed0a6d46]. +D 2024-10-26T11:18:29.408 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 6bf2b3be4e37d5c8ee533573d5950c26ca039daaabded9de238643ac201837a3 +F main.mk 331edc29e1049d73c0cf362d8dbcc570794ff0cafca4ee0f4982089fa4b8f579 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P da50e85d9a2020f4c59a72d6ae775fa32c275f0d5086c3caf9b13ab0a937fe1f -R 061755f9f91986fade258a58345280b1 -U stephan -Z d2486cdcf7233fbb225e9c04aca5fb61 +P 2801fb6507fc98730449168f3cf49495690e634c004c7074b4d45a0bd7513d41 +R 70bfdade4d808226e2272b78ae05fdf2 +U drh +Z 8497a379d1e34c4657864ab74abb5b42 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 266c44444c..87ededfe48 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2801fb6507fc98730449168f3cf49495690e634c004c7074b4d45a0bd7513d41 +58373d523cece0b39a29edcccecf93cfdc7ac68f9f12130ee8e487675d3f6a4d From ccb1211b5470a7e107de9dc632c95e35ed304b58 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 16:03:04 +0000 Subject: [PATCH 163/522] Patch bundle accumulated via /chat: add missing --enable/disable-shared flag to configure script and update testrunner.tcl for other configure script flag changes. FossilOrigin-Name: 32fc9c3f62601684b4ded783a79ebf817d093588c87ece02b449c3542881b65a --- auto.def | 3 ++- autosetup/hwaci-common.tcl | 2 +- main.mk | 6 +++--- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- test/testrunner_data.tcl | 22 +++++++++++----------- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/auto.def b/auto.def index dffe733bbc..ddd52914d3 100644 --- a/auto.def +++ b/auto.def @@ -164,6 +164,7 @@ set flags { editline=0 => {BSD editline support} readline=1 => {Disable readline support} largefile=1 => {Disable large file support} + shared=1 => {Disable build of shared libary} with-readline-lib: => {Readline library} with-readline-inc: => {Readline include paths} with-linenoise:DIR => {} @@ -343,7 +344,7 @@ if {"" eq [hwaci-bin-define install]} { # cross-compiling. define BUILD_CC [get-define CC_FOR_BUILD] define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] -define ENABLE_SHARED 1 +define ENABLE_SHARED [opt-bool shared] define HAVE_TCL 0 ######################################################################## diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index a09dedffea..ef94792639 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -42,7 +42,7 @@ ######################################################################## ######################################################################## -# $hwaci is an internal-use-only array for storing whatever generic +# $hwaci_ is an internal-use-only array for storing whatever generic # internal stuff we need stored. array set hwaci_ {} diff --git a/main.mk b/main.mk index f87c48434c..0538f100f0 100644 --- a/main.mk +++ b/main.mk @@ -329,8 +329,8 @@ T.link.shared = $(T.link) $(LDFLAGS.shobj) # LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ - $(LDFLAGS.math) $(LDFLAGS.dlopen) -# $(LDFLAGS.zlib) + $(LDFLAGS.math) $(LDFLAGS.dlopen) \ + $(LDFLAGS.zlib) # # $(install-dir.XYZ) = dirs for installation. @@ -1789,7 +1789,7 @@ sqlite3$(T.exe): shell.c sqlite3.c $(T.link) -o $@ \ shell.c sqlite3.c \ $(CFLAGS.readline) $(SHELL_OPT) \ - $(LDFLAGS.libsqlite3) $(LDFLAGS.zlib) $(LDFLAGS.readline) $(LDFLAGS.icu) + $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) $(LDFLAGS.icu) # # Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the diff --git a/manifest b/manifest index 3bc880cc53..c3f1866e20 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sthe\scomputation\sof\sLDFLAGS.libsqlite3\sintroduced\sby\s[63218898ed0a6d46]. -D 2024-10-26T11:18:29.408 +C Patch\sbundle\saccumulated\svia\s/chat:\sadd\smissing\s--enable/disable-shared\sflag\sto\sconfigure\sscript\sand\supdate\stestrunner.tcl\sfor\sother\sconfigure\sscript\sflag\schanges. +D 2024-10-26T16:03:04.641 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def f3c94971e3559636a89276adaa9cfe949b1d83f72c300a21226f28377c56ec74 +F auto.def a8e0502e8bf821d88fcacc92d23a640f7256eb105d83fac80a4ec180fc85b1b3 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl ed34d81dc51e8acc934d2101d9da5ded27ae7ae55a01a00896150bbfc7ca52da +F autosetup/hwaci-common.tcl 80482a8b22b6853546bd36616f2064534a7c1f7b8537a52a8498a0b132f2e8f4 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 331edc29e1049d73c0cf362d8dbcc570794ff0cafca4ee0f4982089fa4b8f579 +F main.mk ac10e0b1ed32eac092009a69506637a06b10608ca406c2c126fdc9ad54d5d01b F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -1737,7 +1737,7 @@ F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 F test/testrunner.tcl bc1a8d21a1aa3a5cf7c4883cbee4b6748790fe960fad06ca5db74ec914bd6525 x -F test/testrunner_data.tcl e3037f54cdb67479827cdfe8b8962a38811a496c1ad81956c085c64aa34e7a12 +F test/testrunner_data.tcl ba4aeea28aa03cfa6fe7e57782ddecb7a7b91c3a0b3251583cb4f0ee002de6a6 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2801fb6507fc98730449168f3cf49495690e634c004c7074b4d45a0bd7513d41 -R 70bfdade4d808226e2272b78ae05fdf2 -U drh -Z 8497a379d1e34c4657864ab74abb5b42 +P 58373d523cece0b39a29edcccecf93cfdc7ac68f9f12130ee8e487675d3f6a4d +R 9f71a31c86e4b6aa4c47725d28cb3ea3 +U stephan +Z 76974d6843a3a15446106276560473f0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 87ededfe48..32060590d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58373d523cece0b39a29edcccecf93cfdc7ac68f9f12130ee8e487675d3f6a4d +32fc9c3f62601684b4ded783a79ebf817d093588c87ece02b449c3542881b65a diff --git a/test/testrunner_data.tcl b/test/testrunner_data.tcl index eac3f69a99..9abfb242da 100644 --- a/test/testrunner_data.tcl +++ b/test/testrunner_data.tcl @@ -72,11 +72,11 @@ namespace eval trd { # The following mirrors the set of test suites invoked by "all.test". # set all_configs { - full no_optimization memsubsys1 memsubsys2 singlethread - multithread onefile utf16 exclusive persistent_journal + full no_optimization memsubsys1 memsubsys2 singlethread + multithread onefile utf16 exclusive persistent_journal persistent_journal_error no_journal no_journal_error - autovacuum_ioerr no_mutex_try fullmutex journaltest - inmemory_journal pcache0 pcache10 pcache50 pcache90 + autovacuum_ioerr no_mutex_try fullmutex journaltest + inmemory_journal pcache0 pcache10 pcache50 pcache90 pcache100 prepare mmap } @@ -91,17 +91,17 @@ namespace eval trd { -DSQLITE_ENABLE_STMT_SCANSTATUS } - # These two are used by [testrunner.tcl mdevtest] (All-O0) and + # These two are used by [testrunner.tcl mdevtest] (All-O0) and # [testrunner.tcl sdevtest] (All-Sanitize). # set build(All-Debug) { - --enable-debug --enable-all + --with-debug --enable-all -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES } set build(All-O0) { -O0 --enable-all } - set build(All-Sanitize) { + set build(All-Sanitize) { -DSQLITE_OMIT_LOOKASIDE=1 --enable-all -fsanitize=address,undefined -fno-sanitize-recover=undefined } @@ -112,7 +112,7 @@ namespace eval trd { -DSQLITE_OMIT_LOOKASIDE=1 -DCONFIG_SLOWDOWN_FACTOR=5.0 -DSQLITE_ENABLE_RBU - --enable-debug + --with-debug --enable-all } set build(Stdcall) { @@ -193,7 +193,7 @@ namespace eval trd { set build(Debug-Two) { -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_MAX_EXPR_DEPTH=0 - --enable-debug + --with-debug } set build(Fast-One) { -O6 @@ -564,7 +564,7 @@ proc make_script {cfg srcdir bMsvc} { } --enable-fts5 { lappend opts -DSQLITE_ENABLE_FTS5 - } + } --enable-shared { lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1 } @@ -574,7 +574,7 @@ proc make_script {cfg srcdir bMsvc} { } --enable-all { } - --enable-debug { + --with-debug { # lappend makeOpts OPTIMIZATIONS=0 lappend opts -DSQLITE_DEBUG } From 1c27c3939645746e605ccf2d222d77de18aa6a4d Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 16:04:36 +0000 Subject: [PATCH 164/522] Remove LDFLAGS_ZLIB from sqlite3.pc.in because -lsqlite3 already includes that. FossilOrigin-Name: 47e50fa84dacf83c2aca62140413c7eeba934e57289a6f6e6fff3ce24448d90a --- manifest | 12 ++++++------ manifest.uuid | 2 +- sqlite3.pc.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c3f1866e20..b68747cc3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Patch\sbundle\saccumulated\svia\s/chat:\sadd\smissing\s--enable/disable-shared\sflag\sto\sconfigure\sscript\sand\supdate\stestrunner.tcl\sfor\sother\sconfigure\sscript\sflag\schanges. -D 2024-10-26T16:03:04.641 +C Remove\sLDFLAGS_ZLIB\sfrom\ssqlite3.pc.in\sbecause\s-lsqlite3\salready\sincludes\sthat. +D 2024-10-26T16:04:36.668 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -717,7 +717,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc -F sqlite3.pc.in b8b551878b9bdca1ff148f6e943d0e06206864c757eb07eef030343c27bb10bd +F sqlite3.pc.in da30c8d1a41490e8e3d94c9560ae29b4388b2f7a89de08ff309beea9083a3f20 F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 58373d523cece0b39a29edcccecf93cfdc7ac68f9f12130ee8e487675d3f6a4d -R 9f71a31c86e4b6aa4c47725d28cb3ea3 +P 32fc9c3f62601684b4ded783a79ebf817d093588c87ece02b449c3542881b65a +R 169d63c9faa2852f8ca36d264863190c U stephan -Z 76974d6843a3a15446106276560473f0 +Z a6251b75c82e146562e50403703934b5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 32060590d9..a2cc50da47 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32fc9c3f62601684b4ded783a79ebf817d093588c87ece02b449c3542881b65a +47e50fa84dacf83c2aca62140413c7eeba934e57289a6f6e6fff3ce24448d90a diff --git a/sqlite3.pc.in b/sqlite3.pc.in index 52cda3065d..68c09475e7 100644 --- a/sqlite3.pc.in +++ b/sqlite3.pc.in @@ -9,5 +9,5 @@ Name: SQLite Description: SQL database engine Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lsqlite3 -Libs.private: @LDFLAGS_ZLIB@ @LDFLAGS_READLINE@ +Libs.private: @LDFLAGS_READLINE@ Cflags: -I${includedir} From 5ea8d1ed5af913d61c474080028c2454a066a69c Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 26 Oct 2024 17:47:19 +0000 Subject: [PATCH 165/522] In Makefile.msc, build jimsh0.exe locally, not in the source directory. FossilOrigin-Name: 1b9eb4564bc38cbc6a51ed1c4508f1ba45459630cfda8765c243c9aa0fc7d763 --- Makefile.msc | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 4f50c300d8..863cc0242d 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1069,7 +1069,7 @@ TCLSH_CMD = tclsh JIM_TCLSH = $(TCLSH_CMD) !ENDIF !IFNDEF JIM_TCLSH -JIM_TCLSH = $(TOP)\jimsh0.exe +JIM_TCLSH = jimsh0.exe !ENDIF # <> diff --git a/manifest b/manifest index b68747cc3f..2cb0cec7d6 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Remove\sLDFLAGS_ZLIB\sfrom\ssqlite3.pc.in\sbecause\s-lsqlite3\salready\sincludes\sthat. -D 2024-10-26T16:04:36.668 +C In\sMakefile.msc,\sbuild\sjimsh0.exe\slocally,\snot\sin\sthe\ssource\sdirectory. +D 2024-10-26T17:47:19.419 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 F Makefile.in e880d287a3233a5352b3e260ff9b44baa9388070ba033ec842bc46e2cebdd11e F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 -F Makefile.msc 28318970f86f601ac79b5e6a514a52fb33a1526d0e0e915b4edc2f41846c1d4a +F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 32fc9c3f62601684b4ded783a79ebf817d093588c87ece02b449c3542881b65a -R 169d63c9faa2852f8ca36d264863190c -U stephan -Z a6251b75c82e146562e50403703934b5 +P 47e50fa84dacf83c2aca62140413c7eeba934e57289a6f6e6fff3ce24448d90a +R faad5bee19c3ac86eb55ce27078c47df +U drh +Z 4a825c1d043ad68945d1bd0013a800b9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a2cc50da47..dce88b5b27 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47e50fa84dacf83c2aca62140413c7eeba934e57289a6f6e6fff3ce24448d90a +1b9eb4564bc38cbc6a51ed1c4508f1ba45459630cfda8765c243c9aa0fc7d763 From 59b4f75e0f6c924d4b11747b6b7f387a6a7b384e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 26 Oct 2024 18:09:13 +0000 Subject: [PATCH 166/522] Add test case for fts5 trigram tokenizer. FossilOrigin-Name: ba358d265b7ee360d62b5219faaa1010ea90dac4e20cc7adc3ebd46161a65f94 --- ext/fts5/fts5_tcl.c | 61 +++++++++++++++++++++++++++++++++- ext/fts5/test/fts5trigram.test | 9 ++++- manifest | 16 ++++----- manifest.uuid | 2 +- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index a8ab44096b..df4b2daa41 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -1626,6 +1626,64 @@ static int SQLITE_TCLAPI f5tDropCorruptTable( return TCL_OK; } +/* +** Free a buffer returned to SQLite by the str() function. +*/ +void f5tFree(void *p){ + char *x = (char *)p; + free(&x[-8]); +} + +/* +** Implementation of str(). +*/ +void f5tStrFunc(sqlite3_context *pCtx, int nArg, sqlite3_value **apArg){ + const char *zText = 0; + assert( nArg==1 ); + + zText = sqlite3_value_text(apArg[0]); + if( zText ){ + int nText = sqlite3Strlen30(zText); + char *zCopy = (char*)malloc(nText+8); + if( zCopy==0 ){ + sqlite3_result_error_nomem(pCtx); + }else{ + zCopy += 8; + memcpy(zCopy, zText, nText); + sqlite3_result_text(pCtx, zCopy, nText, f5tFree); + } + } +} + +/* +** sqlite3_fts5_register_str DB +** +** Register the str() function with database handle DB. str() interprets +** its only argument as text and returns a copy of the value in a +** non-nul-terminated buffer. +*/ +static int SQLITE_TCLAPI f5tRegisterStr( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db = 0; + int rc; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( f5tDbPointer(interp, objv[1], &db) ){ + return TCL_ERROR; + } + + sqlite3_create_function(db, "str", 1, SQLITE_UTF8, 0, f5tStrFunc, 0, 0); + + return TCL_OK; +} + /* ** Entry point. */ @@ -1645,7 +1703,8 @@ int Fts5tcl_Init(Tcl_Interp *interp){ { "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 }, { "sqlite3_fts5_register_fts5tokenize", f5tRegisterTok, 0 }, { "sqlite3_fts5_register_origintext",f5tRegisterOriginText, 0 }, - { "sqlite3_fts5_drop_corrupt_table", f5tDropCorruptTable, 0 } + { "sqlite3_fts5_drop_corrupt_table", f5tDropCorruptTable, 0 }, + { "sqlite3_fts5_register_str", f5tRegisterStr, 0 } }; int i; F5tTokenizerContext *pContext; diff --git a/ext/fts5/test/fts5trigram.test b/ext/fts5/test/fts5trigram.test index 3742c647f0..5048f8beea 100644 --- a/ext/fts5/test/fts5trigram.test +++ b/ext/fts5/test/fts5trigram.test @@ -342,6 +342,13 @@ do_test 10.3 { } } {} - +do_execsql_test 11.0 { + CREATE VIRTUAL TABLE t4 USING fts5(y, tokenize=trigram); +} +sqlite3_fts5_register_str db +do_execsql_test 11.1 { + INSERT INTO t4 VALUES( str('') ); +} finish_test + diff --git a/manifest b/manifest index 2cb0cec7d6..169e0e7d1c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sMakefile.msc,\sbuild\sjimsh0.exe\slocally,\snot\sin\sthe\ssource\sdirectory. -D 2024-10-26T17:47:19.419 +C Add\stest\scase\sfor\sfts5\strigram\stokenizer. +D 2024-10-26T18:09:13.006 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -120,7 +120,7 @@ F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6 F ext/fts5/fts5_main.c 50eb059e51d730e8e0c77df4e568b018079e112a755c094488b0d5b1aa06afbb F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c -F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe +F ext/fts5/fts5_tcl.c 9b390c318e36c0dc53af14e20198f55aa3ed46a39350ed7f46bc034e422fe778 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9 @@ -255,7 +255,7 @@ F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test 7937cec672b148223fff8746d21d3e7ed0965fd7caf35ccdc888a005bb452f98 F ext/fts5/test/fts5tokenizer2.test ddb8b10fbe4b84b2a75812671f127774c1d2e3e2bf82d2e0e4f0bb1cd8a2b2d6 F ext/fts5/test/fts5tokenizer3.test eea778f7bb7024c3e904e28915f9d53286141671b138722148be22a9c758bdc3 -F ext/fts5/test/fts5trigram.test fb9ee982edd76280ce979905a2251081cd04ae4c470248bd5d391b2d096430ab +F ext/fts5/test/fts5trigram.test 9927c9e9b35116ea00748c8e41d9cbc2b95a6c90845cd82a59c11fedfd16404a F ext/fts5/test/fts5trigram2.test 6fde9de7f63a6b4aa18dc731be56dbd6be4e755c9b13dcd55479e200d1df0e61 F ext/fts5/test/fts5ubsan.test 9a2dcf399dc8d0e0de661f0d93884d1d27e5b7f0693cfceb97dd24d818df5dd2 F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 47e50fa84dacf83c2aca62140413c7eeba934e57289a6f6e6fff3ce24448d90a -R faad5bee19c3ac86eb55ce27078c47df -U drh -Z 4a825c1d043ad68945d1bd0013a800b9 +P 1b9eb4564bc38cbc6a51ed1c4508f1ba45459630cfda8765c243c9aa0fc7d763 +R 8ff21923791c350decdcbf04d2f23594 +U dan +Z 3e4e525d7b1d9780dcf1603f839dea72 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dce88b5b27..3927059f42 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b9eb4564bc38cbc6a51ed1c4508f1ba45459630cfda8765c243c9aa0fc7d763 +ba358d265b7ee360d62b5219faaa1010ea90dac4e20cc7adc3ebd46161a65f94 From 784623d599e1679ae662abd8b2b8703f8fc692ef Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 18:17:17 +0000 Subject: [PATCH 167/522] Add new configure --with-readline-ldflags/cflags/header flags as brute-force method for clients to tell configure how to compile and link against readline. FossilOrigin-Name: eaa3a8053eb0935bc47abc1001ff101d79b3f181ac7ea51d3e567cb59ae4c7b3 --- auto.def | 303 ++++++++++++++++++++++++++++---------------------- manifest | 14 +-- manifest.uuid | 2 +- 3 files changed, 180 insertions(+), 139 deletions(-) diff --git a/auto.def b/auto.def index ddd52914d3..3c6acd15d9 100644 --- a/auto.def +++ b/auto.def @@ -150,7 +150,7 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # - [hwaci-opt-if-truthy FLAG {THEN} {ELSE}] # # Non-boolean (i.e. string) flags: -# - [opt-val FLAG] +# - [opt-val FLAG ?default?] # ######################################################################## set flags { @@ -165,8 +165,9 @@ set flags { readline=1 => {Disable readline support} largefile=1 => {Disable large file support} shared=1 => {Disable build of shared libary} - with-readline-lib: => {Readline library} - with-readline-inc: => {Readline include paths} + with-readline-ldflags: => {Readline LDFLAGS, e.g. -lreadline -lncurses} + with-readline-cflags: => {Readline CFLAGS, e.g. -I/path/to/includes} + with-readline-header: => {Full path to readline.h, from which --with-readline-cflags will be derived.} with-linenoise:DIR => {} amalgamation=1 => {Disable the amalgamation and instead build all files separately} load-extension=1 => {Disable loading of external extensions} @@ -197,12 +198,6 @@ if {"" ne $DUMP_DEFINES_JSON} { options [subst $flags] unset flags -######################################################################## -# Notes about certain historical flags: -# -# --releasemode: libtool-specific (which we don't have now) -# -# set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] msg-result "srcdir = $srcdir" @@ -749,134 +744,178 @@ if {1} { unset ts tsn } -if {1} { - ########## - # Figure out what C libraries are required to compile programs - # that use "readline()" library. - add-shell-opt -DHAVE_READLINE=[hwaci-check-readline] - # TODO: reimplement: - # --enable-editline - # --with-readline-lib specify readline library - # --with-readline-inc specify readline include paths - # --with-linenoise=DIR source directory for linenoise library -} else { - # Older impl solely for reference while porting... - # - # XXX TARGET_READLINE_LIBS="" - # XXX TARGET_READLINE_INC="" - # XXX TARGET_HAVE_READLINE=0 - # XXX TARGET_HAVE_EDITLINE=0 - if {[opt-bool editline]} { - set with_editline $enableval - } else { - set with_editline auto - } - if {![opt-bool readline]} { - set with_readline $enableval - } else { - set with_readline auto - } - - # XXX if test x"$with_editline" != xno; then - # XXX sLIBS=$LIBS - # XXX LIBS="" - # XXX TARGET_HAVE_EDITLINE=1 - if {[hwaci-check-function-in-lib readline edit]} { - set with_readline no +######################################################################## +# Jump through proverbial hoops to try to find a working line-editing +# library, setting: +# +# - LDFLAGS_READLINE = linker flags +# +# - CFLAGS_READLINE = compilation flags for clients +# +# - READLINE_H = header in the form "<.../readline.h>" IF we can +# figure it out. shell.c does not currently use this. +proc hwaci-check-readline2 {} { + set check [opt-val with-readline-ldflags][opt-val with-readline-cflags][opt-val with-readline-header] + if {"" ne $check} { + # If any one of --with-readline-(ldflags|cflags|header) are provided, + # those trump any automated searching. + set fL [join [opt-val with-readline-ldflags]] + set v [opt-val with-readline-header] + if {"" eq $v} { + set fC [join [opt-val with-readline-cflags]] + define READLINE_H "" + } else { + # Derive CFLAGS from header file name + set v [file dirname $v] + if {[string match */*line $v]} { + # Special case: if the path includes .../*line/readline.h", set + # the -I to one dir up from that because our sources include + # or . Reminder: if + # auto.def is being run by jimsh0 then [file normalize] will not + # work! + set v [file dirname $v] + } + set fC "-I$v" + # Set READLINE_H to an #include-compatible form of the tail of $v: + set x [opt-val with-readline-header] + set x [string replace $x 0 [string length $v]] + define READLINE_H <$x> + unset x + #hwaci-warn "v=$v READLINE_H=[get-define READLINE_H]" + } + define LDFLAGS_READLINE $fL + define CFLAGS_READLINE $fC + define HAVE_READLINE 1 + add-shell-opt -DHAVE_READLINE=1 + msg-result "Using client-provided readline flags: $fC $fL" + } elseif {1} { + # Try the project-agnostic readline detector: + add-shell-opt -DHAVE_READLINE=[hwaci-check-readline] + # TODO: reimplement: + # --enable-editline + # --with-readline-lib specify readline library + # --with-readline-inc specify readline include paths + # --with-linenoise=DIR source directory for linenoise library } else { + # Older impl solely for reference while porting... + # + # XXX TARGET_READLINE_LIBS="" + # XXX TARGET_READLINE_INC="" + # XXX TARGET_HAVE_READLINE=0 # XXX TARGET_HAVE_EDITLINE=0 - } - # XXX TARGET_READLINE_LIBS=$LIBS - # XXX LIBS=$sLIBS - # XXX fi - # XXX if test x"$with_readline" != xno; then - set found "yes" - - if {[opt-val with-readline-lib] ne {}} { - set withval [lindex [opt-val with-readline-lib] end] - set with_readline_lib $withval - } else { - set with_readline_lib "auto" - } - # XXX if test "x$with_readline_lib" = xauto; then - # XXX save_LIBS="$LIBS" - # XXX LIBS="" - if {[hwaci-check-function-in-lib tgetent readline ncurses curses termcap]} { - # XXX term_LIBS="$LIBS" - } else { - # XXX term_LIBS="" - } - if {[hwaci-check-function-in-lib readline readline]} { - # XXX TARGET_READLINE_LIBS="-lreadline" - } else { - set found "no" - } - # XXX TARGET_READLINE_LIBS="$TARGET_READLINE_LIBS $term_LIBS" - # XXX LIBS="$save_LIBS" - # XXX else - # XXX TARGET_READLINE_LIBS="$with_readline_lib" - # XXX fi - - if {[opt-val with-readline-inc] ne {}} { - set withval [lindex [opt-val with-readline-inc] end] - set with_readline_inc $withval - } else { - set with_readline_inc "auto" - } - # XXX if test "x$with_readline_inc" = xauto; then - if {[cc-check-includes readline.h]} { + if {[opt-bool editline]} { + set with_editline $enableval + } else { + set with_editline auto + } + if {![opt-bool readline]} { + set with_readline $enableval + } else { + set with_readline auto + } + + # XXX if test x"$with_editline" != xno; then + # XXX sLIBS=$LIBS + # XXX LIBS="" + # XXX TARGET_HAVE_EDITLINE=1 + if {[hwaci-check-function-in-lib readline edit]} { + set with_readline no + } else { + # XXX TARGET_HAVE_EDITLINE=0 + } + # XXX TARGET_READLINE_LIBS=$LIBS + # XXX LIBS=$sLIBS + # XXX fi + # XXX if test x"$with_readline" != xno; then set found "yes" - } else { - set found "no" - # XXX if test "$cross_compiling" != yes; then - # XXX for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do - # XXX for subdir in include include/readline; do - # XXX AC_CHECK_FILE $dir/$subdir/readline.h found=yes - # XXX if test "$found" = "yes"; then - # XXX TARGET_READLINE_INC="-I$dir/$subdir" - # XXX break + + if {[opt-val with-readline-lib] ne {}} { + set withval [lindex [opt-val with-readline-lib] end] + set with_readline_lib $withval + } else { + set with_readline_lib "auto" + } + # XXX if test "x$with_readline_lib" = xauto; then + # XXX save_LIBS="$LIBS" + # XXX LIBS="" + if {[hwaci-check-function-in-lib tgetent readline ncurses curses termcap]} { + # XXX term_LIBS="$LIBS" + } else { + # XXX term_LIBS="" + } + if {[hwaci-check-function-in-lib readline readline]} { + # XXX TARGET_READLINE_LIBS="-lreadline" + } else { + set found "no" + } + # XXX TARGET_READLINE_LIBS="$TARGET_READLINE_LIBS $term_LIBS" + # XXX LIBS="$save_LIBS" + # XXX else + # XXX TARGET_READLINE_LIBS="$with_readline_lib" + # XXX fi + + if {[opt-val with-readline-inc] ne {}} { + set withval [lindex [opt-val with-readline-inc] end] + set with_readline_inc $withval + } else { + set with_readline_inc "auto" + } + # XXX if test "x$with_readline_inc" = xauto; then + if {[cc-check-includes readline.h]} { + set found "yes" + } else { + set found "no" + # XXX if test "$cross_compiling" != yes; then + # XXX for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do + # XXX for subdir in include include/readline; do + # XXX AC_CHECK_FILE $dir/$subdir/readline.h found=yes + # XXX if test "$found" = "yes"; then + # XXX TARGET_READLINE_INC="-I$dir/$subdir" + # XXX break + # XXX fi + # XXX done + # XXX test "$found" = "yes" && break + # XXX done + # XXX fi + } + # XXX else + # XXX TARGET_READLINE_INC="$with_readline_inc" # XXX fi - # XXX done - # XXX test "$found" = "yes" && break - # XXX done + + # XXX if test x"$found" = xno; then + # XXX TARGET_READLINE_LIBS="" + # XXX TARGET_READLINE_INC="" + # XXX TARGET_HAVE_READLINE=0 + # XXX else + # XXX TARGET_HAVE_READLINE=1 # XXX fi + # XXX fi + if {[opt-val with-linenoise] ne {}} { + set withval [lindex [opt-val with-linenoise] end] + set with_linenoise $withval + } else { + set with_linenoise "no" + } + # XXX if test "x$with_linenoise" != "xno"; then + # XXX TARGET_HAVE_READLINE=0 + # XXX TARGET_HAVE_EDITLINE=0 + # XXX TARGET_HAVE_LINENOISE=1 + # XXX TARGET_READLINE_INC="-I${with_linenoise}" + # XXX TARGET_READLINE_LIBS="${with_linenoise}/linenoise.c" + # XXX echo "using linenoise source code at ${with_linenoise}" + # XXX else + # XXX TARGET_HAVE_LINENOISE=0 + # XXX echo "not using linenoise" + # XXX fi + + # XXX AC_SUBST TARGET_READLINE_LIBS + # XXX AC_SUBST TARGET_READLINE_INC + # XXX AC_SUBST TARGET_HAVE_READLINE + # XXX AC_SUBST TARGET_HAVE_EDITLINE + # XXX AC_SUBST TARGET_HAVE_LINENOISE } - # XXX else - # XXX TARGET_READLINE_INC="$with_readline_inc" - # XXX fi - - # XXX if test x"$found" = xno; then - # XXX TARGET_READLINE_LIBS="" - # XXX TARGET_READLINE_INC="" - # XXX TARGET_HAVE_READLINE=0 - # XXX else - # XXX TARGET_HAVE_READLINE=1 - # XXX fi - # XXX fi - if {[opt-val with-linenoise] ne {}} { - set withval [lindex [opt-val with-linenoise] end] - set with_linenoise $withval - } else { - set with_linenoise "no" - } - # XXX if test "x$with_linenoise" != "xno"; then - # XXX TARGET_HAVE_READLINE=0 - # XXX TARGET_HAVE_EDITLINE=0 - # XXX TARGET_HAVE_LINENOISE=1 - # XXX TARGET_READLINE_INC="-I${with_linenoise}" - # XXX TARGET_READLINE_LIBS="${with_linenoise}/linenoise.c" - # XXX echo "using linenoise source code at ${with_linenoise}" - # XXX else - # XXX TARGET_HAVE_LINENOISE=0 - # XXX echo "not using linenoise" - # XXX fi - - # XXX AC_SUBST TARGET_READLINE_LIBS - # XXX AC_SUBST TARGET_READLINE_INC - # XXX AC_SUBST TARGET_HAVE_READLINE - # XXX AC_SUBST TARGET_HAVE_EDITLINE - # XXX AC_SUBST TARGET_HAVE_LINENOISE -} +}; # hwaci-check-readline2 +hwaci-check-readline2 hwaci-if-opt-truthy load-extension { if {[hwaci-check-function-in-lib dlopen dl]} { @@ -1013,6 +1052,8 @@ hwaci-check-rpath ######################################################################## # Generate the output files. # +# Potential TODO (unclear): in sqlite3.pc.in, do we need to include +# any CFLAGS_READLINE, CFLAGS_ZLIB, etc in its "Cflags:" section? hwaci-make-from-dot-in -touch Makefile sqlite3.pc if {0} { # Requires a hand-written sqlite_cfg.h.in... diff --git a/manifest b/manifest index 169e0e7d1c..dbee42e3ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sfor\sfts5\strigram\stokenizer. -D 2024-10-26T18:09:13.006 +C Add\snew\sconfigure\s--with-readline-ldflags/cflags/header\sflags\sas\sbrute-force\smethod\sfor\sclients\sto\stell\sconfigure\show\sto\scompile\sand\slink\sagainst\sreadline. +D 2024-10-26T18:17:17.351 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a8e0502e8bf821d88fcacc92d23a640f7256eb105d83fac80a4ec180fc85b1b3 +F auto.def ea6cc574b8941830d4e649a76f0ddf44d4e638bc9d695fac3937a8cc65d160b3 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1b9eb4564bc38cbc6a51ed1c4508f1ba45459630cfda8765c243c9aa0fc7d763 -R 8ff21923791c350decdcbf04d2f23594 -U dan -Z 3e4e525d7b1d9780dcf1603f839dea72 +P ba358d265b7ee360d62b5219faaa1010ea90dac4e20cc7adc3ebd46161a65f94 +R 8621f08affc8cf37cd58fa446ab68d39 +U stephan +Z b40873979d7095705212ffeb9f316fba # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3927059f42..c0d5f5c79b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba358d265b7ee360d62b5219faaa1010ea90dac4e20cc7adc3ebd46161a65f94 +eaa3a8053eb0935bc47abc1001ff101d79b3f181ac7ea51d3e567cb59ae4c7b3 From ae50e509f5d913abfe908f5fd33423bf41d76ec8 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 18:34:39 +0000 Subject: [PATCH 168/522] configure flag --disable-readline now trumps --with-readline-... FossilOrigin-Name: b66076e51bc1601864973be0f3f2b702b51139ed3818f17433fbaa8351119ad6 --- auto.def | 9 ++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index 3c6acd15d9..1b531d7afe 100644 --- a/auto.def +++ b/auto.def @@ -755,6 +755,14 @@ if {1} { # - READLINE_H = header in the form "<.../readline.h>" IF we can # figure it out. shell.c does not currently use this. proc hwaci-check-readline2 {} { + define HAVE_READLINE 0 + define LDFLAGS_READLINE "" + define CFLAGS_READLINE "" + define READLINE_H "" + if {![opt-bool readline]} { + msg-result "Readline support explicitly disabled with --disable-readline." + return 0 + } set check [opt-val with-readline-ldflags][opt-val with-readline-cflags][opt-val with-readline-header] if {"" ne $check} { # If any one of --with-readline-(ldflags|cflags|header) are provided, @@ -763,7 +771,6 @@ proc hwaci-check-readline2 {} { set v [opt-val with-readline-header] if {"" eq $v} { set fC [join [opt-val with-readline-cflags]] - define READLINE_H "" } else { # Derive CFLAGS from header file name set v [file dirname $v] diff --git a/manifest b/manifest index dbee42e3ac..8c7adc70a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sconfigure\s--with-readline-ldflags/cflags/header\sflags\sas\sbrute-force\smethod\sfor\sclients\sto\stell\sconfigure\show\sto\scompile\sand\slink\sagainst\sreadline. -D 2024-10-26T18:17:17.351 +C configure\sflag\s--disable-readline\snow\strumps\s--with-readline-... +D 2024-10-26T18:34:39.207 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def ea6cc574b8941830d4e649a76f0ddf44d4e638bc9d695fac3937a8cc65d160b3 +F auto.def 982231b47cf749449c2c04e85ff9583c68774000a4750db277213ccbf75c75dd F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ba358d265b7ee360d62b5219faaa1010ea90dac4e20cc7adc3ebd46161a65f94 -R 8621f08affc8cf37cd58fa446ab68d39 +P eaa3a8053eb0935bc47abc1001ff101d79b3f181ac7ea51d3e567cb59ae4c7b3 +R 6e04fb56f743767a528a8a7b2784bb4a U stephan -Z b40873979d7095705212ffeb9f316fba +Z 41af4b4083539567597ff34d27c40ef9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c0d5f5c79b..a83cea368f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eaa3a8053eb0935bc47abc1001ff101d79b3f181ac7ea51d3e567cb59ae4c7b3 +b66076e51bc1601864973be0f3f2b702b51139ed3818f17433fbaa8351119ad6 From 26068b79015c11292d0b6872c7cbb4f8b747aeb3 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 19:16:18 +0000 Subject: [PATCH 169/522] Remove the install-lib makefile dep from install-tcl, as it breaks non-root-user invocations of 'make install-tcl' when the --prefix is left at its default and --with-tcl is explicitly provided. FossilOrigin-Name: e7eabfb61f72dc396fab9d0671642f8150cde23aea965c5e77ac3d9ad11c749f --- main.mk | 6 ++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index 0538f100f0..c517dc0da2 100644 --- a/main.mk +++ b/main.mk @@ -216,6 +216,7 @@ TCL_STUB_LIB_SPEC ?= TCL_EXEC_PREFIX ?= TCL_VERSION ?= TCLLIBDIR ?= +TCL_CONFIG_SH ?= # # $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not # libsqlite3, and will usually differ from $(LDFLAGS.rpath). @@ -1377,13 +1378,14 @@ libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL) all: libtcl install.tcldir = $(DESTDIR)$(TCLLIBDIR) -install-tcl-1: install-lib $(libtclsqlite3.SO) pkgIndex.tcl +install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl @if [ "x$(DESTDIR)" = "x$(install.tcldir)" ]; then echo "TCLLIBDIR is not set." 1>&2; exit 1; fi $(INSTALL) -d $(install.tcldir) $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) $(INSTALL.noexec) pkgIndex.tcl $(install.tcldir) install-tcl-0 install-tcl-: -install: install-tcl-$(HAVE_TCL) +install-tcl: install-tcl-$(HAVE_TCL) +install: install-tcl tclsqlite3.c: sqlite3.c echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c diff --git a/manifest b/manifest index 8c7adc70a8..0134524d1f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C configure\sflag\s--disable-readline\snow\strumps\s--with-readline-... -D 2024-10-26T18:34:39.207 +C Remove\sthe\sinstall-lib\smakefile\sdep\sfrom\sinstall-tcl,\sas\sit\sbreaks\snon-root-user\sinvocations\sof\s'make\sinstall-tcl'\swhen\sthe\s--prefix\sis\sleft\sat\sits\sdefault\sand\s--with-tcl\sis\sexplicitly\sprovided. +D 2024-10-26T19:16:18.142 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ac10e0b1ed32eac092009a69506637a06b10608ca406c2c126fdc9ad54d5d01b +F main.mk 857da235f57919c3469efbf89b61060f8f35352c6b97a9dce275f5a35b536007 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eaa3a8053eb0935bc47abc1001ff101d79b3f181ac7ea51d3e567cb59ae4c7b3 -R 6e04fb56f743767a528a8a7b2784bb4a +P b66076e51bc1601864973be0f3f2b702b51139ed3818f17433fbaa8351119ad6 +R bb71574ad1e7e09ae31e2176eab9b67d U stephan -Z 41af4b4083539567597ff34d27c40ef9 +Z f881b225d548de8ff8557460eb6c70ce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a83cea368f..efe09cac05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b66076e51bc1601864973be0f3f2b702b51139ed3818f17433fbaa8351119ad6 +e7eabfb61f72dc396fab9d0671642f8150cde23aea965c5e77ac3d9ad11c749f From 1fa0ef3ae8c0026de250da4eee6503d9717f1e8a Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 26 Oct 2024 21:51:04 +0000 Subject: [PATCH 170/522] Get --with-linenoise=DIR configure flag working. FossilOrigin-Name: 66ce47e5de21c607d2ef1f1e6e639f3c6da132ff3db582e12bd174f7d89d8150 --- auto.def | 202 ++++++++++++------------------------- autosetup/hwaci-common.tcl | 25 +++-- main.mk | 2 +- manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 89 insertions(+), 158 deletions(-) diff --git a/auto.def b/auto.def index 1b531d7afe..cd10b84f77 100644 --- a/auto.def +++ b/auto.def @@ -165,10 +165,10 @@ set flags { readline=1 => {Disable readline support} largefile=1 => {Disable large file support} shared=1 => {Disable build of shared libary} - with-readline-ldflags: => {Readline LDFLAGS, e.g. -lreadline -lncurses} - with-readline-cflags: => {Readline CFLAGS, e.g. -I/path/to/includes} - with-readline-header: => {Full path to readline.h, from which --with-readline-cflags will be derived.} - with-linenoise:DIR => {} + with-readline-ldflags:LDFLAGS => {Readline LDFLAGS, e.g. -lreadline -lncurses} + with-readline-cflags:CFLAGS => {Readline CFLAGS, e.g. -I/path/to/includes} + with-readline-header:PATH => {Full path to readline.h, from which --with-readline-cflags will be derived.} + with-linenoise:DIR => {Source directory for linenoise.c and linenoise.h} amalgamation=1 => {Disable the amalgamation and instead build all files separately} load-extension=1 => {Disable loading of external extensions} math=1 => {Disable math functions} @@ -745,23 +745,57 @@ if {1} { } ######################################################################## -# Jump through proverbial hoops to try to find a working line-editing -# library, setting: +# hwaci-check-line-editing jumps through proverbial hoops to try to +# find a working line-editing library, setting: # -# - LDFLAGS_READLINE = linker flags +# - HAVE_READLINE to 0 or 1 +# - HAVE_LINENOISE to 0 or 1 +# - HAVE_EDITLINE to 0 or 1 # -# - CFLAGS_READLINE = compilation flags for clients +# - LDFLAGS_READLINE = linker flags or empty string +# +# - CFLAGS_READLINE = compilation flags for clients or empty string # # - READLINE_H = header in the form "<.../readline.h>" IF we can # figure it out. shell.c does not currently use this. -proc hwaci-check-readline2 {} { +# +# Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to +# linenoise or editline, not necessarily libreadline. +# +# Returns a string describing which line-editing approach to use, or +# "none" if no option is available. +proc hwaci-check-line-editing {} { define HAVE_READLINE 0 + define HAVE_LINENOISE 0 + define HAVE_EDITLINE 0 define LDFLAGS_READLINE "" define CFLAGS_READLINE "" define READLINE_H "" - if {![opt-bool readline]} { - msg-result "Readline support explicitly disabled with --disable-readline." - return 0 + set check [opt-val with-linenoise] + if {"" ne $check} { + # Use linenoise... + set dirLn $check + if {![file isdir $dirLn]} { + hwaci-fatal "--with-linenoise value is not a directory" + } + if {![file exists $dirLn/linenoise.c] } { + hwaci-fatal "Cannot find linenoise.c in $dirLn" + } + if {![file exists $dirLn/linenoise.h] } { + hwaci-fatal "Cannot find linenoise.h in $dirLn" + } + user-notice "Using linenoise from $dirLn" + define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise.c" + define HAVE_LINENOISE 1 + add-shell-opt -DHAVE_LINENOISE=1 + return "linenoise" + } elseif {[opt-bool editline]} { + # Use editline... + user-notice "WARNING: the --enable-editline flag is not yet supported" + return "none" + } elseif {![opt-bool readline]} { + user-notice "Readline support explicitly disabled with --disable-readline." + return "none" } set check [opt-val with-readline-ldflags][opt-val with-readline-cflags][opt-val with-readline-header] if {"" ne $check} { @@ -794,135 +828,23 @@ proc hwaci-check-readline2 {} { define CFLAGS_READLINE $fC define HAVE_READLINE 1 add-shell-opt -DHAVE_READLINE=1 - msg-result "Using client-provided readline flags: $fC $fL" - } elseif {1} { - # Try the project-agnostic readline detector: - add-shell-opt -DHAVE_READLINE=[hwaci-check-readline] - # TODO: reimplement: - # --enable-editline - # --with-readline-lib specify readline library - # --with-readline-inc specify readline include paths - # --with-linenoise=DIR source directory for linenoise library - } else { - # Older impl solely for reference while porting... - # - # XXX TARGET_READLINE_LIBS="" - # XXX TARGET_READLINE_INC="" - # XXX TARGET_HAVE_READLINE=0 - # XXX TARGET_HAVE_EDITLINE=0 - if {[opt-bool editline]} { - set with_editline $enableval - } else { - set with_editline auto - } - if {![opt-bool readline]} { - set with_readline $enableval - } else { - set with_readline auto - } - - # XXX if test x"$with_editline" != xno; then - # XXX sLIBS=$LIBS - # XXX LIBS="" - # XXX TARGET_HAVE_EDITLINE=1 - if {[hwaci-check-function-in-lib readline edit]} { - set with_readline no - } else { - # XXX TARGET_HAVE_EDITLINE=0 - } - # XXX TARGET_READLINE_LIBS=$LIBS - # XXX LIBS=$sLIBS - # XXX fi - # XXX if test x"$with_readline" != xno; then - set found "yes" - - if {[opt-val with-readline-lib] ne {}} { - set withval [lindex [opt-val with-readline-lib] end] - set with_readline_lib $withval - } else { - set with_readline_lib "auto" - } - # XXX if test "x$with_readline_lib" = xauto; then - # XXX save_LIBS="$LIBS" - # XXX LIBS="" - if {[hwaci-check-function-in-lib tgetent readline ncurses curses termcap]} { - # XXX term_LIBS="$LIBS" - } else { - # XXX term_LIBS="" - } - if {[hwaci-check-function-in-lib readline readline]} { - # XXX TARGET_READLINE_LIBS="-lreadline" - } else { - set found "no" - } - # XXX TARGET_READLINE_LIBS="$TARGET_READLINE_LIBS $term_LIBS" - # XXX LIBS="$save_LIBS" - # XXX else - # XXX TARGET_READLINE_LIBS="$with_readline_lib" - # XXX fi - - if {[opt-val with-readline-inc] ne {}} { - set withval [lindex [opt-val with-readline-inc] end] - set with_readline_inc $withval - } else { - set with_readline_inc "auto" - } - # XXX if test "x$with_readline_inc" = xauto; then - if {[cc-check-includes readline.h]} { - set found "yes" - } else { - set found "no" - # XXX if test "$cross_compiling" != yes; then - # XXX for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do - # XXX for subdir in include include/readline; do - # XXX AC_CHECK_FILE $dir/$subdir/readline.h found=yes - # XXX if test "$found" = "yes"; then - # XXX TARGET_READLINE_INC="-I$dir/$subdir" - # XXX break - # XXX fi - # XXX done - # XXX test "$found" = "yes" && break - # XXX done - # XXX fi - } - # XXX else - # XXX TARGET_READLINE_INC="$with_readline_inc" - # XXX fi - - # XXX if test x"$found" = xno; then - # XXX TARGET_READLINE_LIBS="" - # XXX TARGET_READLINE_INC="" - # XXX TARGET_HAVE_READLINE=0 - # XXX else - # XXX TARGET_HAVE_READLINE=1 - # XXX fi - # XXX fi - if {[opt-val with-linenoise] ne {}} { - set withval [lindex [opt-val with-linenoise] end] - set with_linenoise $withval - } else { - set with_linenoise "no" - } - # XXX if test "x$with_linenoise" != "xno"; then - # XXX TARGET_HAVE_READLINE=0 - # XXX TARGET_HAVE_EDITLINE=0 - # XXX TARGET_HAVE_LINENOISE=1 - # XXX TARGET_READLINE_INC="-I${with_linenoise}" - # XXX TARGET_READLINE_LIBS="${with_linenoise}/linenoise.c" - # XXX echo "using linenoise source code at ${with_linenoise}" - # XXX else - # XXX TARGET_HAVE_LINENOISE=0 - # XXX echo "not using linenoise" - # XXX fi - - # XXX AC_SUBST TARGET_READLINE_LIBS - # XXX AC_SUBST TARGET_READLINE_INC - # XXX AC_SUBST TARGET_HAVE_READLINE - # XXX AC_SUBST TARGET_HAVE_EDITLINE - # XXX AC_SUBST TARGET_HAVE_LINENOISE + user-notice "Using client-provided readline flags: $fC $fL" + return "readline" } -}; # hwaci-check-readline2 -hwaci-check-readline2 + + # Try the project-agnostic readline detector: + set v [hwaci-check-readline] + add-shell-opt -DHAVE_READLINE=$v + if {$v} { return "readline" } + # TODO: reimplement: + # --enable-editline + # --with-readline-lib specify readline library + # --with-readline-inc specify readline include paths + # --with-linenoise=DIR source directory for linenoise library + return "none" +}; # hwaci-check-line-editing +msg-checking "Line-editing support for the sqlite3 shell: " +msg-result [hwaci-check-line-editing] hwaci-if-opt-truthy load-extension { if {[hwaci-check-function-in-lib dlopen dl]} { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index ef94792639..1d5912a7e2 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -706,9 +706,16 @@ proc hwaci-check-rpath {} { } ######################################################################## -# Under construction - check for libreadline functionality. Linking -# in readline varies wildly by platform and this check does not cover -# all known options. +# Check for libreadline functionality. Linking in readline varies +# wildly by platform and this check does not cover all known options. +# This detection is known to fail when none of the following +# conditions can be met: +# +# - (pkg-config readline) info is either unavailable for libreadline or +# simply misbehaves. +# +# - Compile-and-link-with-default-path tests fail. This will fail for +# platforms which store readline under, e.g., /usr/locall # # Defines the following vars: # @@ -747,8 +754,10 @@ proc hwaci-check-readline {} { # $ pkg-config --print-requires readline; echo $? # 1 # - # i.e. there's apparently no way to find out that readline - # requires termcap beyond parsing the error message. + # i.e. there's apparently no way to find out that readline requires + # termcap beyond parsing the error message. It turns out it doesn't + # want termcap, it wants -lcurses, but we don't get that info from + # pkg-config either. set h "readline/readline.h" if {[cc-check-includes $h]} { @@ -764,11 +773,11 @@ proc hwaci-check-readline {} { # -I...] } # Numerous TODOs: - # - Requires linking with ncurses or similar on some platforms. + # - Requires linking with [n]curses or similar on some platforms. # - Headers are in a weird place on some BSD systems. # - Add --with-readline=DIR - # - Add --with-readline-lib=lib file - # - Add --with-readline-inc=dir -Idir + # - Add --with-readline-lib=lib ==> pass lib file via LDFLAGS_READLINE + # - Add --with-readline-inc=dir ==> pass -Idir via CFLAGS_READLINE msg-result "libreadline not found." return 0 } diff --git a/main.mk b/main.mk index c517dc0da2..7b2155f24e 100644 --- a/main.mk +++ b/main.mk @@ -146,7 +146,7 @@ LDFLAGS.readline ?= -lreadline # these vary wildly across platforms CFLAGS.readline ?= -I$(prefix)/include/readline # ^^^ When using linenoise instead of readline, do something like: # SHELL_OPT += -DHAVE_LINENOISE -# CFLAGS.readline = $(HOME)/linenoise $(HOME)/linenoise/linenoise.c +# CFLAGS.readline = -I$(HOME)/linenoise $(HOME)/linenoise/linenoise.c # LDFLAGS.readline = # empty # diff --git a/manifest b/manifest index 0134524d1f..6a24c5cb8b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sinstall-lib\smakefile\sdep\sfrom\sinstall-tcl,\sas\sit\sbreaks\snon-root-user\sinvocations\sof\s'make\sinstall-tcl'\swhen\sthe\s--prefix\sis\sleft\sat\sits\sdefault\sand\s--with-tcl\sis\sexplicitly\sprovided. -D 2024-10-26T19:16:18.142 +C Get\s--with-linenoise=DIR\sconfigure\sflag\sworking. +D 2024-10-26T21:51:04.154 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 982231b47cf749449c2c04e85ff9583c68774000a4750db277213ccbf75c75dd +F auto.def 0ed89d2ad8e199017e5a2e14163737b38f0c9f3351a5d94aadeae4e257b38b11 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 80482a8b22b6853546bd36616f2064534a7c1f7b8537a52a8498a0b132f2e8f4 +F autosetup/hwaci-common.tcl 656984306293035db370c8a34030253a860ef42bd168952db8be7e5f8a2f6008 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 857da235f57919c3469efbf89b61060f8f35352c6b97a9dce275f5a35b536007 +F main.mk 39877d7141386ccdbd6fb27968f133cdc6937c38dd8145359faff922d3a1f2e9 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b66076e51bc1601864973be0f3f2b702b51139ed3818f17433fbaa8351119ad6 -R bb71574ad1e7e09ae31e2176eab9b67d +P e7eabfb61f72dc396fab9d0671642f8150cde23aea965c5e77ac3d9ad11c749f +R d65825cd715a121a343a3b84bfbe0e81 U stephan -Z f881b225d548de8ff8557460eb6c70ce +Z 221650a38f381ac274ed56145cfdfb80 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index efe09cac05..762553e524 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7eabfb61f72dc396fab9d0671642f8150cde23aea965c5e77ac3d9ad11c749f +66ce47e5de21c607d2ef1f1e6e639f3c6da132ff3db582e12bd174f7d89d8150 From bad9725a2988d679a3482affe1b4017b90841146 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 02:08:38 +0000 Subject: [PATCH 171/522] Correct sqlite3.pc to represent the library, not the CLI shell. Remove the half-baked an unused READLINE_H config define. Internal tcl doc fixes. FossilOrigin-Name: c8c70353bbdcee20487766f5f03f1638a1c35022bb5f1249141b86d561f1b613 --- auto.def | 10 ---------- autosetup/hwaci-common.tcl | 8 ++------ manifest | 16 ++++++++-------- manifest.uuid | 2 +- sqlite3.pc.in | 2 +- 5 files changed, 12 insertions(+), 26 deletions(-) diff --git a/auto.def b/auto.def index cd10b84f77..806b10e780 100644 --- a/auto.def +++ b/auto.def @@ -756,9 +756,6 @@ if {1} { # # - CFLAGS_READLINE = compilation flags for clients or empty string # -# - READLINE_H = header in the form "<.../readline.h>" IF we can -# figure it out. shell.c does not currently use this. -# # Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to # linenoise or editline, not necessarily libreadline. # @@ -770,7 +767,6 @@ proc hwaci-check-line-editing {} { define HAVE_EDITLINE 0 define LDFLAGS_READLINE "" define CFLAGS_READLINE "" - define READLINE_H "" set check [opt-val with-linenoise] if {"" ne $check} { # Use linenoise... @@ -817,12 +813,6 @@ proc hwaci-check-line-editing {} { set v [file dirname $v] } set fC "-I$v" - # Set READLINE_H to an #include-compatible form of the tail of $v: - set x [opt-val with-readline-header] - set x [string replace $x 0 [string length $v]] - define READLINE_H <$x> - unset x - #hwaci-warn "v=$v READLINE_H=[get-define READLINE_H]" } define LDFLAGS_READLINE $fL define CFLAGS_READLINE $fC diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 1d5912a7e2..df8d57ad2f 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -708,28 +708,25 @@ proc hwaci-check-rpath {} { ######################################################################## # Check for libreadline functionality. Linking in readline varies # wildly by platform and this check does not cover all known options. -# This detection is known to fail when none of the following -# conditions can be met: +# This detection is known to fail under the following conditions: # # - (pkg-config readline) info is either unavailable for libreadline or # simply misbehaves. # # - Compile-and-link-with-default-path tests fail. This will fail for -# platforms which store readline under, e.g., /usr/locall +# platforms which store readline under, e.g., /usr/local. # # Defines the following vars: # # - HAVE_READLINE: 0 or 1 # - LDFLAGS_READLINE: "" or linker flags # - CFLAGS_READLINE: "" or c-flags -# - READLINE_H: "" or "readline/readlin.h" (or similar) # # Returns the value of HAVE_READLINE. proc hwaci-check-readline {} { define HAVE_READLINE 0 define LDFLAGS_READLINE "" define CFLAGS_READLINE "" - define READLINE_H "" if {![opt-bool readline]} { msg-result "libreadline disabled via --disable-readline." return 0 @@ -761,7 +758,6 @@ proc hwaci-check-readline {} { set h "readline/readline.h" if {[cc-check-includes $h]} { - define READLINE_H $h if {[hwaci-check-function-in-lib readline readline]} { msg-result "Enabling libreadline." define HAVE_READLINE 1 diff --git a/manifest b/manifest index 6a24c5cb8b..3cc43cec3c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\s--with-linenoise=DIR\sconfigure\sflag\sworking. -D 2024-10-26T21:51:04.154 +C Correct\ssqlite3.pc\sto\srepresent\sthe\slibrary,\snot\sthe\sCLI\sshell.\sRemove\sthe\shalf-baked\san\sunused\sREADLINE_H\sconfig\sdefine.\sInternal\stcl\sdoc\sfixes. +D 2024-10-27T02:08:38.424 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 0ed89d2ad8e199017e5a2e14163737b38f0c9f3351a5d94aadeae4e257b38b11 +F auto.def a19e0ba4bfdbbf81dbe1fce66929cbc8e9e7d5da6267a7d8e6e4b3ad3c39c160 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 656984306293035db370c8a34030253a860ef42bd168952db8be7e5f8a2f6008 +F autosetup/hwaci-common.tcl dd33af5ee7279956a58254accfb8f86e84d64b153afd69efb8c5dd8937845649 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -717,7 +717,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc -F sqlite3.pc.in da30c8d1a41490e8e3d94c9560ae29b4388b2f7a89de08ff309beea9083a3f20 +F sqlite3.pc.in 02db2fa13bcfb301bf8af5ab06984bed583e78a678a557902726eada3bbb7ff1 F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e7eabfb61f72dc396fab9d0671642f8150cde23aea965c5e77ac3d9ad11c749f -R d65825cd715a121a343a3b84bfbe0e81 +P 66ce47e5de21c607d2ef1f1e6e639f3c6da132ff3db582e12bd174f7d89d8150 +R 0e289bbefd4920bbc9b70aa875271ce3 U stephan -Z 221650a38f381ac274ed56145cfdfb80 +Z 899f1a2fde401493358ac6e1ddbf0e16 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 762553e524..85f85a473a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -66ce47e5de21c607d2ef1f1e6e639f3c6da132ff3db582e12bd174f7d89d8150 +c8c70353bbdcee20487766f5f03f1638a1c35022bb5f1249141b86d561f1b613 diff --git a/sqlite3.pc.in b/sqlite3.pc.in index 68c09475e7..73d65dea23 100644 --- a/sqlite3.pc.in +++ b/sqlite3.pc.in @@ -9,5 +9,5 @@ Name: SQLite Description: SQL database engine Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lsqlite3 -Libs.private: @LDFLAGS_READLINE@ +Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ZLIB@ Cflags: -I${includedir} From 66fee051a646863e18eea8eeac3e8bc52e318fc4 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 02:27:07 +0000 Subject: [PATCH 172/522] Rename --with-readline-ldflags/cflags to --with-readline-lib/inc because it turns out that ldflags/cflags have (when passed an explicit value) the same semantics the legacy lib/inc flags. Still to-fix is that the no-flag-given readline search behavior differs, and is much more limited, from the legacy configure behavior. FossilOrigin-Name: 8f6897b92c6a059f1c658ccce5bdc9ff3d29b41eec8298c6d46c7aeabace1d89 --- auto.def | 20 ++++++++++---------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/auto.def b/auto.def index 806b10e780..7e3ff26f83 100644 --- a/auto.def +++ b/auto.def @@ -165,9 +165,12 @@ set flags { readline=1 => {Disable readline support} largefile=1 => {Disable large file support} shared=1 => {Disable build of shared libary} - with-readline-ldflags:LDFLAGS => {Readline LDFLAGS, e.g. -lreadline -lncurses} - with-readline-cflags:CFLAGS => {Readline CFLAGS, e.g. -I/path/to/includes} - with-readline-header:PATH => {Full path to readline.h, from which --with-readline-cflags will be derived.} + with-readline-lib:LDFLAGS + => {Readline LDFLAGS, e.g. -lreadline -lncurses} + with-readline-inc:CFLAGS + => {Readline CFLAGS, e.g. -I/path/to/includes} + with-readline-header:PATH + => {Full path to readline.h, from which --with-readline-inc will be derived.} with-linenoise:DIR => {Source directory for linenoise.c and linenoise.h} amalgamation=1 => {Disable the amalgamation and instead build all files separately} load-extension=1 => {Disable loading of external extensions} @@ -793,14 +796,14 @@ proc hwaci-check-line-editing {} { user-notice "Readline support explicitly disabled with --disable-readline." return "none" } - set check [opt-val with-readline-ldflags][opt-val with-readline-cflags][opt-val with-readline-header] + set check [opt-val with-readline-lib][opt-val with-readline-inc] if {"" ne $check} { - # If any one of --with-readline-(ldflags|cflags|header) are provided, + # If any one of --with-readline-(lib|inc|header) are provided, # those trump any automated searching. - set fL [join [opt-val with-readline-ldflags]] + set fL [join [opt-val with-readline-lib]] set v [opt-val with-readline-header] if {"" eq $v} { - set fC [join [opt-val with-readline-cflags]] + set fC [join [opt-val with-readline-inc]] } else { # Derive CFLAGS from header file name set v [file dirname $v] @@ -828,9 +831,6 @@ proc hwaci-check-line-editing {} { if {$v} { return "readline" } # TODO: reimplement: # --enable-editline - # --with-readline-lib specify readline library - # --with-readline-inc specify readline include paths - # --with-linenoise=DIR source directory for linenoise library return "none" }; # hwaci-check-line-editing msg-checking "Line-editing support for the sqlite3 shell: " diff --git a/manifest b/manifest index 3cc43cec3c..f1d605b04c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\ssqlite3.pc\sto\srepresent\sthe\slibrary,\snot\sthe\sCLI\sshell.\sRemove\sthe\shalf-baked\san\sunused\sREADLINE_H\sconfig\sdefine.\sInternal\stcl\sdoc\sfixes. -D 2024-10-27T02:08:38.424 +C Rename\s--with-readline-ldflags/cflags\sto\s--with-readline-lib/inc\sbecause\sit\sturns\sout\sthat\sldflags/cflags\shave\s(when\spassed\san\sexplicit\svalue)\sthe\ssame\ssemantics\sthe\slegacy\slib/inc\sflags.\sStill\sto-fix\sis\sthat\sthe\sno-flag-given\sreadline\ssearch\sbehavior\sdiffers,\sand\sis\smuch\smore\slimited,\sfrom\sthe\slegacy\sconfigure\sbehavior. +D 2024-10-27T02:27:07.440 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a19e0ba4bfdbbf81dbe1fce66929cbc8e9e7d5da6267a7d8e6e4b3ad3c39c160 +F auto.def 7846fe16d52eb941504bf7335a876c5a3c6e35f9eef2330e3137cf65b8cac3c2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 66ce47e5de21c607d2ef1f1e6e639f3c6da132ff3db582e12bd174f7d89d8150 -R 0e289bbefd4920bbc9b70aa875271ce3 +P c8c70353bbdcee20487766f5f03f1638a1c35022bb5f1249141b86d561f1b613 +R aee97201b742768a8a881df4101db095 U stephan -Z 899f1a2fde401493358ac6e1ddbf0e16 +Z c7373ae669f742e7f6e85074f4e952ce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 85f85a473a..155d7ae947 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8c70353bbdcee20487766f5f03f1638a1c35022bb5f1249141b86d561f1b613 +8f6897b92c6a059f1c658ccce5bdc9ff3d29b41eec8298c6d46c7aeabace1d89 From ac1f151796f5a247e72e72405033d41cef6b774a Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 04:27:47 +0000 Subject: [PATCH 173/522] Bring the automated readline detection up to parity with the legacy configure script. FossilOrigin-Name: 2ddeb7a8f55735cc7f2cf95cbbb0b20c563ced87db1429816fcfb0ee89e751f0 --- auto.def | 109 ++++++++++++++++++++++++------------- autosetup/hwaci-common.tcl | 109 ++++++++++++++++++++++++++++++------- manifest | 14 ++--- manifest.uuid | 2 +- 4 files changed, 170 insertions(+), 64 deletions(-) diff --git a/auto.def b/auto.def index 7e3ff26f83..2430200f2d 100644 --- a/auto.def +++ b/auto.def @@ -17,12 +17,11 @@ use cc cc-db cc-shared cc-lib hwaci-common pkg-config # Are we cross-compiling? -set cross_compiling 0 -if {[get-define host] ne [get-define build]} { - set cross_compiling 1 -} elseif {1 - && "nope" eq [get-env CC_FOR_BUILD "nope"] - && [get-define CC] ne [get-define CC_FOR_BUILD]} { +set cross_compiling [hwaci-is-cross-compiling] +if {0 + && !$cross_compiling + && "nope" eq [get-env CC_FOR_BUILD "nope"] + && [get-define CC] ne [get-define CC_FOR_BUILD]} { # Arguable/debatable... # # When _not_ cross-compiling and CC_FOR_BUILD is _not_ explcitely @@ -170,7 +169,7 @@ set flags { with-readline-inc:CFLAGS => {Readline CFLAGS, e.g. -I/path/to/includes} with-readline-header:PATH - => {Full path to readline.h, from which --with-readline-inc will be derived.} + => {Full path to readline.h, from which --with-readline-inc will be derived} with-linenoise:DIR => {Source directory for linenoise.c and linenoise.h} amalgamation=1 => {Disable the amalgamation and instead build all files separately} load-extension=1 => {Disable loading of external extensions} @@ -748,7 +747,7 @@ if {1} { } ######################################################################## -# hwaci-check-line-editing jumps through proverbial hoops to try to +# sqlite-check-line-editing jumps through proverbial hoops to try to # find a working line-editing library, setting: # # - HAVE_READLINE to 0 or 1 @@ -764,7 +763,7 @@ if {1} { # # Returns a string describing which line-editing approach to use, or # "none" if no option is available. -proc hwaci-check-line-editing {} { +proc sqlite-check-line-editing {} { define HAVE_READLINE 0 define HAVE_LINENOISE 0 define HAVE_EDITLINE 0 @@ -776,11 +775,9 @@ proc hwaci-check-line-editing {} { set dirLn $check if {![file isdir $dirLn]} { hwaci-fatal "--with-linenoise value is not a directory" - } - if {![file exists $dirLn/linenoise.c] } { + } elseif {![file exists $dirLn/linenoise.c] } { hwaci-fatal "Cannot find linenoise.c in $dirLn" - } - if {![file exists $dirLn/linenoise.h] } { + } elseif {![file exists $dirLn/linenoise.h] } { hwaci-fatal "Cannot find linenoise.h in $dirLn" } user-notice "Using linenoise from $dirLn" @@ -789,23 +786,21 @@ proc hwaci-check-line-editing {} { add-shell-opt -DHAVE_LINENOISE=1 return "linenoise" } elseif {[opt-bool editline]} { - # Use editline... + # TODO: reimplement --enable-editline user-notice "WARNING: the --enable-editline flag is not yet supported" return "none" } elseif {![opt-bool readline]} { - user-notice "Readline support explicitly disabled with --disable-readline." + user-notice "Readline support explicitly disabled with --disable-readline" return "none" } - set check [opt-val with-readline-lib][opt-val with-readline-inc] - if {"" ne $check} { - # If any one of --with-readline-(lib|inc|header) are provided, - # those trump any automated searching. - set fL [join [opt-val with-readline-lib]] - set v [opt-val with-readline-header] - if {"" eq $v} { - set fC [join [opt-val with-readline-inc]] + + # Transform with-readline-header=X to with-readline-inc=-I... + set v [opt-val with-readline-header] + hwaci-opt-set with-readline-header "" + if {"" ne $v} { + if {"auto" eq $v} { + hwaci-opt-set with-readline-inc auto } else { - # Derive CFLAGS from header file name set v [file dirname $v] if {[string match */*line $v]} { # Special case: if the path includes .../*line/readline.h", set @@ -815,26 +810,66 @@ proc hwaci-check-line-editing {} { # work! set v [file dirname $v] } - set fC "-I$v" + hwaci-opt-set with-readline-inc "-I$v" } - define LDFLAGS_READLINE $fL - define CFLAGS_READLINE $fC + } + + # Look for readline.h + set rlInc [opt-val with-readline-inc auto] + if {"auto" eq $rlInc} { + set rlInc "" + if {!$::cross_compiling} { + # ^^^ this check is derived from the legacy configure script + set rlInc [hwaci-search-for-header-dir readline.h \ + -dirs {/usr /usr/local /usr/local/readline /usr/contrib /mingw} \ + -subdirs {include/readline include}] + # ^^^ The -dirs and -subdirs lists are from the legacy configure script + if {"" ne $rlInc} { + if {[string match */*line $rlInc]} { + # See notes above for --with-readline-header + set rlInc [file dirname $rlInc] + } + set rlInc "-I${rlInc}" + } + } + } + + # If readline.h was found/specified, look for libreadline... + set rlLib "" + if {"" ne $rlInc} { + set rlLib [opt-val with-readline-lib] + if {"" eq $rlLib || "auto" eq $rlLib} { + set rlLib "" + set libTerm "" + if {[hwaci-check-function-in-lib tgetent {readline ncurses curses termcap}]} { + # ^^^ that libs list comes from the legacy configure script ^^^ + set libTerm [get-define lib_tgetent] + undefine lib_tgetent + } + if {"readline" eq $libTerm} { + set rlLib $libTerm + } elseif {[hwaci-check-function-in-lib readline readline $libTerm]} { + set rlLib [get-define lib_readline] + lappend rlLib $libTerm + undefine lib_readline + } + } + } + + if {"" ne $rlLib} { + set rlLib [join $rlLib] + set rlInc [join $rlInc] + define LDFLAGS_READLINE $rlLib + define CFLAGS_READLINE $rlInc define HAVE_READLINE 1 add-shell-opt -DHAVE_READLINE=1 - user-notice "Using client-provided readline flags: $fC $fL" + user-notice "Using readline flags: $rlInc $rlLib" return "readline" } - # Try the project-agnostic readline detector: - set v [hwaci-check-readline] - add-shell-opt -DHAVE_READLINE=$v - if {$v} { return "readline" } - # TODO: reimplement: - # --enable-editline return "none" -}; # hwaci-check-line-editing -msg-checking "Line-editing support for the sqlite3 shell: " -msg-result [hwaci-check-line-editing] +}; # sqlite-check-line-editing +msg-result "Line-editing support for the sqlite3 shell: [sqlite-check-line-editing]" hwaci-if-opt-truthy load-extension { if {[hwaci-check-function-in-lib dlopen dl]} { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index df8d57ad2f..d77e7a9c46 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -56,6 +56,12 @@ proc hwaci-fatal {msg} { user-error "ERROR: $msg" } +######################################################################## +# Returns 1 if cross-compiling, else 0. +proc hwaci-is-cross-compiling {} { + return [expr {[get-define host] ne [get-define build]}] +} + ######################################################################## # hwaci-lshift_ shifts $count elements from the list named $listVar # and returns them as a new list. On empty input, returns "". @@ -88,6 +94,37 @@ proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { return $found } +######################################################################## +# Searches for $header in a combination of dirs and subdirs, specified +# by the -dirs {LIST} and -subdirs {LIST} flags (each of which have +# sane defaults). Returns either the first matching dir or an empty +# string. The return value does not contain the filename part. +proc hwaci-search-for-header-dir {header args} { + set subdirs {include} + set dirs {/usr /usr/local /mingw} +# Debatable: +# if {![hwaci-is-cross-compiling]} { +# lappend dirs [get-define prefix] +# } + while {[llength $args]} { + switch -exact -- [lindex $args 0] { + -dirs { set args [lassign $args - dirs] } + -subdirs { set args [lassign $args - subdirs] } + default { + hwaci-fatal "Unhandled argument: $args" + } + } + } + foreach dir $dirs { + foreach sub $subdirs { + if {[file exists $dir/$sub/$header]} { + return "$dir/$sub" + } + } + } + return "" +} + ######################################################################## # If $v is true, [puts $msg] is called, else puts is not called. #proc hwaci-maybe-verbose {v msg} { @@ -706,15 +743,14 @@ proc hwaci-check-rpath {} { } ######################################################################## -# Check for libreadline functionality. Linking in readline varies +# Check for availability of libreadline. Linking in readline varies # wildly by platform and this check does not cover all known options. # This detection is known to fail under the following conditions: # # - (pkg-config readline) info is either unavailable for libreadline or # simply misbehaves. # -# - Compile-and-link-with-default-path tests fail. This will fail for -# platforms which store readline under, e.g., /usr/local. +# - Either of readline.h or libreadline are in an exotic place. # # Defines the following vars: # @@ -722,6 +758,13 @@ proc hwaci-check-rpath {} { # - LDFLAGS_READLINE: "" or linker flags # - CFLAGS_READLINE: "" or c-flags # +# Quirks: +# +# - If readline.h is found in a directory name matching *line then the +# resulting -I... flag points one directory _up_ from that, under +# the assumption that client-side code will #include +# . +# # Returns the value of HAVE_READLINE. proc hwaci-check-readline {} { define HAVE_READLINE 0 @@ -756,24 +799,52 @@ proc hwaci-check-readline {} { # want termcap, it wants -lcurses, but we don't get that info from # pkg-config either. - set h "readline/readline.h" - if {[cc-check-includes $h]} { - if {[hwaci-check-function-in-lib readline readline]} { - msg-result "Enabling libreadline." - define HAVE_READLINE 1 - define LDFLAGS_READLINE [get-define lib_readline] + # Look for readline.h + set rlInc "" + if {![hwaci-is-cross-compiling]} { + # ^^^ this check is derived from SQLite's legacy configure script + set rlInc [hwaci-search-for-header-dir readline.h \ + -subdirs {include/readline include}] + if {"" ne $rlInc} { + if {[string match */*line $rlInc]} { + # Special case: if the path includes .../*line/readline.h", set + # the -I to one dir up from that because our sources include + # or . Reminder: if + # auto.def is being run by jimsh0 then [file normalize] will not + # work! + set rlInc [file dirname $v] + } + set rlInc "-I${rlInc}" + } + } + + # If readline.h was found/specified, look for libreadline... + set rlLib "" + if {"" ne $rlInc} { + set libTerm "" + if {[hwaci-check-function-in-lib tgetent {readline ncurses curses termcap}]} { + # ^^^ check extracted from an ancient autotools configure script. + set libTerm [get-define lib_tgetent] + undefine lib_tgetent + } + if {"readline" eq $libTerm} { + set rlLib $libTerm + } elseif {[hwaci-check-function-in-lib readline readline $libTerm]} { + set rlLib [get-define lib_readline] + lappend rlLib $libTerm undefine lib_readline - return 1 } - # else TODO: look in various places and [define CFLAGS_READLINE - # -I...] - } - # Numerous TODOs: - # - Requires linking with [n]curses or similar on some platforms. - # - Headers are in a weird place on some BSD systems. - # - Add --with-readline=DIR - # - Add --with-readline-lib=lib ==> pass lib file via LDFLAGS_READLINE - # - Add --with-readline-inc=dir ==> pass -Idir via CFLAGS_READLINE + } + + if {"" ne $rlLib} { + set rlLib [join $rlLib] + define LDFLAGS_READLINE $rlLib + define CFLAGS_READLINE $rlInc + define HAVE_READLINE 1 + msg-result "Using readline with flags: $rlInc $rlLib" + return 1 + } + msg-result "libreadline not found." return 0 } diff --git a/manifest b/manifest index f1d605b04c..3ac69bcff8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\s--with-readline-ldflags/cflags\sto\s--with-readline-lib/inc\sbecause\sit\sturns\sout\sthat\sldflags/cflags\shave\s(when\spassed\san\sexplicit\svalue)\sthe\ssame\ssemantics\sthe\slegacy\slib/inc\sflags.\sStill\sto-fix\sis\sthat\sthe\sno-flag-given\sreadline\ssearch\sbehavior\sdiffers,\sand\sis\smuch\smore\slimited,\sfrom\sthe\slegacy\sconfigure\sbehavior. -D 2024-10-27T02:27:07.440 +C Bring\sthe\sautomated\sreadline\sdetection\sup\sto\sparity\swith\sthe\slegacy\sconfigure\sscript. +D 2024-10-27T04:27:47.182 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 7846fe16d52eb941504bf7335a876c5a3c6e35f9eef2330e3137cf65b8cac3c2 +F auto.def aba9d4d29eb7fd5a5bda791d338bf5a32e205d1164af8c9d579bb1b4083ad25d F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl dd33af5ee7279956a58254accfb8f86e84d64b153afd69efb8c5dd8937845649 +F autosetup/hwaci-common.tcl a4276230b1c510b2a283fcaa59424a3ba77eafc441e7761286f55e3b2d155064 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c8c70353bbdcee20487766f5f03f1638a1c35022bb5f1249141b86d561f1b613 -R aee97201b742768a8a881df4101db095 +P 8f6897b92c6a059f1c658ccce5bdc9ff3d29b41eec8298c6d46c7aeabace1d89 +R f0582379bec537e3414c67bad5681477 U stephan -Z c7373ae669f742e7f6e85074f4e952ce +Z cffd0ba4388e6bcce9ac7e976789ab0c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 155d7ae947..7ad8783093 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f6897b92c6a059f1c658ccce5bdc9ff3d29b41eec8298c6d46c7aeabace1d89 +2ddeb7a8f55735cc7f2cf95cbbb0b20c563ced87db1429816fcfb0ee89e751f0 From c9f16f656283de2b3fc61f24e039ba97dd4720f3 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 05:28:52 +0000 Subject: [PATCH 174/522] configure: document why --enable-editline does not work and emit a warning with a potential alternative/workaround if it's used. Various cosmetic cleanups. FossilOrigin-Name: ccb8f16f8a5c500b683800672aa4bc87d2f109e87ebdabf6c54d5b6dc69718f7 --- auto.def | 59 ++++++++++++++++++++++++++------------ autosetup/hwaci-common.tcl | 17 +++++++++-- manifest | 14 ++++----- manifest.uuid | 2 +- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/auto.def b/auto.def index 2430200f2d..c4e587b9db 100644 --- a/auto.def +++ b/auto.def @@ -462,7 +462,7 @@ hwaci-if-opt-truthy with-debug { ######################################################################## # TCL... # -# hwaci-check-tcl performs most of the --with-tcl and --with-tclsh +# sqlite-check-tcl performs most of the --with-tcl and --with-tclsh # handling. Some related bits and pieces are performed before and # after that function is called. # @@ -489,7 +489,7 @@ hwaci-if-opt-truthy with-debug { # components. # define TCLSH_CMD {exit 1} -proc hwaci-check-tcl {} { +proc sqlite-check-tcl {} { # TODO: document the steps this is taking. global top_srcdir puts "Checking for a suitable tcl... " @@ -497,13 +497,13 @@ proc hwaci-check-tcl {} { set use_tcl $optTcl set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] - #puts "hwaci-check-tcl: use_tcl ${use_tcl}" - #puts "hwaci-check-tcl: with_tclsh=${with_tclsh}" - #puts "hwaci-check-tcl: with_tcl=$with_tcl" + #puts "sqlite-check-tcl: use_tcl ${use_tcl}" + #puts "sqlite-check-tcl: with_tclsh=${with_tclsh}" + #puts "sqlite-check-tcl: with_tcl=$with_tcl" if {"" eq $with_tclsh && "" eq $with_tcl} { set with_tclsh [hwaci-first-bin-of tclsh9.0 tclsh8.6 tclsh] } - #puts "hwaci-check-tcl: with_tclsh=${with_tclsh}" + #puts "sqlite-check-tcl: with_tclsh=${with_tclsh}" if {"" ne $with_tclsh} { if {![file isfile $with_tclsh]} { @@ -561,11 +561,11 @@ proc hwaci-check-tcl {} { } } if {![file readable $cfg]} { - hwaci-warn { - Cannot find a usable tclConfig.sh file. - Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. - SQLite does not use TCL internally, but TCL is required to build SQLite - from canonical sources and TCL is required for testing. + hwaci-indented-notice { + WARNING: Cannot find a usable tclConfig.sh file. Use + --with-tcl=DIR to specify a directory where tclConfig.sh + can be found. SQLite does not use TCL internally, but TCL + is required for testing. } break } @@ -587,10 +587,6 @@ proc hwaci-check-tcl {} { # config is not available, this emits empty-string entries for the # various options we're interested in. eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]"] - #puts "hwaci-check-tcl: with_tclsh=$with_tclsh" - #puts "hwaci-check-tcl: with_tcl=$with_tcl" - #puts "hwaci-check-tcl: cfg=$cfg" - #puts "hwaci-check-tcl: use_tcl ${use_tcl}" if {"" eq $with_tclsh} { set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] @@ -646,9 +642,9 @@ proc hwaci-check-tcl {} { } else { hwaci-warn "Cannot find a usable tclsh, so cannot run tests." } -}; # hwaci-check-tcl +}; # sqlite-check-tcl -hwaci-check-tcl +sqlite-check-tcl ######################################################################## # Check which TCL to use as a code generator. Prefer jimsh simply @@ -754,6 +750,8 @@ if {1} { # - HAVE_LINENOISE to 0 or 1 # - HAVE_EDITLINE to 0 or 1 # +# Only one of ^^^ those will be set to 1. +# # - LDFLAGS_READLINE = linker flags or empty string # # - CFLAGS_READLINE = compilation flags for clients or empty string @@ -786,8 +784,31 @@ proc sqlite-check-line-editing {} { add-shell-opt -DHAVE_LINENOISE=1 return "linenoise" } elseif {[opt-bool editline]} { - # TODO: reimplement --enable-editline - user-notice "WARNING: the --enable-editline flag is not yet supported" + # --enable-editline. The problem is finding a system which has it + # available to test on. The man pages for it on OpenBSD do not + # match how shell.c uses it. OpenBSD has a lib named libedit but + # no headers to go with it. The legacy configure script looked for + # readline() in libedit (and libedit.a indeed has the + # readline/history functions used by shell.c) but shell.c expects + # to find when HAVE_EDITLINE=1, and that + # file is nowhere to be found. + # + # However, a workaround which works on the available systems is: + # + # --with-readline-lib=-ledit + # + # And then let it detect readline.h. We "could" re-map + # --enable-editline to do exactly that but it seems likely to + # break on systems for which which HAVE_EDITLINE=1 previously + # worked. + hwaci-indented-notice { + WARNING: the --enable-editline flag is not supported due to + non-availability of systems which have it in a form which the + sqlite3 CLI shell expects to see. On some systems this can be + worked around by passing --with-readline-lib=-ledit instead of + --enable-editline, which will attempt to use the readline.h + supplied by libreadline but link against -ledit. + } return "none" } elseif {![opt-bool readline]} { user-notice "Readline support explicitly disabled with --disable-readline" diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index d77e7a9c46..f7ff89f3a3 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -49,13 +49,24 @@ array set hwaci_ {} proc hwaci-warn {msg} { puts stderr "WARNING: $msg" } -proc hwaci-notice {msg} { - puts stderr "NOTICE: $msg" -} +#proc hwaci-notice {msg} { +# puts stderr "NOTICE: $msg" +#} proc hwaci-fatal {msg} { user-error "ERROR: $msg" } +######################################################################## +# Takes a multi-line message and emits it with consistent indentation +# using user-notice (which means its rendering will be delayed until +# the next time autosetup goes to output a message). +proc hwaci-indented-notice {msg} { + set lines [split $msg \n] + foreach line $lines { + user-notice " [string trim $line]" + } +} + ######################################################################## # Returns 1 if cross-compiling, else 0. proc hwaci-is-cross-compiling {} { diff --git a/manifest b/manifest index 3ac69bcff8..9d04c8ab88 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bring\sthe\sautomated\sreadline\sdetection\sup\sto\sparity\swith\sthe\slegacy\sconfigure\sscript. -D 2024-10-27T04:27:47.182 +C configure:\sdocument\swhy\s--enable-editline\sdoes\snot\swork\sand\semit\sa\swarning\swith\sa\spotential\salternative/workaround\sif\sit's\sused.\sVarious\scosmetic\scleanups. +D 2024-10-27T05:28:52.488 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def aba9d4d29eb7fd5a5bda791d338bf5a32e205d1164af8c9d579bb1b4083ad25d +F auto.def dbd0ab35f0c01b421e53e851cbc6117913d60a4eeea2b75af24a1647838242ee F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl a4276230b1c510b2a283fcaa59424a3ba77eafc441e7761286f55e3b2d155064 +F autosetup/hwaci-common.tcl 247f02d8c92999c0e76e033371c7dd41fee326e70de0251044d00b75562b0a3a F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8f6897b92c6a059f1c658ccce5bdc9ff3d29b41eec8298c6d46c7aeabace1d89 -R f0582379bec537e3414c67bad5681477 +P 2ddeb7a8f55735cc7f2cf95cbbb0b20c563ced87db1429816fcfb0ee89e751f0 +R 4970824a6410e0a6a11b4742e70c246f U stephan -Z cffd0ba4388e6bcce9ac7e976789ab0c +Z bb06d38a89ea42c462deaf8c72e8eb99 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7ad8783093..3b96464b9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ddeb7a8f55735cc7f2cf95cbbb0b20c563ced87db1429816fcfb0ee89e751f0 +ccb8f16f8a5c500b683800672aa4bc87d2f109e87ebdabf6c54d5b6dc69718f7 From 68b0e8db05af152f23ff1cf4cd8f762e31421470 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 06:03:27 +0000 Subject: [PATCH 175/522] Makefile.in: include CPPFLAGS in the CFLAGS, as the legacy Makefile.in did, because some downstream scripts rely on that. Remove a duplicated TCLLIBDIR assignment. FossilOrigin-Name: 8e352f4199e048030113e0cc359eaadb6d29bc4b3dd7a0442d7500f7c3847e50 --- Makefile.in | 10 ++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2556c8c709..b1a5840854 100644 --- a/Makefile.in +++ b/Makefile.in @@ -97,7 +97,7 @@ AR.flags = cr # TODO? Add a configure test to determine this? CC = @CC@ B.cc = @BUILD_CC@ @BUILD_CFLAGS@ T.cc = @CC@ -CFLAGS = @CFLAGS@ @SH_CFLAGS@ +CFLAGS = @CPPFLAGS@ @CFLAGS@ @SH_CFLAGS@ LDFLAGS.shobj = @SHOBJ_LDFLAGS@ LDFLAGS.zlib = @LDFLAGS_ZLIB@ @@ -200,6 +200,9 @@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@ TCL_VERSION = @TCL_VERSION@ TCLLIB_RPATH = @TCLLIB_RPATH@ +# +# Where do we want to install the tcl plugin +# TCLLIBDIR = @TCLLIBDIR@ # @@ -208,11 +211,6 @@ TCLLIBDIR = @TCLLIBDIR@ # TSTRNNR_OPTS = @TSTRNNR_OPTS@ -# -# Where do we want to install the tcl plugin -# -TCLLIBDIR = @TCLLIBDIR@ - # # If gcov support was enabled by the configure script, add the appropriate # flags here. It's not always as easy as just having the user add the right diff --git a/manifest b/manifest index 9d04c8ab88..ecbd5b4d19 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C configure:\sdocument\swhy\s--enable-editline\sdoes\snot\swork\sand\semit\sa\swarning\swith\sa\spotential\salternative/workaround\sif\sit's\sused.\sVarious\scosmetic\scleanups. -D 2024-10-27T05:28:52.488 +C Makefile.in:\sinclude\sCPPFLAGS\sin\sthe\sCFLAGS,\sas\sthe\slegacy\sMakefile.in\sdid,\sbecause\ssome\sdownstream\sscripts\srely\son\sthat.\sRemove\sa\sduplicated\sTCLLIBDIR\sassignment. +D 2024-10-27T06:03:27.496 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 -F Makefile.in e880d287a3233a5352b3e260ff9b44baa9388070ba033ec842bc46e2cebdd11e +F Makefile.in b0f2b40be5273a8a369af03d4d9a56c5027cd4fc2ee41feddced218dfb6c1e1b F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2ddeb7a8f55735cc7f2cf95cbbb0b20c563ced87db1429816fcfb0ee89e751f0 -R 4970824a6410e0a6a11b4742e70c246f +P ccb8f16f8a5c500b683800672aa4bc87d2f109e87ebdabf6c54d5b6dc69718f7 +R ea34d3fe32036f9e4036fc2d28aa1616 U stephan -Z bb06d38a89ea42c462deaf8c72e8eb99 +Z d899eb4b8c2da605c59f9ecc775c852d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3b96464b9a..c860a994ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ccb8f16f8a5c500b683800672aa4bc87d2f109e87ebdabf6c54d5b6dc69718f7 +8e352f4199e048030113e0cc359eaadb6d29bc4b3dd7a0442d7500f7c3847e50 From e34646b5dc51d51624af2bc163213e4ab90ee23a Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 07:06:03 +0000 Subject: [PATCH 176/522] configure: add --with-icu-lib=LDFLAGS and --enable-icu-collations. Fix auto-reconfigure when flags contain spaces. FossilOrigin-Name: 2a881a2e1b7355c7733c3a41a82290ba6f3983232a9ec378d9a1b62ee4109f54 --- Makefile.in | 1 + auto.def | 81 +++++++++++++++++++++++++++++++++------------------ manifest | 14 ++++----- manifest.uuid | 2 +- 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/Makefile.in b/Makefile.in index b1a5840854..994ec4bc4e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -107,6 +107,7 @@ LDFLAGS.pthread = @LDFLAGS_PTHREAD@ LDFLAGS.dlopen = @LDFLAGS_DLOPEN@ LDFLAGS.readline = @LDFLAGS_READLINE@ CFLAGS.readline = @CFLAGS_READLINE@ +LDFLAGS.icu = @LDFLAGS_ICU@ ENABLE_SHARED = @ENABLE_SHARED@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ diff --git a/auto.def b/auto.def index c4e587b9db..d5f9d2f550 100644 --- a/auto.def +++ b/auto.def @@ -12,8 +12,6 @@ # # JimTCL: https://jim.tcl.tk # - - use cc cc-db cc-shared cc-lib hwaci-common pkg-config # Are we cross-compiling? @@ -171,6 +169,8 @@ set flags { with-readline-header:PATH => {Full path to readline.h, from which --with-readline-inc will be derived} with-linenoise:DIR => {Source directory for linenoise.c and linenoise.h} + with-icu-lib:LDFLAGS => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} + icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-lib=...} amalgamation=1 => {Disable the amalgamation and instead build all files separately} load-extension=1 => {Disable loading of external extensions} math=1 => {Disable math functions} @@ -202,18 +202,22 @@ unset flags set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] -msg-result "srcdir = $srcdir" -msg-result "top_srcdir = $top_srcdir" -set PACKAGE_VERSION [readfile $::autosetup(srcdir)/VERSION] -msg-result "VERSION = $PACKAGE_VERSION" - +set PACKAGE_VERSION [readfile $srcdir/VERSION] define PACKAGE_NAME "sqlite" define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION $PACKAGE_VERSION define PACKAGE_STRING "[get-define PACKAGE_NAME] $PACKAGE_VERSION" define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum -define-append SQLITE_AUTOREMAKE cd $::autosetup(srcdir) && $top_srcdir/configure {*}$::autosetup(argv) +msg-result "srcdir = $srcdir" +msg-result "top_srcdir = $top_srcdir" +msg-result "VERSION = $PACKAGE_VERSION" + +define-append SQLITE_AUTOREMAKE cd '$srcdir' && '$top_srcdir/configure' +#{*}$::autosetup(argv) breaks with --flag='val with spaces', so... +foreach arg $::autosetup(argv) { + define-append SQLITE_AUTOREMAKE '$arg' +} set outOfTreeBuild 0 if {![file exists sqlite3.pc.in]} { @@ -437,6 +441,11 @@ if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { define LDFLAGS_ZLIB "" } +# +# Determine proper rpath-handling flags. +# +hwaci-check-rpath + hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ "Use amalgamation for builds?" @@ -934,6 +943,24 @@ if {![get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} { } unset emccsh +######################################################################## +# ICU +if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-lib ""]]]} { + # Flags sets seen in the wild for ICU: + # {-licui18n -licuuc -licudata} {-licui18n -licuuc} + add-feature-flag -DSQLITE_ENABLE_ICU + msg-result "Enabling ICU support with libs: [get-define LDFLAGS_ICU]" + if {[opt-bool icu-collations]} { + msg-result "Enabling ICU collations." + add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS + } + + # --enable-icu-collations is handled later, along with the other + # --simple-feature-flag options. +} elseif {[opt-bool icu-collations]} { + hwaci-warn "ignoring --enable-icu-collations because --with-icu-lib was not specified" +} + ######################################################################## # Check for log(3) in libm and die with an error if it is not # found. $why should be the feature name which requires that function @@ -964,19 +991,19 @@ foreach {boolFlag featureFlag ifSetEvalThis} { rtree -DSQLITE_ENABLE_RTREE {} session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {} update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {} + memsys5 -DSQLITE_ENABLE_MEMSYS5 {} memsys3 {} { if {[opt-bool memsys5]} { - msg-result "NOT enabling memsys3 because memsys5 is enabled." + hwaci-warn "not enabling memsys3 because memsys5 is enabled." + expr 0 } else { add-feature-flag -DSQLITE_ENABLE_MEMSYS3 } } - memsys5 -DSQLITE_ENABLE_MEMSYS5 {} } { hwaci-if-opt-truthy $boolFlag { add-feature-flag $featureFlag - eval $ifSetEvalThis - if {"all" ne $boolFlag} { + if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} { msg-result "Enabling $boolFlag" } } { @@ -1000,6 +1027,20 @@ foreach {boolFlag featureFlag} { } } +######################################################################### +# Show the final feature flag sets: +set oFF [get-define OPT_FEATURE_FLAGS] +if {"" ne $oFF} { + define OPT_FEATURE_FLAGS [lsort -unique $oFF] + msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]" +} +set oFF [get-define OPT_SHELL] +if {"" ne $oFF} { + define OPT_SHELL [lsort -unique $oFF] + msg-result "Shell options: [get-define OPT_SHELL]" +} +unset oFF + ######################################################################## # Maybe extend JimTCL a bit. As of this writing (2024-09-27) it only # needs (-DHAVE_REALPATH or -DHAVE__FULLPATH) and -DHAVE_DIRENT_H to @@ -1020,10 +1061,6 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available }; # JimTCL -######################################################################## -# Determine proper rpath-handling flags -hwaci-check-rpath - ######################################################################## # Generate the output files. # @@ -1046,18 +1083,6 @@ if {0} { } #TODO hwaci-make-from-dot-in ext/wasm/GNUmakefile -set oFF [get-define OPT_FEATURE_FLAGS] -if {"" ne $oFF} { - define OPT_FEATURE_FLAGS [lsort -unique $oFF] - msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]" -} -set oFF [get-define OPT_SHELL] -if {"" ne $oFF} { - define OPT_SHELL [lsort -unique $oFF] - msg-result "Shell options: [get-define OPT_SHELL]" -} -unset oFF - if {"" ne $DUMP_DEFINES_JSON} { ######################################################################## # Dump config-defines.json... diff --git a/manifest b/manifest index ecbd5b4d19..53dd1cdd5e 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Makefile.in:\sinclude\sCPPFLAGS\sin\sthe\sCFLAGS,\sas\sthe\slegacy\sMakefile.in\sdid,\sbecause\ssome\sdownstream\sscripts\srely\son\sthat.\sRemove\sa\sduplicated\sTCLLIBDIR\sassignment. -D 2024-10-27T06:03:27.496 +C configure:\sadd\s--with-icu-lib=LDFLAGS\sand\s--enable-icu-collations.\sFix\sauto-reconfigure\swhen\sflags\scontain\sspaces. +D 2024-10-27T07:06:03.774 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 -F Makefile.in b0f2b40be5273a8a369af03d4d9a56c5027cd4fc2ee41feddced218dfb6c1e1b +F Makefile.in c9fb22b54d1b9aafba00cc22306286a479e97e498f426414fcc1861486ed2260 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def dbd0ab35f0c01b421e53e851cbc6117913d60a4eeea2b75af24a1647838242ee +F auto.def 376f5bd1f1d88602ce9d964e69ce4df6ec9bfeafcb7988c0cabe8fc06036b450 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ccb8f16f8a5c500b683800672aa4bc87d2f109e87ebdabf6c54d5b6dc69718f7 -R ea34d3fe32036f9e4036fc2d28aa1616 +P 8e352f4199e048030113e0cc359eaadb6d29bc4b3dd7a0442d7500f7c3847e50 +R f3abdd771eb17cd501d5fa951125d236 U stephan -Z d899eb4b8c2da605c59f9ecc775c852d +Z f4577442737993b89d90f014d56548e1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c860a994ca..b059654579 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e352f4199e048030113e0cc359eaadb6d29bc4b3dd7a0442d7500f7c3847e50 +2a881a2e1b7355c7733c3a41a82290ba6f3983232a9ec378d9a1b62ee4109f54 From e2a4ec39218dea9ddc7c549386dafec4f1de1d92 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 08:10:56 +0000 Subject: [PATCH 177/522] Ensure that --disable-tcl is honored. Move LDFLAGS.icu from the CLI shell target to LDFLAGS.libsqlite3. FossilOrigin-Name: 39ce3f6350d811f27e5104e3dd01de2b04ce2a36edcbefd08596b8ca6c6226ff --- auto.def | 8 +++++++- main.mk | 8 ++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/auto.def b/auto.def index d5f9d2f550..e703a276d1 100644 --- a/auto.def +++ b/auto.def @@ -500,8 +500,14 @@ hwaci-if-opt-truthy with-debug { define TCLSH_CMD {exit 1} proc sqlite-check-tcl {} { # TODO: document the steps this is taking. + if {![opt-bool tcl]} { + msg-result "TCL disabled via --disable-tcl" + define HAVE_TCL 0 + return + } + global top_srcdir - puts "Checking for a suitable tcl... " + msg-result "Checking for a suitable tcl... " set optTcl [hwaci-opt-truthy tcl] set use_tcl $optTcl set with_tclsh [opt-val with-tclsh] diff --git a/main.mk b/main.mk index 7b2155f24e..0bb299f0a8 100644 --- a/main.mk +++ b/main.mk @@ -141,11 +141,11 @@ LDFLAGS.dlopen ?= -ldl LDFLAGS.shobj ?= -shared LDFLAGS.icu ?= # -licui18n -licuuc -licudata # libreadline (or a workalike): -# To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE +# To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE=1 LDFLAGS.readline ?= -lreadline # these vary wildly across platforms CFLAGS.readline ?= -I$(prefix)/include/readline # ^^^ When using linenoise instead of readline, do something like: -# SHELL_OPT += -DHAVE_LINENOISE +# SHELL_OPT += -DHAVE_LINENOISE=1 # CFLAGS.readline = -I$(HOME)/linenoise $(HOME)/linenoise/linenoise.c # LDFLAGS.readline = # empty @@ -331,7 +331,7 @@ T.link.shared = $(T.link) $(LDFLAGS.shobj) LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ $(LDFLAGS.math) $(LDFLAGS.dlopen) \ - $(LDFLAGS.zlib) + $(LDFLAGS.zlib) $(LDFLAGS.icu) # # $(install-dir.XYZ) = dirs for installation. @@ -1791,7 +1791,7 @@ sqlite3$(T.exe): shell.c sqlite3.c $(T.link) -o $@ \ shell.c sqlite3.c \ $(CFLAGS.readline) $(SHELL_OPT) \ - $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) $(LDFLAGS.icu) + $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) # # Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the diff --git a/manifest b/manifest index 53dd1cdd5e..f93c6a631f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C configure:\sadd\s--with-icu-lib=LDFLAGS\sand\s--enable-icu-collations.\sFix\sauto-reconfigure\swhen\sflags\scontain\sspaces. -D 2024-10-27T07:06:03.774 +C Ensure\sthat\s--disable-tcl\sis\shonored.\sMove\sLDFLAGS.icu\sfrom\sthe\sCLI\sshell\starget\sto\sLDFLAGS.libsqlite3. +D 2024-10-27T08:10:56.809 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 376f5bd1f1d88602ce9d964e69ce4df6ec9bfeafcb7988c0cabe8fc06036b450 +F auto.def 18ca9a2671add80c3b2b4c9731cf07b117aa548fc3256f1a456675358f2a0212 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 39877d7141386ccdbd6fb27968f133cdc6937c38dd8145359faff922d3a1f2e9 +F main.mk 3848740b1005402b9edc0a75b00dc11f97d1ef5ed545e2eaf4a2e7e38544e596 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8e352f4199e048030113e0cc359eaadb6d29bc4b3dd7a0442d7500f7c3847e50 -R f3abdd771eb17cd501d5fa951125d236 +P 2a881a2e1b7355c7733c3a41a82290ba6f3983232a9ec378d9a1b62ee4109f54 +R 2a289c2467c69f1c5ce59b8bade64652 U stephan -Z f4577442737993b89d90f014d56548e1 +Z c7b47ea7fee87be569801383233f37ef # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b059654579..f374054532 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a881a2e1b7355c7733c3a41a82290ba6f3983232a9ec378d9a1b62ee4109f54 +39ce3f6350d811f27e5104e3dd01de2b04ce2a36edcbefd08596b8ca6c6226ff From b909f23581c8924d303b253ab11f542aef0451de Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 08:29:18 +0000 Subject: [PATCH 178/522] Generic auto.def cleanups. FossilOrigin-Name: 19a5377e608e7ab8fb5733a87ab02a6a69511570c3829e2c1befecc582a6f8ee --- auto.def | 21 +++++++++++---------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/auto.def b/auto.def index e703a276d1..e605d1b158 100644 --- a/auto.def +++ b/auto.def @@ -345,15 +345,13 @@ if {"" eq [hwaci-bin-define install]} { # cross-compiling. define BUILD_CC [get-define CC_FOR_BUILD] define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] -define ENABLE_SHARED [opt-bool shared] -define HAVE_TCL 0 ######################################################################## # Handle --with-wasi-sdk=DIR # # This must be early because it may change the toolchain and disable # several config options. -proc hwaci-check-wasi-sdk {} { +proc sqlite-check-wasi-sdk {} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] define HAVE_WASI_SDK 0 #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" @@ -368,12 +366,11 @@ proc hwaci-check-wasi-sdk {} { msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading" define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir - hwaci-opt-set load-extension 0; # ==> --disable-load-extension - hwaci-opt-set threadsafe 0; # ==> --threadsafe=0 - hwaci-opt-set tcl 0; # ==> --disable-tcl - define HAVE_TCL 0 + hwaci-opt-set load-extension 0 ;# ==> --disable-load-extension + hwaci-opt-set threadsafe 0 ;# ==> --threadsafe=0 + hwaci-opt-set tcl 0 ;# ==> --disable-tcl + hwaci-opt-set shared 0 ;# ==> --disable-shared set cross_compiling 1 - define ENABLE_SHARED 0 # Changing --host and --target have no effect here except to possibly # cause confusion. autoconf has finished processing them by this @@ -391,8 +388,8 @@ proc hwaci-check-wasi-sdk {} { define LD "${wasiSdkDir}/bin/wasm-ld" #define STRIP "${wasiSdkDir}/bin/strip" return 1 -}; # hwaci-check-wasi-sdk -hwaci-check-wasi-sdk +}; # sqlite-check-wasi-sdk +sqlite-check-wasi-sdk # # Enable large file support (if special flags are necessary) @@ -446,6 +443,9 @@ if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { # hwaci-check-rpath +hwaci-define-if-opt-truthy shared ENABLE_SHARED \ + "Build shared library?" + hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ "Use amalgamation for builds?" @@ -498,6 +498,7 @@ hwaci-if-opt-truthy with-debug { # components. # define TCLSH_CMD {exit 1} +define HAVE_TCL [opt-bool tcl] proc sqlite-check-tcl {} { # TODO: document the steps this is taking. if {![opt-bool tcl]} { diff --git a/manifest b/manifest index f93c6a631f..9e4b351c9f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\s--disable-tcl\sis\shonored.\sMove\sLDFLAGS.icu\sfrom\sthe\sCLI\sshell\starget\sto\sLDFLAGS.libsqlite3. -D 2024-10-27T08:10:56.809 +C Generic\sauto.def\scleanups. +D 2024-10-27T08:29:18.130 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 18ca9a2671add80c3b2b4c9731cf07b117aa548fc3256f1a456675358f2a0212 +F auto.def 609cdc6d06e1e51ac56477d524e27f741cb88a0bc60d59cda2fbc503f29039a1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2a881a2e1b7355c7733c3a41a82290ba6f3983232a9ec378d9a1b62ee4109f54 -R 2a289c2467c69f1c5ce59b8bade64652 +P 39ce3f6350d811f27e5104e3dd01de2b04ce2a36edcbefd08596b8ca6c6226ff +R 20239e0cf9be7057ef4c04014869eaaa U stephan -Z c7b47ea7fee87be569801383233f37ef +Z dcb9b16969f6593d9a8aab48eccda49c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f374054532..1afc6ef1fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39ce3f6350d811f27e5104e3dd01de2b04ce2a36edcbefd08596b8ca6c6226ff +19a5377e608e7ab8fb5733a87ab02a6a69511570c3829e2c1befecc582a6f8ee From 6c45a5d60e84090e4bd4dcd3b7864ab8573b808d Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 08:52:20 +0000 Subject: [PATCH 179/522] Re-add the --disable-static flag to (mostly) disable static lib build. Some components require the static lib and will trump this preference if they are activated. FossilOrigin-Name: e296cd11a2bd87bffc9c661baea6539c0258b5e9cf3e9bc516f07c758b3e5939 --- Makefile.in | 1 + auto.def | 6 ++++++ main.mk | 16 ++++++++++++++-- manifest | 18 +++++++++--------- manifest.uuid | 2 +- tool/mksqlite3h.tcl | 2 +- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 994ec4bc4e..9bdee26d73 100644 --- a/Makefile.in +++ b/Makefile.in @@ -110,6 +110,7 @@ CFLAGS.readline = @CFLAGS_READLINE@ LDFLAGS.icu = @LDFLAGS_ICU@ ENABLE_SHARED = @ENABLE_SHARED@ +ENABLE_STATIC = @ENABLE_STATIC@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ T.cc.sqlite = $(T.cc) @TARGET_DEBUG@ diff --git a/auto.def b/auto.def index e605d1b158..46acce97bb 100644 --- a/auto.def +++ b/auto.def @@ -162,6 +162,7 @@ set flags { readline=1 => {Disable readline support} largefile=1 => {Disable large file support} shared=1 => {Disable build of shared libary} + static=1 => {Disable build of static library} with-readline-lib:LDFLAGS => {Readline LDFLAGS, e.g. -lreadline -lncurses} with-readline-inc:CFLAGS @@ -446,6 +447,11 @@ hwaci-check-rpath hwaci-define-if-opt-truthy shared ENABLE_SHARED \ "Build shared library?" +if {![hwaci-define-if-opt-truthy static ENABLE_STATIC \ + "Build static library?"]} { + hwaci-warn "static lib build may be implicitly re-activated by other components, e.g. libtclsqlite3." +} + hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ "Use amalgamation for builds?" diff --git a/main.mk b/main.mk index 0bb299f0a8..3b58767c2b 100644 --- a/main.mk +++ b/main.mk @@ -167,6 +167,14 @@ INSTALL ?= install # ENABLE_SHARED ?= 1 # +# $(ENABLE_STATIC) = +# +# 1 if libsqlite3.$(T.lib) should be built. Some components, +# e.g. libtclsqlite3 and some test apps, implicitly require the static +# library and will ignore this preference. +# +ENABLE_STATIC ?= 1 +# # $(USE_AMALGAMATION) # # 1 if the amalgamation (sqlite3.c/h) should be built/used, otherwise @@ -1277,7 +1285,9 @@ sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(B.tclsh) # has_tclsh84 # $(libsqlite3.LIB): $(LIBOBJ) $(AR) $(AR.flags) $@ $(LIBOBJ) -lib: $(libsqlite3.LIB) +$(libsqlite3.LIB)-1: $(libsqlite3.LIB) +$(libsqlite3.LIB)-0 $(libsqlite3.LIB)-: +lib: $(libsqlite3.LIB)-$(ENABLE_STATIC) all: lib # @@ -1351,8 +1361,10 @@ install: install-so # # Install $(libsqlite3.LIB) # -install-lib: $(install-dir.lib) $(libsqlite3.LIB) +install-lib-1: $(install-dir.lib) $(libsqlite3.LIB) $(INSTALL.noexec) $(libsqlite3.LIB) $(install-dir.lib) +install-lib-0 install-lib-: +install-lib: install-lib-$(ENABLE_STATIC) install: install-lib # diff --git a/manifest b/manifest index 9e4b351c9f..5c86bf4e2a 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Generic\sauto.def\scleanups. -D 2024-10-27T08:29:18.130 +C Re-add\sthe\s--disable-static\sflag\sto\s(mostly)\sdisable\sstatic\slib\sbuild.\sSome\scomponents\srequire\sthe\sstatic\slib\sand\swill\strump\sthis\spreference\sif\sthey\sare\sactivated. +D 2024-10-27T08:52:20.817 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 -F Makefile.in c9fb22b54d1b9aafba00cc22306286a479e97e498f426414fcc1861486ed2260 +F Makefile.in 957cbf0d25ced08f6703b82f2070cbea791aeeb2d6059c4426c30cd87c80250f F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 609cdc6d06e1e51ac56477d524e27f741cb88a0bc60d59cda2fbc503f29039a1 +F auto.def 7151bfb1a546622f5f24ecac6524b93e239804c5ee73231c65f2ca9f23ab2995 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 3848740b1005402b9edc0a75b00dc11f97d1ef5ed545e2eaf4a2e7e38544e596 +F main.mk d943a2d0a0deb14daea10e036ef3a55e1b641cd57f5893a2fba29e65cc33acc0 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2167,7 +2167,7 @@ F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b0 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f F tool/mksqlite3c.tcl 98a250d6f2ea60343268e32e2997790e678205ce128aa0d0a67a3f70811615af -F tool/mksqlite3h.tcl 1d996a99cda519e8519e9e514b564fa29b37a49d20263d57494903d685caf067 +F tool/mksqlite3h.tcl 2a6ba8955adf9cfabd0617ee5949760e531e0b75b703b5faf8d1150657b5628f F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c7a27c F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 39ce3f6350d811f27e5104e3dd01de2b04ce2a36edcbefd08596b8ca6c6226ff -R 20239e0cf9be7057ef4c04014869eaaa +P 19a5377e608e7ab8fb5733a87ab02a6a69511570c3829e2c1befecc582a6f8ee +R c734fae877980ad0616908d05f844de0 U stephan -Z dcb9b16969f6593d9a8aab48eccda49c +Z 665a360661ddb1e8c7d2ec84497b82c2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1afc6ef1fb..0f5e7cfdf7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19a5377e608e7ab8fb5733a87ab02a6a69511570c3829e2c1befecc582a6f8ee +e296cd11a2bd87bffc9c661baea6539c0258b5e9cf3e9bc516f07c758b3e5939 diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 8a723f01a6..c02b80044a 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -67,7 +67,7 @@ exec $PWD/mksourceid manifest > $tmpfile set fd [open $tmpfile rb] set zSourceId [string trim [read $fd]] close $fd -#file delete -force $tmpfile +file delete -force $tmpfile cd $PWD # Set up patterns for recognizing API declarations. From 954c02b4147576b9c81ad795ce28e3f7efa0e458 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 09:28:35 +0000 Subject: [PATCH 180/522] Remove some incorrect code comments. FossilOrigin-Name: 6dfda7f5799f5a2448d3bd57fe9422de100bd8f4f9e53e97f73eeb85c3707b0f --- auto.def | 3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/auto.def b/auto.def index 46acce97bb..074e75c10b 100644 --- a/auto.def +++ b/auto.def @@ -967,9 +967,6 @@ if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-lib ""]]]} { msg-result "Enabling ICU collations." add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS } - - # --enable-icu-collations is handled later, along with the other - # --simple-feature-flag options. } elseif {[opt-bool icu-collations]} { hwaci-warn "ignoring --enable-icu-collations because --with-icu-lib was not specified" } diff --git a/manifest b/manifest index 5c86bf4e2a..5c7469809d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Re-add\sthe\s--disable-static\sflag\sto\s(mostly)\sdisable\sstatic\slib\sbuild.\sSome\scomponents\srequire\sthe\sstatic\slib\sand\swill\strump\sthis\spreference\sif\sthey\sare\sactivated. -D 2024-10-27T08:52:20.817 +C Remove\ssome\sincorrect\scode\scomments. +D 2024-10-27T09:28:35.309 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 7151bfb1a546622f5f24ecac6524b93e239804c5ee73231c65f2ca9f23ab2995 +F auto.def fbbacb5a62b32a5d6f831694cca4d429ea58f6f6a7e7d04bdd8918f08e372b89 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 19a5377e608e7ab8fb5733a87ab02a6a69511570c3829e2c1befecc582a6f8ee -R c734fae877980ad0616908d05f844de0 +P e296cd11a2bd87bffc9c661baea6539c0258b5e9cf3e9bc516f07c758b3e5939 +R 5d5ad95200e7c5109af61ebfd07263d7 U stephan -Z 665a360661ddb1e8c7d2ec84497b82c2 +Z 95ea8249ecaf50181ff273c040483fb3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0f5e7cfdf7..96f90f171e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e296cd11a2bd87bffc9c661baea6539c0258b5e9cf3e9bc516f07c758b3e5939 +6dfda7f5799f5a2448d3bd57fe9422de100bd8f4f9e53e97f73eeb85c3707b0f From 5598a3f8da6ccab2a7c24412584677bacff049d0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 27 Oct 2024 10:33:47 +0000 Subject: [PATCH 181/522] Help systems still using Tcl8.6 to compile tclsqlite.c by changing a typedef into a #define. FossilOrigin-Name: 82ab8ff399aafa3a1faec9c85e9d6bdd26636f28f3ea22287999a868bb78db57 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5c7469809d..0803ac4932 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sincorrect\scode\scomments. -D 2024-10-27T09:28:35.309 +C Help\ssystems\sstill\susing\sTcl8.6\sto\scompile\stclsqlite.c\sby\schanging\sa\ntypedef\sinto\sa\s#define. +D 2024-10-27T10:33:47.353 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -797,7 +797,7 @@ F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 47d4bb6eb06aab48d643eeb8c4f65b5fa9529fa5526fdcbf223ea32277ed1b56 -F src/tclsqlite.h 529047feec49e7f463374749147f64d3f17505b0ebd84b3477a364c6f46a9de1 +F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 370668f1832dc7bc2ab0212d807d880b6cdb0d5949550489593ce0cdb4a61012 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e296cd11a2bd87bffc9c661baea6539c0258b5e9cf3e9bc516f07c758b3e5939 -R 5d5ad95200e7c5109af61ebfd07263d7 -U stephan -Z 95ea8249ecaf50181ff273c040483fb3 +P 6dfda7f5799f5a2448d3bd57fe9422de100bd8f4f9e53e97f73eeb85c3707b0f +R acfe37f64308f303e7877171f580928d +U drh +Z 48fd3c7997c1ca83de275f6cc35d4431 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 96f90f171e..554a1a3270 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6dfda7f5799f5a2448d3bd57fe9422de100bd8f4f9e53e97f73eeb85c3707b0f +82ab8ff399aafa3a1faec9c85e9d6bdd26636f28f3ea22287999a868bb78db57 diff --git a/src/tclsqlite.h b/src/tclsqlite.h index 9997e4de26..a9a1262931 100644 --- a/src/tclsqlite.h +++ b/src/tclsqlite.h @@ -36,7 +36,7 @@ #if TCL_MAJOR_VERSION==9 # define CONST const #elif !defined(Tcl_Size) - typedef int Tcl_Size; +# define Tcl_Size int #endif /****** Any edits to this file must mirrored in tclsqlite.c ***********/ From 0064c43a889aeb886b4ad7e3f5ef593ae68ac203 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 27 Oct 2024 10:48:06 +0000 Subject: [PATCH 182/522] Improvements to the PATTERN option of the "testrunner.tcl joblist" command. The pattern match is case insensitive and applies to the state and displaytype in addition to displayname. FossilOrigin-Name: 63a8f60f98115d4ee6e40de3ae775770aba76e19df6ddde68bccb7967b0200dc --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/testrunner.tcl | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0803ac4932..a5433fd4b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Help\ssystems\sstill\susing\sTcl8.6\sto\scompile\stclsqlite.c\sby\schanging\sa\ntypedef\sinto\sa\s#define. -D 2024-10-27T10:33:47.353 +C Improvements\sto\sthe\sPATTERN\soption\sof\sthe\s"testrunner.tcl\sjoblist"\scommand.\nThe\spattern\smatch\sis\scase\sinsensitive\sand\sapplies\sto\sthe\sstate\sand\sdisplaytype\nin\saddition\sto\sdisplayname. +D 2024-10-27T10:48:06.296 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -1736,7 +1736,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 -F test/testrunner.tcl bc1a8d21a1aa3a5cf7c4883cbee4b6748790fe960fad06ca5db74ec914bd6525 x +F test/testrunner.tcl 4e764b0da245add9670d1010a69a3ac5474a5dfe15e1d3183294c23cca43ef13 x F test/testrunner_data.tcl ba4aeea28aa03cfa6fe7e57782ddecb7a7b91c3a0b3251583cb4f0ee002de6a6 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6dfda7f5799f5a2448d3bd57fe9422de100bd8f4f9e53e97f73eeb85c3707b0f -R acfe37f64308f303e7877171f580928d +P 82ab8ff399aafa3a1faec9c85e9d6bdd26636f28f3ea22287999a868bb78db57 +R 0d75fc44cce96c36a84fecce905e5052 U drh -Z 48fd3c7997c1ca83de275f6cc35d4431 +Z 2356ac73b439e525952354a1e2e52d93 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 554a1a3270..85767773f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82ab8ff399aafa3a1faec9c85e9d6bdd26636f28f3ea22287999a868bb78db57 +63a8f60f98115d4ee6e40de3ae775770aba76e19df6ddde68bccb7967b0200dc diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 964465d9b2..09c9f8ac24 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -663,7 +663,9 @@ if {[llength $argv]>=1 set SQL {SELECT displaytype, displayname, state FROM jobs} if {$pattern!=""} { regsub -all {[^a-zA-Z0-9*.-/]} $pattern ? pattern - append SQL " WHERE displayname GLOB '*$pattern*'" + set pattern [string tolower $pattern] + append SQL \ + " WHERE lower(concat(state,' ',displaytype,' ',displayname)) GLOB '*$pattern*'" } append SQL " ORDER BY starttime" From 346f1e0ed94b0afe95c288ad1295268e48af4dc1 Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 27 Oct 2024 15:58:28 +0000 Subject: [PATCH 183/522] Fix test code added by [ba358d26]. FossilOrigin-Name: b7da7980d33e2f2d5d0a4384a43eff39e1a2de4f53b8b4074eea48598a35b9d7 --- ext/fts5/fts5_tcl.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index df4b2daa41..dc5811ce4d 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -1631,7 +1631,7 @@ static int SQLITE_TCLAPI f5tDropCorruptTable( */ void f5tFree(void *p){ char *x = (char *)p; - free(&x[-8]); + ckfree(&x[-8]); } /* @@ -1644,7 +1644,7 @@ void f5tStrFunc(sqlite3_context *pCtx, int nArg, sqlite3_value **apArg){ zText = sqlite3_value_text(apArg[0]); if( zText ){ int nText = sqlite3Strlen30(zText); - char *zCopy = (char*)malloc(nText+8); + char *zCopy = (char*)ckalloc(nText+8); if( zCopy==0 ){ sqlite3_result_error_nomem(pCtx); }else{ diff --git a/manifest b/manifest index a5433fd4b9..5fc5d28931 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sPATTERN\soption\sof\sthe\s"testrunner.tcl\sjoblist"\scommand.\nThe\spattern\smatch\sis\scase\sinsensitive\sand\sapplies\sto\sthe\sstate\sand\sdisplaytype\nin\saddition\sto\sdisplayname. -D 2024-10-27T10:48:06.296 +C Fix\stest\scode\sadded\sby\s[ba358d26]. +D 2024-10-27T15:58:28.881 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -120,7 +120,7 @@ F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6 F ext/fts5/fts5_main.c 50eb059e51d730e8e0c77df4e568b018079e112a755c094488b0d5b1aa06afbb F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c -F ext/fts5/fts5_tcl.c 9b390c318e36c0dc53af14e20198f55aa3ed46a39350ed7f46bc034e422fe778 +F ext/fts5/fts5_tcl.c 055a52c54a72171f0adbdf674e21ee0b36798eeec7b99243913c43d8aa6496a7 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 82ab8ff399aafa3a1faec9c85e9d6bdd26636f28f3ea22287999a868bb78db57 -R 0d75fc44cce96c36a84fecce905e5052 -U drh -Z 2356ac73b439e525952354a1e2e52d93 +P 63a8f60f98115d4ee6e40de3ae775770aba76e19df6ddde68bccb7967b0200dc +R 3f7cd00e3e49e0565ff5c1eb686e6334 +U dan +Z 219db953539c68d8f9036d10ef1d93d0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 85767773f8..46f5a11977 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63a8f60f98115d4ee6e40de3ae775770aba76e19df6ddde68bccb7967b0200dc +b7da7980d33e2f2d5d0a4384a43eff39e1a2de4f53b8b4074eea48598a35b9d7 From 6d05f9af814503db015a83627f3a80a77494c5a2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 27 Oct 2024 16:12:58 +0000 Subject: [PATCH 184/522] Fix build errors in fts5_tcl.c on Mac. FossilOrigin-Name: 133fff8bd79d46f74eeeee677a929b611f3af79cbc492864211e61e2a35846e9 --- ext/fts5/fts5_tcl.c | 5 +++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index dc5811ce4d..dd2ed82c9e 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -21,6 +21,7 @@ #include "fts5.h" #include #include +#include #ifdef SQLITE_DEBUG extern int sqlite3_fts5_may_be_corrupt; @@ -1643,14 +1644,14 @@ void f5tStrFunc(sqlite3_context *pCtx, int nArg, sqlite3_value **apArg){ zText = sqlite3_value_text(apArg[0]); if( zText ){ - int nText = sqlite3Strlen30(zText); + sqlite3_int64 nText = strlen(zText); char *zCopy = (char*)ckalloc(nText+8); if( zCopy==0 ){ sqlite3_result_error_nomem(pCtx); }else{ zCopy += 8; memcpy(zCopy, zText, nText); - sqlite3_result_text(pCtx, zCopy, nText, f5tFree); + sqlite3_result_text64(pCtx, zCopy, nText, f5tFree, SQLITE_UTF8); } } } diff --git a/manifest b/manifest index 5fc5d28931..c5fc4c5b26 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stest\scode\sadded\sby\s[ba358d26]. -D 2024-10-27T15:58:28.881 +C Fix\sbuild\serrors\sin\sfts5_tcl.c\son\sMac. +D 2024-10-27T16:12:58.185 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -120,7 +120,7 @@ F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6 F ext/fts5/fts5_main.c 50eb059e51d730e8e0c77df4e568b018079e112a755c094488b0d5b1aa06afbb F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c -F ext/fts5/fts5_tcl.c 055a52c54a72171f0adbdf674e21ee0b36798eeec7b99243913c43d8aa6496a7 +F ext/fts5/fts5_tcl.c 5b16a249962809b2aaaab964bf58838ea72f30b8b12373cafe612f8cc71e2a40 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 63a8f60f98115d4ee6e40de3ae775770aba76e19df6ddde68bccb7967b0200dc -R 3f7cd00e3e49e0565ff5c1eb686e6334 -U dan -Z 219db953539c68d8f9036d10ef1d93d0 +P b7da7980d33e2f2d5d0a4384a43eff39e1a2de4f53b8b4074eea48598a35b9d7 +R a534ed4b3db6daee016a753585ff9b49 +U drh +Z 8a0f59c10b6f6bb02e3fc54754d114cf # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 46f5a11977..361f79d273 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7da7980d33e2f2d5d0a4384a43eff39e1a2de4f53b8b4074eea48598a35b9d7 +133fff8bd79d46f74eeeee677a929b611f3af79cbc492864211e61e2a35846e9 From 9905e7e22bca3c5ef07d77aed1e09823697d345d Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 18:46:11 +0000 Subject: [PATCH 185/522] When readline is enabled, attempt to determine whether the completion API is compatible and, if it's not, disable it in the shell app. FossilOrigin-Name: 4564dbe4ac0040803b5d139c9fff22a60a45b4769d80ad7c824456cc6b9f1722 --- auto.def | 20 ++++++++++++++++++++ autosetup/hwaci-common.tcl | 2 +- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/shell.c.in | 5 +++-- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/auto.def b/auto.def index 074e75c10b..8b9e71fd23 100644 --- a/auto.def +++ b/auto.def @@ -907,6 +907,26 @@ proc sqlite-check-line-editing {} { define HAVE_READLINE 1 add-shell-opt -DHAVE_READLINE=1 user-notice "Using readline flags: $rlInc $rlLib" + + # Now check whether rl_completion_matches() has a signature we can use. + # cctest is producing unexpected test output when using: + # -includes {stdio.h readline/readline.h} + # so we have to use -source instead and write the whole test app inline + if {[cctest \ + -cflags $rlInc -libs $rlLib -nooutput 1 -source { + #include + #include + static char * rcg(const char *z, int i){return 0;} + int main(void) { + char ** x = rl_completion_matches("one", rcg); + return 0; + } + }]} { + user-notice "Readline completion enabled" + } else { + user-notice "WARNING: readline completion disabled due to rl_completion_matches() signature mismatch" + add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION + } return "readline" } diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index f7ff89f3a3..9c11a21ae5 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -548,7 +548,7 @@ proc hwaci-looks-like-windows {{key host}} { } if {$key eq "build"} { # These apply only to the local OS, not a cross-compilation target, - # as the above check can potentially. + # as the above check potentially can. if {$::autosetup(iswin)} { return 1 } if {[find-an-executable cygpath] ne "" || $::tcl_platform(os)=="Windows NT"} { return 1 diff --git a/manifest b/manifest index c5fc4c5b26..de949837a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sbuild\serrors\sin\sfts5_tcl.c\son\sMac. -D 2024-10-27T16:12:58.185 +C When\sreadline\sis\senabled,\sattempt\sto\sdetermine\swhether\sthe\scompletion\sAPI\sis\scompatible\sand,\sif\sit's\snot,\sdisable\sit\sin\sthe\sshell\sapp. +D 2024-10-27T18:46:11.275 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def fbbacb5a62b32a5d6f831694cca4d429ea58f6f6a7e7d04bdd8918f08e372b89 +F auto.def ec6ba41a7e40137dc0fbff5a9898886a76bba6c3fe88f4b2ffba7ec02ca9cb46 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 247f02d8c92999c0e76e033371c7dd41fee326e70de0251044d00b75562b0a3a +F autosetup/hwaci-common.tcl 0e8643bcacf4fd73be0b194faf21b18a7229dd61347eb204a368fef45a0bee87 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -788,7 +788,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 0662f9bcf0725461778d0254a06150e5d61c08c5a87a7281ccdf45552050c79d +F src/shell.c.in 2fb0947424944f8baa1b4efdfd9eca70dc0691bbc1cb4d283db7fc142937fa3a F src/sqlite.h.in 29fc900a58f394c7488d093fd7a8dcb14d3fa6399d5178cb20adcf88dbedfe39 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b7da7980d33e2f2d5d0a4384a43eff39e1a2de4f53b8b4074eea48598a35b9d7 -R a534ed4b3db6daee016a753585ff9b49 -U drh -Z 8a0f59c10b6f6bb02e3fc54754d114cf +P 133fff8bd79d46f74eeeee677a929b611f3af79cbc492864211e61e2a35846e9 +R 0ec65f180d97227b7302a157e1743b13 +U stephan +Z fda94993ae5f9ecaf502d7e40734c943 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 361f79d273..2a7ae021c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -133fff8bd79d46f74eeeee677a929b611f3af79cbc492864211e61e2a35846e9 +4564dbe4ac0040803b5d139c9fff22a60a45b4769d80ad7c824456cc6b9f1722 diff --git a/src/shell.c.in b/src/shell.c.in index bbf08f8098..df0c3500de 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -5759,7 +5759,8 @@ void close_db(sqlite3 *db){ } } -#if HAVE_READLINE || HAVE_EDITLINE +#if (HAVE_READLINE || HAVE_EDITLINE) \ + && !defined(SQLITE_OMIT_READLINE_COMPLETION) /* ** Readline completion callbacks */ @@ -13259,7 +13260,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } } if( zHistory ){ shell_read_history(zHistory); } -#if HAVE_READLINE || HAVE_EDITLINE +#if (HAVE_READLINE || HAVE_EDITLINE) && !defined(SQLITE_OMIT_READLINE_COMPLETION) rl_attempted_completion_function = readline_completion; #elif HAVE_LINENOISE linenoiseSetCompletionCallback(linenoise_completion, NULL); From 6bb44daae4a7c38a14aeae2ccf886addb5b1aa87 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 19:26:54 +0000 Subject: [PATCH 186/522] When ICU is enabled, ensure that the CLI shell build enables its feature flag and include LDFLAGS_ICU in sqlite3.pc. FossilOrigin-Name: abec913c00564ee5453075f45b1a6680e92ee1b1e61e3b19e4cf74e46785d3bf --- auto.def | 1 + manifest | 14 +++++++------- manifest.uuid | 2 +- sqlite3.pc.in | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index 8b9e71fd23..97ed72569e 100644 --- a/auto.def +++ b/auto.def @@ -982,6 +982,7 @@ if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-lib ""]]]} { # Flags sets seen in the wild for ICU: # {-licui18n -licuuc -licudata} {-licui18n -licuuc} add-feature-flag -DSQLITE_ENABLE_ICU + add-shell-opt -DSQLITE_ENABLE_ICU msg-result "Enabling ICU support with libs: [get-define LDFLAGS_ICU]" if {[opt-bool icu-collations]} { msg-result "Enabling ICU collations." diff --git a/manifest b/manifest index de949837a5..3fbf97aad1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sreadline\sis\senabled,\sattempt\sto\sdetermine\swhether\sthe\scompletion\sAPI\sis\scompatible\sand,\sif\sit's\snot,\sdisable\sit\sin\sthe\sshell\sapp. -D 2024-10-27T18:46:11.275 +C When\sICU\sis\senabled,\sensure\sthat\sthe\sCLI\sshell\sbuild\senables\sits\sfeature\sflag\sand\sinclude\sLDFLAGS_ICU\sin\ssqlite3.pc. +D 2024-10-27T19:26:54.435 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def ec6ba41a7e40137dc0fbff5a9898886a76bba6c3fe88f4b2ffba7ec02ca9cb46 +F auto.def 580df10aeb7d12fb939a5f503cd30d2a5d619ac6bb8e94cd3f3f8b425388da13 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -717,7 +717,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc -F sqlite3.pc.in 02db2fa13bcfb301bf8af5ab06984bed583e78a678a557902726eada3bbb7ff1 +F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 133fff8bd79d46f74eeeee677a929b611f3af79cbc492864211e61e2a35846e9 -R 0ec65f180d97227b7302a157e1743b13 +P 4564dbe4ac0040803b5d139c9fff22a60a45b4769d80ad7c824456cc6b9f1722 +R 862234bfe7dc3dea608ab0b1a9f6ed4c U stephan -Z fda94993ae5f9ecaf502d7e40734c943 +Z 08f197b7ace262c34243258f45fb1526 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2a7ae021c4..139804b3dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4564dbe4ac0040803b5d139c9fff22a60a45b4769d80ad7c824456cc6b9f1722 +abec913c00564ee5453075f45b1a6680e92ee1b1e61e3b19e4cf74e46785d3bf diff --git a/sqlite3.pc.in b/sqlite3.pc.in index 73d65dea23..a9f941b1e4 100644 --- a/sqlite3.pc.in +++ b/sqlite3.pc.in @@ -9,5 +9,5 @@ Name: SQLite Description: SQL database engine Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lsqlite3 -Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ZLIB@ +Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ZLIB@ @LDFLAGS_ICU@ Cflags: -I${includedir} From f6e86e38ac16621d7f97db398043426064075090 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 20:04:23 +0000 Subject: [PATCH 187/522] Rename --with-readline-lib/inc to --with-readline-ldflags/cflags, for clarity, but retain the older names as aliases using autosetup's "hidden alias" feature. Rename the newly-added --with-icu-lib to --with-icu-ldflags (with no backwards compatibility). FossilOrigin-Name: e50a03f9f2a40a5e65f874ffff234a7b397ce4ebdc7b360d4e6ade7575577c38 --- auto.def | 43 +++++++++++++++++++++++++------------- autosetup/hwaci-common.tcl | 21 +++++++++++++++++++ manifest | 14 ++++++------- manifest.uuid | 2 +- 4 files changed, 58 insertions(+), 22 deletions(-) diff --git a/auto.def b/auto.def index 97ed72569e..3ced03f751 100644 --- a/auto.def +++ b/auto.def @@ -163,15 +163,21 @@ set flags { largefile=1 => {Disable large file support} shared=1 => {Disable build of shared libary} static=1 => {Disable build of static library} - with-readline-lib:LDFLAGS + # --with-readline-lib is a legacy name, now a backwards-compatible + # alias for --with-readline-ldflags. + with-readline-lib: + with-readline-ldflags:LDFLAGS => {Readline LDFLAGS, e.g. -lreadline -lncurses} - with-readline-inc:CFLAGS + # --with-readline-inc is a legacy name, now a backwards-compatible + # alias for --with-readline-ldflags. + with-readline-inc: + with-readline-cflags:CFLAGS => {Readline CFLAGS, e.g. -I/path/to/includes} with-readline-header:PATH - => {Full path to readline.h, from which --with-readline-inc will be derived} + => {Full path to readline.h, from which --with-readline-cflags will be derived} with-linenoise:DIR => {Source directory for linenoise.c and linenoise.h} - with-icu-lib:LDFLAGS => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} - icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-lib=...} + with-icu-ldflags:LDFLAGS => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} + icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...} amalgamation=1 => {Disable the amalgamation and instead build all files separately} load-extension=1 => {Disable loading of external extensions} math=1 => {Disable math functions} @@ -201,6 +207,15 @@ if {"" ne $DUMP_DEFINES_JSON} { options [subst $flags] unset flags +# Apply values from hidden --flag aliases over to their canonical +# forms. +foreach {hidden flag canonical} { + with-readline-inc => with-readline-cflags + with-readline-lib => with-readline-ldflags +} { + hwaci-xfer-opt-alias $hidden $canonical +} + set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] set PACKAGE_VERSION [readfile $srcdir/VERSION] @@ -817,7 +832,7 @@ proc sqlite-check-line-editing {} { # # However, a workaround which works on the available systems is: # - # --with-readline-lib=-ledit + # --with-readline-ldflags=-ledit # # And then let it detect readline.h. We "could" re-map # --enable-editline to do exactly that but it seems likely to @@ -827,7 +842,7 @@ proc sqlite-check-line-editing {} { WARNING: the --enable-editline flag is not supported due to non-availability of systems which have it in a form which the sqlite3 CLI shell expects to see. On some systems this can be - worked around by passing --with-readline-lib=-ledit instead of + worked around by passing --with-readline-ldflags=-ledit instead of --enable-editline, which will attempt to use the readline.h supplied by libreadline but link against -ledit. } @@ -837,12 +852,12 @@ proc sqlite-check-line-editing {} { return "none" } - # Transform with-readline-header=X to with-readline-inc=-I... + # Transform with-readline-header=X to with-readline-cflags=-I... set v [opt-val with-readline-header] hwaci-opt-set with-readline-header "" if {"" ne $v} { if {"auto" eq $v} { - hwaci-opt-set with-readline-inc auto + hwaci-opt-set with-readline-cflags auto } else { set v [file dirname $v] if {[string match */*line $v]} { @@ -853,12 +868,12 @@ proc sqlite-check-line-editing {} { # work! set v [file dirname $v] } - hwaci-opt-set with-readline-inc "-I$v" + hwaci-opt-set with-readline-cflags "-I$v" } } # Look for readline.h - set rlInc [opt-val with-readline-inc auto] + set rlInc [opt-val with-readline-cflags auto] if {"auto" eq $rlInc} { set rlInc "" if {!$::cross_compiling} { @@ -880,7 +895,7 @@ proc sqlite-check-line-editing {} { # If readline.h was found/specified, look for libreadline... set rlLib "" if {"" ne $rlInc} { - set rlLib [opt-val with-readline-lib] + set rlLib [opt-val with-readline-ldflags] if {"" eq $rlLib || "auto" eq $rlLib} { set rlLib "" set libTerm "" @@ -978,7 +993,7 @@ unset emccsh ######################################################################## # ICU -if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-lib ""]]]} { +if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]]]} { # Flags sets seen in the wild for ICU: # {-licui18n -licuuc -licudata} {-licui18n -licuuc} add-feature-flag -DSQLITE_ENABLE_ICU @@ -989,7 +1004,7 @@ if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-lib ""]]]} { add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS } } elseif {[opt-bool icu-collations]} { - hwaci-warn "ignoring --enable-icu-collations because --with-icu-lib was not specified" + hwaci-warn "ignoring --enable-icu-collations because --with-icu-ldflags was not specified" } ######################################################################## diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 9c11a21ae5..4c3c0585c8 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -975,3 +975,24 @@ proc hwaci-dump-defs-json {file args} { msg-result "Created $file" } } + +######################################################################## +# Expects configure flags with the given names to have been registered +# with autosetup. If [opt-val $hidden] has a value but [opt-val +# $canonical] does not, it copies the former over the latter. If both +# have explicit values a fatal usage error is triggered. +# +# Autosetup accounts for hidden aliases in [options] lists but does no +# further handling of them, e.g. fetching [opt-val foo] will not, even +# if foo is an alias for bar, see a value passed in as --bar=baz. +proc hwaci-xfer-opt-alias {hidden canonical} { + set x [opt-val $hidden "-9-9-9-"] + if {"-9-9-9-" ne $x} { + set y [opt-val $canonical "-0-0-0-"] + if {"-0-0-0-" eq $y} { + hwaci-opt-set $canonical $x + } else { + hwaci-fatal "both --$canonical and its hidden alias --$hidden were used. Use only one or the other." + } + } +} diff --git a/manifest b/manifest index 3fbf97aad1..5796e3c9c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sICU\sis\senabled,\sensure\sthat\sthe\sCLI\sshell\sbuild\senables\sits\sfeature\sflag\sand\sinclude\sLDFLAGS_ICU\sin\ssqlite3.pc. -D 2024-10-27T19:26:54.435 +C Rename\s--with-readline-lib/inc\sto\s--with-readline-ldflags/cflags,\sfor\sclarity,\sbut\sretain\sthe\solder\snames\sas\saliases\susing\sautosetup's\s"hidden\salias"\sfeature.\sRename\sthe\snewly-added\s--with-icu-lib\sto\s--with-icu-ldflags\s(with\sno\sbackwards\scompatibility). +D 2024-10-27T20:04:23.738 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 580df10aeb7d12fb939a5f503cd30d2a5d619ac6bb8e94cd3f3f8b425388da13 +F auto.def 7f4a0a1421306ed8bca11d54b754f01dbf76054d17894c7c88fad0c05e2fadba F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 0e8643bcacf4fd73be0b194faf21b18a7229dd61347eb204a368fef45a0bee87 +F autosetup/hwaci-common.tcl 7839c061ae85648d1440ef95f75f4c1f18008458b7a3a81beaebeb7d2470a0dc F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4564dbe4ac0040803b5d139c9fff22a60a45b4769d80ad7c824456cc6b9f1722 -R 862234bfe7dc3dea608ab0b1a9f6ed4c +P abec913c00564ee5453075f45b1a6680e92ee1b1e61e3b19e4cf74e46785d3bf +R 8c93632539b57f8beda5bb3056f97174 U stephan -Z 08f197b7ace262c34243258f45fb1526 +Z 46a44527cb166d23de983b40142b0922 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 139804b3dc..c1c05dc35c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abec913c00564ee5453075f45b1a6680e92ee1b1e61e3b19e4cf74e46785d3bf +e50a03f9f2a40a5e65f874ffff234a7b397ce4ebdc7b360d4e6ade7575577c38 From 5be20f3927288832218667051671c4d87418c6bc Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 20:14:49 +0000 Subject: [PATCH 188/522] Doc additions and minor cleanups in the --flag alias handling. FossilOrigin-Name: 37a1da038195365cd7eb866b3aa749ad8060a656ac38063520fdb70cf0a0e5f1 --- auto.def | 6 ++++-- autosetup/hwaci-common.tcl | 22 ++++++++++++++-------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/auto.def b/auto.def index 3ced03f751..0f6cc74a06 100644 --- a/auto.def +++ b/auto.def @@ -207,9 +207,11 @@ if {"" ne $DUMP_DEFINES_JSON} { options [subst $flags] unset flags -# Apply values from hidden --flag aliases over to their canonical +# +# Carry values from hidden --flag aliases over to their canonical flag # forms. -foreach {hidden flag canonical} { +# +foreach {hidden => canonical} { with-readline-inc => with-readline-cflags with-readline-lib => with-readline-ldflags } { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 4c3c0585c8..bb9836f7dc 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -979,17 +979,23 @@ proc hwaci-dump-defs-json {file args} { ######################################################################## # Expects configure flags with the given names to have been registered # with autosetup. If [opt-val $hidden] has a value but [opt-val -# $canonical] does not, it copies the former over the latter. If both -# have explicit values a fatal usage error is triggered. -# -# Autosetup accounts for hidden aliases in [options] lists but does no -# further handling of them, e.g. fetching [opt-val foo] will not, even -# if foo is an alias for bar, see a value passed in as --bar=baz. +# $canonical] does not, it copies the former over the latter. If +# $hidden has no value set, this is a no-op. If both have explicit +# values a fatal usage error is triggered. +# +# Motivation: autosetup accounts for hidden aliases in [options] lists +# but does no further handling of them. For example, when --foo is a +# hidden alias of the canonical flag --bar, and a user passes --foo=X, +# [opt-val bar] returns no value. i.e. the script must check both +# [opt-val foo] and [opt-val bar], despite them being aliases. The +# intent is that this function be passed each such mapping immediately +# after [options] is processed, to carry over any values from hidden +# aliases into their canonical names, so that in the above example +# [opt-value bar] will return X if --foo=X is passed in. proc hwaci-xfer-opt-alias {hidden canonical} { set x [opt-val $hidden "-9-9-9-"] if {"-9-9-9-" ne $x} { - set y [opt-val $canonical "-0-0-0-"] - if {"-0-0-0-" eq $y} { + if {"-0-0-0-" eq [opt-val $canonical "-0-0-0-"]} { hwaci-opt-set $canonical $x } else { hwaci-fatal "both --$canonical and its hidden alias --$hidden were used. Use only one or the other." diff --git a/manifest b/manifest index 5796e3c9c0..bab329676f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\s--with-readline-lib/inc\sto\s--with-readline-ldflags/cflags,\sfor\sclarity,\sbut\sretain\sthe\solder\snames\sas\saliases\susing\sautosetup's\s"hidden\salias"\sfeature.\sRename\sthe\snewly-added\s--with-icu-lib\sto\s--with-icu-ldflags\s(with\sno\sbackwards\scompatibility). -D 2024-10-27T20:04:23.738 +C Doc\sadditions\sand\sminor\scleanups\sin\sthe\s--flag\salias\shandling. +D 2024-10-27T20:14:49.852 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 7f4a0a1421306ed8bca11d54b754f01dbf76054d17894c7c88fad0c05e2fadba +F auto.def a5cc3792cfe6e82561c810f5f6383186ee5ce73cdde4ca06b70f18252ec38f84 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 7839c061ae85648d1440ef95f75f4c1f18008458b7a3a81beaebeb7d2470a0dc +F autosetup/hwaci-common.tcl f8b683adc42ac4a9d1a950118f024b8b7d2b90460ee39c5a9a0feb8e7ad9d179 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P abec913c00564ee5453075f45b1a6680e92ee1b1e61e3b19e4cf74e46785d3bf -R 8c93632539b57f8beda5bb3056f97174 +P e50a03f9f2a40a5e65f874ffff234a7b397ce4ebdc7b360d4e6ade7575577c38 +R 689f8e7c0b273a0d5f61c39635b6551a U stephan -Z 46a44527cb166d23de983b40142b0922 +Z 9c99ac6705fb06550102fd68e4fd933c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c1c05dc35c..d17d4d17dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e50a03f9f2a40a5e65f874ffff234a7b397ce4ebdc7b360d4e6ade7575577c38 +37a1da038195365cd7eb866b3aa749ad8060a656ac38063520fdb70cf0a0e5f1 From 2005250d7f585e26b313e7c3e3a09ca261c3272f Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 20:46:09 +0000 Subject: [PATCH 189/522] Generic cleanups in auto.def and hwaci-common.tcl. FossilOrigin-Name: 428e542452bac99d48950f1f62b65b4e235636540b946151747e2d5b59dbfd99 --- auto.def | 16 ++++------ autosetup/hwaci-common.tcl | 65 +++++++++++++++++++++++++++----------- manifest | 14 ++++---- manifest.uuid | 2 +- 4 files changed, 62 insertions(+), 35 deletions(-) diff --git a/auto.def b/auto.def index 0f6cc74a06..9ea09c8d11 100644 --- a/auto.def +++ b/auto.def @@ -163,15 +163,15 @@ set flags { largefile=1 => {Disable large file support} shared=1 => {Disable build of shared libary} static=1 => {Disable build of static library} - # --with-readline-lib is a legacy name, now a backwards-compatible - # alias for --with-readline-ldflags. + # --with-readline-lib is a backwards-compatible alias for + # --with-readline-ldflags with-readline-lib: - with-readline-ldflags:LDFLAGS + with-readline-ldflags:=auto => {Readline LDFLAGS, e.g. -lreadline -lncurses} - # --with-readline-inc is a legacy name, now a backwards-compatible - # alias for --with-readline-ldflags. + # --with-readline-inc is a backwards-compatible alias for + # --with-readline-cflags with-readline-inc: - with-readline-cflags:CFLAGS + with-readline-cflags:=auto => {Readline CFLAGS, e.g. -I/path/to/includes} with-readline-header:PATH => {Full path to readline.h, from which --with-readline-cflags will be derived} @@ -211,11 +211,9 @@ unset flags # Carry values from hidden --flag aliases over to their canonical flag # forms. # -foreach {hidden => canonical} { +hwaci-xfer-options-aliases { with-readline-inc => with-readline-cflags with-readline-lib => with-readline-ldflags -} { - hwaci-xfer-opt-alias $hidden $canonical } set srcdir $::autosetup(srcdir) diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index bb9836f7dc..611238f080 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -93,6 +93,21 @@ proc hwaci-lshift_ {listVar {count 1}} { return $r } +######################################################################## +# Expects to receive string input, which it splits on newlines, strips +# out any lines which begin with an number of whitespace followed by a +# '#', and returns a value containing the [append]ed results of each +# remaining line with a \n between each. +proc hwaci-strip-comments {val} { + set x {} + foreach line [split $val \n] { + if {![string match "#*" [string trimleft $line]]} { + append x $line \n + } + } + return $x +} + ######################################################################## # A proxy for cc-check-function-in-lib which "undoes" any changes that # routine makes to the LIBS define. Returns the result of @@ -977,28 +992,42 @@ proc hwaci-dump-defs-json {file args} { } ######################################################################## -# Expects configure flags with the given names to have been registered -# with autosetup. If [opt-val $hidden] has a value but [opt-val +# Expects a list of pairs of configure flags with the given names to +# have been registered with autosetup, in this form: +# +# { alias1 => canonical1 +# aliasN => canonicalN ... } +# +# The names must not have their leading -- part and must be in the +# form which autosetup will expect for passing to [opt-val NAME] and +# friends. +# +# Commend lines are permitted in the input. +# +# If [opt-val $hidden] has a value but [opt-val # $canonical] does not, it copies the former over the latter. If # $hidden has no value set, this is a no-op. If both have explicit # values a fatal usage error is triggered. # -# Motivation: autosetup accounts for hidden aliases in [options] lists -# but does no further handling of them. For example, when --foo is a -# hidden alias of the canonical flag --bar, and a user passes --foo=X, -# [opt-val bar] returns no value. i.e. the script must check both -# [opt-val foo] and [opt-val bar], despite them being aliases. The -# intent is that this function be passed each such mapping immediately -# after [options] is processed, to carry over any values from hidden -# aliases into their canonical names, so that in the above example -# [opt-value bar] will return X if --foo=X is passed in. -proc hwaci-xfer-opt-alias {hidden canonical} { - set x [opt-val $hidden "-9-9-9-"] - if {"-9-9-9-" ne $x} { - if {"-0-0-0-" eq [opt-val $canonical "-0-0-0-"]} { - hwaci-opt-set $canonical $x - } else { - hwaci-fatal "both --$canonical and its hidden alias --$hidden were used. Use only one or the other." +# Motivation: autosetup enables "hidden aliases" in [options] lists, +# and elides the aliases from --help output but does no further +# handling of them. For example, when --alias is a hidden alias of +# --canonical and a user passes --alias=X, [opt-val canonical] returns +# no value. i.e. the script must check both [opt-val alias] and +# [opt-val canonical]. The intent here is that this function be +# passed such mappings immediately after [options] is called, +# to carry over any values from hidden aliases into their canonical +# names, so that in the above example [opt-value canonical] will +# return X if --alias=X is passed in. +proc hwaci-xfer-options-aliases {mapping} { + foreach {hidden => canonical} [hwaci-strip-comments $mapping] { + set x [opt-val $hidden "~9~9~9~"] + if {"~9~9~9~" ne $x} { + if {"~0~0~0~" eq [opt-val $canonical "~0~0~0~"]} { + hwaci-opt-set $canonical $x + } else { + hwaci-fatal "both --$canonical and its alias --$hidden were used. Use only one or the other." + } } } } diff --git a/manifest b/manifest index bab329676f..9d55604594 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Doc\sadditions\sand\sminor\scleanups\sin\sthe\s--flag\salias\shandling. -D 2024-10-27T20:14:49.852 +C Generic\scleanups\sin\sauto.def\sand\shwaci-common.tcl. +D 2024-10-27T20:46:09.058 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a5cc3792cfe6e82561c810f5f6383186ee5ce73cdde4ca06b70f18252ec38f84 +F auto.def dd9bda48dc2a4c515d1a518f342b992c1cdea46c0d4e20a25d515ab423de2d49 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl f8b683adc42ac4a9d1a950118f024b8b7d2b90460ee39c5a9a0feb8e7ad9d179 +F autosetup/hwaci-common.tcl c6a68fe4ad416db70260bc0f8a85ee9f52d6976ca796aaa8ae013a1bf632b49d F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e50a03f9f2a40a5e65f874ffff234a7b397ce4ebdc7b360d4e6ade7575577c38 -R 689f8e7c0b273a0d5f61c39635b6551a +P 37a1da038195365cd7eb866b3aa749ad8060a656ac38063520fdb70cf0a0e5f1 +R 4a5971ae5787ab5ca5bc6c1b2940924e U stephan -Z 9c99ac6705fb06550102fd68e4fd933c +Z f7c559f6f234bc23301783ef1baa5b93 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d17d4d17dd..bc0860a133 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -37a1da038195365cd7eb866b3aa749ad8060a656ac38063520fdb70cf0a0e5f1 +428e542452bac99d48950f1f62b65b4e235636540b946151747e2d5b59dbfd99 From 3a92a5c4b3c6596ad025b8876929a185044bd2b1 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 22:18:33 +0000 Subject: [PATCH 190/522] Re-order the auto.def flags logical groups. Add some discrete bold formatting to select configure output. Remove some dead code. Account for behavior misunderstanding of user-notice. Add the start of a 'make help' target. General cosmetic cleanups. FossilOrigin-Name: ab95ee33dfe56bd3b223f978626e6014414881c30443a2b88c782de724c39ae1 --- auto.def | 246 ++++++++++++++----------------------- autosetup/hwaci-common.tcl | 88 +++++++++---- main.mk | 9 ++ manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 174 insertions(+), 187 deletions(-) diff --git a/auto.def b/auto.def index 9ea09c8d11..07502b966f 100644 --- a/auto.def +++ b/auto.def @@ -14,31 +14,6 @@ # use cc cc-db cc-shared cc-lib hwaci-common pkg-config -# Are we cross-compiling? -set cross_compiling [hwaci-is-cross-compiling] -if {0 - && !$cross_compiling - && "nope" eq [get-env CC_FOR_BUILD "nope"] - && [get-define CC] ne [get-define CC_FOR_BUILD]} { - # Arguable/debatable... - # - # When _not_ cross-compiling and CC_FOR_BUILD is _not_ explcitely - # specified, force CC_FOR_BUILD to be the same as CC, so that: - # - # ./configure CC=clang - # - # will use CC_FOR_BUILD=clang, instead of cc, for building in-tree - # tools. This is based off of an email discussion and is thought to - # be likely to cause less confusion than seeing 'cc' invocations - # will when the user passes CC=clang. - # - # Sidebar: if we do this before the cc package is installed, it gets - # reverted by that package. Ergo, the cc package init will tell the - # user "Build C compiler...cc" shortly before we tell them: - msg-result "Re-defining CC_FOR_BUILD to CC=[get-define CC]. To avoid this, explicitly pass CC_FOR_BUILD=..." - define CC_FOR_BUILD [get-define CC] -} - # $DUMP_DEFINES_TXT is the file emitted by --dump-defines, intended # only for build debugging and not part of the public build interface. set DUMP_DEFINES_TXT ./config.defines.txt @@ -151,23 +126,42 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # ######################################################################## set flags { + # with-debug:=1 => {Enable debug build flags} + shared=1 => {Disable build of shared libary} + static=1 => {Disable build of static library (mostly)} + amalgamation=1 => {Disable the amalgamation and instead build all files separately.} + # + # + threadsafe=1 => {Disable mutexing} + with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always} + largefile=1 => {Disable large file support} + load-extension=1 => {Disable loading of external extensions} + math=1 => {Disable math functions} + json=1 => {Disable JSON functions} + all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} + memsys5 => {Enable MEMSYS5} + memsys3 => {Enable MEMSYS3} + fts3 => {Enable the FTS3 extension} + fts4 => {Enable the FTS4 extension} + fts5 => {Enable the FTS5 extension} + update-limit => {Enable the UPDATE/DELETE LIMIT clause} + geopoly => {Enable the GEOPOLY extension} + rtree => {Enable the RTREE extension} + session => {Enable the SESSION extension} + # + # with-tclsh:PATH => {Full pathname of tclsh to use} with-tcl:DIR => {Directory containing tclConfig.sh} tcl=1 => {Disable components which require TCL-dev} - test-status => {Enable status of tests} - threadsafe=1 => {Disable mutexing} - with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always} - editline=0 => {BSD editline support} + # + # readline=1 => {Disable readline support} - largefile=1 => {Disable large file support} - shared=1 => {Disable build of shared libary} - static=1 => {Disable build of static library} # --with-readline-lib is a backwards-compatible alias for # --with-readline-ldflags with-readline-lib: with-readline-ldflags:=auto - => {Readline LDFLAGS, e.g. -lreadline -lncurses} + => {Readline LDFLAGS, e.g. -lreadline -lncurses} # --with-readline-inc is a backwards-compatible alias for # --with-readline-cflags with-readline-inc: @@ -176,28 +170,23 @@ set flags { with-readline-header:PATH => {Full path to readline.h, from which --with-readline-cflags will be derived} with-linenoise:DIR => {Source directory for linenoise.c and linenoise.h} + editline=0 => {BSD editline support} + # + # with-icu-ldflags:LDFLAGS => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...} - amalgamation=1 => {Disable the amalgamation and instead build all files separately} - load-extension=1 => {Disable loading of external extensions} - math=1 => {Disable math functions} - json=1 => {Disable JSON functions} - all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} - memsys5 => {Enable MEMSYS5} - memsys3 => {Enable MEMSYS3} - fts3 => {Enable the FTS3 extension} - fts4 => {Enable the FTS4 extension} - fts5 => {Enable the FTS5 extension} - update-limit => {Enable the UPDATE/DELETE LIMIT clause} - geopoly => {Enable the GEOPOLY extension} - rtree => {Enable the RTREE extension} - session => {Enable the SESSION extension} - gcov=0 => {Enable coverage testing using gcov} - linemacros => {Enable #line macros in the amalgamation.} + # + # with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build} with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} + # + # + test-status => {Enable status of tests} + gcov=0 => {Enable coverage testing using gcov} + linemacros => {Enable #line macros in the amalgamation.} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} + # } if {"" ne $DUMP_DEFINES_JSON} { lappend flags \ @@ -227,7 +216,7 @@ define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum msg-result "srcdir = $srcdir" msg-result "top_srcdir = $top_srcdir" -msg-result "VERSION = $PACKAGE_VERSION" +msg-result [hwaci-bold "Configuring SQLite version $PACKAGE_VERSION"] define-append SQLITE_AUTOREMAKE cd '$srcdir' && '$top_srcdir/configure' #{*}$::autosetup(argv) breaks with --flag='val with spaces', so... @@ -235,90 +224,36 @@ foreach arg $::autosetup(argv) { define-append SQLITE_AUTOREMAKE '$arg' } -set outOfTreeBuild 0 + +# Are we cross-compiling? +set cross_compiling [hwaci-is-cross-compiling] if {![file exists sqlite3.pc.in]} { msg-result "This appears to be an out-of-tree build." - set outOfTreeBuild 1 } cc-check-tools ld ar +define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags. +define OPT_SHELL {} ; # CFLAGS for the sqlite3 CLI app ######################################################################## -# The build process allows for using a cross-compiler. But the default -# action is to target the same platform that we are running on. The -# configure script needs to discover the following properties of the -# build and target systems: -# -# srcdir -# -# The is the name of the directory that contains the -# "configure" shell script. All source files are -# located relative to this directory. -# -# bindir -# -# The name of the directory where executables should be -# written by the "install" target of the makefile. -# -# program_prefix -# -# Add this prefix to the names of all executables that run -# on the target machine. Default: "" -# -# ENABLE_SHARED -# -# True if shared libraries should be generated. -# -# BUILD_CC -# -# The name of a command that is used to convert C -# source files into executables that run on the build -# platform. -# -# BUILD_CFLAGS -# -# Switches that the build compiler needs in order to construct -# command-line programs. -# -# BUILD_LIBS -# -# Libraries that the build compiler needs in order to construct -# command-line programs. -# -# TCL_* -# -# Lots of values are read in from the tclConfig.sh script, -# if that script is available. This values are used for -# constructing and installing the TCL extension. -# -# TARGET_READLINE_LIBS -# -# This is the library directives passed to the target linker -# that cause the executable to link against the readline library. -# This might be a switch like "-lreadline" or pathnames of library -# file like "../../src/libreadline.a". -# -# TARGET_READLINE_INC -# -# This variables define the directory that contain header -# files for the readline library. If the compiler is able -# to find on its own, then this can be blank. - -# -# OPT_FEATURE_FLAGS = -DSQLITE_OMIT/ENABLE flags. -define OPT_FEATURE_FLAGS {} -define OPT_SHELL {}; # CFLAGS for the sqlite3 CLI app - # Adds $args, if not empty, to OPT_FEATURE_FLAGS. -proc add-feature-flag {args} { +# If the first arg is -shell then it strips that arg +# and passes the remaining args th sqlite-add-shell-opt +# before adding them to OPF_FEATURE_FLAGS. +proc sqlite-add-feature-flag {args} { + set shell "" + if {"-shell" eq [lindex $args 0]} { + set args [lassign $args shell] + } if {"" ne $args} { + if {"" ne $shell} { + sqlite-add-shell-opt {*}$args + } define-append OPT_FEATURE_FLAGS {*}$args } } -# add-feature-flag -DSQLITE_JUST_TESTING=3 - -# Adds $args, if not empty, to OPT_SHELL. -proc add-shell-opt {args} { +# Appends $args, if not empty, to OPT_SHELL. +proc sqlite-add-shell-opt {args} { if {"" ne $args} { define-append OPT_SHELL {*}$args } @@ -328,11 +263,11 @@ hwaci-file-extensions if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_UNIX 0 define SQLITE_OS_WIN 1 - # todo? add -DSQLITE_OS_WIN=1 to CFLAGS? + # todo? add -DSQLITE_OS_WIN=1 to CFLAGS or CFLAGS_sqlite3_os? } else { define SQLITE_OS_UNIX 1 define SQLITE_OS_WIN 0 - # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS? + # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS or CFLAGS_sqlite3_os } ######### @@ -448,7 +383,7 @@ if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { # Note that -DSQLITE_HAVE_ZLIB=1 is handled separately from the # other feature flags in the autotools build. Do we need to emulate # that? - add-shell-opt -DSQLITE_HAVE_ZLIB=1 + sqlite-add-shell-opt -DSQLITE_HAVE_ZLIB=1 } else { define HAVE_ZLIB 0 define LDFLAGS_ZLIB "" @@ -745,7 +680,7 @@ unset cgtcl msg-checking "Support threadsafe operation? " hwaci-if-opt-truthy threadsafe { msg-result yes - add-feature-flag -DSQLITE_THREADSAFE=1 + sqlite-add-feature-flag -DSQLITE_THREADSAFE=1 if {![hwaci-check-function-in-lib pthread_create pthread] || ![hwaci-check-function-in-lib pthread_mutexattr_init pthread]} { user-error "Missing required pthread bits" @@ -754,7 +689,7 @@ hwaci-if-opt-truthy threadsafe { undefine lib_pthread_create } { msg-result no - add-feature-flag -DSQLITE_THREADSAFE=0 + sqlite-add-feature-flag -DSQLITE_THREADSAFE=0 define LDFLAGS_PTHREAD "" } @@ -799,6 +734,7 @@ if {1} { # Returns a string describing which line-editing approach to use, or # "none" if no option is available. proc sqlite-check-line-editing {} { + msg-result "Checking for line-editing capability..." define HAVE_READLINE 0 define HAVE_LINENOISE 0 define HAVE_EDITLINE 0 @@ -815,10 +751,10 @@ proc sqlite-check-line-editing {} { } elseif {![file exists $dirLn/linenoise.h] } { hwaci-fatal "Cannot find linenoise.h in $dirLn" } - user-notice "Using linenoise from $dirLn" + msg-result "Using linenoise from $dirLn" define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise.c" define HAVE_LINENOISE 1 - add-shell-opt -DHAVE_LINENOISE=1 + sqlite-add-shell-opt -DHAVE_LINENOISE=1 return "linenoise" } elseif {[opt-bool editline]} { # --enable-editline. The problem is finding a system which has it @@ -848,7 +784,7 @@ proc sqlite-check-line-editing {} { } return "none" } elseif {![opt-bool readline]} { - user-notice "Readline support explicitly disabled with --disable-readline" + msg-result "Readline support explicitly disabled with --disable-readline" return "none" } @@ -920,8 +856,8 @@ proc sqlite-check-line-editing {} { define LDFLAGS_READLINE $rlLib define CFLAGS_READLINE $rlInc define HAVE_READLINE 1 - add-shell-opt -DHAVE_READLINE=1 - user-notice "Using readline flags: $rlInc $rlLib" + sqlite-add-shell-opt -DHAVE_READLINE=1 + msg-result "Using readline flags: $rlInc $rlLib" # Now check whether rl_completion_matches() has a signature we can use. # cctest is producing unexpected test output when using: @@ -937,10 +873,10 @@ proc sqlite-check-line-editing {} { return 0; } }]} { - user-notice "Readline completion enabled" + msg-result "Readline completion enabled" } else { user-notice "WARNING: readline completion disabled due to rl_completion_matches() signature mismatch" - add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION + sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION } return "readline" } @@ -958,7 +894,7 @@ hwaci-if-opt-truthy load-extension { } } { define LDFLAGS_DLOPEN "" - add-feature-flag {-DSQLITE_OMIT_LOAD_EXTENSION=1} + sqlite-add-feature-flag {-DSQLITE_OMIT_LOAD_EXTENSION=1} msg-result "Disabling loadable extensions." } @@ -968,7 +904,7 @@ hwaci-if-opt-truthy math { } define LDFLAGS_MATH [get-define lib_ceil] undefine lib_ceil - add-feature-flag {-DSQLITE_ENABLE_MATH_FUNCTIONS} + sqlite-add-feature-flag {-DSQLITE_ENABLE_MATH_FUNCTIONS} msg-result "Enabling math SQL functions [get-define LDFLAGS_MATH]" } { define LDFLAGS_MATH "" @@ -992,16 +928,18 @@ if {![get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} { unset emccsh ######################################################################## -# ICU +# ICU - International Components for Unicode if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]]]} { # Flags sets seen in the wild for ICU: - # {-licui18n -licuuc -licudata} {-licui18n -licuuc} - add-feature-flag -DSQLITE_ENABLE_ICU - add-shell-opt -DSQLITE_ENABLE_ICU + # - -licui18n -licuuc -licudata + # - -licui18n -licuuc + # - /usr/local/bin/icu-config --ldflags + sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU msg-result "Enabling ICU support with libs: [get-define LDFLAGS_ICU]" if {[opt-bool icu-collations]} { msg-result "Enabling ICU collations." - add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS + sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU_COLLATIONS + # Recall that shell.c builds with sqlite3.c } } elseif {[opt-bool icu-collations]} { hwaci-warn "ignoring --enable-icu-collations because --with-icu-ldflags was not specified" @@ -1014,7 +952,7 @@ if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]]]} { # required linker flags (which may be empty even if the math APIs are # found, depending on the OS). proc affirm-have-math {why} { - if {![hwaci-check-function-in-lib log m]} { + if {![msg-quiet hwaci-check-function-in-lib log m]} { user-error "Missing math APIs for $why" } define LDFLAGS_MATH [get-define lib_log ""] @@ -1023,6 +961,7 @@ proc affirm-have-math {why} { ######################################################################## # Handle various SQLITE_ENABLE_... feature flags. +msg-result "Feature flags..." foreach {boolFlag featureFlag ifSetEvalThis} { all {} { hwaci-opt-set fts4 @@ -1043,33 +982,33 @@ foreach {boolFlag featureFlag ifSetEvalThis} { hwaci-warn "not enabling memsys3 because memsys5 is enabled." expr 0 } else { - add-feature-flag -DSQLITE_ENABLE_MEMSYS3 + sqlite-add-feature-flag -DSQLITE_ENABLE_MEMSYS3 } } } { hwaci-if-opt-truthy $boolFlag { - add-feature-flag $featureFlag + sqlite-add-feature-flag $featureFlag if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} { - msg-result "Enabling $boolFlag" + msg-result " - Enabling $boolFlag" } } { - msg-result "Not enabling $boolFlag" + msg-result " - Not enabling $boolFlag" } } ######################################################################## # Invert the above loop's logic for some explicit SQLITE_OMIT_... -# cases. If config option $boolFlag is set, [add-feature-flag +# cases. If config option $boolFlag is set, [sqlite-add-feature-flag # $featureFlag], where $featureFlag is intended to be # -DSQLITE_OMIT_... foreach {boolFlag featureFlag} { json -DSQLITE_OMIT_JSON } { if {[hwaci-opt-truthy $boolFlag]} { - msg-result "Enabling $boolFlag" + msg-result " - Enabling $boolFlag" } else { - add-feature-flag $featureFlag - msg-result "Disabling $boolFlag" + sqlite-add-feature-flag $featureFlag + msg-result " - Disabling $boolFlag" } } @@ -1155,9 +1094,8 @@ if {"" ne $DUMP_DEFINES_JSON} { ######################################################################## # Some build-dev/debug-only output hwaci-if-opt-truthy dump-defines { - global DUMP_DEFINES_TXT - msg-result "--dump-defines is creating $DUMP_DEFINES_TXT" - make-config-header $DUMP_DEFINES_TXT \ + msg-result "--dump-defines is creating $::DUMP_DEFINES_TXT" + make-config-header $::DUMP_DEFINES_TXT \ -bare {SQLITE_OS* SQLITE_DEBUG USE_*} \ -str {BIN_* CC LD AR LDFLAG* OPT_*} \ -auto {*} @@ -1170,4 +1108,4 @@ hwaci-if-opt-truthy dump-defines { } } -msg-result "Done! Now run make." +msg-result [hwaci-bold "Source tree is configured! Run make to build it."] diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 611238f080..1cde5703c7 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -12,25 +12,28 @@ # Routines for Steve Bennett's autosetup which are common to trees # managed in and around the umbrella of the SQLite project. # -# Routines with a suffix of _ are intended for internal use, -# within this file, and are not part of the API which auto.def files -# should rely on. -# # This file was initially derived from one used in the libfossil -# project, authored by the same person who ported it here, noted here -# only as an indication that there are no licensing issue despite this -# code having at least two near-twins running around in other trees. +# project, authored by the same person who ported it here, and this is +# noted here only as an indication that there are no licensing issues +# despite this code having at least two near-twins running around a +# handful of third-party source trees. # ######################################################################## # -# Design notes: by and large, autosetup prefers to update global state -# with the results of feature checks, e.g. whether the compiler -# supports flag --X. In this developer's opinion that (A) causes more -# confusion than it solves[^1] and (B) adds an unnecessary layer of -# "voodoo" between the autosetup user and its internals. This module, -# in contrast, instead injects the results of its own tests into -# well-defined variables and leaves the integration of those values to -# the caller's discretion. +# Design notes: +# +# - Symbols with a suffix of _ are intended for internal use within +# this file, and are not part of the API which auto.def files should +# rely on. +# +# - By and large, autosetup prefers to update global state with the +# results of feature checks, e.g. whether the compiler supports flag +# --X. In this developer's opinion that (A) causes more confusion +# than it solves[^1] and (B) adds an unnecessary layer of "voodoo" +# between the autosetup user and its internals. This module, in +# contrast, instead injects the results of its own tests into +# well-defined variables and leaves the integration of those values +# to the caller's discretion. # # [1]: As an example: testing for the -rpath flag, using # cc-check-flags, can break later checks which use @@ -45,25 +48,37 @@ # $hwaci_ is an internal-use-only array for storing whatever generic # internal stuff we need stored. array set hwaci_ {} +set hwaci_(isatty) [isatty? stdout] proc hwaci-warn {msg} { puts stderr "WARNING: $msg" } -#proc hwaci-notice {msg} { -# puts stderr "NOTICE: $msg" -#} proc hwaci-fatal {msg} { - user-error "ERROR: $msg" + show-notices + puts stderr "ERROR: $msg" + exit 1 +} + +######################################################################## +# If this function believes that the current console might support +# ANSI escape sequences then this returns $str wrapped in a sequence +# to bold that text, else it returns $str as-is. +proc hwaci-bold {str} { + if {$::autosetup(iswin) || !$::hwaci_(isatty)} { + return $str + } + return "\033\[1m${str}\033\[0m" } ######################################################################## # Takes a multi-line message and emits it with consistent indentation -# using user-notice (which means its rendering will be delayed until -# the next time autosetup goes to output a message). +# using [user-notice] (which means its rendering will (A) go to stderr +# and (B) be delayed until the next time autosetup goes to output a +# message). proc hwaci-indented-notice {msg} { set lines [split $msg \n] foreach line $lines { - user-notice " [string trim $line]" + user-notice " [string trimleft $line]" } } @@ -98,7 +113,7 @@ proc hwaci-lshift_ {listVar {count 1}} { # out any lines which begin with an number of whitespace followed by a # '#', and returns a value containing the [append]ed results of each # remaining line with a \n between each. -proc hwaci-strip-comments {val} { +proc hwaci-strip-hash-comments_ {val} { set x {} foreach line [split $val \n] { if {![string match "#*" [string trimleft $line]]} { @@ -1020,7 +1035,7 @@ proc hwaci-dump-defs-json {file args} { # names, so that in the above example [opt-value canonical] will # return X if --alias=X is passed in. proc hwaci-xfer-options-aliases {mapping} { - foreach {hidden => canonical} [hwaci-strip-comments $mapping] { + foreach {hidden => canonical} [hwaci-strip-hash-comments_ $mapping] { set x [opt-val $hidden "~9~9~9~"] if {"~9~9~9~" ne $x} { if {"~0~0~0~" eq [opt-val $canonical "~0~0~0~"]} { @@ -1031,3 +1046,28 @@ proc hwaci-xfer-options-aliases {mapping} { } } } + +######################################################################## +# Arguable/debatable... +# +# When _not_ cross-compiling and CC_FOR_BUILD is _not_ explcitely +# specified, force CC_FOR_BUILD to be the same as CC, so that: +# +# ./configure CC=clang +# +# will use CC_FOR_BUILD=clang, instead of cc, for building in-tree +# tools. This is based off of an email discussion and is thought to +# be likely to cause less confusion than seeing 'cc' invocations +# will when the user passes CC=clang. +# +# Sidebar: if we do this before the cc package is installed, it gets +# reverted by that package. Ergo, the cc package init will tell the +# user "Build C compiler...cc" shortly before we tell them: +proc hwaci-redefine-cc-for-build {} { + if {![hwaci-is-cross-compiling] + && "nope" eq [get-env CC_FOR_BUILD "nope"] + && [get-define CC] ne [get-define CC_FOR_BUILD]} { + user-notice "Re-defining CC_FOR_BUILD to CC=[get-define CC]. To avoid this, explicitly pass CC_FOR_BUILD=..." + define CC_FOR_BUILD [get-define CC] + } +} diff --git a/main.mk b/main.mk index 3b58767c2b..2c8f64324e 100644 --- a/main.mk +++ b/main.mk @@ -2075,6 +2075,15 @@ sqlite3.dll: $(LIBOBJ) sqlite3.def $(T.cc.sqlite) $(LDFLAGS.shobj) -o $@ sqlite3.def \ -Wl,"--strip-all" $(LIBOBJ) +# +# Emit a list of commonly-used targets +help: + @echo "Frequently-used high-level make targets:"; \ + echo " - all (default) = builds most components"; \ + echo " - clean = cleans up most build products"; \ + echo " - distclean = cleans up all build products"; \ + echo "...and many more" + # Remove build products sufficient so that subsequent makes will recompile # everything from scratch. Do not remove: diff --git a/manifest b/manifest index 9d55604594..b44839c988 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Generic\scleanups\sin\sauto.def\sand\shwaci-common.tcl. -D 2024-10-27T20:46:09.058 +C Re-order\sthe\sauto.def\sflags\slogical\sgroups.\sAdd\ssome\sdiscrete\sbold\sformatting\sto\sselect\sconfigure\soutput.\sRemove\ssome\sdead\scode.\sAccount\sfor\sbehavior\smisunderstanding\sof\suser-notice.\sAdd\sthe\sstart\sof\sa\s'make\shelp'\starget.\sGeneral\scosmetic\scleanups. +D 2024-10-27T22:18:33.718 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def dd9bda48dc2a4c515d1a518f342b992c1cdea46c0d4e20a25d515ab423de2d49 +F auto.def 10eac711b57bce9705555c052e8970e62aa6754b91e1ff37a51c50b040cc4897 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl c6a68fe4ad416db70260bc0f8a85ee9f52d6976ca796aaa8ae013a1bf632b49d +F autosetup/hwaci-common.tcl bc48c6ddfcd33a0eaf17f1709cde60622ff29c479e0356e8c6bcabe5b58a4d51 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk d943a2d0a0deb14daea10e036ef3a55e1b641cd57f5893a2fba29e65cc33acc0 +F main.mk 7533ef1b3a1338b96445a672ba6dbfa48279f05089a0555ff8822dcd1dcb000a F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 37a1da038195365cd7eb866b3aa749ad8060a656ac38063520fdb70cf0a0e5f1 -R 4a5971ae5787ab5ca5bc6c1b2940924e +P 428e542452bac99d48950f1f62b65b4e235636540b946151747e2d5b59dbfd99 +R c11fb367c51c71ad6dcdc1b5cebfcffd U stephan -Z f7c559f6f234bc23301783ef1baa5b93 +Z 989475d21f0d39382974a32645a7533c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bc0860a133..31638cc682 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -428e542452bac99d48950f1f62b65b4e235636540b946151747e2d5b59dbfd99 +ab95ee33dfe56bd3b223f978626e6014414881c30443a2b88c782de724c39ae1 From e550d98bbf89f90c8bb547f7e54d03c9e1b4dae7 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 27 Oct 2024 22:34:07 +0000 Subject: [PATCH 191/522] Expand the 'make help' target and clean up some overly-noisy configure output. FossilOrigin-Name: c895766ed31f55c02f05d357333e9cf45e82ec5af4d8b0491270e4fda7a57d42 --- auto.def | 12 +++++++----- main.mk | 20 +++++++++++++++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/auto.def b/auto.def index 07502b966f..b4201b79c1 100644 --- a/auto.def +++ b/auto.def @@ -873,9 +873,9 @@ proc sqlite-check-line-editing {} { return 0; } }]} { - msg-result "Readline completion enabled" } else { user-notice "WARNING: readline completion disabled due to rl_completion_matches() signature mismatch" + show-notices sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION } return "readline" @@ -989,10 +989,12 @@ foreach {boolFlag featureFlag ifSetEvalThis} { hwaci-if-opt-truthy $boolFlag { sqlite-add-feature-flag $featureFlag if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} { - msg-result " - Enabling $boolFlag" + msg-result " + $boolFlag" } } { - msg-result " - Not enabling $boolFlag" + if {"all" ne $boolFlag} { + msg-result " - $boolFlag" + } } } @@ -1005,10 +1007,10 @@ foreach {boolFlag featureFlag} { json -DSQLITE_OMIT_JSON } { if {[hwaci-opt-truthy $boolFlag]} { - msg-result " - Enabling $boolFlag" + msg-result " + $boolFlag" } else { sqlite-add-feature-flag $featureFlag - msg-result " - Disabling $boolFlag" + msg-result " - $boolFlag" } } diff --git a/main.mk b/main.mk index 2c8f64324e..a815354471 100644 --- a/main.mk +++ b/main.mk @@ -2078,11 +2078,25 @@ sqlite3.dll: $(LIBOBJ) sqlite3.def # # Emit a list of commonly-used targets help: - @echo "Frequently-used high-level make targets:"; \ - echo " - all (default) = builds most components"; \ + @echo; echo "Frequently-used high-level make targets:"; echo; \ + echo " - all [default] = builds most components"; \ echo " - clean = cleans up most build products"; \ echo " - distclean = cleans up all build products"; \ - echo "...and many more" + echo " - install = installs activated components"; \ + echo; echo "Testing-related targets:"; echo; \ + echo " - test = a number of sanity checks"; \ + echo " - quicktest = minimal tests"; \ + echo " - releasetest = pre-release tests"; \ + echo " - devtest = Minimum tests required before code check-ins"; \ + echo " - mdevtest = A variant of devtest"; \ + echo " - sdevtest = A variant of devtest"; \ + echo " - tcltest = Runs test/veryquick.test"; \ + echo " - testrunner = Like tcltest but spread across multiple cores"; \ + echo " - fuzztest = The core fuzz tester (see target docs for important info)"; \ + echo " - valgrindfuzz = Runs fuzztest under valgrind"; \ + echo " - soaktest = Really, really long tests"; \ + echo " - alltest = Runs most or all TCL tests"; \ + echo # Remove build products sufficient so that subsequent makes will recompile diff --git a/manifest b/manifest index b44839c988..d9d6800c4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Re-order\sthe\sauto.def\sflags\slogical\sgroups.\sAdd\ssome\sdiscrete\sbold\sformatting\sto\sselect\sconfigure\soutput.\sRemove\ssome\sdead\scode.\sAccount\sfor\sbehavior\smisunderstanding\sof\suser-notice.\sAdd\sthe\sstart\sof\sa\s'make\shelp'\starget.\sGeneral\scosmetic\scleanups. -D 2024-10-27T22:18:33.718 +C Expand\sthe\s'make\shelp'\starget\sand\sclean\sup\ssome\soverly-noisy\sconfigure\soutput. +D 2024-10-27T22:34:07.986 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 10eac711b57bce9705555c052e8970e62aa6754b91e1ff37a51c50b040cc4897 +F auto.def ccbcecdf3a348fb463cd11e5fbcc1b2954059103e99531bf84d18a5f56c1351f F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 7533ef1b3a1338b96445a672ba6dbfa48279f05089a0555ff8822dcd1dcb000a +F main.mk 4b0bcec36d5cc83fd60d9c10666f1493c8835cec11b67b3c980ae021e225db03 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 428e542452bac99d48950f1f62b65b4e235636540b946151747e2d5b59dbfd99 -R c11fb367c51c71ad6dcdc1b5cebfcffd +P ab95ee33dfe56bd3b223f978626e6014414881c30443a2b88c782de724c39ae1 +R 4f2f3f9048608d15144b74fa8694e059 U stephan -Z 989475d21f0d39382974a32645a7533c +Z f0d4b898dbccc821754c02bc4f1ee2af # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 31638cc682..dd090aaa96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab95ee33dfe56bd3b223f978626e6014414881c30443a2b88c782de724c39ae1 +c895766ed31f55c02f05d357333e9cf45e82ec5af4d8b0491270e4fda7a57d42 From 1682fedaa0bade7f1ba5efba056374ccf81f5085 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 00:56:31 +0000 Subject: [PATCH 192/522] Add --with-icu-config flag to use the icu-config binary to find the required ldflags for linking the ICU libraries. FossilOrigin-Name: 64f33bb125102b3fec3901f4b56098429509ec0b6ce6e6b88af2393c344ac864 --- auto.def | 88 ++++++++++++++++++++++++++++++++------ autosetup/hwaci-common.tcl | 11 ++++- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 94 insertions(+), 21 deletions(-) diff --git a/auto.def b/auto.def index b4201b79c1..a1a7043a01 100644 --- a/auto.def +++ b/auto.def @@ -173,8 +173,10 @@ set flags { editline=0 => {BSD editline support} # # - with-icu-ldflags:LDFLAGS => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} - icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...} + with-icu-ldflags:LDFLAGS + => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} + icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...} + with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU and fetch linker flags from the given icu-config binary} # # with-wasi-sdk:=/opt/wasi-sdk @@ -878,6 +880,26 @@ proc sqlite-check-line-editing {} { show-notices sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION } + + # Now check whether rl_completion_matches() has a signature we can use. + # cctest is producing unexpected test output when using: + # -includes {stdio.h readline/readline.h} + # so we have to use -source instead and write the whole test app inline + if {[cctest \ + -cflags $rlInc -libs $rlLib -nooutput 1 -source { + #include + #include + static char * rcg(const char *z, int i){return 0;} + int main(void) { + char ** x = rl_completion_matches("one", rcg); + return 0; + } + }]} { + user-notice "Readline completion enabled" + } else { + user-notice "WARNING: readline completion disabled due to rl_completion_matches() signature mismatch" + add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION + } return "readline" } @@ -929,21 +951,63 @@ unset emccsh ######################################################################## # ICU - International Components for Unicode -if {"" ne [define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]]]} { +# +# Handles these flags: +# +# --with-icu-ldflags=LDFLAGS +# --with-icu-config[=/path/to/icu-config] +# --enable-icu-collations +# +# If both icu-ldflags and icu-config are provided, they are +# cumulative. If neither are provided, icu-collations is not honored +# and a warning is emitted if it is provided. +# +# Design note: though we can automatically enable ICU if the +# icu-config binary is found, we specifically do not. ICU is always an +# opt-in feature. +proc sqlite-check-icu {} { + define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]] # Flags sets seen in the wild for ICU: # - -licui18n -licuuc -licudata # - -licui18n -licuuc # - /usr/local/bin/icu-config --ldflags - sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU - msg-result "Enabling ICU support with libs: [get-define LDFLAGS_ICU]" - if {[opt-bool icu-collations]} { - msg-result "Enabling ICU collations." - sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU_COLLATIONS - # Recall that shell.c builds with sqlite3.c + if {[hwaci-opt-was-provided with-icu-config]} { + set bin [opt-val with-icu-config] + if {"auto" eq $bin} { + set bin [hwaci-first-bin-of \ + [get-define prefix]/bin/icu-config \ + /usr/local/bin/icu-config \ + /usr/bin/icu-config] + if {"" eq $bin} { + hwaci-fatal "--with-icu-config=auto cannot find icu-config binary" + } + } + if {[file-isexec $bin]} { + set x [exec $bin --ldflags] + if {"" eq $x} { + hwaci-fatal "$bin --ldflags returned no data" + } + define-append LDFLAGS_ICU $x + } else { + hwaci-fatal "--with-icu-config=$bin does not refer to an executable" + } } -} elseif {[opt-bool icu-collations]} { - hwaci-warn "ignoring --enable-icu-collations because --with-icu-ldflags was not specified" -} + set flags [define LDFLAGS_ICU [string trim [get-define LDFLAGS_ICU]]] + if {"" ne $flags} { + sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU + msg-result "Enabling ICU support with libs: $flags" + if {[opt-bool icu-collations]} { + msg-result "Enabling ICU collations." + sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU_COLLATIONS + # Recall that shell.c builds with sqlite3.c + } + } elseif {[opt-bool icu-collations]} { + hwaci-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags" + } else { + msg-result "ICU support is disabled." + } +}; # sqlite-check-icu +sqlite-check-icu ######################################################################## # Check for log(3) in libm and die with an error if it is not diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 1cde5703c7..126cad2550 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -187,7 +187,7 @@ proc hwaci-find-executable-path {args} { set verbose 0 if {[lindex $args 0] eq "-v"} { set verbose 1 - set binName [lrange $args 1 end] + set args [lassign $args - binName] msg-checking "Looking for $binName ... " } set check [find-executable-path $binName] @@ -255,6 +255,15 @@ proc hwaci-require-bash {} { return $bash } +######################################################################## +# Returns 1 if the user specifically provided the given configure +# flag, else 0. This can be used to distinguish between options which +# have a default value and those which were specifically provided by +# the user. +proc hwaci-opt-was-provided {key} { + return [dict exists $::autosetup(optset) $key] +} + ######################################################################## # Force-set autosetup option $flag to $val. The value can be fetched # later with [opt-val], [opt-bool], and friends. diff --git a/manifest b/manifest index d9d6800c4b..8862d9b64c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\sthe\s'make\shelp'\starget\sand\sclean\sup\ssome\soverly-noisy\sconfigure\soutput. -D 2024-10-27T22:34:07.986 +C Add\s--with-icu-config\sflag\sto\suse\sthe\sicu-config\sbinary\sto\sfind\sthe\srequired\sldflags\sfor\slinking\sthe\sICU\slibraries. +D 2024-10-28T00:56:31.767 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def ccbcecdf3a348fb463cd11e5fbcc1b2954059103e99531bf84d18a5f56c1351f +F auto.def a876018881cc52bd5ac45015d460164fa0c5bc0c92bb820aee3b49c3f38d1394 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl bc48c6ddfcd33a0eaf17f1709cde60622ff29c479e0356e8c6bcabe5b58a4d51 +F autosetup/hwaci-common.tcl e3913fd13debb4e0382c9e68ae46c61f9bc1afcfd2e9996a9b43557deefefb03 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab95ee33dfe56bd3b223f978626e6014414881c30443a2b88c782de724c39ae1 -R 4f2f3f9048608d15144b74fa8694e059 +P c895766ed31f55c02f05d357333e9cf45e82ec5af4d8b0491270e4fda7a57d42 +R 0c3cc11e229eb9f60e9d6e1a23d1a429 U stephan -Z f0d4b898dbccc821754c02bc4f1ee2af +Z cf4b95e7dea0c78a9db6ff8b45d5a758 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dd090aaa96..0c41ed5c78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c895766ed31f55c02f05d357333e9cf45e82ec5af4d8b0491270e4fda7a57d42 +64f33bb125102b3fec3901f4b56098429509ec0b6ce6e6b88af2393c344ac864 From 36cb4d03acabbb3ff04f4cc5e36694b00a8cc7c0 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 01:13:00 +0000 Subject: [PATCH 193/522] Docs and small code cleanups in hwaci-common.tcl. FossilOrigin-Name: 1353d4b600ae2849d2591b3fba0cad71289ee996334222a6886dc01cd4be5c07 --- autosetup/hwaci-common.tcl | 19 ++++++++++++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 126cad2550..8dc76d4f15 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -258,15 +258,27 @@ proc hwaci-require-bash {} { ######################################################################## # Returns 1 if the user specifically provided the given configure # flag, else 0. This can be used to distinguish between options which -# have a default value and those which were specifically provided by -# the user. +# have a default value and those which were explicitly provided by the +# user, even if the latter is done in a way which uses the default +# value. +# +# For example, with a configure flag defined like: +# +# { foo-bar:=baz => {its help text} } +# +# This function will, when passed foo-bar, return 1 only if the user +# passes --foo-bar to configure, even if that invocation would resolve +# to the default value of baz. If the user does not explicitly pass in +# --foo-bar (with or without a value) then this returns 0. proc hwaci-opt-was-provided {key} { - return [dict exists $::autosetup(optset) $key] + dict exists $::autosetup(optset) $key } ######################################################################## # Force-set autosetup option $flag to $val. The value can be fetched # later with [opt-val], [opt-bool], and friends. +# +# Returns $val. proc hwaci-opt-set {flag {val 1}} { global autosetup if {$flag ni $::autosetup(options)} { @@ -275,6 +287,7 @@ proc hwaci-opt-set {flag {val 1}} { lappend ::autosetup(options) $flag } dict set ::autosetup(optset) $flag $val + return $val } ######################################################################## diff --git a/manifest b/manifest index 8862d9b64c..dec3d45e47 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s--with-icu-config\sflag\sto\suse\sthe\sicu-config\sbinary\sto\sfind\sthe\srequired\sldflags\sfor\slinking\sthe\sICU\slibraries. -D 2024-10-28T00:56:31.767 +C Docs\sand\ssmall\scode\scleanups\sin\shwaci-common.tcl. +D 2024-10-28T01:13:00.918 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl e3913fd13debb4e0382c9e68ae46c61f9bc1afcfd2e9996a9b43557deefefb03 +F autosetup/hwaci-common.tcl 0cf12e082cc5045eba20aa323d5139bd3893a2cedcecdccbc8331b069c783d43 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c895766ed31f55c02f05d357333e9cf45e82ec5af4d8b0491270e4fda7a57d42 -R 0c3cc11e229eb9f60e9d6e1a23d1a429 +P 64f33bb125102b3fec3901f4b56098429509ec0b6ce6e6b88af2393c344ac864 +R b9a4b55e0b90ed0b1b286d5c8ffe18f5 U stephan -Z cf4b95e7dea0c78a9db6ff8b45d5a758 +Z 103ccefab8e9ee7baf6989214f50afc6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0c41ed5c78..016a828e90 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64f33bb125102b3fec3901f4b56098429509ec0b6ce6e6b88af2393c344ac864 +1353d4b600ae2849d2591b3fba0cad71289ee996334222a6886dc01cd4be5c07 From 5a6dc86df2d1027d0bd72d68b65a2be18cd52570 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 02:11:51 +0000 Subject: [PATCH 194/522] Have --enable-editline fail rather than emit a warning which would easily be overlooked by automated builds. The error message explains a potential workaround for activating libedit. FossilOrigin-Name: 2bd1b9557a1619adcaf5aa6dc5d5d0972e8416dafc9f36621b409192be95223d --- auto.def | 11 ++++++----- autosetup/hwaci-common.tcl | 15 +++++++++++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/auto.def b/auto.def index a1a7043a01..8e708a7e7b 100644 --- a/auto.def +++ b/auto.def @@ -776,13 +776,14 @@ proc sqlite-check-line-editing {} { # --enable-editline to do exactly that but it seems likely to # break on systems for which which HAVE_EDITLINE=1 previously # worked. - hwaci-indented-notice { - WARNING: the --enable-editline flag is not supported due to + hwaci-indented-notice -error { + ERROR: the --enable-editline flag is not supported due to non-availability of systems which have it in a form which the sqlite3 CLI shell expects to see. On some systems this can be - worked around by passing --with-readline-ldflags=-ledit instead of - --enable-editline, which will attempt to use the readline.h - supplied by libreadline but link against -ledit. + worked around by passing --with-readline-ldflags=-ledit instead + of --enable-editline, which will attempt to use the readline.h + supplied by libreadline but link against -ledit. On systems + tested so far, that works. } return "none" } elseif {![opt-bool readline]} { diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 8dc76d4f15..053a30a370 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -75,11 +75,22 @@ proc hwaci-bold {str} { # using [user-notice] (which means its rendering will (A) go to stderr # and (B) be delayed until the next time autosetup goes to output a # message). -proc hwaci-indented-notice {msg} { - set lines [split $msg \n] +# +# If its first argument is -error then it renders the message +# immediately and then exits. +proc hwaci-indented-notice {args} { + set fErr "" + switch -exact -- [lindex $args 0] { + -error { set args [lassign $args fErr] } + } + set lines [split [join $args] \n] foreach line $lines { user-notice " [string trimleft $line]" } + if {"" ne $fErr} { + show-notices + exit 1 + } } ######################################################################## diff --git a/manifest b/manifest index dec3d45e47..6fe2eecd7a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Docs\sand\ssmall\scode\scleanups\sin\shwaci-common.tcl. -D 2024-10-28T01:13:00.918 +C Have\s--enable-editline\sfail\srather\sthan\semit\sa\swarning\swhich\swould\seasily\sbe\soverlooked\sby\sautomated\sbuilds.\sThe\serror\smessage\sexplains\sa\spotential\sworkaround\sfor\sactivating\slibedit. +D 2024-10-28T02:11:51.336 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a876018881cc52bd5ac45015d460164fa0c5bc0c92bb820aee3b49c3f38d1394 +F auto.def 33b45a5d8a51f0f8a211c8983c1c7306120a672f4c37dccf8b3e4c343c8d4569 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 0cf12e082cc5045eba20aa323d5139bd3893a2cedcecdccbc8331b069c783d43 +F autosetup/hwaci-common.tcl 064900a2e7512e6e1ce9f25bb74d6850574d294b026885f0329dbe69585407dd F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 64f33bb125102b3fec3901f4b56098429509ec0b6ce6e6b88af2393c344ac864 -R b9a4b55e0b90ed0b1b286d5c8ffe18f5 +P 1353d4b600ae2849d2591b3fba0cad71289ee996334222a6886dc01cd4be5c07 +R c5d541f8ce498a3c24d538d7cf4698ef U stephan -Z 103ccefab8e9ee7baf6989214f50afc6 +Z 8668cf4e3948e2d9e4ce3d2e5557772d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 016a828e90..b9ceddc997 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1353d4b600ae2849d2591b3fba0cad71289ee996334222a6886dc01cd4be5c07 +2bd1b9557a1619adcaf5aa6dc5d5d0972e8416dafc9f36621b409192be95223d From 99438c843c294475ec8093e4485c14bd4392ee9b Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 02:46:57 +0000 Subject: [PATCH 195/522] Correct the default config value for HAVE_TCL (0 until proven otherwise) and fix the starting dir for SQLITE_AUTORECONFIG (formerly SQLITE_AUTOREMAKE), as reported in [forum:8ab69387008f2f6c | forum post 8ab69387008f2f6c]. FossilOrigin-Name: 55f78b639624ad360d04c102339ef7147d6d24dd9bd0d17b346df0c03ee443b6 --- Makefile.in | 12 +++++++----- auto.def | 17 +++++++++++------ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9bdee26d73..4b42018e92 100644 --- a/Makefile.in +++ b/Makefile.in @@ -120,6 +120,8 @@ T.cc.sqlite = $(T.cc) @TARGET_DEBUG@ # can include the generated sqlite_cfg.h. # T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite +T.cc.sqlite += -I$(prefix)/include + # # main.mk will fill out T.cc.sqlite with some flags common to all builds. @@ -241,7 +243,7 @@ AS_AUTO_DEF = $(TOP)/auto.def # Shell commands to re-run $(TOP)/configure with the same args it was # invoked with to produce this makefile. # -AS_AUTOREMAKE = @SQLITE_AUTOREMAKE@ +AS_AUTORECONFIG = @SQLITE_AUTORECONFIG@ USE_AMALGAMATION ?= @USE_AMALGAMATION@ AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ @@ -252,16 +254,16 @@ AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ SHELL_OPT ?= @OPT_SHELL@ Makefile: $(TOP)/Makefile.in $(AS_AUTO_DEF) - $(AS_AUTOREMAKE) + $(AS_AUTORECONFIG) @touch $@ sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF) - $(AS_AUTOREMAKE) + $(AS_AUTORECONFIG) @touch $@ install: install-pc # defined in main.mk sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) - $(AS_AUTOREMAKE) + $(AS_AUTORECONFIG) @touch $@ # @@ -311,7 +313,7 @@ clean-autosetup: clean: clean-autosetup distclean-autosetup: clean - rm -f sqlite_cfg.h config.log config.status config.defines.json Makefile sqlite3.pc + rm -f sqlite_cfg.h config.log config.status config.defines.* Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh rm -f libsqlite3*$(T.dll) rm -f jimsh0* diff --git a/auto.def b/auto.def index 8e708a7e7b..e2ba5f1db9 100644 --- a/auto.def +++ b/auto.def @@ -220,10 +220,15 @@ msg-result "srcdir = $srcdir" msg-result "top_srcdir = $top_srcdir" msg-result [hwaci-bold "Configuring SQLite version $PACKAGE_VERSION"] -define-append SQLITE_AUTOREMAKE cd '$srcdir' && '$top_srcdir/configure' +# +# SQLITE_AUTORECONFIG contains make target rules for re-running the +# configure script with the same arguments it was initially invoked +# with. This can be used to automatically reconfigure +# +define-append SQLITE_AUTORECONFIG cd '$::autosetup(builddir)' && '$top_srcdir/configure' #{*}$::autosetup(argv) breaks with --flag='val with spaces', so... foreach arg $::autosetup(argv) { - define-append SQLITE_AUTOREMAKE '$arg' + define-append SQLITE_AUTORECONFIG '$arg' } @@ -456,7 +461,7 @@ hwaci-if-opt-truthy with-debug { # components. # define TCLSH_CMD {exit 1} -define HAVE_TCL [opt-bool tcl] +define HAVE_TCL 0 proc sqlite-check-tcl {} { # TODO: document the steps this is taking. if {![opt-bool tcl]} { @@ -1127,11 +1132,11 @@ if {0} { # Requires no input template... make-config-header sqlite_cfg.h \ -bare {SIZEOF_* HAVE_DECL_*} \ - -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG TARGET_* USE_GCOV TCL_*} \ -auto {HAVE_* PACKAGE_*} \ -none * - hwaci-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTOREMAKE@ + hwaci-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@ } #TODO hwaci-make-from-dot-in ext/wasm/GNUmakefile @@ -1144,7 +1149,7 @@ if {"" ne $DUMP_DEFINES_JSON} { define OPT_SHELL.list [get-define OPT_SHELL] set dumpDefsOpt { -bare {SIZEOF_* HAVE_DECL_*} - -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTOREMAKE TARGET_* USE_GCOV TCL_*} + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG TARGET_* USE_GCOV TCL_*} -array {*.list} -auto {OPT_* PACKAGE_* HAVE_*} } diff --git a/manifest b/manifest index 6fe2eecd7a..8d308587c4 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Have\s--enable-editline\sfail\srather\sthan\semit\sa\swarning\swhich\swould\seasily\sbe\soverlooked\sby\sautomated\sbuilds.\sThe\serror\smessage\sexplains\sa\spotential\sworkaround\sfor\sactivating\slibedit. -D 2024-10-28T02:11:51.336 +C Correct\sthe\sdefault\sconfig\svalue\sfor\sHAVE_TCL\s(0\suntil\sproven\sotherwise)\sand\sfix\sthe\sstarting\sdir\sfor\sSQLITE_AUTORECONFIG\s(formerly\sSQLITE_AUTOREMAKE),\sas\sreported\sin\s[forum:8ab69387008f2f6c\s|\sforum\spost\s8ab69387008f2f6c]. +D 2024-10-28T02:46:57.310 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 -F Makefile.in 957cbf0d25ced08f6703b82f2070cbea791aeeb2d6059c4426c30cd87c80250f +F Makefile.in 783a6819b11669d374d867e68cffb018cc5fd78b1113dd10be1d04f14c62a3b3 F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 33b45a5d8a51f0f8a211c8983c1c7306120a672f4c37dccf8b3e4c343c8d4569 +F auto.def 57635a8f8c2e5e91e4c21094a70bbb56473811366e75679ceec9b6626e49a826 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1353d4b600ae2849d2591b3fba0cad71289ee996334222a6886dc01cd4be5c07 -R c5d541f8ce498a3c24d538d7cf4698ef +P 2bd1b9557a1619adcaf5aa6dc5d5d0972e8416dafc9f36621b409192be95223d +R e1aee29c1c29ac7235c75bc587493265 U stephan -Z 8668cf4e3948e2d9e4ce3d2e5557772d +Z 50271136afde4fe48404bfa37e74b2eb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9ceddc997..51271d0f40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2bd1b9557a1619adcaf5aa6dc5d5d0972e8416dafc9f36621b409192be95223d +55f78b639624ad360d04c102339ef7147d6d24dd9bd0d17b346df0c03ee443b6 From ee0b5e9bedb9222abf766e825dcfa226bf6247a9 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 02:49:45 +0000 Subject: [PATCH 196/522] Document why -IPREFIX/include is now part of T.cc.sqlite. FossilOrigin-Name: d64dcb1a897f6cc690c680cdaf85272e2dd249f36798219834116b1375f74d34 --- Makefile.in | 4 ++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4b42018e92..67cc9ac453 100644 --- a/Makefile.in +++ b/Makefile.in @@ -120,6 +120,10 @@ T.cc.sqlite = $(T.cc) @TARGET_DEBUG@ # can include the generated sqlite_cfg.h. # T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite +# +# -I$(prefix)/include is primarily so that the ICU +# headers can be found. +# T.cc.sqlite += -I$(prefix)/include # diff --git a/manifest b/manifest index 8d308587c4..b3142b0746 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Correct\sthe\sdefault\sconfig\svalue\sfor\sHAVE_TCL\s(0\suntil\sproven\sotherwise)\sand\sfix\sthe\sstarting\sdir\sfor\sSQLITE_AUTORECONFIG\s(formerly\sSQLITE_AUTOREMAKE),\sas\sreported\sin\s[forum:8ab69387008f2f6c\s|\sforum\spost\s8ab69387008f2f6c]. -D 2024-10-28T02:46:57.310 +C Document\swhy\s-IPREFIX/include\sis\snow\spart\sof\sT.cc.sqlite. +D 2024-10-28T02:49:45.984 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 -F Makefile.in 783a6819b11669d374d867e68cffb018cc5fd78b1113dd10be1d04f14c62a3b3 +F Makefile.in 02ea00ff433902dba369d4a55b3aeb6bb1ffe2d82f777194984b8cdd7ed7c3ad F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2bd1b9557a1619adcaf5aa6dc5d5d0972e8416dafc9f36621b409192be95223d -R e1aee29c1c29ac7235c75bc587493265 +P 55f78b639624ad360d04c102339ef7147d6d24dd9bd0d17b346df0c03ee443b6 +R 682368e231656f5796597ceeb6bfca0b U stephan -Z 50271136afde4fe48404bfa37e74b2eb +Z 165d962fa0afbbbe6a9fa8d04b79266b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 51271d0f40..f3ce270dda 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55f78b639624ad360d04c102339ef7147d6d24dd9bd0d17b346df0c03ee443b6 +d64dcb1a897f6cc690c680cdaf85272e2dd249f36798219834116b1375f74d34 From 5f05a7c3c706c39359f62b767de08508df1d8886 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 11:13:00 +0000 Subject: [PATCH 197/522] Simplify how hwaci-xfer-options-aliases figures out whether flags are provided. FossilOrigin-Name: f06122a543f7dac016c8da1cd92a629eb647142b95c85a131b9da8e0dc5516b0 --- autosetup/hwaci-common.tcl | 11 +++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/autosetup/hwaci-common.tcl b/autosetup/hwaci-common.tcl index 053a30a370..4168b87460 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/hwaci-common.tcl @@ -1068,13 +1068,12 @@ proc hwaci-dump-defs-json {file args} { # names, so that in the above example [opt-value canonical] will # return X if --alias=X is passed in. proc hwaci-xfer-options-aliases {mapping} { - foreach {hidden => canonical} [hwaci-strip-hash-comments_ $mapping] { - set x [opt-val $hidden "~9~9~9~"] - if {"~9~9~9~" ne $x} { - if {"~0~0~0~" eq [opt-val $canonical "~0~0~0~"]} { - hwaci-opt-set $canonical $x - } else { + foreach {hidden - canonical} [hwaci-strip-hash-comments_ $mapping] { + if {[hwaci-opt-was-provided $hidden]} { + if {[hwaci-opt-was-provided $canonical]} { hwaci-fatal "both --$canonical and its alias --$hidden were used. Use only one or the other." + } else { + hwaci-opt-set $canonical [opt-val $hidden] } } } diff --git a/manifest b/manifest index b3142b0746..2c35456c3c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Document\swhy\s-IPREFIX/include\sis\snow\spart\sof\sT.cc.sqlite. -D 2024-10-28T02:49:45.984 +C Simplify\show\shwaci-xfer-options-aliases\sfigures\sout\swhether\sflags\sare\sprovided. +D 2024-10-28T11:13:00.630 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 064900a2e7512e6e1ce9f25bb74d6850574d294b026885f0329dbe69585407dd +F autosetup/hwaci-common.tcl 48c221838bca6e362b34c85c3dff2ba7f69efcec9558d3807c9b33b1d8c13c28 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2237,8 +2237,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 55f78b639624ad360d04c102339ef7147d6d24dd9bd0d17b346df0c03ee443b6 -R 682368e231656f5796597ceeb6bfca0b +P d64dcb1a897f6cc690c680cdaf85272e2dd249f36798219834116b1375f74d34 +R 2d6ac9d6e14c6a624c64205aaf80d12a U stephan -Z 165d962fa0afbbbe6a9fa8d04b79266b +Z 8a53b827d8fcdc17c9d21906a45eb0d2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f3ce270dda..c4f30ccd67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d64dcb1a897f6cc690c680cdaf85272e2dd249f36798219834116b1375f74d34 +f06122a543f7dac016c8da1cd92a629eb647142b95c85a131b9da8e0dc5516b0 From dfa64c55424ac0ddad20ecf3d63f39a98648101e Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Oct 2024 13:16:32 +0000 Subject: [PATCH 198/522] Remove the long-unused, legacy vsixtest/ logic from the source tree. FossilOrigin-Name: 45ec9415b2b76a757e8bd25eed520dcc012ba67cbb3530ee8dcc42ac6125464a --- manifest | 33 +- manifest.uuid | 2 +- vsixtest/App.xaml | 8 - vsixtest/App.xaml.cpp | 120 ------ vsixtest/App.xaml.h | 27 -- vsixtest/Assets/LockScreenLogo.scale-200.png | Bin 1430 -> 0 bytes vsixtest/Assets/SplashScreen.scale-200.png | Bin 7700 -> 0 bytes .../Assets/Square150x150Logo.scale-200.png | Bin 2937 -> 0 bytes vsixtest/Assets/Square44x44Logo.scale-200.png | Bin 1647 -> 0 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 1255 -> 0 bytes vsixtest/Assets/StoreLogo.png | Bin 1451 -> 0 bytes vsixtest/Assets/Wide310x150Logo.scale-200.png | Bin 3204 -> 0 bytes vsixtest/MainPage.xaml | 13 - vsixtest/MainPage.xaml.cpp | 53 --- vsixtest/MainPage.xaml.h | 22 -- vsixtest/Package.appxmanifest | 49 --- vsixtest/pch.cpp | 6 - vsixtest/pch.h | 11 - vsixtest/vsixtest.sln | 39 -- vsixtest/vsixtest.tcl | 373 ------------------ vsixtest/vsixtest.vcxproj.data | 198 ---------- vsixtest/vsixtest.vcxproj.filters | 57 --- vsixtest/vsixtest_TemporaryKey.pfx | Bin 2520 -> 0 bytes 23 files changed, 7 insertions(+), 1004 deletions(-) delete mode 100644 vsixtest/App.xaml delete mode 100644 vsixtest/App.xaml.cpp delete mode 100644 vsixtest/App.xaml.h delete mode 100644 vsixtest/Assets/LockScreenLogo.scale-200.png delete mode 100644 vsixtest/Assets/SplashScreen.scale-200.png delete mode 100644 vsixtest/Assets/Square150x150Logo.scale-200.png delete mode 100644 vsixtest/Assets/Square44x44Logo.scale-200.png delete mode 100644 vsixtest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png delete mode 100644 vsixtest/Assets/StoreLogo.png delete mode 100644 vsixtest/Assets/Wide310x150Logo.scale-200.png delete mode 100644 vsixtest/MainPage.xaml delete mode 100644 vsixtest/MainPage.xaml.cpp delete mode 100644 vsixtest/MainPage.xaml.h delete mode 100644 vsixtest/Package.appxmanifest delete mode 100644 vsixtest/pch.cpp delete mode 100644 vsixtest/pch.h delete mode 100644 vsixtest/vsixtest.sln delete mode 100644 vsixtest/vsixtest.tcl delete mode 100644 vsixtest/vsixtest.vcxproj.data delete mode 100644 vsixtest/vsixtest.vcxproj.filters delete mode 100644 vsixtest/vsixtest_TemporaryKey.pfx diff --git a/manifest b/manifest index 2c35456c3c..b4a42b176a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\show\shwaci-xfer-options-aliases\sfigures\sout\swhether\sflags\sare\sprovided. -D 2024-10-28T11:13:00.630 +C Remove\sthe\slong-unused,\slegacy\svsixtest/\slogic\sfrom\sthe\ssource\stree. +D 2024-10-28T13:16:32.455 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -2216,29 +2216,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -F vsixtest/App.xaml b76d3b48860e7454775c47ea38ffea9c4abe3e85 -F vsixtest/App.xaml.cpp 41158ee43269820136fa3bba00c0bd91b26cc38b650ee392aec2a8d823e54318 -F vsixtest/App.xaml.h 4a9768e2983d05600ad1e1c2f1b00a132967da9f -F vsixtest/Assets/LockScreenLogo.scale-200.png e820c9a3deb909197081b0bf3216c06e13905f0a -F vsixtest/Assets/SplashScreen.scale-200.png cab70988ca71bebec7bfeb3b6dbafe17b9ab0b4a -F vsixtest/Assets/Square150x150Logo.scale-200.png e17b40817db7a239fc239d83efcc951fb824e3ff -F vsixtest/Assets/Square44x44Logo.scale-200.png 2f166237094dea94d952d10b9eeae81806844f1c -F vsixtest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png 5f6a6d391b95a3061ccca6e6fdd6955ede63b4ed -F vsixtest/Assets/StoreLogo.png 0828b7257db74a4ecd5eeb6b7b4971f0fdc4d9d1 -F vsixtest/Assets/Wide310x150Logo.scale-200.png 04ddefe5bc5f43ae12a7433f6f236ddab101ac42 -F vsixtest/MainPage.xaml 34f49897e3ca533a7e74506ba0759b66eebce151 -F vsixtest/MainPage.xaml.cpp 7f31fc6de751b64676c0924c97a5485d950a91d7 -F vsixtest/MainPage.xaml.h cc05cca10d50a003f6c6e4448b701cdd07f52f29 -F vsixtest/Package.appxmanifest 6b6db1eb7df3a315c5d681059754d5f0e0c47a93 -F vsixtest/pch.cpp cb823cfac36f1a39a7eb0acbd7e9a0b0de8f23af -F vsixtest/pch.h 9cab7980f2ac4baa40807d8b5e52af32a21cf78c -F vsixtest/vsixtest.sln 77cadbe4e96c1fe1bf51cd77de9e9b0a12ada547 -F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080bb302912 -F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc -F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e -F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d64dcb1a897f6cc690c680cdaf85272e2dd249f36798219834116b1375f74d34 -R 2d6ac9d6e14c6a624c64205aaf80d12a -U stephan -Z 8a53b827d8fcdc17c9d21906a45eb0d2 +P f06122a543f7dac016c8da1cd92a629eb647142b95c85a131b9da8e0dc5516b0 +R 12ff824529fe88bfe6b4597dc4df53e3 +U drh +Z 126f0766a209d0ba5b53f17fec16055d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c4f30ccd67..d64be41552 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f06122a543f7dac016c8da1cd92a629eb647142b95c85a131b9da8e0dc5516b0 +45ec9415b2b76a757e8bd25eed520dcc012ba67cbb3530ee8dcc42ac6125464a diff --git a/vsixtest/App.xaml b/vsixtest/App.xaml deleted file mode 100644 index 80889024ca..0000000000 --- a/vsixtest/App.xaml +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/vsixtest/App.xaml.cpp b/vsixtest/App.xaml.cpp deleted file mode 100644 index c90604a830..0000000000 --- a/vsixtest/App.xaml.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// -// App.xaml.cpp -// Implementation of the App class. -// - -#include "pch.h" -#include "MainPage.xaml.h" - -using namespace vsixtest; - -using namespace Platform; -using namespace Windows::ApplicationModel; -using namespace Windows::ApplicationModel::Activation; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace Windows::UI::Xaml; -using namespace Windows::UI::Xaml::Controls; -using namespace Windows::UI::Xaml::Controls::Primitives; -using namespace Windows::UI::Xaml::Data; -using namespace Windows::UI::Xaml::Input; -using namespace Windows::UI::Xaml::Interop; -using namespace Windows::UI::Xaml::Media; -using namespace Windows::UI::Xaml::Navigation; - -/// -/// Initializes the singleton application object. This is the first line of authored code -/// executed, and as such is the logical equivalent of main() or WinMain(). -/// -App::App() -{ - InitializeComponent(); - Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending); -} - -/// -/// Invoked when the application is launched normally by the end user. Other entry points -/// will be used such as when the application is launched to open a specific file. -/// -/// Details about the launch request and process. -void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) -{ - -#if _DEBUG - // Show graphics profiling information while debugging. - if (IsDebuggerPresent()) - { - // Display the current frame rate counters - DebugSettings->EnableFrameRateCounter = true; - } -#endif - - auto rootFrame = dynamic_cast(Window::Current->Content); - - // Do not repeat app initialization when the Window already has content, - // just ensure that the window is active - if (rootFrame == nullptr) - { - // Create a Frame to act as the navigation context and associate it with - // a SuspensionManager key - rootFrame = ref new Frame(); - - rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed); - - if (e->PreviousExecutionState == ApplicationExecutionState::Terminated) - { - // TODO: Restore the saved session state only when appropriate, scheduling the - // final launch steps after the restore is complete - - } - - if (rootFrame->Content == nullptr) - { - // When the navigation stack isn't restored navigate to the first page, - // configuring the new page by passing required information as a navigation - // parameter - rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments); - } - // Place the frame in the current Window - Window::Current->Content = rootFrame; - // Ensure the current window is active - Window::Current->Activate(); - } - else - { - if (rootFrame->Content == nullptr) - { - // When the navigation stack isn't restored navigate to the first page, - // configuring the new page by passing required information as a navigation - // parameter - rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments); - } - // Ensure the current window is active - Window::Current->Activate(); - } -} - -/// -/// Invoked when application execution is being suspended. Application state is saved -/// without knowing whether the application will be terminated or resumed with the contents -/// of memory still intact. -/// -/// The source of the suspend request. -/// Details about the suspend request. -void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e) -{ - (void) sender; // Unused parameter - (void) e; // Unused parameter - - //TODO: Save application state and stop any background activity -} - -/// -/// Invoked when Navigation to a certain page fails -/// -/// The Frame which failed navigation -/// Details about the navigation failure -void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e) -{ - throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name); -} diff --git a/vsixtest/App.xaml.h b/vsixtest/App.xaml.h deleted file mode 100644 index 5fa8837d38..0000000000 --- a/vsixtest/App.xaml.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// App.xaml.h -// Declaration of the App class. -// - -#pragma once - -#include "App.g.h" - -namespace vsixtest -{ - /// - /// Provides application-specific behavior to supplement the default Application class. - /// - ref class App sealed - { - protected: - virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override; - - internal: - App(); - - private: - void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e); - void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e); - }; -} diff --git a/vsixtest/Assets/LockScreenLogo.scale-200.png b/vsixtest/Assets/LockScreenLogo.scale-200.png deleted file mode 100644 index 735f57adb5dfc01886d137b4e493d7e97cf13af3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1430 zcmaJ>TTC2P7~aKltDttVHYH6u8Io4i*}3fO&d$gd*bA_<3j~&e7%8(eXJLfhS!M@! zKrliY>>6yT4+Kr95$!DoD(Qn-5TP|{V_KS`k~E6(LGS@#`v$hQo&^^BKsw3HIsZBT z_y6C2n`lK@apunKojRQ^(_P}Mgewt$(^BBKCTZ;*xa?J3wQ7~@S0lUvbcLeq1Bg4o zH-bvQi|wt~L7q$~a-gDFP!{&TQfc3fX*6=uHv* zT&1&U(-)L%Xp^djI2?~eBF2cxC@YOP$+9d?P&h?lPy-9M2UT9fg5jKm1t$m#iWE{M zIf%q9@;fyT?0UP>tcw-bLkz;s2LlKl2qeP0w zECS7Ate+Awk|KQ+DOk;fl}Xsy4o^CY=pwq%QAAKKl628_yNPsK>?A>%D8fQG6IgdJ ztnxttBz#NI_a@fk7SU`WtrpsfZsNs9^0(2a z@C3#YO3>k~w7?2hipBf{#b6`}Xw1hlG$yi?;1dDs7k~xDAw@jiI*+tc;t2Lflg&bM)0!Y;0_@=w%`LW^8DsYpS#-bLOklX9r?Ei}TScw|4DbpW%+7 zFgAI)f51s}{y-eWb|vrU-Ya!GuYKP)J7z#*V_k^Xo>4!1Yqj*m)x&0L^tg3GJbVAJ zJ-Pl$R=NAabouV=^z_t;^K*0AvFs!vYU>_<|I^#c?>>CR<(T?=%{;U=aI*SbZADLH z&(f2wz_Y0??Tf|g;?|1Znw6}6U43Q#qNRwv1vp9uFn1)V#*4p&%$mP9x&15^OaBiDS(XppT|z^>;B{PLVEbS3IFYV yGvCsSX*m diff --git a/vsixtest/Assets/SplashScreen.scale-200.png b/vsixtest/Assets/SplashScreen.scale-200.png deleted file mode 100644 index 023e7f1feda78d5100569825acedfd213a0d84e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7700 zcmeHLYj~4Yw%(;oxoEH#Kxq-eR|+VkP17b#Vk;?4QwkI+A{L04G+#<<(x#Un1#+h5>eArRq zTw$)ZvTWW_Y?bDho0nPVTh08+s`sp!j74rJTTtXIDww0SILedFv?sZ?yb@@}GN;#8 znk_b~Q(A0YR#uV4ef!osoV1M3;vQ8N$O|fStfgf$S5;ddUNv`tWtGjM;koG#N;7M< zP*84lnx(bn_KF&9Z5Ai$)#Cs3a|$OFw>WKCT$of*L7_CqQEinflT|W{JT+aKp-E0v zsxmYg)1(T>DROm+LN1eQw8}KCTp=C!$H7`PU!t9_Hw@TsTI2`udRZv*!a5`#A9hK6Y95L(CDUX&_@QxKV z_feX{UhA#ZWlvgpL$#w^D#lq`_A4AzDqd|Zv6y9PX&DNcN|l}_D^{q@GG&H^Pg583 z8FI6N8^H7b5WjGp;urW)d7F+_lcp%KsLX0viCmE(OHH+=%ZfD_=`voUuoUxFO^L;- z;!;2{g-YiiO6m4bs89OuF9!p{FGtH-f%8<2gY!h9s)4ciN%{Kh1+`}{^}M~+TDH9N z^Z5PlgVXMC&2&k*Hw^Lb9gny#ro$MOIxIt{+r)EA10$VR3 zanN8D{TUkl+v0CQ_>ZoHP<M-x#8@8ZiT#$Kh`(uRaX1g$Bg|qy$<#7 zSSAi{Nb8Y=lvNVeio+UGLCAtoLBfL`iOv`)yoJMDJBN>4IH@(l7YRF;61@>qq1iM9 zr@b#OC~SAxSle?5Pp8Z78{VO0YFr1x7kZU64Z23eLf2T2#6J_t;-E}DkB?NufZ0Ug zi?J&byXeaB-uTNVhuiM!UVQw}bZrJ3GtAETYp->!{q#zfN7D3AS9@Q7*V^85jGx#R z(QxYV(wW#F0XF9^^s>>H8pPlVJ>)3Oz z&_X8Sf@~?cH_O*cgi$U#`v`RRfv#y3m(ZpKk^5uLup+lVs$~}FZU$r_+}#hl%?g5m z-u-}-666ssp-xWQak~>PPy$mRc|~?pVSs1_@mBEXpPVfLF6(Ktf1S* zPPh@QZ=tFMs?LM2(5P3L2;l_6XX6s&cYsP1ip#eg0`ZEP0HGYh{UmS@o`MihLLvkU zgyAG0G`b1|qjxxh1(ODKFE%AP}Dq=3vK$P7TXP4GrM1kQ72!GUVMDl`rDC&2;TA}*nF z8$nQD&6ys_nc1*E7$*1S@R8$ymy(sQV}imGSedB@{!QR5P&N_H=-^o!?LsWs+2|mH z-e=)T^SvI)=_JIm7}j4;@*Z17=(#}m=~YF~z~CLI+vdAGlJDcdF$TM?CVI1%LhUrN zaa6DJ=Yh$)$k&Oz{-~8yw^GM^8prYxSxo zvI4k#ibryMa%%*8oI-5m61Koa_A_xg=(fwp0aBX{;X4Q;NXUhtaoJDo1>TqhWtn=_ zd5~chq#&6~c%8JZK#t_&J(9EVUU&upYeIovLt1>vaHe}UUq>#RGQj!EN#5+0@T`(@ z^g~>*c`VGRiSt;!$_4+0hk^I!@O3``5=sZ8IwlxWW7km1B&_t&E*u0_9UBa#VqwY* zz>nxv?FAsVnRaD(Bui=6i==BFUw0k4n$>`umU`F2l?7CYTD^)c2X+d9X&ddS9|gj? zM?knGkGCX&W8offw8aLC2$D{PjC3nVZwd4k?eZH8*mZ)U@3Qk8RDFOz_#WUA#vnzy zyP>KrCfKwSXea7}jgJjBc}PGY+4#6%lbZyjhy`5sZd_Vy6Wz;ixa?czkN}J9It1K6 zY!eu>|AwF^fwZlLAYyQI*lM@^>O>Iu6Vf6i>Q$?v!SeUS<{>UYMwz$*%Aq?w^`j{h z!$GZbhu=^D{&ET8;))LL%ZBDZkQqRd2;u~!d9bHGmLRhLDctNgYyjsuvoSZ#iVdoB z2!f--UUA#U;<{je#?cYt^{PIyKa%hW>}uepWMyAI{{Zo7?2>?$c9;whJae%oN|I-kpTQSx_C$Z&;f zi2i)qmEn=y4U0uvk)$m;zKfjPK@oc?I`}1Jzl$Q~aoKBd3kt7L#7gyt|A_qgz6ai< z=X%D1i!d2h?rHR^R8SUj&G||dkC?DT>{o#Yau<@uqVT{Xef&XG}5*E4aPk{}~ zplx&XhaV)&1EfI3Em;Bw#O5SV^c;{twb-1Rw)+=0!e_BLbd7tYmXCH0wrlOSS+~`7He8Iqx0{CN+DVit9;*6L~JAN zD&cyT)2?h}xnYmL?^)<7YyzZ3$FHU^Eg;DLqAV{#wv#Wj7S`Jdl1pX&{3(uZ?!uh} zDc$ZTNV*7le_W6}Hju~GMTxZQ1aWCeUc%!jv3MHAzt>Y-nQK%zfT*3ebDQA5b?iGn; zBjv3B+GhLTexd_(CzZDP4|#n5^~scvB6#Pk%Ho!kQ>yYw((Dv{6=$g3jT1!u6gORW zx5#`7Wy-ZHRa~IxGHdrp(bm%lf>2%J660nj$fCqN(epv@y!l9s7@k6EvxS{AMP>WY zX4$@F8^kayphIx-RGO$+LYl9YdoI5d|4#q9##`_F5Xnx`&GPzp2fB{-{P@ATw=X@~ z_|&^UMWAKD;jjBKTK(~o?cUFRK8EX=6>cXpfzg4ZpMB>*w_^8GSiT-Jp|xBOnzM+j z*09-@-~qJ(eqWq5@R4i^u4^{McCP(!3}C|v_WsTR*bIUxN(Nx`u##3B4{sE`Z`v8w zAwIG`?1~PkID~W{uDzmqH98Pew_1(;x2%8r^vY{)_&J2K)cN{W+h5+g)ZcjP&Ci#O zgy|8K@4kyMfwilHd&6TDlhb%++Pk!>9HRld6HT7gwyZGrxS$}CsD6`>6!!2K1@Mjf z(P0WYB7V_OFZyeWrbOFb>O54BNXf~K&?}3=^v;v_wT{DKr?jN^DtN&DXwX%u?s*c6`%8>WFz z7}YW^tp0bp^NriE)AB6M2l<7rn7fzePtR*omOevpfm9n?}2V*+0iW;S)C zhg`NAjL?D=W#k*$aR{>pGf~lD-rVtD;5jW1_*Jn1j1=es@Kcx4ySM_bwcQCT=d+DV z>Sz~L=Hj@(X%31nK$mWI@7d>}ORB`K(p=+`UD)+99YUGQc7y^bHZ1F(8|tL0 zdK*DT0kSXG_{BKTpP2*2PecdKV9;dq$^ZZDP;Nyq1kp-&GI5eAyZsK!e3V zK@rPy*{(`KIfo+lc878mDKk^V#`VT05}64kBtk%DgwLrOvLMj5-;*GNKv6c6pzMuL z6EP%ob|_0IW}lLRXCP2!9wWhEw3LA7iF#1O1mIZ@Z=6&bz41F;@S_GvYAG-#CW3z{ zP3+6vHhvP&A3$##Vo9$dT^#MoGg^|MDm=Bt1d2RRwSZ<;ZHICpLBv5Xs!D?BH^(9_ z7`H=N&^v|Z-%mP}wNzG{aiFCsRgwzwq!N6obW9+7(R; z(SZ=23`|`>qil!LMGG{_Heq!BD>(Y-zV9wD)}hz25JA37YR%39;kI4y9pgtcUass6 zP24}ZY$vvYeI`zy&)A_X#nY3017ap*0&jx|mVwyGhg3;!keU53a}Uhm3BZI$N$6Se zLWlAmy1S0xKJm4G_U@sN_Tm=`$xWJSEwKU98rZ&)1R^*$$1vA3oG#&*%SMxY_~oGP zP&PFJatFLM-Ps%84IV-+Ow)T{C7cqUAvauy4C z(FRz&?6$Rypj{xO!`y=*J5o4@U8Q-(y5(*=YoKeZ+-1YdljXxkA#B)zo=FeQH#?Le zycNUmEEHWO9a=X^pb#&cOq7-`7UA87#|S22)<7RUtZo|(zibX=w;K3qur9vy#`MNV z6UUcf9ZwEnKCCp+OoBnF@OdbvH)ANXO0o~Pi9l8=x3))}L<#vO0-~O4!~--Ket?d} zJaqsj<@CD1%S2cTW%rOP{Vto%0sGW~1RMa_j^)5nil0Yw- z0EE#bP+l4#P^%PQ+N*oxu1Zq05xZ!bXfYTg>9c{(Iw*lnjR^>kz%lAN^zFce7rppy zY8zA~3GD=A6d*hze&l4D_wA~+O!56)BZTe_rEu}Ezi<4!kG|W#amBZ5{&XS2@6R~H z{9o^y*BkH4$~yX9U&@CgbOzX1bn9xqF|zh$Dh0Y5y*E0e90*$!ObrHY3Ok0`2=O~r zCuke6KrP9KOf?V(YDsM<6pX2nVoN%M$LT^q#FmtaF?1^27F*IcNX~XRB(|hCFvdcc zc)$=S-)acdk$g4?_>jRqxpI6M3vHZk?0c^3=byamYDNf;uB{3NlKW5IhnOS3DNkMV z?tK8?kJ}pmvp%&&eTVOVjHP`q34hN1@!aK}H(K!vI`~gf|Gv+FNEQD5Yd<~yX7k_l h&G-K)@HZb3BABY{)U1?^%I#E6`MGoTtustd{~yM6srvu` diff --git a/vsixtest/Assets/Square150x150Logo.scale-200.png b/vsixtest/Assets/Square150x150Logo.scale-200.png deleted file mode 100644 index af49fec1a5484db1d52a7f9b5ec90a27c7030186..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2937 zcma)84OCO-8BSud5)jwMLRVKgX(S?$n?Ld|vrsm<$CF7)&zTbyy1FE5bU`Q17MRv`9ue$;R(@8kR;#vJ*IM0>cJIAOte!d7oRgdH zd%ySjdB6L9=gX^A6)VzH7p2l@v~3zJAMw|DFy#^)F@@F*`mqUn=Il>l)8_+ab;nOW{%+iPx z+s{Eu|&pIs)Z7{La9~?xKfyl z#43?gjEL15d4WbOZo#SiP%>DB^+BcnJ=7dHEe;r#G=tuw|ka z%q@}##Uh7;tc%L_64m(kHtw74ty%BJMb)_1)#S0j`)F8_1jF7vScpsnH=0V19bO8y zR`0SjIdCUo&=>JwMQF8KHA<{ODHTiQh}0^@5QRmCA?gOH6_H3K^-_sNB^RrdNuK-R zOO*vOrKCVvDwgUck`kF(E7j{I#iiN;b*ZdCt4m@HPA`EuEqGGf4%!K<;(=I=&Vyrw z%TwcWtxa}8mCZ%Cyf&ActJ6_$ox5z6-D!0-dvnRx6t7y3d+h6QYpKWO;8OdnvERo7 zuEf>ih5`wqY)~o@OeVt-wM?Q!>QzdGRj!bz6fzYrfw$hZfAKzr2-M+D+R>}~oT574c;_3zquHcElqKIsryILt3g8n3jcMb+j?i?-L3FpZJ z2WRVBRdDPc+G5aaYg#5hpE+6nQ|(VSoxT3|biF;BUq#==-27Xi=gihDPYP$7?=9cP zYKE$jeQ|3~_L0VG-(F~2ZPyD0=k{J4Q~h(t__{-mz_w8{JDY9{`1ouzz!Vr5!ECdE z6U~O1k8c}24V7~zzXWTV-Pe4)y}wQJS&q%H5`Fo_f_JvIU489aCX$;P`u#!I-=^4ijC2{&9!O&h>mi?9oYD=GC#%)6{GzN6nQYw+Fal50!#x^asjBBR50i`+mho*ttoqV)ubM2KD9S~k7+FR4>{29?6 z{!l6kDdyTN0YJ9LgkPWeXm|gyi@zM3?0@{&pXT12w|78&W-q!RRF)&iLCEZVH<|fR zN0fr2^t8H(>L?>K#>^+jWROLral(Qy-xoBq1U7A&DV||wClb)Otd9?(gZ|8znMF}D zf<1haWz^s0qgecz;RFGt0C-B4g`jNGHsFU+;{<%t65v^sjk^h$lmWn#B0#_)9ij&d z-~lc`A)YYExi^7sBuPM^Y|wA2g*5?`K?#7tzELQYNxGo$UB$4J8RJp1k(8Jj+~hMT zlN~>M@KTTh^--8y3PK_NZ@AC!{PT=CziBzGd+wTJ^@icH!Bd}%)g8V)%K?|c&WTUk zy}qv1C%(fjRoZ4ozC3{O%@5?)XzH35zHns$pgU*Q?fj4v?fp1Qbm+j;3l;9jam9Da zXVcKjPlQ73x78QPu|Ffm6x?`~e3oD=gl=4kYK?={kD5j~QCXU)`HSdduNNENzA*2$ zOm3PzF!lN5e*06-f1Uot67wY#{o-S1!KZ7E=!~7ynnk9_iJR#kFoNbAOT#^2Gd17F zMmvU6>lndZQGd|ax9kUoXXO+$N?|j@6qpsF&_j7YXvwo_C{JpmLw5&#e6k>atv%es z5)7r*Wvv_JkUpT}M!_o!nVlEk1Zbl=a*2hQ*<|%*K1Glj^FcF`6kTzGQ3lz~2tCc@ z&x|tj;aH&1&9HwcJBcT`;{?a+pnej;M1HO(6Z{#J!cZA04hnFl;NXA+&`=7bjW_^o zfC40u3LMG?NdPtwGl>Tq6u}*QG)}-y;)lu-_>ee3kibW(69n0$0Zy!}9rQz%*v1iO zT9_H>99yIrSPYVy6^);rR}7Yo=J_T@hi+qhTZXnVWyf;JDYm5#eYLTxr*?kiNn!+Y zQ+LUkBafNJ#rH#C(?d5^;gw9o#%daEI{mA*LHPIHPU`#|H$hD zwm>0&+kahQ)E#%~k>&5@&#Vg82H?s%71=)(soi@174pi9--2{w{1$}Sz4zGn3Du&x bht0Iza^2ykEt4(epJ78uh5nDlX8(TxzDYwP diff --git a/vsixtest/Assets/Square44x44Logo.scale-200.png b/vsixtest/Assets/Square44x44Logo.scale-200.png deleted file mode 100644 index ce342a2ec8a61291ba76c54604aea7e9d20af11b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1647 zcmaJ?eM}Q)7(e+G1Q(|`V9JhTI2>MkceK4;p;PR&$Pi?ejk3YQ_3o`S&|W_dsOZ8# zWPTt69g`t$ab`0cj-Y0yiBSOqmd)tG7G(}M5aP0_%&9TijB#&)I{zSE^4@#z^FF`l z`8{8`o%wlL(UI|y2!cdsuVamHH~H86F!*-15em4)NqUpCQM5?aoC_eCf@lV4wvF2a zjDQn1JBL69f&@2M3rvzJcfE!eZ8FZUBlFlC5RD)it33{mF9#B82AiyQE%w)`vlwa> zv{<1sm&kSKK$&%2jSFn7$t&P%%6Ue>R=EAnG8N7fqynWG8L3p!4801a;8{+nliO(qd(jNJ_?+9W3#hLIDLoT6~3fx9=`CC-D}-AMrpEO7HK zt3$GicGPc?GmDjy7K2P@La;eu4!$zWCZ`ym{Z$b zu-O6RM&K4JT|BIZB`E-gxqG%FzanI#+2FFmqHqXG7yxWB=w55RGOM)$xMb(>kSNR z2w=1AZi%z=AmG~yea~XaXJR!v7vLn(RUnELfiB1|6D84ICOS}^Zo2AdN}<&*h}G_u z{xZ!(%>tLT3J3<5XhWy-tg+6)0nmUUENLW8TWA{R6bgVd3X;anYFZ^IRis*_P-C-r z;i>%1^eL3UI2-{w8nuFFcs0e~7J{O2k^~Ce%+Ly4U?|=!0LH=t6()xi<^I-rs+9sF z*q{E-CxZbGPeu#a;XJwE;9S1?#R&uns>^0G3p`hEUF*v`M?@h%T%J%RChmD|EVydq zmHWh*_=S%emRC*mhxaVLzT@>Z2SX0u9v*DIJ@WC^kLVdlGV6LpK$KIrlJqc zpJ921)+3JJdTx|<`G&kXpKkjGJv=76R`yYIQ{#c-`%+`#V(7}Q;&@6U8!Td1`d;?N z_9mnI#?AA}4J!r)LN4!E-@H5eXauuB7TOawS>Y|{-P?NNx-lq+z1W-+y(;39P&&LP zL{N80?&=C*qKmdA^moMZRuPcD!B<*mq$ch=0Cnlitw#txRWhb3%TQvPqjkC`F69G4b! ze7z9MZ#+;_#l?H37UqUhDFb^l&s2{oM$3I0o^Q!yx;;V)QmCMo)Tb_ui|mit8MS?U zm##6$sZZ1$@|s%?l@>4Z<*Q}sRBSKMhb4I{e5LdEhsHIHTe8Bod5c>6QtT>$XgUBz z6MK`kO$=jmt@FqggOhJ5j~e@ygRbG;<{Vu)*+nn9aQeo0;$#j;|MS=S$&L?BeV25z xs3B`@=#`5TF{^6(A1rvdY@|-RtQ|iS5{tyX+wH?;n8E)G$kykv-D^wh{{!TZT%7;_ diff --git a/vsixtest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/vsixtest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png deleted file mode 100644 index f6c02ce97e0a802b85f6021e822c89f8bf57d5cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1255 zcmaJ>TWs4@7*5+{G#S+&C!qC#> zf>5N3P6jO*Cz>ug*(_DmW=)kea&m$gZ^+nyiF`;j%w@}y8)>p*SH}C`m?DXeieF2U zyQHecc_L%Gh!7GMt+hG06y;+|p4>m~}PjA}rKViGiEnn7G0ZO<>G|7q;2?NwGCM3s?eued6%hd$B+ z*kQJ{#~$S=DFE(%=E+UkmlEI*%3llUf~8Ja9YU1Vui0IbGBkW_gHB%Rd&!!ioX zs40O?i9I{};kle7GMvE7(rk`la=gTI)47=>%?q@^iL-nUo3}h4S}N-KHn8t5mVP8w z&bSErwp+37 zNJJ8?a|{r5Q3R0Z5s-LB1WHOwYC@7pCHWND#cL1cZ?{kJ368_*(UDWUDyb<}0y@o# zfMF016iMWPCb6obAxT$JlB6(2DrlXDTB&!0`!m??4F(qWMhjVZo?JXQmz`1*58Z=& zcDmB|S-E@j?BoFGix0flckqdS4jsPNzhfWyWIM98GxcLs89C(~dw%$_t;JjX-SD}E zfiGV;{8Q%8r}w9x>EEigW81>`kvnU@pK)4+xk9@+bNj9L!AAZ@SZ@q|)&BmY3+HZx zul~BeG4|}-;L%cHViQGQX?^zFfO0&#cHwel=d`lH9sJ-@Sl@n*(8J2>%Ac`IxyY?Q z{=GhWvC#gu-~Ia7*n{=+;qM?Ul_wy1+u7ho;=`>EwP^g~R@{unBds`!#@}tluZQpS zm)M~nYEifJWJGx?_6DcTy>#uh%>!H9=hb^(v`=m3F1{L>db=<5_tm+_&knAQ2EU$s Mu9UqpbNZeC0BbUo^Z)<= diff --git a/vsixtest/Assets/StoreLogo.png b/vsixtest/Assets/StoreLogo.png deleted file mode 100644 index 7385b56c0e4d3c6b0efe3324aa1194157d837826..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1451 zcmaJ>eN5D57_Z|bH;{0+1#mbl)eTU3{h)Wf7EZV?;HD@XL@{B`Ui%(2aMxQ~xdXSv z5nzWi(LW)U2=Vc-cY@s7nPt{i0hc6!7xN4NNHI#EQl>YNBy8l4%x9gr_W-j zEZMQmmTIy(>;lblRfh`dIyTgc9W5d!VP$L4(kKrN1c5G~(O_#xG zAJCNTstD^5SeXFB+&$h=ToJP2H>xr$iqPs-#O*;4(!Fjw25-!gEb*)mU}=)J;Iu>w zxK(5XoD0wrPSKQ~rbL^Cw6O_03*l*}i=ydbu7adJ6y;%@tjFeXIXT+ms30pmbOP%Q zX}S;+LBh8Tea~TSkHzvX6$rYb)+n&{kSbIqh|c7hmlxmwSiq5iVhU#iEQ<>a18|O^Sln-8t&+t`*{qBWo5M?wFM(JuimAOb5!K#D}XbslM@#1ZVz_;!9U zpfEpLAOz=0g@bd6Xj_ILi-x^!M}73h^o@}hM$1jflTs|Yuj9AL@A3<-?MV4!^4q`e z)fO@A;{9K^?W?DbnesnPr6kK>$zaKo&;FhFd(GYFCIU^T+OIMb%Tqo+P%oq(IdX7S zf6+HLO?7o0m+p>~Tp5UrXWh!UH!wZ5kv!E`_w)PTpI(#Iw{AS`gH4^b(bm^ZCq^FZ zY9DD7bH}rq9mg88+KgA$Zp!iWncuU2n1AuIa@=sWvUR-s`Qb{R*kk(SPU^`$6BXz8 zn#7yaFOIK%qGxyi`dYtm#&qqox0$h=pNi#u=M8zUG@bpiZ=3sT=1}Trr}39cC)H|v zbL?W)=&s4zrh)7>L(|cc%$1#!zfL?HjpeP%T+x_a+jZ16b^iKOHxFEX$7d|8${H-* zIrOJ5w&i$>*D>AKaIoYg`;{L@jM((Kt?$N$5OnuPqVvq**Nm}(f0wwOF%iX_Pba;V z;m@wxX&NcV3?<1+u?A{y_DIj7#m3Af1rCE)o`D&Y3}0%7E;iX1yMDiS)sh0wKi!36 zL!Wmq?P^Ku&rK~HJd97KkLTRl>ScGFYZNlYytWnhmuu|)L&ND8_PmkayQb{HOY640 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x diff --git a/vsixtest/Assets/Wide310x150Logo.scale-200.png b/vsixtest/Assets/Wide310x150Logo.scale-200.png deleted file mode 100644 index 288995b397fdbef1fb7e85afd71445d5de1952c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3204 zcmbVPeQXow8NYmBd90>}0NP?GhXW~VaeThm=a0tV#EwJMI!)6M3}|c4_Bl3=Kd>G0 z(GHx1wl<7(tP?FsOQkTilSo*iIvF%uArExJ73~P zSv1xEy!U(Wd4A9D`FQV@W3@F^qJ@PEF$@z`Z!*BbFsS(^?B zyiAzJ+q})bkgiQHWqEb*jJD-coHYr1^iocg)l!Qa{Xqs-l~6J}p-|##ZHYofskQ3$ zI0;xzXyhazBeXhIsg5A=%ufo@f)1yy&ScKS0;HF^!r_2UE^lpZEom(+@duma3awTv zCrCL-%D_SvYWIcdHkmI}#50(fkUi)Qgx!80ju>g1za^}ff>JI8Z@^-iCiaCgg@TgF z+vtE?Q9{VQUX&MW9SYYmGcxA14%N2@7FwBTD4N<(2{nWgV8$e3?-F=L^&FrtWn~(U_Q~~^uYiyeY6-KoTnfh9AWz@ zIKje0)u!_Lw)E}G!#kEfwKVdNt(UAf9*f>tEL_(=xco-T%jTi@7YlC3hs2ik%Le0H ztj}RTeCF(5mwvi3_56>-yB?l;J>-1%!9~=fs|QcNG3J~a@JCu`4SB460s0ZO+##4fFUSGLcj_ja^fL4&BKALfb#$6$O?>P@qx2Agl^x0i&ugt zsy5Pyu=()`7HRMG3IB7F1@`_ z+-!J%#i6e^U$e#+C%Q>_qVRzWRsG^W_n+@OcX@vzI&z;mzHNb!GQ?LWA(wtpqHqTM z1OFw_{Zn?fD)p)`c`kOgv{de=v@suGRqY{N^U7gI1VF3*F=obwaXI6ob5__Yn zVTguS!%(NI09J8x#AO_aW!9W7k*UvB;IWDFC3srwftr{kHj%g)fvnAm;&h_dnl~

        MY- zf+K}sCe8qU6Ujs`3ua{U0Of$R_gVQBuUA za0v=mu#vIOqiiAZOr&h*$WyOw&k-xr$;G4Ixa!#TJNr>95(h>l%)PUy4p+^SgR(uR zta%k*?ny-+nAr8spEk1fo{J4i!b^Fia`N{_F6@zidA2ZTTrjl#^5Z-2KfB@Cu}l9s z(*|Z2jc?p~vn2f)3y9i*7zJV1L{$?|&q)4oaT;uXi6>1GkRXVTOzAz(RHEmr=eFIi z`}<>-Q?K0GN8!IYxeP1XKXO+jsJbp~o^);Bc;%b7Flpe7;1`Ny@3r7ZR;?R)aJt8C ziNlEC<@3f_lIV4TwV}&e;D!Ee5_|e#g0LUh=5vmYWYm7&2h*M>QPKvGh9-)wfMMW3 z8J9b%1k7dzPzO0_NGQy92BZ^FR6R~6;^6?lqO;-QUP4BY%cG%3vEhbm#>4vIhPBh3 z-+pZGjh$x%Hp{?=FHsMp0&wNPlj00us{&`1ZOZTqs8%4X&xH=UDr*xyBW(Zp&Em94 zf)ZSfn#yg0N)>!1kWdkqJ^S*z0FF5|fj&qcE#Na|%OY0$uO>!&hP+1ywfD_WXk@4J(?MBftK7>$Nvqh@tDuarN%PrTLQ2Uzysx>UV=V zk^RrDSvdQ?0;=hY67EgII-f4`t=+i*yS=Y~!XlqIy_4x&%+OdfbKOFPXS2X5%4R{N z$SQMX^AK6(fA - - - - - diff --git a/vsixtest/MainPage.xaml.cpp b/vsixtest/MainPage.xaml.cpp deleted file mode 100644 index e67dcb83b2..0000000000 --- a/vsixtest/MainPage.xaml.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// MainPage.xaml.cpp -// Implementation of the MainPage class. -// - -#include "pch.h" -#include "MainPage.xaml.h" -#include "sqlite3.h" - -using namespace vsixtest; - -using namespace Platform; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace Windows::UI::Xaml; -using namespace Windows::UI::Xaml::Controls; -using namespace Windows::UI::Xaml::Controls::Primitives; -using namespace Windows::UI::Xaml::Data; -using namespace Windows::UI::Xaml::Input; -using namespace Windows::UI::Xaml::Media; -using namespace Windows::UI::Xaml::Navigation; - -// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 - -MainPage::MainPage() -{ - InitializeComponent(); - UseSQLite(); -} - -void MainPage::UseSQLite(void) -{ - int rc = SQLITE_OK; - sqlite3 *pDb = nullptr; - - rc = sqlite3_open_v2("test.db", &pDb, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr); - - if (rc != SQLITE_OK) - throw ref new FailureException("Failed to open database."); - - rc = sqlite3_exec(pDb, "VACUUM;", nullptr, nullptr, nullptr); - - if (rc != SQLITE_OK) - throw ref new FailureException("Failed to vacuum database."); - - rc = sqlite3_close(pDb); - - if (rc != SQLITE_OK) - throw ref new FailureException("Failed to close database."); - - pDb = nullptr; -} diff --git a/vsixtest/MainPage.xaml.h b/vsixtest/MainPage.xaml.h deleted file mode 100644 index ea327a3e4c..0000000000 --- a/vsixtest/MainPage.xaml.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// MainPage.xaml.h -// Declaration of the MainPage class. -// - -#pragma once - -#include "MainPage.g.h" - -namespace vsixtest -{ - ///

        - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public ref class MainPage sealed - { - public: - MainPage(); - void UseSQLite(void); - - }; -} diff --git a/vsixtest/Package.appxmanifest b/vsixtest/Package.appxmanifest deleted file mode 100644 index 106b3f1e41..0000000000 --- a/vsixtest/Package.appxmanifest +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - vsixtest - mistachkin - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vsixtest/pch.cpp b/vsixtest/pch.cpp deleted file mode 100644 index 97b544ec11..0000000000 --- a/vsixtest/pch.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// -// pch.cpp -// Include the standard header and generate the precompiled header. -// - -#include "pch.h" diff --git a/vsixtest/pch.h b/vsixtest/pch.h deleted file mode 100644 index b793236d02..0000000000 --- a/vsixtest/pch.h +++ /dev/null @@ -1,11 +0,0 @@ -// -// pch.h -// Header for standard system include files. -// - -#pragma once - -#include -#include - -#include "App.xaml.h" diff --git a/vsixtest/vsixtest.sln b/vsixtest/vsixtest.sln deleted file mode 100644 index 1ab6e064f9..0000000000 --- a/vsixtest/vsixtest.sln +++ /dev/null @@ -1,39 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vsixtest", "vsixtest.vcxproj", "{60BB14A5-0871-4656-BC38-4F0958230F9A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|ARM = Release|ARM - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|ARM.ActiveCfg = Debug|ARM - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|ARM.Build.0 = Debug|ARM - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|ARM.Deploy.0 = Debug|ARM - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x64.ActiveCfg = Debug|x64 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x64.Build.0 = Debug|x64 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x64.Deploy.0 = Debug|x64 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x86.ActiveCfg = Debug|Win32 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x86.Build.0 = Debug|Win32 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x86.Deploy.0 = Debug|Win32 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|ARM.ActiveCfg = Release|ARM - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|ARM.Build.0 = Release|ARM - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|ARM.Deploy.0 = Release|ARM - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x64.ActiveCfg = Release|x64 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x64.Build.0 = Release|x64 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x64.Deploy.0 = Release|x64 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x86.ActiveCfg = Release|Win32 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x86.Build.0 = Release|Win32 - {60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x86.Deploy.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/vsixtest/vsixtest.tcl b/vsixtest/vsixtest.tcl deleted file mode 100644 index 8b2288be35..0000000000 --- a/vsixtest/vsixtest.tcl +++ /dev/null @@ -1,373 +0,0 @@ -#!/usr/bin/tclsh -# -# This script is used to quickly test a VSIX (Visual Studio Extension) file -# with Visual Studio 2015 on Windows. -# -# PREREQUISITES -# -# 1. This tool is Windows only. -# -# 2. This tool must be executed with "elevated administrator" privileges. -# -# 3. Tcl 8.4 and later are supported, earlier versions have not been tested. -# -# 4. The "sqlite-UWP-output.vsix" file is assumed to exist in the parent -# directory of the directory containing this script. The [optional] first -# command line argument to this script may be used to specify an alternate -# file. However, currently, the file must be compatible with both Visual -# Studio 2015 and the Universal Windows Platform. -# -# 5. The "VERSION" file is assumed to exist in the parent directory of the -# directory containing this script. It must contain a version number that -# matches the VSIX file being tested. -# -# 6. The temporary directory specified in the TEMP or TMP environment variables -# must refer to an existing directory writable by the current user. -# -# 7. The VS140COMNTOOLS environment variable must refer to the Visual Studio -# 2015 common tools directory. -# -# USAGE -# -# The first argument to this script is optional. If specified, it must be the -# name of the VSIX file to test. -# -package require Tcl 8.4 - -proc fail { {error ""} {usage false} } { - if {[string length $error] > 0} then { - puts stdout $error - if {!$usage} then {exit 1} - } - - puts stdout "usage:\ -[file tail [info nameofexecutable]]\ -[file tail [info script]] \[vsixFile\]" - - exit 1 -} - -proc isWindows {} { - # - # NOTE: Returns non-zero only when running on Windows. - # - return [expr {[info exists ::tcl_platform(platform)] && \ - $::tcl_platform(platform) eq "windows"}] -} - -proc isAdministrator {} { - # - # NOTE: Returns non-zero only when running as "elevated administrator". - # - if {[isWindows]} then { - if {[catch {exec -- whoami /groups} groups] == 0} then { - set groups [string map [list \r\n \n] $groups] - - foreach group [split $groups \n] { - # - # NOTE: Match this group line against the "well-known" SID for - # the "Administrators" group on Windows. - # - if {[regexp -- {\sS-1-5-32-544\s} $group]} then { - # - # NOTE: Match this group line against the attributes column - # sub-value that should be present when running with - # elevated administrator credentials. - # - if {[regexp -- {\sEnabled group(?:,|\s)} $group]} then { - return true - } - } - } - } - } - - return false -} - -proc getEnvironmentVariable { name } { - # - # NOTE: Returns the value of the specified environment variable or an empty - # string for environment variables that do not exist in the current - # process environment. - # - return [expr {[info exists ::env($name)] ? $::env($name) : ""}] -} - -proc getTemporaryPath {} { - # - # NOTE: Returns the normalized path to the first temporary directory found - # in the typical set of environment variables used for that purpose - # or an empty string to signal a failure to locate such a directory. - # - set names [list] - - foreach name [list TEMP TMP] { - lappend names [string toupper $name] [string tolower $name] \ - [string totitle $name] - } - - foreach name $names { - set value [getEnvironmentVariable $name] - - if {[string length $value] > 0} then { - return [file normalize $value] - } - } - - return "" -} - -proc appendArgs { args } { - # - # NOTE: Returns all passed arguments joined together as a single string - # with no intervening spaces between arguments. - # - eval append result $args -} - -proc readFile { fileName } { - # - # NOTE: Reads and returns the entire contents of the specified file, which - # may contain binary data. - # - set file_id [open $fileName RDONLY] - fconfigure $file_id -translation binary - set result [read $file_id] - close $file_id - return $result -} - -proc writeFile { fileName data } { - # - # NOTE: Writes the entire contents of the specified file, which may contain - # binary data. - # - set file_id [open $fileName {WRONLY CREAT TRUNC}] - fconfigure $file_id -translation binary - puts -nonewline $file_id $data - close $file_id - return "" -} - -proc putsAndEval { command } { - # - # NOTE: Outputs a command to the standard output channel and then evaluates - # it in the callers context. - # - catch { - puts stdout [appendArgs "Running: " [lrange $command 1 end] ...\n] - } - - return [uplevel 1 $command] -} - -proc isBadDirectory { directory } { - # - # NOTE: Returns non-zero if the directory is empty, does not exist, -OR- is - # not a directory. - # - catch { - puts stdout [appendArgs "Checking directory \"" $directory \"...\n] - } - - return [expr {[string length $directory] == 0 || \ - ![file exists $directory] || ![file isdirectory $directory]}] -} - -proc isBadFile { fileName } { - # - # NOTE: Returns non-zero if the file name is empty, does not exist, -OR- is - # not a regular file. - # - catch { - puts stdout [appendArgs "Checking file \"" $fileName \"...\n] - } - - return [expr {[string length $fileName] == 0 || \ - ![file exists $fileName] || ![file isfile $fileName]}] -} - -# -# NOTE: This is the entry point for this script. -# -set script [file normalize [info script]] - -if {[string length $script] == 0} then { - fail "script file currently being evaluated is unknown" true -} - -if {![isWindows]} then { - fail "this tool only works properly on Windows" -} - -if {![isAdministrator]} then { - fail "this tool must run with \"elevated administrator\" privileges" -} - -set path [file normalize [file dirname $script]] -set argc [llength $argv]; if {$argc > 1} then {fail "" true} - -if {$argc == 1} then { - set vsixFileName [lindex $argv 0] -} else { - set vsixFileName [file join \ - [file dirname $path] sqlite-UWP-output.vsix] -} - -############################################################################### - -if {[isBadFile $vsixFileName]} then { - fail [appendArgs \ - "VSIX file \"" $vsixFileName "\" does not exist"] -} - -set versionFileName [file join [file dirname $path] VERSION] - -if {[isBadFile $versionFileName]} then { - fail [appendArgs \ - "Version file \"" $versionFileName "\" does not exist"] -} - -set projectTemplateFileName [file join $path vsixtest.vcxproj.data] - -if {[isBadFile $projectTemplateFileName]} then { - fail [appendArgs \ - "Project template file \"" $projectTemplateFileName \ - "\" does not exist"] -} - -set envVarName VS140COMNTOOLS -set vsDirectory [getEnvironmentVariable $envVarName] - -if {[isBadDirectory $vsDirectory]} then { - fail [appendArgs \ - "Visual Studio 2015 directory \"" $vsDirectory \ - "\" from environment variable \"" $envVarName \ - "\" does not exist"] -} - -set vsixInstaller [file join \ - [file dirname $vsDirectory] IDE VSIXInstaller.exe] - -if {[isBadFile $vsixInstaller]} then { - fail [appendArgs \ - "Visual Studio 2015 VSIX installer \"" $vsixInstaller \ - "\" does not exist"] -} - -set envVarName ProgramFiles -set programFiles [getEnvironmentVariable $envVarName] - -if {[isBadDirectory $programFiles]} then { - fail [appendArgs \ - "Program Files directory \"" $programFiles \ - "\" from environment variable \"" $envVarName \ - "\" does not exist"] -} - -set msBuild [file join $programFiles MSBuild 14.0 Bin MSBuild.exe] - -if {[isBadFile $msBuild]} then { - fail [appendArgs \ - "MSBuild v14.0 executable file \"" $msBuild \ - "\" does not exist"] -} - -set temporaryDirectory [getTemporaryPath] - -if {[isBadDirectory $temporaryDirectory]} then { - fail [appendArgs \ - "Temporary directory \"" $temporaryDirectory \ - "\" does not exist"] -} - -############################################################################### - -set installLogFileName [appendArgs \ - [file rootname [file tail $vsixFileName]] \ - -install- [pid] .log] - -set commands(1) [list exec [file nativename $vsixInstaller]] - -lappend commands(1) /quiet /norepair -lappend commands(1) [appendArgs /logFile: $installLogFileName] -lappend commands(1) [file nativename $vsixFileName] - -############################################################################### - -set buildLogFileName [appendArgs \ - [file rootname [file tail $vsixFileName]] \ - -build-%configuration%-%platform%- [pid] .log] - -set commands(2) [list exec [file nativename $msBuild]] - -lappend commands(2) [file nativename [file join $path vsixtest.sln]] -lappend commands(2) /target:Rebuild -lappend commands(2) /property:Configuration=%configuration% -lappend commands(2) /property:Platform=%platform% - -lappend commands(2) [appendArgs \ - /logger:FileLogger,Microsoft.Build.Engine\;Logfile= \ - [file nativename [file join $temporaryDirectory \ - $buildLogFileName]] \;Verbosity=diagnostic] - -############################################################################### - -set uninstallLogFileName [appendArgs \ - [file rootname [file tail $vsixFileName]] \ - -uninstall- [pid] .log] - -set commands(3) [list exec [file nativename $vsixInstaller]] - -lappend commands(3) /quiet /norepair -lappend commands(3) [appendArgs /logFile: $uninstallLogFileName] -lappend commands(3) [appendArgs /uninstall:SQLite.UWP.2015] - -############################################################################### - -if {1} then { - catch { - puts stdout [appendArgs \ - "Install log: \"" [file nativename [file join \ - $temporaryDirectory $installLogFileName]] \"\n] - } - - catch { - puts stdout [appendArgs \ - "Build logs: \"" [file nativename [file join \ - $temporaryDirectory $buildLogFileName]] \"\n] - } - - catch { - puts stdout [appendArgs \ - "Uninstall log: \"" [file nativename [file join \ - $temporaryDirectory $uninstallLogFileName]] \"\n] - } -} - -############################################################################### - -if {1} then { - putsAndEval $commands(1) - - set versionNumber [string trim [readFile $versionFileName]] - set data [readFile $projectTemplateFileName] - set data [string map [list %versionNumber% $versionNumber] $data] - - set projectFileName [file join $path vsixtest.vcxproj] - writeFile $projectFileName $data - - set platforms [list x86 x64 ARM] - set configurations [list Debug Release] - - foreach platform $platforms { - foreach configuration $configurations { - putsAndEval [string map [list \ - %platform% $platform %configuration% $configuration] \ - $commands(2)] - } - } - - putsAndEval $commands(3) -} diff --git a/vsixtest/vsixtest.vcxproj.data b/vsixtest/vsixtest.vcxproj.data deleted file mode 100644 index a64584c3a2..0000000000 --- a/vsixtest/vsixtest.vcxproj.data +++ /dev/null @@ -1,198 +0,0 @@ - - - - {60bb14a5-0871-4656-bc38-4f0958230f9a} - vsixtest - en-US - 14.0 - true - Windows Store - 10.0.10586.0 - 10.0.10586.0 - 10.0 - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - Application - true - v140 - - - Application - true - v140 - - - Application - true - v140 - - - Application - false - true - v140 - true - - - Application - false - true - v140 - true - - - Application - false - true - v140 - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - vsixtest_TemporaryKey.pfx - - - - /bigobj %(AdditionalOptions) - 4453;28204 - - - - - /bigobj %(AdditionalOptions) - 4453;28204 - - - - - /bigobj %(AdditionalOptions) - 4453;28204 - - - - - /bigobj %(AdditionalOptions) - 4453;28204 - - - - - /bigobj %(AdditionalOptions) - 4453;28204 - - - - - /bigobj %(AdditionalOptions) - 4453;28204 - - - - - - App.xaml - - - MainPage.xaml - - - - - Designer - - - Designer - - - - - Designer - - - - - - - - - - - - - - - App.xaml - - - MainPage.xaml - - - Create - Create - Create - Create - Create - Create - - - - - - - - - \ No newline at end of file diff --git a/vsixtest/vsixtest.vcxproj.filters b/vsixtest/vsixtest.vcxproj.filters deleted file mode 100644 index ac1dfca421..0000000000 --- a/vsixtest/vsixtest.vcxproj.filters +++ /dev/null @@ -1,57 +0,0 @@ - - - - - 60bb14a5-0871-4656-bc38-4f0958230f9a - - - e6271362-8f96-476d-907f-4da227b02435 - bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png - - - - - - - - - - - - - - - - - - Assets - - - Assets - - - Assets - - - Assets - - - Assets - - - Assets - - - Assets - - - - - - - - - - - - \ No newline at end of file diff --git a/vsixtest/vsixtest_TemporaryKey.pfx b/vsixtest/vsixtest_TemporaryKey.pfx deleted file mode 100644 index e6787bcad0527ecc86a43ea007ba8776c4b26215..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2520 zcmY*ac|6o>7ypeJ!=Nx|G_o{dY||aaG7*=uRdx}&bTP8McB-MVjL1zQ`_@>78g~pM zA?Xf@v>;?lA^YyizFzOI`+48{e%{ade4q22?>Xl=&p*%i!BY{vTo5Rpib#PYl;Ta} zw~jz~Aca&!42+7PfHWCT<=*|j6!!v*$~^ zY4Gr)FkYQeF~j*M(BHYZc)DOz*q}&)S9!g{H0k1#-rUN(n(H$|6{LPDexJiZ-kU&FbKR@6F34qKTFux@xniVPiG3Im6+bkmhv?r))l&Dh z+rGAjRwjvXTA0-DCAE3)udY3mp1vfqB3r%W%g$US-xNB~H$WB(SFOM2DM~Wb`WBSD zrsmnx6crY!JKAQdDOCEnQ5#8nJ>48`5K7FJFeu*hS-7x2Y$2yv`B>Nx-3hmP;(RFy z>4r0O+foVl^mk0SOzpMr@0RX8mCUL5tlyl{MKF0b;i|tRD>LlIMi~&oU!IG7AxM`F zd_#_lI(}YT;&5QhZ+qcdpq3+<;;1m9=S>c>udYxaep@Dvv^}7m$fO>mSS38a5RhJ6 zp-1GMa^ics&P9wCvgLhqgvMPaCFq6dHGY*&sET#^P??s~ts;S1JG!ou^>D}dQmSjt1sMDg_CQC%AyT@e zMd7E`TfZE>FFm5?)Q$>8wZZ0VB>N!J@)r83mQBqaF}Y{Uwi%mz)NkpyE3B;@=v5}}d$e3g6>CQ4uG3CVAPb8E{o(WDWx64dZr zp~GyP4l06CQ6(2E;~nvGUC7z+hVM-7p?<&URkIz5MT@xX$>*0mA1g!F3`(i~we1?> zCme&g0u{bUVnnHIuSxUgYmd71`BL_R*$o++|bK}tOlc$|~C=(DW z&rQ$s(beUf`fbWSPAX_@_3*gC*Pkr9Yphb#z6pFcxnVw45Y=$<_o5u#Z_=V`n9!zz zu)AsO#IDlGltwGD^nU@JbmfQa8rJ={g`Km$J)Ta=Pd1Z6YsPH0D+QJE2dCV$Z;mRI zoyfEnsZE4uRpk571wJ}vL|(m}H{2-3%p*&Vn2nbA%Z=y0XEDc((lKYlJv)TC>;1l{ z4O+%tJU7;gv*DgXg{FE!g~fLkvE1lRk_skAi?6>_chzTNljJ+_axug1@=%PeWB%0Y zZx${;(*_#DG_0;p@A?Y9U^3>$)UmrQ#fxUW;;Vns_?~!>9+eAzIa9V4%IASYmApcF z%JBQ$bLiT+QY3$;Vb67wcR@TzA`POm7enC3ZEnyb6f!7AO1VbsZpaJYTo8C3S`57| zib#6NF2;0k*oxm5IQb~biC%Ilb4$wJT?c9XTEws}tY+sLtuz1`yKZw@cF0ubssp1c zsrJo*BF$6j?XPg1Y{hG@mGJXpv)&=crtdfV3DmC&tEcKL<)ULX(L`jYyE!8px{zbP zdcV+{=k8NPMs9i?<7q~8ki-zKG0b$`U)-gMXFKhc0}U67EBYJ~Z%a(oY5lr`<-5oy zH+1oHbv!E+fu0J{^=?;<>A;KpBbNvP0D2z#VV}p$e#h-WBvX zKm#;QaE}AjK_h_~9B>A}10Eo701>PvfpupppN3TP0xDgON^?RXv4sJk^KVx0KFp@SC#Ri>(&9VxcHC3dS?;)F)TWn|xj%(VJ3 z?BI|MHp9_6I#{*17;l37liej`h=-Ca6?L&By%5V;q{3x*D>k(vPJVCyEv&7uJXYo% z`;aL*(Xf#x!O0$>BRgIW^>r~tePV%+pyjw** zk#KpMa)N4+fIjYL{witoF=GL3nQ#>6VURDreL& z;+XWM^-=}m0p0s-z#CP%=~x~n{!7Wma!&{A9~LhUX0X)%-UCX(CLz2T92^D@sI+U@p4S%bFf zuBKCWyS+m`-R;8L+8BouJXjmaBoWznxBFaMql1&t9#(R1%2LWMEzjnN&_X$kt647= z?@6{FoIXEqpW|P0Yan0FI)Mqy{4^nXZ?_B}Y!}4;hL|`Wwnw?p8qjp^wxiS`Z8(W% ze_U458SQ|L%qoqZZ!)U>GH3Z<}rm!iAu)PJfu6%(D`ZS;c)h+(>7zq-s~-0TiS8^=Zq#g60fDwvpi)UWfH^ zk-&0}S@!2@#YsE()`jPgMQ-2rjQtJ5^3%|_Ch^?iMYS>zd>0rju3O#f6!sHHJ!^tBb zDZ7Q;qZ(Sillt1*f-02@<4O^;t9Am&{hY+1%H+{^ubidQN*j-*o#kUV$N5(&)pqV< z>m2PDzKKBfp8fGUMJXRfnKRBDv6{3k@yF}nrSUv)Zsns;E;LLu%ZHQS71R@}Q`~3B lyiSSy3ZJrriAr|rpzb`|H|fj2WbtYE^sH7-kL-^J_itHiY_0$R From de4fc707b57a77cef9126cf990b638c8510f55a7 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 14:16:50 +0000 Subject: [PATCH 199/522] Rename the 'hwaci' auto.def utility API to the more generic 'proj' API, per /chat discussion. Fix a function name typo which caused readline detection to kill the configure in one code path. FossilOrigin-Name: e20610f06bfc6f4ebc5806da05c307d91e1f0a8c7a7501a7953273dbf1816fee --- auto.def | 168 ++++++++--------- autosetup/{hwaci-common.tcl => proj.tcl} | 218 +++++++++++------------ manifest | 16 +- manifest.uuid | 2 +- 4 files changed, 202 insertions(+), 202 deletions(-) rename autosetup/{hwaci-common.tcl => proj.tcl} (86%) diff --git a/auto.def b/auto.def index e2ba5f1db9..042656ff3c 100644 --- a/auto.def +++ b/auto.def @@ -12,7 +12,7 @@ # # JimTCL: https://jim.tcl.tk # -use cc cc-db cc-shared cc-lib hwaci-common pkg-config +use cc cc-db cc-shared cc-lib proj pkg-config # $DUMP_DEFINES_TXT is the file emitted by --dump-defines, intended # only for build debugging and not part of the public build interface. @@ -118,8 +118,8 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # booleans: use one of: # - [opt-bool FLAG] is autosetup's built-in command for this, but we # have some convenience variants: -# - [hwaci-opt-truthy FLAG] -# - [hwaci-opt-if-truthy FLAG {THEN} {ELSE}] +# - [proj-opt-truthy FLAG] +# - [proj-opt-if-truthy FLAG {THEN} {ELSE}] # # Non-boolean (i.e. string) flags: # - [opt-val FLAG ?default?] @@ -202,7 +202,7 @@ unset flags # Carry values from hidden --flag aliases over to their canonical flag # forms. # -hwaci-xfer-options-aliases { +proj-xfer-options-aliases { with-readline-inc => with-readline-cflags with-readline-lib => with-readline-ldflags } @@ -218,7 +218,7 @@ define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum msg-result "srcdir = $srcdir" msg-result "top_srcdir = $top_srcdir" -msg-result [hwaci-bold "Configuring SQLite version $PACKAGE_VERSION"] +msg-result [proj-bold "Configuring SQLite version $PACKAGE_VERSION"] # # SQLITE_AUTORECONFIG contains make target rules for re-running the @@ -233,7 +233,7 @@ foreach arg $::autosetup(argv) { # Are we cross-compiling? -set cross_compiling [hwaci-is-cross-compiling] +set cross_compiling [proj-is-cross-compiling] if {![file exists sqlite3.pc.in]} { msg-result "This appears to be an out-of-tree build." } @@ -266,7 +266,7 @@ proc sqlite-add-shell-opt {args} { } } -hwaci-file-extensions +proj-file-extensions if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_UNIX 0 define SQLITE_OS_WIN 1 @@ -279,8 +279,8 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { ######### # Programs needed -if {"" eq [hwaci-bin-define install]} { - hwaci-warn "Cannot find install binary, so 'make install' will not work." +if {"" eq [proj-bin-define install]} { + proj-warn "Cannot find install binary, so 'make install' will not work." # Reminder: we historically have ./install-sh in the source tree. # Can we not simply use that? # @@ -316,18 +316,18 @@ proc sqlite-check-wasi-sdk {} { if {$wasiSdkDir eq ""} { return 0 } elseif {$::cross_compiling} { - hwaci-fatal "Cannot combine --with-wasi-sdk with cross-compilation" + proj-fatal "Cannot combine --with-wasi-sdk with cross-compilation" } msg-result "Checking WASI SDK directory \[$wasiSdkDir]... " #puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" - hwaci-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] + proj-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading" define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir - hwaci-opt-set load-extension 0 ;# ==> --disable-load-extension - hwaci-opt-set threadsafe 0 ;# ==> --threadsafe=0 - hwaci-opt-set tcl 0 ;# ==> --disable-tcl - hwaci-opt-set shared 0 ;# ==> --disable-shared + proj-opt-set load-extension 0 ;# ==> --disable-load-extension + proj-opt-set threadsafe 0 ;# ==> --threadsafe=0 + proj-opt-set tcl 0 ;# ==> --disable-tcl + proj-opt-set shared 0 ;# ==> --disable-shared set cross_compiling 1 # Changing --host and --target have no effect here except to possibly @@ -367,7 +367,7 @@ cc-with {-includes stdint.h} \ cc-check-functions gmtime_r isnan localtime_r localtime_s \ malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 -hwaci-check-function-in-lib fdatasync rt +proj-check-function-in-lib fdatasync rt define LDFLAGS_FDATASYNC [get-define lib_fdatasync] undefine lib_fdatasync @@ -383,7 +383,7 @@ cc-check-includes \ # code generation: cc-check-includes dirent.h sys/time.h -if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { +if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { # TODO: port over the more sophisticated zlib search from the fossil auto.def define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" define LDFLAGS_ZLIB -lz @@ -399,30 +399,30 @@ if {[cc-check-includes zlib.h] && [hwaci-check-function-in-lib deflate z]} { # # Determine proper rpath-handling flags. # -hwaci-check-rpath +proj-check-rpath -hwaci-define-if-opt-truthy shared ENABLE_SHARED \ +proj-define-if-opt-truthy shared ENABLE_SHARED \ "Build shared library?" -if {![hwaci-define-if-opt-truthy static ENABLE_STATIC \ +if {![proj-define-if-opt-truthy static ENABLE_STATIC \ "Build static library?"]} { - hwaci-warn "static lib build may be implicitly re-activated by other components, e.g. libtclsqlite3." + proj-warn "static lib build may be implicitly re-activated by other components, e.g. libtclsqlite3." } -hwaci-define-if-opt-truthy amalgamation USE_AMALGAMATION \ +proj-define-if-opt-truthy amalgamation USE_AMALGAMATION \ "Use amalgamation for builds?" -hwaci-define-if-opt-truthy gcov USE_GCOV "Use gcov?" +proj-define-if-opt-truthy gcov USE_GCOV "Use gcov?" -hwaci-define-if-opt-truthy test-status TSTRNNR_OPTS \ +proj-define-if-opt-truthy test-status TSTRNNR_OPTS \ "test-runner flags:" {--status} {} -hwaci-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \ +proj-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \ "Use #line macros in the amalgamation:" msg-checking "Debug build? " -hwaci-if-opt-truthy with-debug { +proj-if-opt-truthy with-debug { define SQLITE_DEBUG 1 define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} msg-result yes @@ -472,7 +472,7 @@ proc sqlite-check-tcl {} { global top_srcdir msg-result "Checking for a suitable tcl... " - set optTcl [hwaci-opt-truthy tcl] + set optTcl [proj-opt-truthy tcl] set use_tcl $optTcl set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] @@ -480,15 +480,15 @@ proc sqlite-check-tcl {} { #puts "sqlite-check-tcl: with_tclsh=${with_tclsh}" #puts "sqlite-check-tcl: with_tcl=$with_tcl" if {"" eq $with_tclsh && "" eq $with_tcl} { - set with_tclsh [hwaci-first-bin-of tclsh9.0 tclsh8.6 tclsh] + set with_tclsh [proj-first-bin-of tclsh9.0 tclsh8.6 tclsh] } #puts "sqlite-check-tcl: with_tclsh=${with_tclsh}" if {"" ne $with_tclsh} { if {![file isfile $with_tclsh]} { - hwaci-fatal "TCL shell $with_tclsh is not a file" + proj-fatal "TCL shell $with_tclsh is not a file" } elseif {![file-isexec $with_tclsh]} { - hwaci-fatal "TCL shell $with_tclsh is not executable" + proj-fatal "TCL shell $with_tclsh is not executable" } else { define TCLSH_CMD $with_tclsh msg-result "Using tclsh: $with_tclsh" @@ -500,7 +500,7 @@ proc sqlite-check-tcl {} { if {"" ne $with_tcl && [file isdir $with_tcl]} { msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl" } else { - hwaci-warn "$with_tclsh is unable to recommand a tclConfig.sh" + proj-warn "$with_tclsh is unable to recommand a tclConfig.sh" set use_tcl 0 } } @@ -522,7 +522,7 @@ proc sqlite-check-tcl {} { } } if {"" eq $cfg} { - hwaci-fatal "No tclConfig.sh found under ${with_tcl}" + proj-fatal "No tclConfig.sh found under ${with_tcl}" } } else { # If we have not yet found a tclConfig.sh file, look in $libdir which is @@ -540,7 +540,7 @@ proc sqlite-check-tcl {} { } } if {![file readable $cfg]} { - hwaci-indented-notice { + proj-indented-notice { WARNING: Cannot find a usable tclConfig.sh file. Use --with-tcl=DIR to specify a directory where tclConfig.sh can be found. SQLite does not use TCL internally, but TCL @@ -551,9 +551,9 @@ proc sqlite-check-tcl {} { } msg-result "Using tclConfig.sh: $cfg" } elseif {!$optTcl} { - hwaci-warn "Unable to run tests because of --disable-tcl" + proj-warn "Unable to run tests because of --disable-tcl" } else { - hwaci-warn "Unable to run tests because no tclConfig.sh file could be located" + proj-warn "Unable to run tests because no tclConfig.sh file could be located" } break } @@ -572,7 +572,7 @@ proc sqlite-check-tcl {} { if {![file-isexec $with_tclsh]} { set with_tclsh2 [get-define TCL_EXEC_PREFIX]/bin/tclsh if {![file-isexec $with_tclsh2]} { - hwaci-warn "Cannot find a usable tclsh (tried: $with_tclsh $with_tclsh2)" + proj-warn "Cannot find a usable tclsh (tried: $with_tclsh $with_tclsh2)" } else { set with_tclsh $with_tclsh2 } @@ -592,7 +592,7 @@ proc sqlite-check-tcl {} { } } } else { - hwaci-warn "Cannot determine TCLLIBDIR" + proj-warn "Cannot determine TCLLIBDIR" } } set tclrpath "" @@ -609,7 +609,7 @@ proc sqlite-check-tcl {} { } define TCLLIBDIR $tcllibdir define TCLLIB_RPATH $tclrpath - #hwaci-fatal "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" + #proj-fatal "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" } else { define TCLLIBDIR "" define TCLLIB_RPATH "" @@ -619,7 +619,7 @@ proc sqlite-check-tcl {} { msg-result "Using tclsh: $with_tclsh" define HAVE_TCL 1 } else { - hwaci-warn "Cannot find a usable tclsh, so cannot run tests." + proj-warn "Cannot find a usable tclsh, so cannot run tests." } }; # sqlite-check-tcl @@ -670,7 +670,7 @@ if {"jimsh" ne $cgtcl} { } set cgtcl [get-define TCLSH_CMD] if {![file exists $cgtcl]} { - hwaci-fatal "Cannot find a tclsh to use for code generation." + proj-fatal "Cannot find a tclsh to use for code generation." } define BTCLSH "\$(TCLSH_CMD)" } @@ -685,11 +685,11 @@ unset cgtcl ######################################################################## # Thread safety? msg-checking "Support threadsafe operation? " -hwaci-if-opt-truthy threadsafe { +proj-if-opt-truthy threadsafe { msg-result yes sqlite-add-feature-flag -DSQLITE_THREADSAFE=1 - if {![hwaci-check-function-in-lib pthread_create pthread] - || ![hwaci-check-function-in-lib pthread_mutexattr_init pthread]} { + if {![proj-check-function-in-lib pthread_create pthread] + || ![proj-check-function-in-lib pthread_mutexattr_init pthread]} { user-error "Missing required pthread bits" } define LDFLAGS_PTHREAD [get-define lib_pthread_create] @@ -752,11 +752,11 @@ proc sqlite-check-line-editing {} { # Use linenoise... set dirLn $check if {![file isdir $dirLn]} { - hwaci-fatal "--with-linenoise value is not a directory" + proj-fatal "--with-linenoise value is not a directory" } elseif {![file exists $dirLn/linenoise.c] } { - hwaci-fatal "Cannot find linenoise.c in $dirLn" + proj-fatal "Cannot find linenoise.c in $dirLn" } elseif {![file exists $dirLn/linenoise.h] } { - hwaci-fatal "Cannot find linenoise.h in $dirLn" + proj-fatal "Cannot find linenoise.h in $dirLn" } msg-result "Using linenoise from $dirLn" define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise.c" @@ -781,7 +781,7 @@ proc sqlite-check-line-editing {} { # --enable-editline to do exactly that but it seems likely to # break on systems for which which HAVE_EDITLINE=1 previously # worked. - hwaci-indented-notice -error { + proj-indented-notice -error { ERROR: the --enable-editline flag is not supported due to non-availability of systems which have it in a form which the sqlite3 CLI shell expects to see. On some systems this can be @@ -798,10 +798,10 @@ proc sqlite-check-line-editing {} { # Transform with-readline-header=X to with-readline-cflags=-I... set v [opt-val with-readline-header] - hwaci-opt-set with-readline-header "" + proj-opt-set with-readline-header "" if {"" ne $v} { if {"auto" eq $v} { - hwaci-opt-set with-readline-cflags auto + proj-opt-set with-readline-cflags auto } else { set v [file dirname $v] if {[string match */*line $v]} { @@ -812,7 +812,7 @@ proc sqlite-check-line-editing {} { # work! set v [file dirname $v] } - hwaci-opt-set with-readline-cflags "-I$v" + proj-opt-set with-readline-cflags "-I$v" } } @@ -822,7 +822,7 @@ proc sqlite-check-line-editing {} { set rlInc "" if {!$::cross_compiling} { # ^^^ this check is derived from the legacy configure script - set rlInc [hwaci-search-for-header-dir readline.h \ + set rlInc [proj-search-for-header-dir readline.h \ -dirs {/usr /usr/local /usr/local/readline /usr/contrib /mingw} \ -subdirs {include/readline include}] # ^^^ The -dirs and -subdirs lists are from the legacy configure script @@ -843,14 +843,14 @@ proc sqlite-check-line-editing {} { if {"" eq $rlLib || "auto" eq $rlLib} { set rlLib "" set libTerm "" - if {[hwaci-check-function-in-lib tgetent {readline ncurses curses termcap}]} { + if {[proj-check-function-in-lib tgetent {readline ncurses curses termcap}]} { # ^^^ that libs list comes from the legacy configure script ^^^ set libTerm [get-define lib_tgetent] undefine lib_tgetent } if {"readline" eq $libTerm} { set rlLib $libTerm - } elseif {[hwaci-check-function-in-lib readline readline $libTerm]} { + } elseif {[proj-check-function-in-lib readline readline $libTerm]} { set rlLib [get-define lib_readline] lappend rlLib $libTerm undefine lib_readline @@ -904,7 +904,7 @@ proc sqlite-check-line-editing {} { user-notice "Readline completion enabled" } else { user-notice "WARNING: readline completion disabled due to rl_completion_matches() signature mismatch" - add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION + sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION } return "readline" } @@ -913,8 +913,8 @@ proc sqlite-check-line-editing {} { }; # sqlite-check-line-editing msg-result "Line-editing support for the sqlite3 shell: [sqlite-check-line-editing]" -hwaci-if-opt-truthy load-extension { - if {[hwaci-check-function-in-lib dlopen dl]} { +proj-if-opt-truthy load-extension { + if {[proj-check-function-in-lib dlopen dl]} { define LDFLAGS_DLOPEN [get-define lib_dlopen] undefine lib_dlopen } else { @@ -926,8 +926,8 @@ hwaci-if-opt-truthy load-extension { msg-result "Disabling loadable extensions." } -hwaci-if-opt-truthy math { - if {![hwaci-check-function-in-lib ceil m]} { +proj-if-opt-truthy math { + if {![proj-check-function-in-lib ceil m]} { user-error "Cannot find libm functions. Use --disable-math to bypass this." } define LDFLAGS_MATH [get-define lib_ceil] @@ -945,9 +945,9 @@ define cross_compiling ${cross_compiling} # Emscripten SDK for building the web-based wasm components. # set emccsh $srcdir/tool/emcc.sh -if {![get-define HAVE_WASI_SDK] && [hwaci-check-emsdk]} { +if {![get-define HAVE_WASI_SDK] && [proj-check-emsdk]} { define EMCC_WRAPPER $emccsh - hwaci-make-from-dot-in $emccsh + proj-make-from-dot-in $emccsh catch {exec chmod u+x $emccsh} } else { define EMCC_WRAPPER "" @@ -977,25 +977,25 @@ proc sqlite-check-icu {} { # - -licui18n -licuuc -licudata # - -licui18n -licuuc # - /usr/local/bin/icu-config --ldflags - if {[hwaci-opt-was-provided with-icu-config]} { + if {[proj-opt-was-provided with-icu-config]} { set bin [opt-val with-icu-config] if {"auto" eq $bin} { - set bin [hwaci-first-bin-of \ + set bin [proj-first-bin-of \ [get-define prefix]/bin/icu-config \ /usr/local/bin/icu-config \ /usr/bin/icu-config] if {"" eq $bin} { - hwaci-fatal "--with-icu-config=auto cannot find icu-config binary" + proj-fatal "--with-icu-config=auto cannot find icu-config binary" } } if {[file-isexec $bin]} { set x [exec $bin --ldflags] if {"" eq $x} { - hwaci-fatal "$bin --ldflags returned no data" + proj-fatal "$bin --ldflags returned no data" } define-append LDFLAGS_ICU $x } else { - hwaci-fatal "--with-icu-config=$bin does not refer to an executable" + proj-fatal "--with-icu-config=$bin does not refer to an executable" } } set flags [define LDFLAGS_ICU [string trim [get-define LDFLAGS_ICU]]] @@ -1008,7 +1008,7 @@ proc sqlite-check-icu {} { # Recall that shell.c builds with sqlite3.c } } elseif {[opt-bool icu-collations]} { - hwaci-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags" + proj-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags" } else { msg-result "ICU support is disabled." } @@ -1022,7 +1022,7 @@ sqlite-check-icu # required linker flags (which may be empty even if the math APIs are # found, depending on the OS). proc affirm-have-math {why} { - if {![msg-quiet hwaci-check-function-in-lib log m]} { + if {![msg-quiet proj-check-function-in-lib log m]} { user-error "Missing math APIs for $why" } define LDFLAGS_MATH [get-define lib_log ""] @@ -1034,29 +1034,29 @@ proc affirm-have-math {why} { msg-result "Feature flags..." foreach {boolFlag featureFlag ifSetEvalThis} { all {} { - hwaci-opt-set fts4 - hwaci-opt-set fts5 - hwaci-opt-set geopoly - hwaci-opt-set rtree - hwaci-opt-set session + proj-opt-set fts4 + proj-opt-set fts5 + proj-opt-set geopoly + proj-opt-set rtree + proj-opt-set session } fts4 -DSQLITE_ENABLE_FTS4 {affirm-have-math fts4} fts5 -DSQLITE_ENABLE_FTS5 {affirm-have-math fts5} - geopoly -DSQLITE_ENABLE_GEOPOLY {hwaci-opt-set rtree} + geopoly -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree} rtree -DSQLITE_ENABLE_RTREE {} session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {} update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {} memsys5 -DSQLITE_ENABLE_MEMSYS5 {} memsys3 {} { if {[opt-bool memsys5]} { - hwaci-warn "not enabling memsys3 because memsys5 is enabled." + proj-warn "not enabling memsys3 because memsys5 is enabled." expr 0 } else { sqlite-add-feature-flag -DSQLITE_ENABLE_MEMSYS3 } } } { - hwaci-if-opt-truthy $boolFlag { + proj-if-opt-truthy $boolFlag { sqlite-add-feature-flag $featureFlag if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} { msg-result " + $boolFlag" @@ -1076,7 +1076,7 @@ foreach {boolFlag featureFlag ifSetEvalThis} { foreach {boolFlag featureFlag} { json -DSQLITE_OMIT_JSON } { - if {[hwaci-opt-truthy $boolFlag]} { + if {[proj-opt-truthy $boolFlag]} { msg-result " + $boolFlag" } else { sqlite-add-feature-flag $featureFlag @@ -1123,10 +1123,10 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { # # Potential TODO (unclear): in sqlite3.pc.in, do we need to include # any CFLAGS_READLINE, CFLAGS_ZLIB, etc in its "Cflags:" section? -hwaci-make-from-dot-in -touch Makefile sqlite3.pc +proj-make-from-dot-in -touch Makefile sqlite3.pc if {0} { # Requires a hand-written sqlite_cfg.h.in... - hwaci-make-from-dot-in sqlite_cfg.h + proj-make-from-dot-in sqlite_cfg.h # vs... } else { # Requires no input template... @@ -1136,9 +1136,9 @@ if {0} { TARGET_* USE_GCOV TCL_*} \ -auto {HAVE_* PACKAGE_*} \ -none * - hwaci-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@ + proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@ } -#TODO hwaci-make-from-dot-in ext/wasm/GNUmakefile +#TODO proj-make-from-dot-in ext/wasm/GNUmakefile if {"" ne $DUMP_DEFINES_JSON} { ######################################################################## @@ -1154,18 +1154,18 @@ if {"" ne $DUMP_DEFINES_JSON} { -auto {OPT_* PACKAGE_* HAVE_*} } if {[opt-bool defines-json-include-lowercase]} { - lappend dumpDefsOpt -none {lib_*} ; # remnants from hwaci-check-function-in-lib and friends + lappend dumpDefsOpt -none {lib_*} ; # remnants from proj-check-function-in-lib and friends lappend dumpDefsOpt -auto {[a-z]*} } lappend dumpDefsOpt -none * - hwaci-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt + proj-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt undefine OPT_FEATURE_FLAGS.list undefine OPT_SHELL.list } ######################################################################## # Some build-dev/debug-only output -hwaci-if-opt-truthy dump-defines { +proj-if-opt-truthy dump-defines { msg-result "--dump-defines is creating $::DUMP_DEFINES_TXT" make-config-header $::DUMP_DEFINES_TXT \ -bare {SQLITE_OS* SQLITE_DEBUG USE_*} \ @@ -1180,4 +1180,4 @@ hwaci-if-opt-truthy dump-defines { } } -msg-result [hwaci-bold "Source tree is configured! Run make to build it."] +msg-result [proj-bold "Source tree is configured! Run make to build it."] diff --git a/autosetup/hwaci-common.tcl b/autosetup/proj.tcl similarity index 86% rename from autosetup/hwaci-common.tcl rename to autosetup/proj.tcl index 4168b87460..5fdf94d2d2 100644 --- a/autosetup/hwaci-common.tcl +++ b/autosetup/proj.tcl @@ -45,15 +45,15 @@ ######################################################################## ######################################################################## -# $hwaci_ is an internal-use-only array for storing whatever generic +# $proj_ is an internal-use-only array for storing whatever generic # internal stuff we need stored. -array set hwaci_ {} -set hwaci_(isatty) [isatty? stdout] +array set proj_ {} +set proj_(isatty) [isatty? stdout] -proc hwaci-warn {msg} { +proc proj-warn {msg} { puts stderr "WARNING: $msg" } -proc hwaci-fatal {msg} { +proc proj-fatal {msg} { show-notices puts stderr "ERROR: $msg" exit 1 @@ -63,8 +63,8 @@ proc hwaci-fatal {msg} { # If this function believes that the current console might support # ANSI escape sequences then this returns $str wrapped in a sequence # to bold that text, else it returns $str as-is. -proc hwaci-bold {str} { - if {$::autosetup(iswin) || !$::hwaci_(isatty)} { +proc proj-bold {str} { + if {$::autosetup(iswin) || !$::proj_(isatty)} { return $str } return "\033\[1m${str}\033\[0m" @@ -78,7 +78,7 @@ proc hwaci-bold {str} { # # If its first argument is -error then it renders the message # immediately and then exits. -proc hwaci-indented-notice {args} { +proc proj-indented-notice {args} { set fErr "" switch -exact -- [lindex $args 0] { -error { set args [lassign $args fErr] } @@ -95,16 +95,16 @@ proc hwaci-indented-notice {args} { ######################################################################## # Returns 1 if cross-compiling, else 0. -proc hwaci-is-cross-compiling {} { +proc proj-is-cross-compiling {} { return [expr {[get-define host] ne [get-define build]}] } ######################################################################## -# hwaci-lshift_ shifts $count elements from the list named $listVar +# proj-lshift_ shifts $count elements from the list named $listVar # and returns them as a new list. On empty input, returns "". # # Modified slightly from: https://wiki.tcl-lang.org/page/lshift -proc hwaci-lshift_ {listVar {count 1}} { +proc proj-lshift_ {listVar {count 1}} { upvar 1 $listVar l if {![info exists l]} { # make the error message show the real variable name @@ -124,7 +124,7 @@ proc hwaci-lshift_ {listVar {count 1}} { # out any lines which begin with an number of whitespace followed by a # '#', and returns a value containing the [append]ed results of each # remaining line with a \n between each. -proc hwaci-strip-hash-comments_ {val} { +proc proj-strip-hash-comments_ {val} { set x {} foreach line [split $val \n] { if {![string match "#*" [string trimleft $line]]} { @@ -138,7 +138,7 @@ proc hwaci-strip-hash-comments_ {val} { # A proxy for cc-check-function-in-lib which "undoes" any changes that # routine makes to the LIBS define. Returns the result of # cc-check-function-in-lib. -proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { +proc proj-check-function-in-lib {function libs {otherlibs {}}} { set found 0 define-push {LIBS} { set found [cc-check-function-in-lib $function $libs $otherlibs] @@ -151,11 +151,11 @@ proc hwaci-check-function-in-lib {function libs {otherlibs {}}} { # by the -dirs {LIST} and -subdirs {LIST} flags (each of which have # sane defaults). Returns either the first matching dir or an empty # string. The return value does not contain the filename part. -proc hwaci-search-for-header-dir {header args} { +proc proj-search-for-header-dir {header args} { set subdirs {include} set dirs {/usr /usr/local /mingw} # Debatable: -# if {![hwaci-is-cross-compiling]} { +# if {![proj-is-cross-compiling]} { # lappend dirs [get-define prefix] # } while {[llength $args]} { @@ -163,7 +163,7 @@ proc hwaci-search-for-header-dir {header args} { -dirs { set args [lassign $args - dirs] } -subdirs { set args [lassign $args - subdirs] } default { - hwaci-fatal "Unhandled argument: $args" + proj-fatal "Unhandled argument: $args" } } } @@ -179,21 +179,21 @@ proc hwaci-search-for-header-dir {header args} { ######################################################################## # If $v is true, [puts $msg] is called, else puts is not called. -#proc hwaci-maybe-verbose {v msg} { +#proc proj-maybe-verbose {v msg} { # if {$v} { # puts $msg # } #} ######################################################################## -# Usage: hwaci-find-executable-path ?-v? binaryName +# Usage: proj-find-executable-path ?-v? binaryName # # Works similarly to autosetup's [find-executable-path $binName] but: # # - If the first arg is -v, it's verbose about searching, else it's quiet. # # Returns the full path to the result or an empty string. -proc hwaci-find-executable-path {args} { +proc proj-find-executable-path {args} { set binName $args set verbose 0 if {[lindex $args 0] eq "-v"} { @@ -213,15 +213,15 @@ proc hwaci-find-executable-path {args} { } ######################################################################## -# Uses [hwaci-find-executable-path $binName] to (verbosely) search for +# Uses [proj-find-executable-path $binName] to (verbosely) search for # a binary, sets a define (see below) to the result, and returns the # result (an empty string if not found). # # The define'd name is: if defName is empty then "BIN_X" is used, # where X is the upper-case form of $binName with any '-' characters # replaced with '_'. -proc hwaci-bin-define {binName {defName {}}} { - set check [hwaci-find-executable-path -v $binName] +proc proj-bin-define {binName {defName {}}} { + set check [proj-find-executable-path -v $binName] if {"" eq $defName} { set defName "BIN_[string toupper [string map {- _} $binName]]" } @@ -230,7 +230,7 @@ proc hwaci-bin-define {binName {defName {}}} { } ######################################################################## -# Usage: hwaci-first-bin-of bin... +# Usage: proj-first-bin-of bin... # # Looks for the first binary found of the names passed to this # function. If a match is found, the full path to that binary is @@ -240,7 +240,7 @@ proc hwaci-bin-define {binName {defName {}}} { # any define'd name that function stores for the result (because the # caller has no sensible way of knowing which result it was unless # they pass only a single argument). -proc hwaci-first-bin-of {args} { +proc proj-first-bin-of {args} { foreach b $args { if {[cc-path-progs $b]} { set u [string toupper $b] @@ -258,8 +258,8 @@ proc hwaci-first-bin-of {args} { # # TODO: move this out of this file and back into the 1 or 2 downstream # trees which use it. -proc hwaci-require-bash {} { - set bash [hwaci-bin-define bash] +proc proj-require-bash {} { + set bash [proj-bin-define bash] if {"" eq $bash} { user-error "Cannot find required bash shell" } @@ -281,7 +281,7 @@ proc hwaci-require-bash {} { # passes --foo-bar to configure, even if that invocation would resolve # to the default value of baz. If the user does not explicitly pass in # --foo-bar (with or without a value) then this returns 0. -proc hwaci-opt-was-provided {key} { +proc proj-opt-was-provided {key} { dict exists $::autosetup(optset) $key } @@ -290,7 +290,7 @@ proc hwaci-opt-was-provided {key} { # later with [opt-val], [opt-bool], and friends. # # Returns $val. -proc hwaci-opt-set {flag {val 1}} { +proc proj-opt-set {flag {val 1}} { global autosetup if {$flag ni $::autosetup(options)} { # We have to add this to autosetup(options) or else future calls @@ -304,15 +304,15 @@ proc hwaci-opt-set {flag {val 1}} { ######################################################################## # Returns 1 if $val appears to be a truthy value, else returns # 0. Truthy values are any of {1 on enabled yes} -proc hwaci-val-truthy {val} { +proc proj-val-truthy {val} { expr {$val in {1 on enabled yes}} } ######################################################################## # Returns 1 if [opt-val $flag] appears to be a truthy value or -# [opt-bool $flag] is true. See hwaci-val-truthy. -proc hwaci-opt-truthy {flag} { - if {[hwaci-val-truthy [opt-val $flag]]} { return 1 } +# [opt-bool $flag] is true. See proj-val-truthy. +proc proj-opt-truthy {flag} { + if {[proj-val-truthy [opt-val $flag]]} { return 1 } set rc 0 catch { # opt-bool will throw if $flag is not a known boolean flag @@ -322,9 +322,9 @@ proc hwaci-opt-truthy {flag} { } ######################################################################## -# If [hwaci-opt-truthy $flag] is true, eval $then, else eval $else. -proc hwaci-if-opt-truthy {boolFlag thenScript {elseScript {}}} { - if {[hwaci-opt-truthy $boolFlag]} { +# If [proj-opt-truthy $flag] is true, eval $then, else eval $else. +proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} { + if {[proj-opt-truthy $boolFlag]} { uplevel 1 $thenScript } else { uplevel 1 $elseScript @@ -332,23 +332,23 @@ proc hwaci-if-opt-truthy {boolFlag thenScript {elseScript {}}} { } ######################################################################## -# If [hwaci-opt-truthy $flag] then [define $def $iftrue] else [define +# If [proj-opt-truthy $flag] then [define $def $iftrue] else [define # $def $iffalse]. If $msg is not empty, output [msg-checking $msg] and # a [msg-results ...] which corresponds to the result. Returns 1 if # the opt-truthy check passes, else 0. -proc hwaci-define-if-opt-truthy {flag def {msg ""} {iftrue 1} {iffalse 0}} { +proc proj-define-if-opt-truthy {flag def {msg ""} {iftrue 1} {iffalse 0}} { if {"" ne $msg} { msg-checking "$msg " } set rcMsg "" set rc 0 - if {[hwaci-opt-truthy $flag]} { + if {[proj-opt-truthy $flag]} { define $def $iftrue set rc 1 } else { define $def $iffalse } - switch -- [hwaci-val-truthy [get-define $def]] { + switch -- [proj-val-truthy [get-define $def]] { 0 { set rcMsg no } 1 { set rcMsg yes } } @@ -361,28 +361,28 @@ proc hwaci-define-if-opt-truthy {flag def {msg ""} {iftrue 1} {iffalse 0}} { ######################################################################## # Args: [-v] optName defName {descr {}} # -# Checks [hwaci-opt-truthy $optName] and calls [define $defName X] +# Checks [proj-opt-truthy $optName] and calls [define $defName X] # where X is 0 for false and 1 for true. descr is an optional # [msg-checking] argument which defaults to $defName. Returns X. # # If args[0] is -v then the boolean semantics are inverted: if # the option is set, it gets define'd to 0, else 1. Returns the # define'd value. -proc hwaci-opt-define-bool {args} { +proc proj-opt-define-bool {args} { set invert 0 if {[lindex $args 0] eq "-v"} { set invert 1 set args [lrange $args 1 end] } - set optName [hwaci-lshift_ args] - set defName [hwaci-lshift_ args] - set descr [hwaci-lshift_ args] + set optName [proj-lshift_ args] + set defName [proj-lshift_ args] + set descr [proj-lshift_ args] if {"" eq $descr} { set descr $defName } set rc 0 msg-checking "$descr ... " - if {[hwaci-opt-truthy $optName]} { + if {[proj-opt-truthy $optName]} { if {0 eq $invert} { set rc 1 } else { @@ -414,7 +414,7 @@ proc hwaci-opt-define-bool {args} { # # Note that if it finds LIBLTDL it does not look for LIBDL, so will # report only that is has LIBLTDL. -proc hwaci-check-module-loader {} { +proc proj-check-module-loader {} { msg-checking "Looking for module-loader APIs... " if {99 ne [get-define LDFLAGS_MODULE_LOADER 99]} { if {1 eq [get-define HAVE_LIBLTDL 0]} { @@ -460,11 +460,11 @@ proc hwaci-check-module-loader {} { } ######################################################################## -# Sets all flags which would be set by hwaci-check-module-loader to +# Sets all flags which would be set by proj-check-module-loader to # empty/falsy values, as if those checks had failed to find a module # loader. Intended to be called in place of that function when # a module loader is explicitly not desired. -proc hwaci-no-check-module-loader {} { +proc proj-no-check-module-loader {} { define HAVE_LIBDL 0 define HAVE_LIBLTDL 0 define LDFLAGS_MODULE_LOADER "" @@ -472,7 +472,7 @@ proc hwaci-no-check-module-loader {} { ######################################################################## # Opens the given file, reads all of its content, and returns it. -proc hwaci-file-content {fname} { +proc proj-file-content {fname} { set fp [open $fname r] set rc [read $fp] close $fp @@ -482,7 +482,7 @@ proc hwaci-file-content {fname} { ######################################################################## # Returns the contents of the given file as an array of lines, with # the EOL stripped from each input line. -proc hwaci-file-content-list {fname} { +proc proj-file-content-list {fname} { set fp [open $fname r] set rc {} while { [gets $fp line] >= 0 } { @@ -501,9 +501,9 @@ proc hwaci-file-content-list {fname} { # # This test has a long history of false positive results because of # compilers reacting differently to the -MJ flag. -proc hwaci-check-compile-commands {{configOpt {}}} { +proc proj-check-compile-commands {{configOpt {}}} { msg-checking "compile_commands.json support... " - if {"" ne $configOpt && ![hwaci-opt-truthy $configOpt]} { + if {"" ne $configOpt && ![proj-opt-truthy $configOpt]} { msg-result "explicitly disabled" define MAKE_COMPILATION_DB no return 0 @@ -525,14 +525,14 @@ proc hwaci-check-compile-commands {{configOpt {}}} { ######################################################################## # Runs the 'touch' command on one or more files, ignoring any errors. -proc hwaci-touch {filename} { +proc proj-touch {filename} { catch { exec touch {*}$filename } } ######################################################################## # Usage: # -# hwaci-make-from-dot-in ?-touch? filename(s)... +# proj-make-from-dot-in ?-touch? filename(s)... # # Uses [make-template] to create makefile(-like) file(s) $filename # from $filename.in but explicitly makes the output read-only, to @@ -545,7 +545,7 @@ proc hwaci-touch {filename} { # please the build process. # # Failures when running chmod or touch are silently ignored. -proc hwaci-make-from-dot-in {args} { +proc proj-make-from-dot-in {args} { set filename $args set touch 0 if {[lindex $args 0] eq "-touch"} { @@ -557,7 +557,7 @@ proc hwaci-make-from-dot-in {args} { catch { exec chmod u+w $f } make-template $f.in $f if {$touch} { - hwaci-touch $f + proj-touch $f } catch { exec chmod -w $f } } @@ -574,9 +574,9 @@ proc hwaci-make-from-dot-in {args} { # order to avoid potential problems with escaping, space-containing # tokens, and interfering with autosetup's use of these vars, this # routine does not directly modify CFLAGS or LDFLAGS. -proc hwaci-check-profile-flag {{flagname profile}} { - #puts "flagname=$flagname ?[hwaci-opt-truthy $flagname]?" - if {[hwaci-opt-truthy $flagname]} { +proc proj-check-profile-flag {{flagname profile}} { + #puts "flagname=$flagname ?[proj-opt-truthy $flagname]?" + if {[proj-opt-truthy $flagname]} { set CC [get-define CC] regsub {.*ccache *} $CC "" CC # ^^^ if CC="ccache gcc" then [exec] treats "ccache gcc" as a @@ -602,7 +602,7 @@ proc hwaci-check-profile-flag {{flagname profile}} { # machine, i.e. the local host). If $key == "build" then some # additional checks may be performed which are not applicable when # $key == "host". -proc hwaci-looks-like-windows {{key host}} { +proc proj-looks-like-windows {{key host}} { global autosetup switch -glob -- [get-define $key] { *-*-ming* - *-*-cygwin - *-*-msys { @@ -628,7 +628,7 @@ proc hwaci-looks-like-windows {{key host}} { # # TODO: have someone verify whether this is correct for the # non-Linux/BSD platforms. -proc hwaci-looks-like-mac {{key host}} { +proc proj-looks-like-mac {{key host}} { switch -glob -- [get-define $key] { *apple* { return 1 @@ -645,13 +645,13 @@ proc hwaci-looks-like-mac {{key host}} { # build environment is then BUILD_EXEEXT is [define]'d to ".exe", else # "". If the target, a.k.a. "host", is then TARGET_EXEEXT is # [define]'d to ".exe", else "". -proc hwaci-exe-extension {} { +proc proj-exe-extension {} { set rH "" set rB "" - if {[hwaci-looks-like-windows host]} { + if {[proj-looks-like-windows host]} { set rH ".exe" } - if {[hwaci-looks-like-windows build]} { + if {[proj-looks-like-windows build]} { set rB ".exe" } define BUILD_EXEEXT $rB @@ -659,7 +659,7 @@ proc hwaci-exe-extension {} { } ######################################################################## -# Works like hwaci-exe-extension except that it defines BUILD_DLLEXT +# Works like proj-exe-extension except that it defines BUILD_DLLEXT # and TARGET_DLLEXT to one of (.so, ,dll, .dylib). # # Trivia: for .dylib files, the linker needs the -dynamiclib flag @@ -667,7 +667,7 @@ proc hwaci-exe-extension {} { # # TODO: have someone verify whether this is correct for the # non-Linux/BSD platforms. -proc hwaci-dll-extension {} { +proc proj-dll-extension {} { proc inner {key} { switch -glob -- [get-define $key] { *apple* { @@ -686,10 +686,10 @@ proc hwaci-dll-extension {} { } ######################################################################## -# Static-library counterpart of hwaci-dll-extension. Defines +# Static-library counterpart of proj-dll-extension. Defines # BUILD_LIBEXT and TARGET_LIBEXT to the conventional static library # extension for the being-built-on resp. the target platform. -proc hwaci-lib-extension {} { +proc proj-lib-extension {} { proc inner {key} { switch -glob -- [get-define $key] { *-*-ming* - *-*-cygwin - *-*-msys { @@ -705,11 +705,11 @@ proc hwaci-lib-extension {} { } ######################################################################## -# Calls all of the hwaci-*-extension functions. -proc hwaci-file-extensions {} { - hwaci-exe-extension - hwaci-dll-extension - hwaci-lib-extension +# Calls all of the proj-*-extension functions. +proc proj-file-extensions {} { + proj-exe-extension + proj-dll-extension + proj-lib-extension } ######################################################################## @@ -717,7 +717,7 @@ proc hwaci-file-extensions {} { # the filesystem, it fails fatally with an informative message. # Returns the last file name it checks. If the first argument is -v # then it emits msg-checking/msg-result messages for each file. -proc hwaci-affirm-files-exist {args} { +proc proj-affirm-files-exist {args} { set rc "" set verbose 0 if {[lindex $args 0] eq "-v"} { @@ -753,7 +753,7 @@ proc hwaci-affirm-files-exist {args} { # but BIN_EMCC is then emcc was not found in the EMSDK_HOME, in which # case we have to rely on the fact that sourcing $EMSDK_ENV from a # shell will add emcc to the $PATH. -proc hwaci-check-emsdk {} { +proc proj-check-emsdk {} { set emsdkHome [opt-val with-emsdk] define EMSDK_HOME "" define EMSDK_ENV "" @@ -794,7 +794,7 @@ proc hwaci-check-emsdk {} { # Achtung: we have seen platforms which report that a given option # checked here will work but then fails at build-time, and the current # order of checks reflects that. -proc hwaci-check-rpath {} { +proc proj-check-rpath {} { set rc 1 set lp "[get-define prefix]/lib" # If we _don't_ use cc-with {} here (to avoid updating the global @@ -840,7 +840,7 @@ proc hwaci-check-rpath {} { # . # # Returns the value of HAVE_READLINE. -proc hwaci-check-readline {} { +proc proj-check-readline {} { define HAVE_READLINE 0 define LDFLAGS_READLINE "" define CFLAGS_READLINE "" @@ -875,9 +875,9 @@ proc hwaci-check-readline {} { # Look for readline.h set rlInc "" - if {![hwaci-is-cross-compiling]} { + if {![proj-is-cross-compiling]} { # ^^^ this check is derived from SQLite's legacy configure script - set rlInc [hwaci-search-for-header-dir readline.h \ + set rlInc [proj-search-for-header-dir readline.h \ -subdirs {include/readline include}] if {"" ne $rlInc} { if {[string match */*line $rlInc]} { @@ -896,14 +896,14 @@ proc hwaci-check-readline {} { set rlLib "" if {"" ne $rlInc} { set libTerm "" - if {[hwaci-check-function-in-lib tgetent {readline ncurses curses termcap}]} { + if {[proj-check-function-in-lib tgetent {readline ncurses curses termcap}]} { # ^^^ check extracted from an ancient autotools configure script. set libTerm [get-define lib_tgetent] undefine lib_tgetent } if {"readline" eq $libTerm} { set rlLib $libTerm - } elseif {[hwaci-check-function-in-lib readline readline $libTerm]} { + } elseif {[proj-check-function-in-lib readline readline $libTerm]} { set rlLib [get-define lib_readline] lappend rlLib $libTerm undefine lib_readline @@ -925,12 +925,12 @@ proc hwaci-check-readline {} { ######################################################################## -# Internal helper for hwaci-dump-defs-json. Expects to be passed a +# Internal helper for proj-dump-defs-json. Expects to be passed a # [define] name and the variadic $args which are passed to -# hwaci-dump-defs-json. If it finds a pattern match for the given +# proj-dump-defs-json. If it finds a pattern match for the given # $name in the various $args, it returns the type flag for that $name, # e.g. "-str" or "-bare", else returns an empty string. -proc hwaci-defs-type_ {name spec} { +proc proj-defs-type_ {name spec} { foreach {type patterns} $spec { foreach pattern $patterns { if {[string match $pattern $name]} { @@ -942,50 +942,50 @@ proc hwaci-defs-type_ {name spec} { } ######################################################################## -# Internal helper for hwaci-defs-format_: returns a JSON-ish quoted +# Internal helper for proj-defs-format_: returns a JSON-ish quoted # form of the given (JSON) string-type values. -proc hwaci-quote-str_ {value} { +proc proj-quote-str_ {value} { return \"[string map [list \\ \\\\ \" \\\"] $value]\" } ######################################################################## -# An internal impl detail of hwaci-dump-defs-json. Requires a data +# An internal impl detail of proj-dump-defs-json. Requires a data # type specifier, as used by make-config-header, and a value. Returns -# the formatted value or the value $::hwaci_(defs-skip) if the caller +# the formatted value or the value $::proj_(defs-skip) if the caller # should skip emitting that value. -set hwaci_(defs-skip) "-hwaci-defs-format_ sentinel" -proc hwaci-defs-format_ {type value} { +set proj_(defs-skip) "-proj-defs-format_ sentinel" +proc proj-defs-format_ {type value} { switch -exact -- $type { -bare { # Just output the value unchanged } -none { - set value $::hwaci_(defs-skip) + set value $::proj_(defs-skip) } -str { - set value [hwaci-quote-str_ $value] + set value [proj-quote-str_ $value] } -auto { # Automatically determine the type if {![string is integer -strict $value]} { - set value [hwaci-quote-str_ $value] + set value [proj-quote-str_ $value] } } -array { set ar {} foreach v $value { - set v [hwaci-defs-format_ -auto $v] - if {$::hwaci_(defs-skip) ne $v} { + set v [proj-defs-format_ -auto $v] + if {$::proj_(defs-skip) ne $v} { lappend ar $v } } set value "\[ [join $ar {, }] \]" } "" { - set value $::hwaci_(defs-skip) + set value $::proj_(defs-skip) } default { - hwaci-fatal "Unknown type in hwaci-dump-defs-json: $type" + proj-fatal "Unknown type in proj-dump-defs-json: $type" } } return $value @@ -1021,14 +1021,14 @@ proc hwaci-defs-format_ {type value} { # Neither is especially satisfactory (and the second is useless), and # handling of such values is subject to change if any such values ever # _really_ need to be processed by our source trees. -proc hwaci-dump-defs-json {file args} { +proc proj-dump-defs-json {file args} { file mkdir [file dirname $file] set lines {} lappend args -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_* foreach n [lsort [dict keys [all-defines]]] { - set type [hwaci-defs-type_ $n $args] - set value [hwaci-defs-format_ $type [get-define $n]] - if {$::hwaci_(defs-skip) ne $value} { + set type [proj-defs-type_ $n $args] + set value [proj-defs-format_ $type [get-define $n]] + if {$::proj_(defs-skip) ne $value} { lappend lines "\"$n\": ${value}" } } @@ -1067,13 +1067,13 @@ proc hwaci-dump-defs-json {file args} { # to carry over any values from hidden aliases into their canonical # names, so that in the above example [opt-value canonical] will # return X if --alias=X is passed in. -proc hwaci-xfer-options-aliases {mapping} { - foreach {hidden - canonical} [hwaci-strip-hash-comments_ $mapping] { - if {[hwaci-opt-was-provided $hidden]} { - if {[hwaci-opt-was-provided $canonical]} { - hwaci-fatal "both --$canonical and its alias --$hidden were used. Use only one or the other." +proc proj-xfer-options-aliases {mapping} { + foreach {hidden - canonical} [proj-strip-hash-comments_ $mapping] { + if {[proj-opt-was-provided $hidden]} { + if {[proj-opt-was-provided $canonical]} { + proj-fatal "both --$canonical and its alias --$hidden were used. Use only one or the other." } else { - hwaci-opt-set $canonical [opt-val $hidden] + proj-opt-set $canonical [opt-val $hidden] } } } @@ -1095,8 +1095,8 @@ proc hwaci-xfer-options-aliases {mapping} { # Sidebar: if we do this before the cc package is installed, it gets # reverted by that package. Ergo, the cc package init will tell the # user "Build C compiler...cc" shortly before we tell them: -proc hwaci-redefine-cc-for-build {} { - if {![hwaci-is-cross-compiling] +proc proj-redefine-cc-for-build {} { + if {![proj-is-cross-compiling] && "nope" eq [get-env CC_FOR_BUILD "nope"] && [get-define CC] ne [get-define CC_FOR_BUILD]} { user-notice "Re-defining CC_FOR_BUILD to CC=[get-define CC]. To avoid this, explicitly pass CC_FOR_BUILD=..." diff --git a/manifest b/manifest index b4a42b176a..793262005d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\slong-unused,\slegacy\svsixtest/\slogic\sfrom\sthe\ssource\stree. -D 2024-10-28T13:16:32.455 +C Rename\sthe\s'hwaci'\sauto.def\sutility\sAPI\sto\sthe\smore\sgeneric\s'proj'\sAPI,\sper\s/chat\sdiscussion.\sFix\sa\sfunction\sname\stypo\swhich\scaused\sreadline\sdetection\sto\skill\sthe\sconfigure\sin\sone\scode\spath. +D 2024-10-28T14:16:50.100 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 57635a8f8c2e5e91e4c21094a70bbb56473811366e75679ceec9b6626e49a826 +F auto.def 537d9e3cd85ed5a454ee6055585a4eadedde921fbb686fcb40c8446933be2b5a F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -47,9 +47,9 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/hwaci-common.tcl 48c221838bca6e362b34c85c3dff2ba7f69efcec9558d3807c9b33b1d8c13c28 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba +F autosetup/proj.tcl b01940e6b2e9c24f2c50f0e180d308a0a4f88d2e2b00c6902edd5980d221becf w autosetup/hwaci-common.tcl F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2216,8 +2216,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f06122a543f7dac016c8da1cd92a629eb647142b95c85a131b9da8e0dc5516b0 -R 12ff824529fe88bfe6b4597dc4df53e3 -U drh -Z 126f0766a209d0ba5b53f17fec16055d +P 45ec9415b2b76a757e8bd25eed520dcc012ba67cbb3530ee8dcc42ac6125464a +R 958d2a4928946501ff168cf6ab041f76 +U stephan +Z a0759550cfa13ca8b9d7c93a198730e1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d64be41552..b92894ab56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45ec9415b2b76a757e8bd25eed520dcc012ba67cbb3530ee8dcc42ac6125464a +e20610f06bfc6f4ebc5806da05c307d91e1f0a8c7a7501a7953273dbf1816fee From 1a466a386e2d9b5014568fb2b4a8985b9eaa198e Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 14:24:36 +0000 Subject: [PATCH 200/522] Link libtclsqlite3.so to libsqlite3.so, not libsqlite3.a. FossilOrigin-Name: 45315f8f275db6059bdff7a8269014f06a793debd90675ac877f3a6f5c6ba4a4 --- main.mk | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/main.mk b/main.mk index a815354471..cbc0ec4541 100644 --- a/main.mk +++ b/main.mk @@ -1380,10 +1380,10 @@ install: install-includes pkgIndex.tcl: echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(T.dll) -$(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.LIB) +$(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.SO) $(T.link.shared) -o $@ tclsqlite.o \ $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS.libsqlite3) \ - $(libsqlite3.LIB) $(TCLLIB_RPATH) + $(libsqlite3.SO) $(TCLLIB_RPATH) $(libtclsqlite3.SO)-1: $(libtclsqlite3.SO) $(libtclsqlite3.SO)-0 $(libtclsqlite3.SO)-: libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL) diff --git a/manifest b/manifest index 793262005d..ff71b708bb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\s'hwaci'\sauto.def\sutility\sAPI\sto\sthe\smore\sgeneric\s'proj'\sAPI,\sper\s/chat\sdiscussion.\sFix\sa\sfunction\sname\stypo\swhich\scaused\sreadline\sdetection\sto\skill\sthe\sconfigure\sin\sone\scode\spath. -D 2024-10-28T14:16:50.100 +C Link\slibtclsqlite3.so\sto\slibsqlite3.so,\snot\slibsqlite3.a. +D 2024-10-28T14:24:36.077 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl b01940e6b2e9c24f2c50f0e180d308a0a4f88d2e2b00c6902edd5980d221becf w autosetup/hwaci-common.tcl +F autosetup/proj.tcl b01940e6b2e9c24f2c50f0e180d308a0a4f88d2e2b00c6902edd5980d221becf F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -707,7 +707,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 4b0bcec36d5cc83fd60d9c10666f1493c8835cec11b67b3c980ae021e225db03 +F main.mk 0fe71859e14e362e01687f75cbd19f8031ca3be07a364dcd17fde6822d101edc F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2216,8 +2216,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 45ec9415b2b76a757e8bd25eed520dcc012ba67cbb3530ee8dcc42ac6125464a -R 958d2a4928946501ff168cf6ab041f76 +P e20610f06bfc6f4ebc5806da05c307d91e1f0a8c7a7501a7953273dbf1816fee +R 2c01085fc26bf300ec3c7e7f45bf74e3 U stephan -Z a0759550cfa13ca8b9d7c93a198730e1 +Z 59570355b6239d7861477e5d0bb0a15c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b92894ab56..06d91b8aba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e20610f06bfc6f4ebc5806da05c307d91e1f0a8c7a7501a7953273dbf1816fee +45315f8f275db6059bdff7a8269014f06a793debd90675ac877f3a6f5c6ba4a4 From 4b4b5ff1d8a961544f305906e90fce6b2acb33aa Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 14:46:33 +0000 Subject: [PATCH 201/522] Update Makefile.linux-generic to account for recent var renaming. FossilOrigin-Name: 6cb7cb7e33835d42cbab2e5468d73de7bb3b01971da078ce1c1344edc11ab1b3 --- Makefile.linux-generic | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.linux-generic b/Makefile.linux-generic index b91861bbe7..13a0419238 100644 --- a/Makefile.linux-generic +++ b/Makefile.linux-generic @@ -42,7 +42,7 @@ LDFLAGS.zlib = -lz # # Library's version number. # -VERSION.XYZ ?= $(shell cat $(TOP)/VERSION 2>/dev/null) +PACKAGE_VERSION ?= $(shell cat $(TOP)/VERSION 2>/dev/null) # sqlite_cfg.h is typically created by the configure script. It's # commonly not needed but main.mk does not know that so we have to diff --git a/manifest b/manifest index ff71b708bb..aa369bcd38 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Link\slibtclsqlite3.so\sto\slibsqlite3.so,\snot\slibsqlite3.a. -D 2024-10-28T14:24:36.077 +C Update\sMakefile.linux-generic\sto\saccount\sfor\srecent\svar\srenaming. +D 2024-10-28T14:46:33.572 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 F Makefile.in 02ea00ff433902dba369d4a55b3aeb6bb1ffe2d82f777194984b8cdd7ed7c3ad -F Makefile.linux-generic 8df0e6ee5e4671f844caf27f88d2be7421e904639f7a0ffdce0e2cd4ea11e8c0 +F Makefile.linux-generic 69b54c58ab2424a0d30f340d9defd7e87c25690a55b77acb9bdc657bd9a223f1 F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 @@ -2216,8 +2216,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e20610f06bfc6f4ebc5806da05c307d91e1f0a8c7a7501a7953273dbf1816fee -R 2c01085fc26bf300ec3c7e7f45bf74e3 +P 45315f8f275db6059bdff7a8269014f06a793debd90675ac877f3a6f5c6ba4a4 +R c80a48e5113a14e0ef09fa948ac8efb3 U stephan -Z 59570355b6239d7861477e5d0bb0a15c +Z 4fcc77ebd91e5407126b8031e682ac52 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 06d91b8aba..4aac8f94d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45315f8f275db6059bdff7a8269014f06a793debd90675ac877f3a6f5c6ba4a4 +6cb7cb7e33835d42cbab2e5468d73de7bb3b01971da078ce1c1344edc11ab1b3 From 8625bd64c2936ec7b837e495a9ee1e1dd1467a09 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Oct 2024 14:53:45 +0000 Subject: [PATCH 202/522] Omit ext/consio from the tree. No longer needed or supported. FossilOrigin-Name: 1ce8507f732a26508a9b336cb27756a0a8638e14395efdd59b5faef40526ede5 --- ext/consio/console_io.c | 773 ---------------------------------------- ext/consio/console_io.h | 287 --------------- main.mk | 2 - manifest | 16 +- manifest.uuid | 2 +- 5 files changed, 8 insertions(+), 1072 deletions(-) delete mode 100755 ext/consio/console_io.c delete mode 100644 ext/consio/console_io.h diff --git a/ext/consio/console_io.c b/ext/consio/console_io.c deleted file mode 100755 index 75324a34fd..0000000000 --- a/ext/consio/console_io.c +++ /dev/null @@ -1,773 +0,0 @@ -/* -** 2023 November 4 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -******************************************************************************** -** This file implements various interfaces used for console and stream I/O -** by the SQLite project command-line tools, as explained in console_io.h . -** Functions prefixed by "SQLITE_INTERNAL_LINKAGE" behave as described there. -*/ - -#ifndef SQLITE_CDECL -# define SQLITE_CDECL -#endif - -#ifndef SHELL_NO_SYSINC -# include -# include -# include -# include -# include -# include "sqlite3.h" -#endif -#ifndef HAVE_CONSOLE_IO_H -# include "console_io.h" -#endif -#if defined(_MSC_VER) -# pragma warning(disable : 4204) -#endif - -#ifndef SQLITE_CIO_NO_TRANSLATE -# if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT -# ifndef SHELL_NO_SYSINC -# include -# include -# undef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# include -# endif -# define CIO_WIN_WC_XLATE 1 /* Use WCHAR Windows APIs for console I/O */ -# else -# ifndef SHELL_NO_SYSINC -# include -# endif -# define CIO_WIN_WC_XLATE 0 /* Use plain C library stream I/O at console */ -# endif -#else -# define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */ -#endif - -#if CIO_WIN_WC_XLATE -static HANDLE handleOfFile(FILE *pf){ - int fileDesc = _fileno(pf); - union { intptr_t osfh; HANDLE fh; } fid = { - (fileDesc>=0)? _get_osfhandle(fileDesc) : (intptr_t)INVALID_HANDLE_VALUE - }; - return fid.fh; -} -#endif - -#ifndef SQLITE_CIO_NO_TRANSLATE -typedef struct PerStreamTags { -# if CIO_WIN_WC_XLATE - HANDLE hx; - DWORD consMode; - char acIncomplete[4]; -# else - short reachesConsole; -# endif - FILE *pf; -} PerStreamTags; - -/* Define NULL-like value for things which can validly be 0. */ -# define SHELL_INVALID_FILE_PTR ((FILE *)~0) -# if CIO_WIN_WC_XLATE -# define SHELL_INVALID_CONS_MODE 0xFFFF0000 -# endif - -# if CIO_WIN_WC_XLATE -# define PST_INITIALIZER { INVALID_HANDLE_VALUE, SHELL_INVALID_CONS_MODE, \ - {0,0,0,0}, SHELL_INVALID_FILE_PTR } -# else -# define PST_INITIALIZER { 0, SHELL_INVALID_FILE_PTR } -# endif - -/* Quickly say whether a known output is going to the console. */ -# if CIO_WIN_WC_XLATE -static short pstReachesConsole(PerStreamTags *ppst){ - return (ppst->hx != INVALID_HANDLE_VALUE); -} -# else -# define pstReachesConsole(ppst) 0 -# endif - -# if CIO_WIN_WC_XLATE -static void restoreConsoleArb(PerStreamTags *ppst){ - if( pstReachesConsole(ppst) ) SetConsoleMode(ppst->hx, ppst->consMode); -} -# else -# define restoreConsoleArb(ppst) -# endif - -/* Say whether FILE* appears to be a console, collect associated info. */ -static short streamOfConsole(FILE *pf, /* out */ PerStreamTags *ppst){ -# if CIO_WIN_WC_XLATE - short rv = 0; - DWORD dwCM = SHELL_INVALID_CONS_MODE; - HANDLE fh = handleOfFile(pf); - ppst->pf = pf; - if( INVALID_HANDLE_VALUE != fh ){ - rv = (GetFileType(fh) == FILE_TYPE_CHAR && GetConsoleMode(fh,&dwCM)); - } - ppst->hx = (rv)? fh : INVALID_HANDLE_VALUE; - ppst->consMode = dwCM; - return rv; -# else - ppst->pf = pf; - ppst->reachesConsole = ( (short)isatty(fileno(pf)) ); - return ppst->reachesConsole; -# endif -} - -# ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING -# define ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x4) -# endif - -# if CIO_WIN_WC_XLATE -/* Define console modes for use with the Windows Console API. */ -# define SHELL_CONI_MODE \ - (ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | 0x80 \ - | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT) -# define SHELL_CONO_MODE (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT \ - | ENABLE_VIRTUAL_TERMINAL_PROCESSING) -# endif - -typedef struct ConsoleInfo { - PerStreamTags pstSetup[3]; - PerStreamTags pstDesignated[3]; - StreamsAreConsole sacSetup; -} ConsoleInfo; - -static short isValidStreamInfo(PerStreamTags *ppst){ - return (ppst->pf != SHELL_INVALID_FILE_PTR); -} - -static ConsoleInfo consoleInfo = { - { /* pstSetup */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER }, - { /* pstDesignated[] */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER }, - SAC_NoConsole /* sacSetup */ -}; - -SQLITE_INTERNAL_LINKAGE FILE* invalidFileStream = (FILE *)~0; - -# if CIO_WIN_WC_XLATE -static void maybeSetupAsConsole(PerStreamTags *ppst, short odir){ - if( pstReachesConsole(ppst) ){ - DWORD cm = odir? SHELL_CONO_MODE : SHELL_CONI_MODE; - SetConsoleMode(ppst->hx, cm); - } -} -# else -# define maybeSetupAsConsole(ppst,odir) -# endif - -SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void){ -# if CIO_WIN_WC_XLATE - int ix = 0; - while( ix < 6 ){ - PerStreamTags *ppst = (ix<3)? - &consoleInfo.pstSetup[ix] : &consoleInfo.pstDesignated[ix-3]; - maybeSetupAsConsole(ppst, (ix % 3)>0); - ++ix; - } -# endif -} - -SQLITE_INTERNAL_LINKAGE StreamsAreConsole -consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ){ - StreamsAreConsole rv = SAC_NoConsole; - FILE* apf[3] = { pfIn, pfOut, pfErr }; - int ix; - for( ix = 2; ix >= 0; --ix ){ - PerStreamTags *ppst = &consoleInfo.pstSetup[ix]; - if( streamOfConsole(apf[ix], ppst) ){ - rv |= (SAC_InConsole< 0 ) fflush(apf[ix]); - } - consoleInfo.sacSetup = rv; - consoleRenewSetup(); - return rv; -} - -SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ){ -# if CIO_WIN_WC_XLATE - static ConsoleInfo *pci = &consoleInfo; - if( pci->sacSetup ){ - int ix; - for( ix=0; ix<3; ++ix ){ - if( pci->sacSetup & (SAC_InConsole<pstSetup[ix]; - SetConsoleMode(ppst->hx, ppst->consMode); - } - } - } -# endif -} -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#ifdef SQLITE_CIO_INPUT_REDIR -/* Say whether given FILE* is among those known, via either -** consoleClassifySetup() or set{Output,Error}Stream, as -** readable, and return an associated PerStreamTags pointer -** if so. Otherwise, return 0. -*/ -static PerStreamTags * isKnownReadable(FILE *pf){ - static PerStreamTags *apst[] = { - &consoleInfo.pstDesignated[0], &consoleInfo.pstSetup[0], 0 - }; - int ix = 0; - do { - if( apst[ix]->pf == pf ) break; - } while( apst[++ix] != 0 ); - return apst[ix]; -} -#endif - -#ifndef SQLITE_CIO_NO_TRANSLATE -/* Say whether given FILE* is among those known, via either -** consoleClassifySetup() or set{Output,Error}Stream, as -** writable, and return an associated PerStreamTags pointer -** if so. Otherwise, return 0. -*/ -static PerStreamTags * isKnownWritable(FILE *pf){ - static PerStreamTags *apst[] = { - &consoleInfo.pstDesignated[1], &consoleInfo.pstDesignated[2], - &consoleInfo.pstSetup[1], &consoleInfo.pstSetup[2], 0 - }; - int ix = 0; - do { - if( apst[ix]->pf == pf ) break; - } while( apst[++ix] != 0 ); - return apst[ix]; -} - -static FILE *designateEmitStream(FILE *pf, unsigned chix){ - FILE *rv = consoleInfo.pstDesignated[chix].pf; - if( pf == invalidFileStream ) return rv; - else{ - /* Setting a possibly new output stream. */ - PerStreamTags *ppst = isKnownWritable(pf); - if( ppst != 0 ){ - PerStreamTags pst = *ppst; - consoleInfo.pstDesignated[chix] = pst; - }else streamOfConsole(pf, &consoleInfo.pstDesignated[chix]); - } - return rv; -} - -SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf){ - return designateEmitStream(pf, 1); -} -# ifdef CONSIO_SET_ERROR_STREAM -SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf){ - return designateEmitStream(pf, 2); -} -# endif -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#ifndef SQLITE_CIO_NO_SETMODE -# if CIO_WIN_WC_XLATE -static void setModeFlushQ(FILE *pf, short bFlush, int mode){ - if( bFlush ) fflush(pf); - _setmode(_fileno(pf), mode); -} -# else -# define setModeFlushQ(f, b, m) if(b) fflush(f) -# endif - -SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *pf, short bFlush){ - setModeFlushQ(pf, bFlush, _O_BINARY); -} -SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *pf, short bFlush){ - setModeFlushQ(pf, bFlush, _O_TEXT); -} -# undef setModeFlushQ - -#else /* defined(SQLITE_CIO_NO_SETMODE) */ -# define setBinaryMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0) -# define setTextMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0) -#endif /* defined(SQLITE_CIO_NO_SETMODE) */ - -#ifndef SQLITE_CIO_NO_TRANSLATE -# if CIO_WIN_WC_XLATE -/* Write buffer cBuf as output to stream known to reach console, -** limited to ncTake char's. Return ncTake on success, else 0. */ -static int conZstrEmit(PerStreamTags *ppst, const char *z, int ncTake){ - int rv = 0; - if( z!=NULL ){ - int nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, 0,0); - if( nwc > 0 ){ - WCHAR *zw = sqlite3_malloc64(nwc*sizeof(WCHAR)); - if( zw!=NULL ){ - nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, zw,nwc); - if( nwc > 0 ){ - /* Translation from UTF-8 to UTF-16, then WCHARs out. */ - if( WriteConsoleW(ppst->hx, zw,nwc, 0, NULL) ){ - rv = ncTake; - } - } - sqlite3_free(zw); - } - } - } - return rv; -} - -/* For {f,o,e}PrintfUtf8() when stream is known to reach console. */ -static int conioVmPrintf(PerStreamTags *ppst, const char *zFormat, va_list ap){ - char *z = sqlite3_vmprintf(zFormat, ap); - if( z ){ - int rv = conZstrEmit(ppst, z, (int)strlen(z)); - sqlite3_free(z); - return rv; - }else return 0; -} -# endif /* CIO_WIN_WC_XLATE */ - -# ifdef CONSIO_GET_EMIT_STREAM -static PerStreamTags * getDesignatedEmitStream(FILE *pf, unsigned chix, - PerStreamTags *ppst){ - PerStreamTags *rv = isKnownWritable(pf); - short isValid = (rv!=0)? isValidStreamInfo(rv) : 0; - if( rv != 0 && isValid ) return rv; - streamOfConsole(pf, ppst); - return ppst; -} -# endif - -/* Get stream info, either for designated output or error stream when -** chix equals 1 or 2, or for an arbitrary stream when chix == 0. -** In either case, ppst references a caller-owned PerStreamTags -** struct which may be filled in if none of the known writable -** streams is being held by consoleInfo. The ppf parameter is a -** byref output when chix!=0 and a byref input when chix==0. - */ -static PerStreamTags * -getEmitStreamInfo(unsigned chix, PerStreamTags *ppst, - /* in/out */ FILE **ppf){ - PerStreamTags *ppstTry; - FILE *pfEmit; - if( chix > 0 ){ - ppstTry = &consoleInfo.pstDesignated[chix]; - if( !isValidStreamInfo(ppstTry) ){ - ppstTry = &consoleInfo.pstSetup[chix]; - pfEmit = ppst->pf; - }else pfEmit = ppstTry->pf; - if( !isValidStreamInfo(ppstTry) ){ - pfEmit = (chix > 1)? stderr : stdout; - ppstTry = ppst; - streamOfConsole(pfEmit, ppstTry); - } - *ppf = pfEmit; - }else{ - ppstTry = isKnownWritable(*ppf); - if( ppstTry != 0 ) return ppstTry; - streamOfConsole(*ppf, ppst); - return ppst; - } - return ppstTry; -} - -SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...){ - va_list ap; - int rv; - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - rv = conioVmPrintf(ppst, zFormat, ap); - }else{ -# endif - rv = vfprintf(pfOut, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...){ - va_list ap; - int rv; - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# else - getEmitStreamInfo(2, &pst, &pfErr); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - rv = conioVmPrintf(ppst, zFormat, ap); - }else{ -# endif - rv = vfprintf(pfErr, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...){ - va_list ap; - int rv; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); -# else - getEmitStreamInfo(0, &pst, &pfO); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - maybeSetupAsConsole(ppst, 1); - rv = conioVmPrintf(ppst, zFormat, ap); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - }else{ -# endif - rv = vfprintf(pfO, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO){ - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); -# else - getEmitStreamInfo(0, &pst, &pfO); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - int rv; - maybeSetupAsConsole(ppst, 1); - rv = conZstrEmit(ppst, z, (int)strlen(z)); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - return rv; - }else { -# endif - return (fputs(z, pfO)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z){ - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# else - getEmitStreamInfo(2, &pst, &pfErr); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z)); - else { -# endif - return (fputs(z, pfErr)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z){ - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z)); - else { -# endif - return (fputs(z, pfOut)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#if !(defined(SQLITE_CIO_NO_UTF8SCAN) && defined(SQLITE_CIO_NO_TRANSLATE)) -/* Skip over as much z[] input char sequence as is valid UTF-8, -** limited per nAccept char's or whole characters and containing -** no char cn such that ((1<=0 => char count, nAccept<0 => character - */ -SQLITE_INTERNAL_LINKAGE const char* -zSkipValidUtf8(const char *z, int nAccept, long ccm){ - int ng = (nAccept<0)? -nAccept : 0; - const char *pcLimit = (nAccept>=0)? z+nAccept : 0; - assert(z!=0); - while( (pcLimit)? (z= pcLimit ) return z; - else{ - char ct = *zt++; - if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){ - /* Trailing bytes are too few, too many, or invalid. */ - return z; - } - } - } while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */ - z = zt; - } - } - return z; -} -#endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/ - -#ifndef SQLITE_CIO_NO_TRANSLATE -# ifdef CONSIO_SPUTB -SQLITE_INTERNAL_LINKAGE int -fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){ - assert(pfO!=0); -# if CIO_WIN_WC_XLATE - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); - if( pstReachesConsole(ppst) ){ - int rv; - maybeSetupAsConsole(ppst, 1); - rv = conZstrEmit(ppst, cBuf, nAccept); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - return rv; - }else { -# endif - return (int)fwrite(cBuf, 1, nAccept, pfO); -# if CIO_WIN_WC_XLATE - } -# endif -} -# endif - -SQLITE_INTERNAL_LINKAGE int -oPutbUtf8(const char *cBuf, int nAccept){ - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - return conZstrEmit(ppst, cBuf, nAccept); - }else { -# endif - return (int)fwrite(cBuf, 1, nAccept, pfOut); -# if CIO_WIN_WC_XLATE - } -# endif -} - -/* -** Flush the given output stream. Return non-zero for success, else 0. -*/ -#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE) -SQLITE_INTERNAL_LINKAGE int -fFlushBuffer(FILE *pfOut){ -# if CIO_WIN_WC_XLATE && !defined(SHELL_OMIT_FIO_DUPE) - return FlushFileBuffers(handleOfFile(pfOut))? 1 : 0; -# else - return fflush(pfOut); -# endif -} -#endif - -#if CIO_WIN_WC_XLATE \ - && !defined(SHELL_OMIT_FIO_DUPE) \ - && defined(SQLITE_USE_ONLY_WIN32) -static struct FileAltIds { - int fd; - HANDLE fh; -} altIdsOfFile(FILE *pf){ - struct FileAltIds rv = { _fileno(pf) }; - union { intptr_t osfh; HANDLE fh; } fid = { - (rv.fd>=0)? _get_osfhandle(rv.fd) : (intptr_t)INVALID_HANDLE_VALUE - }; - rv.fh = fid.fh; - return rv; -} - -SQLITE_INTERNAL_LINKAGE size_t -cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){ - size_t rv = 0; - struct FileAltIds fai = altIdsOfFile(pf); - int fmode = _setmode(fai.fd, _O_BINARY); - _setmode(fai.fd, fmode); - while( rv < ocnt ){ - size_t nbo = osz; - while( nbo > 0 ){ - DWORD dwno = (nbo>(1L<<24))? 1L<<24 : (DWORD)nbo; - BOOL wrc = TRUE; - BOOL genCR = (fmode & _O_TEXT)!=0; - if( genCR ){ - const char *pnl = (const char*)memchr(buf, '\n', nbo); - if( pnl ) nbo = pnl - (const char*)buf; - else genCR = 0; - } - if( dwno>0 ) wrc = WriteFile(fai.fh, buf, dwno, 0,0); - if( genCR && wrc ){ - wrc = WriteFile(fai.fh, "\r\n", 2, 0,0); - ++dwno; /* Skip over the LF */ - } - if( !wrc ) return rv; - buf = (const char*)buf + dwno; - nbo += dwno; - } - ++rv; - } - return rv; -} - -/* An fgets() equivalent, using Win32 file API for actual input. -** Input ends when given buffer is filled or a newline is read. -** If the FILE object is in text mode, swallows 0x0D. (ASCII CR) -*/ -SQLITE_INTERNAL_LINKAGE char * -cfGets(char *cBuf, int n, FILE *pf){ - int nci = 0; - struct FileAltIds fai = altIdsOfFile(pf); - int fmode = _setmode(fai.fd, _O_BINARY); - BOOL eatCR = (fmode & _O_TEXT)!=0; - _setmode(fai.fd, fmode); - while( nci < n-1 ){ - DWORD nr; - if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break; - if( nr>0 && (!eatCR || cBuf[nci]!='\r') ){ - nci += nr; - if( cBuf[nci-nr]=='\n' ) break; - } - } - if( nci < n ) cBuf[nci] = 0; - return (nci>0)? cBuf : 0; -} -# else -# define cfWrite(b,os,no,f) fwrite(b,os,no,f) -# define cfGets(b,n,f) fgets(b,n,f) -# endif - -# ifdef CONSIO_EPUTB -SQLITE_INTERNAL_LINKAGE int -ePutbUtf8(const char *cBuf, int nAccept){ - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - return conZstrEmit(ppst, cBuf, nAccept); - }else { -# endif - return (int)cfWrite(cBuf, 1, nAccept, pfErr); -# if CIO_WIN_WC_XLATE - } -# endif -} -# endif /* defined(CONSIO_EPUTB) */ - -SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){ - if( pfIn==0 ) pfIn = stdin; -# if CIO_WIN_WC_XLATE - if( pfIn == consoleInfo.pstSetup[0].pf - && (consoleInfo.sacSetup & SAC_InConsole)!=0 ){ -# if CIO_WIN_WC_XLATE==1 -# define SHELL_GULP 150 /* Count of WCHARS to be gulped at a time */ - WCHAR wcBuf[SHELL_GULP+1]; - int lend = 0, noc = 0; - if( ncMax > 0 ) cBuf[0] = 0; - while( noc < ncMax-8-1 && !lend ){ - /* There is room for at least 2 more characters and a 0-terminator. */ - int na = (ncMax > SHELL_GULP*4+1 + noc)? SHELL_GULP : (ncMax-1 - noc)/4; -# undef SHELL_GULP - DWORD nbr = 0; - BOOL bRC = ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf, na, &nbr, 0); - if( bRC && nbr>0 && (wcBuf[nbr-1]&0xF800)==0xD800 ){ - /* Last WHAR read is first of a UTF-16 surrogate pair. Grab its mate. */ - DWORD nbrx; - bRC &= ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf+nbr, 1, &nbrx, 0); - if( bRC ) nbr += nbrx; - } - if( !bRC || (noc==0 && nbr==0) ) return 0; - if( nbr > 0 ){ - int nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,0,0,0,0); - if( nmb != 0 && noc+nmb <= ncMax ){ - int iseg = noc; - nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,cBuf+noc,nmb,0,0); - noc += nmb; - /* Fixup line-ends as coded by Windows for CR (or "Enter".) - ** This is done without regard for any setMode{Text,Binary}() - ** call that might have been done on the interactive input. - */ - if( noc > 0 ){ - if( cBuf[noc-1]=='\n' ){ - lend = 1; - if( noc > 1 && cBuf[noc-2]=='\r' ) cBuf[--noc-1] = '\n'; - } - } - /* Check for ^Z (anywhere in line) too, to act as EOF. */ - while( iseg < noc ){ - if( cBuf[iseg]=='\x1a' ){ - noc = iseg; /* Chop ^Z and anything following. */ - lend = 1; /* Counts as end of line too. */ - break; - } - ++iseg; - } - }else break; /* Drop apparent garbage in. (Could assert.) */ - }else break; - } - /* If got nothing, (after ^Z chop), must be at end-of-file. */ - if( noc > 0 ){ - cBuf[noc] = 0; - return cBuf; - }else return 0; -# endif - }else{ -# endif - return cfGets(cBuf, ncMax, pfIn); -# if CIO_WIN_WC_XLATE - } -# endif -} -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#if defined(_MSC_VER) -# pragma warning(default : 4204) -#endif - -#undef SHELL_INVALID_FILE_PTR diff --git a/ext/consio/console_io.h b/ext/consio/console_io.h deleted file mode 100644 index 1affa15bad..0000000000 --- a/ext/consio/console_io.h +++ /dev/null @@ -1,287 +0,0 @@ -/* -** 2023 November 1 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -******************************************************************************** -** This file exposes various interfaces used for console and other I/O -** by the SQLite project command-line tools. These interfaces are used -** at either source conglomeration time, compilation time, or run time. -** This source provides for either inclusion into conglomerated, -** "single-source" forms or separate compilation then linking. -** -** Platform dependencies are "hidden" here by various stratagems so -** that, provided certain conditions are met, the programs using this -** source or object code compiled from it need no explicit conditional -** compilation in their source for their console and stream I/O. -** -** The symbols and functionality exposed here are not a public API. -** This code may change in tandem with other project code as needed. -** -** When this .h file and its companion .c are directly incorporated into -** a source conglomeration (such as shell.c), the preprocessor symbol -** CIO_WIN_WC_XLATE is defined as 0 or 1, reflecting whether console I/O -** translation for Windows is effected for the build. -*/ -#define HAVE_CONSOLE_IO_H 1 -#ifndef SQLITE_INTERNAL_LINKAGE -# define SQLITE_INTERNAL_LINKAGE extern /* external to translation unit */ -# include -#else -# define SHELL_NO_SYSINC /* Better yet, modify mkshellc.tcl for this. */ -#endif - -#ifndef SQLITE3_H -# include "sqlite3.h" -#endif - -#ifndef SQLITE_CIO_NO_CLASSIFY - -/* Define enum for use with following function. */ -typedef enum StreamsAreConsole { - SAC_NoConsole = 0, - SAC_InConsole = 1, SAC_OutConsole = 2, SAC_ErrConsole = 4, - SAC_AnyConsole = 0x7 -} StreamsAreConsole; - -/* -** Classify the three standard I/O streams according to whether -** they are connected to a console attached to the process. -** -** Returns the bit-wise OR of SAC_{In,Out,Err}Console values, -** or SAC_NoConsole if none of the streams reaches a console. -** -** This function should be called before any I/O is done with -** the given streams. As a side-effect, the given inputs are -** recorded so that later I/O operations on them may be done -** differently than the C library FILE* I/O would be done, -** iff the stream is used for the I/O functions that follow, -** and to support the ones that use an implicit stream. -** -** On some platforms, stream or console mode alteration (aka -** "Setup") may be made which is undone by consoleRestore(). -*/ -SQLITE_INTERNAL_LINKAGE StreamsAreConsole -consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ); -/* A usual call for convenience: */ -#define SQLITE_STD_CONSOLE_INIT() consoleClassifySetup(stdin,stdout,stderr) - -/* -** After an initial call to consoleClassifySetup(...), renew -** the same setup it effected. (A call not after is an error.) -** This will restore state altered by consoleRestore(); -** -** Applications which run an inferior (child) process which -** inherits the same I/O streams may call this function after -** such a process exits to guard against console mode changes. -*/ -SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void); - -/* -** Undo any side-effects left by consoleClassifySetup(...). -** -** This should be called after consoleClassifySetup() and -** before the process terminates normally. It is suitable -** for use with the atexit() C library procedure. After -** this call, no console I/O should be done until one of -** console{Classify or Renew}Setup(...) is called again. -** -** Applications which run an inferior (child) process that -** inherits the same I/O streams might call this procedure -** before so that said process will have a console setup -** however users have configured it or come to expect. -*/ -SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ); - -#else /* defined(SQLITE_CIO_NO_CLASSIFY) */ -# define consoleClassifySetup(i,o,e) -# define consoleRenewSetup() -# define consoleRestore() -#endif /* defined(SQLITE_CIO_NO_CLASSIFY) */ - -#ifndef SQLITE_CIO_NO_REDIRECT -/* -** Set stream to be used for the functions below which write -** to "the designated X stream", where X is Output or Error. -** Returns the previous value. -** -** Alternatively, pass the special value, invalidFileStream, -** to get the designated stream value without setting it. -** -** Before the designated streams are set, they default to -** those passed to consoleClassifySetup(...), and before -** that is called they default to stdout and stderr. -** -** It is error to close a stream so designated, then, without -** designating another, use the corresponding {o,e}Emit(...). -*/ -SQLITE_INTERNAL_LINKAGE FILE *invalidFileStream; -SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf); -# ifdef CONSIO_SET_ERROR_STREAM -SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf); -# endif -#else -# define setOutputStream(pf) -# define setErrorStream(pf) -#endif /* !defined(SQLITE_CIO_NO_REDIRECT) */ - -#ifndef SQLITE_CIO_NO_TRANSLATE -/* -** Emit output like fprintf(). If the output is going to the -** console and translation from UTF-8 is necessary, perform -** the needed translation. Otherwise, write formatted output -** to the provided stream almost as-is, possibly with newline -** translation as specified by set{Binary,Text}Mode(). -*/ -SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...); -/* Like fPrintfUtf8 except stream is always the designated output. */ -SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...); -/* Like fPrintfUtf8 except stream is always the designated error. */ -SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...); - -/* -** Emit output like fputs(). If the output is going to the -** console and translation from UTF-8 is necessary, perform -** the needed translation. Otherwise, write given text to the -** provided stream almost as-is, possibly with newline -** translation as specified by set{Binary,Text}Mode(). -*/ -SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO); -/* Like fPutsUtf8 except stream is always the designated output. */ -SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z); -/* Like fPutsUtf8 except stream is always the designated error. */ -SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z); - -/* -** Emit output like fPutsUtf8(), except that the length of the -** accepted char or character sequence is limited by nAccept. -** -** Returns the number of accepted char values. -*/ -#ifdef CONSIO_SPUTB -SQLITE_INTERNAL_LINKAGE int -fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept); -/* Like fPutbUtf8 except stream is always the designated output. */ -#endif -SQLITE_INTERNAL_LINKAGE int -oPutbUtf8(const char *cBuf, int nAccept); -/* Like fPutbUtf8 except stream is always the designated error. */ -#ifdef CONSIO_EPUTB -SQLITE_INTERNAL_LINKAGE int -ePutbUtf8(const char *cBuf, int nAccept); -#endif - -/* -** Flush the given output stream. Return non-zero for success, else 0. -*/ -#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE) -SQLITE_INTERNAL_LINKAGE int -fFlushBuffer(FILE *pfOut); -#endif - -/* -** Collect input like fgets(...) with special provisions for input -** from the console on such platforms as require same. Newline -** translation may be done as set by set{Binary,Text}Mode(). -** As a convenience, pfIn==NULL is treated as stdin. -*/ -SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn); -/* Like fGetsUtf8 except stream is always the designated input. */ -/* SQLITE_INTERNAL_LINKAGE char* iGetsUtf8(char *cBuf, int ncMax); */ - -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#ifndef SQLITE_CIO_NO_SETMODE -/* -** Set given stream for binary mode, where newline translation is -** not done, or for text mode where, for some platforms, newlines -** are translated to the platform's conventional char sequence. -** If bFlush true, flush the stream. -** -** An additional side-effect is that if the stream is one passed -** to consoleClassifySetup() as an output, it is flushed first. -** -** Note that binary/text mode has no effect on console I/O -** translation. On all platforms, newline to the console starts -** a new line and CR,LF chars from the console become a newline. -*/ -SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *, short bFlush); -SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *, short bFlush); -#endif - -#ifdef SQLITE_CIO_PROMPTED_IN -typedef struct Prompts { - int numPrompts; - const char **azPrompts; -} Prompts; - -/* -** Macros for use of a line editor. -** -** The following macros define operations involving use of a -** line-editing library or simple console interaction. -** A "T" argument is a text (char *) buffer or filename. -** A "N" argument is an integer. -** -** SHELL_ADD_HISTORY(T) // Record text as line(s) of history. -** SHELL_READ_HISTORY(T) // Read history from file named by T. -** SHELL_WRITE_HISTORY(T) // Write history to file named by T. -** SHELL_STIFLE_HISTORY(N) // Limit history to N entries. -** -** A console program which does interactive console input is -** expected to call: -** SHELL_READ_HISTORY(T) before collecting such input; -** SHELL_ADD_HISTORY(T) as record-worthy input is taken; -** SHELL_STIFLE_HISTORY(N) after console input ceases; then -** SHELL_WRITE_HISTORY(T) before the program exits. -*/ - -/* -** Retrieve a single line of input text from an input stream. -** -** If pfIn is the input stream passed to consoleClassifySetup(), -** and azPrompt is not NULL, then a prompt is issued before the -** line is collected, as selected by the isContinuation flag. -** Array azPrompt[{0,1}] holds the {main,continuation} prompt. -** -** If zBufPrior is not NULL then it is a buffer from a prior -** call to this routine that can be reused, or will be freed. -** -** The result is stored in space obtained from malloc() and -** must either be freed by the caller or else passed back to -** this function as zBufPrior for reuse. -** -** This function may call upon services of a line-editing -** library to interactively collect line edited input. -*/ -SQLITE_INTERNAL_LINKAGE char * -shellGetLine(FILE *pfIn, char *zBufPrior, int nLen, - short isContinuation, Prompts azPrompt); -#endif /* defined(SQLITE_CIO_PROMPTED_IN) */ -/* -** TBD: Define an interface for application(s) to generate -** completion candidates for use by the line-editor. -** -** This may be premature; the CLI is the only application -** that does this. Yet, getting line-editing melded into -** console I/O is desirable because a line-editing library -** may have to establish console operating mode, possibly -** in a way that interferes with the above functionality. -*/ - -#if !(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE)) -/* Skip over as much z[] input char sequence as is valid UTF-8, -** limited per nAccept char's or whole characters and containing -** no char cn such that ((1<=0 => char count, nAccept<0 => character - */ -SQLITE_INTERNAL_LINKAGE const char* -zSkipValidUtf8(const char *z, int nAccept, long ccm); - -#endif diff --git a/main.mk b/main.mk index cbc0ec4541..1502b05c7e 100644 --- a/main.mk +++ b/main.mk @@ -1971,8 +1971,6 @@ mptest: mptester$(T.exe) # Source and header files that shell.c depends on SHELL_DEP = \ $(TOP)/src/shell.c.in \ - $(TOP)/ext/consio/console_io.c \ - $(TOP)/ext/consio/console_io.h \ $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/sqlite3expert.h \ $(TOP)/ext/intck/sqlite3intck.c \ diff --git a/manifest b/manifest index aa369bcd38..383228d3e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sMakefile.linux-generic\sto\saccount\sfor\srecent\svar\srenaming. -D 2024-10-28T14:46:33.572 +C Omit\sext/consio\sfrom\sthe\stree.\s\sNo\slonger\sneeded\sor\ssupported. +D 2024-10-28T14:53:45.379 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -71,8 +71,6 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94 F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a -F ext/consio/console_io.c d2b74afae8d301de2e8447b1045fcd33eb59df13bf581d906d99c74fe5d2b13f x -F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5 F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 F ext/expert/expert1.test 1d2da6606623b57bb47064e02140823ce1daecd4cacbf402c73ad3473d7f000c @@ -707,7 +705,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 0fe71859e14e362e01687f75cbd19f8031ca3be07a364dcd17fde6822d101edc +F main.mk ed437c3fb9ef480a534aa3205fff1f380ce776c1aa1069e3623b692770f86404 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2216,8 +2214,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 45315f8f275db6059bdff7a8269014f06a793debd90675ac877f3a6f5c6ba4a4 -R c80a48e5113a14e0ef09fa948ac8efb3 -U stephan -Z 4fcc77ebd91e5407126b8031e682ac52 +P 6cb7cb7e33835d42cbab2e5468d73de7bb3b01971da078ce1c1344edc11ab1b3 +R 00f0377d2b4f46d55243305df3135edf +U drh +Z 05dc840cebf23762b49de298db68f9dc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4aac8f94d8..1592140732 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6cb7cb7e33835d42cbab2e5468d73de7bb3b01971da078ce1c1344edc11ab1b3 +1ce8507f732a26508a9b336cb27756a0a8638e14395efdd59b5faef40526ede5 From 42516b2ef9e9460400387eee3b2d64691d76e154 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Oct 2024 15:38:53 +0000 Subject: [PATCH 203/522] Omit the antiquated and long-unsupport async extension since it has been superseded by WAL mode for over a decade. FossilOrigin-Name: 10b1b86821bfc21377e7ccceb31146ab01aa6eaf418b85a204abcab5b793958e --- Makefile.msc | 2 - ext/async/README.txt | 170 ---- ext/async/sqlite3async.c | 1706 -------------------------------------- ext/async/sqlite3async.h | 222 ----- main.mk | 4 +- manifest | 37 +- manifest.uuid | 2 +- src/test_async.c | 241 ------ src/test_tclsh.c | 2 - test/async.test | 90 -- test/async2.test | 126 --- test/async3.test | 76 -- test/async4.test | 168 ---- test/async5.test | 68 -- test/lock.test | 2 +- test/main.test | 43 - test/memleak.test | 2 - test/permutations.test | 11 +- test/tkt-94c04eaadb.test | 72 -- 19 files changed, 23 insertions(+), 3021 deletions(-) delete mode 100644 ext/async/README.txt delete mode 100644 ext/async/sqlite3async.c delete mode 100644 ext/async/sqlite3async.h delete mode 100644 src/test_async.c delete mode 100644 test/async.test delete mode 100644 test/async2.test delete mode 100644 test/async3.test delete mode 100644 test/async4.test delete mode 100644 test/async5.test delete mode 100644 test/tkt-94c04eaadb.test diff --git a/Makefile.msc b/Makefile.msc index 863cc0242d..32b8143768 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1585,7 +1585,6 @@ TESTSRC = \ $(TOP)\src\test8.c \ $(TOP)\src\test9.c \ $(TOP)\src\test_autoext.c \ - $(TOP)\src\test_async.c \ $(TOP)\src\test_backup.c \ $(TOP)\src\test_bestindex.c \ $(TOP)\src\test_blob.c \ @@ -1682,7 +1681,6 @@ TESTSRC2 = \ $(SRC01) \ $(SRC07) \ $(SRC10) \ - $(TOP)\ext\async\sqlite3async.c \ fts5.c # Header files used by all library source files. diff --git a/ext/async/README.txt b/ext/async/README.txt deleted file mode 100644 index f62fa2fc17..0000000000 --- a/ext/async/README.txt +++ /dev/null @@ -1,170 +0,0 @@ -NOTE (2012-11-29): - -The functionality implemented by this extension has been superseded -by WAL-mode. This module is no longer supported or maintained. The -code is retained for historical reference only. - ------------------------------------------------------------------------------- - -Normally, when SQLite writes to a database file, it waits until the write -operation is finished before returning control to the calling application. -Since writing to the file-system is usually very slow compared with CPU -bound operations, this can be a performance bottleneck. This directory -contains an extension that causes SQLite to perform all write requests -using a separate thread running in the background. Although this does not -reduce the overall system resources (CPU, disk bandwidth etc.) at all, it -allows SQLite to return control to the caller quickly even when writing to -the database, eliminating the bottleneck. - - 1. Functionality - - 1.1 How it Works - 1.2 Limitations - 1.3 Locking and Concurrency - - 2. Compilation and Usage - - 3. Porting - - - -1. FUNCTIONALITY - - With asynchronous I/O, write requests are handled by a separate thread - running in the background. This means that the thread that initiates - a database write does not have to wait for (sometimes slow) disk I/O - to occur. The write seems to happen very quickly, though in reality - it is happening at its usual slow pace in the background. - - Asynchronous I/O appears to give better responsiveness, but at a price. - You lose the Durable property. With the default I/O backend of SQLite, - once a write completes, you know that the information you wrote is - safely on disk. With the asynchronous I/O, this is not the case. If - your program crashes or if a power loss occurs after the database - write but before the asynchronous write thread has completed, then the - database change might never make it to disk and the next user of the - database might not see your change. - - You lose Durability with asynchronous I/O, but you still retain the - other parts of ACID: Atomic, Consistent, and Isolated. Many - appliations get along fine without the Durablity. - - 1.1 How it Works - - Asynchronous I/O works by creating a special SQLite "vfs" structure - and registering it with sqlite3_vfs_register(). When files opened via - this vfs are written to (using the vfs xWrite() method), the data is not - written directly to disk, but is placed in the "write-queue" to be - handled by the background thread. - - When files opened with the asynchronous vfs are read from - (using the vfs xRead() method), the data is read from the file on - disk and the write-queue, so that from the point of view of - the vfs reader the xWrite() appears to have already completed. - - The special vfs is registered (and unregistered) by calls to the - API functions sqlite3async_initialize() and sqlite3async_shutdown(). - See section "Compilation and Usage" below for details. - - 1.2 Limitations - - In order to gain experience with the main ideas surrounding asynchronous - IO, this implementation is deliberately kept simple. Additional - capabilities may be added in the future. - - For example, as currently implemented, if writes are happening at a - steady stream that exceeds the I/O capability of the background writer - thread, the queue of pending write operations will grow without bound. - If this goes on for long enough, the host system could run out of memory. - A more sophisticated module could to keep track of the quantity of - pending writes and stop accepting new write requests when the queue of - pending writes grows too large. - - 1.3 Locking and Concurrency - - Multiple connections from within a single process that use this - implementation of asynchronous IO may access a single database - file concurrently. From the point of view of the user, if all - connections are from within a single process, there is no difference - between the concurrency offered by "normal" SQLite and SQLite - using the asynchronous backend. - - If file-locking is enabled (it is enabled by default), then connections - from multiple processes may also read and write the database file. - However concurrency is reduced as follows: - - * When a connection using asynchronous IO begins a database - transaction, the database is locked immediately. However the - lock is not released until after all relevant operations - in the write-queue have been flushed to disk. This means - (for example) that the database may remain locked for some - time after a "COMMIT" or "ROLLBACK" is issued. - - * If an application using asynchronous IO executes transactions - in quick succession, other database users may be effectively - locked out of the database. This is because when a BEGIN - is executed, a database lock is established immediately. But - when the corresponding COMMIT or ROLLBACK occurs, the lock - is not released until the relevant part of the write-queue - has been flushed through. As a result, if a COMMIT is followed - by a BEGIN before the write-queue is flushed through, the database - is never unlocked,preventing other processes from accessing - the database. - - File-locking may be disabled at runtime using the sqlite3async_control() - API (see below). This may improve performance when an NFS or other - network file-system, as the synchronous round-trips to the server be - required to establish file locks are avoided. However, if multiple - connections attempt to access the same database file when file-locking - is disabled, application crashes and database corruption is a likely - outcome. - - -2. COMPILATION AND USAGE - - The asynchronous IO extension consists of a single file of C code - (sqlite3async.c), and a header file (sqlite3async.h) that defines the - C API used by applications to activate and control the modules - functionality. - - To use the asynchronous IO extension, compile sqlite3async.c as - part of the application that uses SQLite. Then use the API defined - in sqlite3async.h to initialize and configure the module. - - The asynchronous IO VFS API is described in detail in comments in - sqlite3async.h. Using the API usually consists of the following steps: - - 1. Register the asynchronous IO VFS with SQLite by calling the - sqlite3async_initialize() function. - - 2. Create a background thread to perform write operations and call - sqlite3async_run(). - - 3. Use the normal SQLite API to read and write to databases via - the asynchronous IO VFS. - - Refer to sqlite3async.h for details. - - -3. PORTING - - Currently the asynchronous IO extension is compatible with win32 systems - and systems that support the pthreads interface, including Mac OSX, Linux, - and other varieties of Unix. - - To port the asynchronous IO extension to another platform, the user must - implement mutex and condition variable primitives for the new platform. - Currently there is no externally available interface to allow this, but - modifying the code within sqlite3async.c to include the new platforms - concurrency primitives is relatively easy. Search within sqlite3async.c - for the comment string "PORTING FUNCTIONS" for details. Then implement - new versions of each of the following: - - static void async_mutex_enter(int eMutex); - static void async_mutex_leave(int eMutex); - static void async_cond_wait(int eCond, int eMutex); - static void async_cond_signal(int eCond); - static void async_sched_yield(void); - - The functionality required of each of the above functions is described - in comments in sqlite3async.c. diff --git a/ext/async/sqlite3async.c b/ext/async/sqlite3async.c deleted file mode 100644 index eed7c8d738..0000000000 --- a/ext/async/sqlite3async.c +++ /dev/null @@ -1,1706 +0,0 @@ -/* -** 2005 December 14 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** $Id: sqlite3async.c,v 1.7 2009/07/18 11:52:04 danielk1977 Exp $ -** -** This file contains the implementation of an asynchronous IO backend -** for SQLite. -*/ - -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO) - -#include "sqlite3async.h" -#include "sqlite3.h" -#include -#include -#include - -/* Useful macros used in several places */ -#define MIN(x,y) ((x)<(y)?(x):(y)) -#define MAX(x,y) ((x)>(y)?(x):(y)) - -#ifndef SQLITE_AMALGAMATION -/* Macro to mark parameters as unused and silence compiler warnings. */ -#define UNUSED_PARAMETER(x) (void)(x) -#endif - -/* Forward references */ -typedef struct AsyncWrite AsyncWrite; -typedef struct AsyncFile AsyncFile; -typedef struct AsyncFileData AsyncFileData; -typedef struct AsyncFileLock AsyncFileLock; -typedef struct AsyncLock AsyncLock; - -/* Enable for debugging */ -#ifndef NDEBUG -#include -static int sqlite3async_trace = 0; -# define ASYNC_TRACE(X) if( sqlite3async_trace ) asyncTrace X -static void asyncTrace(const char *zFormat, ...){ - char *z; - va_list ap; - va_start(ap, zFormat); - z = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - fprintf(stderr, "[%d] %s", 0 /* (int)pthread_self() */, z); - sqlite3_free(z); -} -#else -# define ASYNC_TRACE(X) -#endif - -/* -** THREAD SAFETY NOTES -** -** Basic rules: -** -** * Both read and write access to the global write-op queue must be -** protected by the async.queueMutex. As are the async.ioError and -** async.nFile variables. -** -** * The async.pLock list and all AsyncLock and AsyncFileLock -** structures must be protected by the async.lockMutex mutex. -** -** * The file handles from the underlying system are not assumed to -** be thread safe. -** -** * See the last two paragraphs under "The Writer Thread" for -** an assumption to do with file-handle synchronization by the Os. -** -** Deadlock prevention: -** -** There are three mutex used by the system: the "writer" mutex, -** the "queue" mutex and the "lock" mutex. Rules are: -** -** * It is illegal to block on the writer mutex when any other mutex -** are held, and -** -** * It is illegal to block on the queue mutex when the lock mutex -** is held. -** -** i.e. mutex's must be grabbed in the order "writer", "queue", "lock". -** -** File system operations (invoked by SQLite thread): -** -** xOpen -** xDelete -** xFileExists -** -** File handle operations (invoked by SQLite thread): -** -** asyncWrite, asyncClose, asyncTruncate, asyncSync -** -** The operations above add an entry to the global write-op list. They -** prepare the entry, acquire the async.queueMutex momentarily while -** list pointers are manipulated to insert the new entry, then release -** the mutex and signal the writer thread to wake up in case it happens -** to be asleep. -** -** -** asyncRead, asyncFileSize. -** -** Read operations. Both of these read from both the underlying file -** first then adjust their result based on pending writes in the -** write-op queue. So async.queueMutex is held for the duration -** of these operations to prevent other threads from changing the -** queue in mid operation. -** -** -** asyncLock, asyncUnlock, asyncCheckReservedLock -** -** These primitives implement in-process locking using a hash table -** on the file name. Files are locked correctly for connections coming -** from the same process. But other processes cannot see these locks -** and will therefore not honor them. -** -** -** The writer thread: -** -** The async.writerMutex is used to make sure only there is only -** a single writer thread running at a time. -** -** Inside the writer thread is a loop that works like this: -** -** WHILE (write-op list is not empty) -** Do IO operation at head of write-op list -** Remove entry from head of write-op list -** END WHILE -** -** The async.queueMutex is always held during the test, and when the entry is removed from the head -** of the write-op list. Sometimes it is held for the interim -** period (while the IO is performed), and sometimes it is -** relinquished. It is relinquished if (a) the IO op is an -** ASYNC_CLOSE or (b) when the file handle was opened, two of -** the underlying systems handles were opened on the same -** file-system entry. -** -** If condition (b) above is true, then one file-handle -** (AsyncFile.pBaseRead) is used exclusively by sqlite threads to read the -** file, the other (AsyncFile.pBaseWrite) by sqlite3_async_flush() -** threads to perform write() operations. This means that read -** operations are not blocked by asynchronous writes (although -** asynchronous writes may still be blocked by reads). -** -** This assumes that the OS keeps two handles open on the same file -** properly in sync. That is, any read operation that starts after a -** write operation on the same file system entry has completed returns -** data consistent with the write. We also assume that if one thread -** reads a file while another is writing it all bytes other than the -** ones actually being written contain valid data. -** -** If the above assumptions are not true, set the preprocessor symbol -** SQLITE_ASYNC_TWO_FILEHANDLES to 0. -*/ - - -#ifndef NDEBUG -# define TESTONLY( X ) X -#else -# define TESTONLY( X ) -#endif - -/* -** PORTING FUNCTIONS -** -** There are two definitions of the following functions. One for pthreads -** compatible systems and one for Win32. These functions isolate the OS -** specific code required by each platform. -** -** The system uses three mutexes and a single condition variable. To -** block on a mutex, async_mutex_enter() is called. The parameter passed -** to async_mutex_enter(), which must be one of ASYNC_MUTEX_LOCK, -** ASYNC_MUTEX_QUEUE or ASYNC_MUTEX_WRITER, identifies which of the three -** mutexes to lock. Similarly, to unlock a mutex, async_mutex_leave() is -** called with a parameter identifying the mutex being unlocked. Mutexes -** are not recursive - it is an error to call async_mutex_enter() to -** lock a mutex that is already locked, or to call async_mutex_leave() -** to unlock a mutex that is not currently locked. -** -** The async_cond_wait() and async_cond_signal() functions are modelled -** on the pthreads functions with similar names. The first parameter to -** both functions is always ASYNC_COND_QUEUE. When async_cond_wait() -** is called the mutex identified by the second parameter must be held. -** The mutex is unlocked, and the calling thread simultaneously begins -** waiting for the condition variable to be signalled by another thread. -** After another thread signals the condition variable, the calling -** thread stops waiting, locks mutex eMutex and returns. The -** async_cond_signal() function is used to signal the condition variable. -** It is assumed that the mutex used by the thread calling async_cond_wait() -** is held by the caller of async_cond_signal() (otherwise there would be -** a race condition). -** -** It is guaranteed that no other thread will call async_cond_wait() when -** there is already a thread waiting on the condition variable. -** -** The async_sched_yield() function is called to suggest to the operating -** system that it would be a good time to shift the current thread off the -** CPU. The system will still work if this function is not implemented -** (it is not currently implemented for win32), but it might be marginally -** more efficient if it is. -*/ -static void async_mutex_enter(int eMutex); -static void async_mutex_leave(int eMutex); -static void async_cond_wait(int eCond, int eMutex); -static void async_cond_signal(int eCond); -static void async_sched_yield(void); - -/* -** There are also two definitions of the following. async_os_initialize() -** is called when the asynchronous VFS is first installed, and os_shutdown() -** is called when it is uninstalled (from within sqlite3async_shutdown()). -** -** For pthreads builds, both of these functions are no-ops. For win32, -** they provide an opportunity to initialize and finalize the required -** mutex and condition variables. -** -** If async_os_initialize() returns other than zero, then the initialization -** fails and SQLITE_ERROR is returned to the user. -*/ -static int async_os_initialize(void); -static void async_os_shutdown(void); - -/* Values for use as the 'eMutex' argument of the above functions. The -** integer values assigned to these constants are important for assert() -** statements that verify that mutexes are locked in the correct order. -** Specifically, it is unsafe to try to lock mutex N while holding a lock -** on mutex M if (M<=N). -*/ -#define ASYNC_MUTEX_LOCK 0 -#define ASYNC_MUTEX_QUEUE 1 -#define ASYNC_MUTEX_WRITER 2 - -/* Values for use as the 'eCond' argument of the above functions. */ -#define ASYNC_COND_QUEUE 0 - -/************************************************************************* -** Start of OS specific code. -*/ -#if SQLITE_OS_WIN || defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) - -#include - -/* The following block contains the win32 specific code. */ - -#define mutex_held(X) (GetCurrentThreadId()==primitives.aHolder[X]) - -static struct AsyncPrimitives { - int isInit; - DWORD aHolder[3]; - CRITICAL_SECTION aMutex[3]; - HANDLE aCond[1]; -} primitives = { 0 }; - -static int async_os_initialize(void){ - if( !primitives.isInit ){ - primitives.aCond[0] = CreateEvent(NULL, TRUE, FALSE, 0); - if( primitives.aCond[0]==NULL ){ - return 1; - } - InitializeCriticalSection(&primitives.aMutex[0]); - InitializeCriticalSection(&primitives.aMutex[1]); - InitializeCriticalSection(&primitives.aMutex[2]); - primitives.isInit = 1; - } - return 0; -} -static void async_os_shutdown(void){ - if( primitives.isInit ){ - DeleteCriticalSection(&primitives.aMutex[0]); - DeleteCriticalSection(&primitives.aMutex[1]); - DeleteCriticalSection(&primitives.aMutex[2]); - CloseHandle(primitives.aCond[0]); - primitives.isInit = 0; - } -} - -/* The following block contains the Win32 specific code. */ -static void async_mutex_enter(int eMutex){ - assert( eMutex==0 || eMutex==1 || eMutex==2 ); - assert( eMutex!=2 || (!mutex_held(0) && !mutex_held(1) && !mutex_held(2)) ); - assert( eMutex!=1 || (!mutex_held(0) && !mutex_held(1)) ); - assert( eMutex!=0 || (!mutex_held(0)) ); - EnterCriticalSection(&primitives.aMutex[eMutex]); - TESTONLY( primitives.aHolder[eMutex] = GetCurrentThreadId(); ) -} -static void async_mutex_leave(int eMutex){ - assert( eMutex==0 || eMutex==1 || eMutex==2 ); - assert( mutex_held(eMutex) ); - TESTONLY( primitives.aHolder[eMutex] = 0; ) - LeaveCriticalSection(&primitives.aMutex[eMutex]); -} -static void async_cond_wait(int eCond, int eMutex){ - ResetEvent(primitives.aCond[eCond]); - async_mutex_leave(eMutex); - WaitForSingleObject(primitives.aCond[eCond], INFINITE); - async_mutex_enter(eMutex); -} -static void async_cond_signal(int eCond){ - assert( mutex_held(ASYNC_MUTEX_QUEUE) ); - SetEvent(primitives.aCond[eCond]); -} -static void async_sched_yield(void){ - Sleep(0); -} -#else - -/* The following block contains the pthreads specific code. */ -#include -#include - -#define mutex_held(X) pthread_equal(primitives.aHolder[X], pthread_self()) - -static int async_os_initialize(void) {return 0;} -static void async_os_shutdown(void) {} - -static struct AsyncPrimitives { - pthread_mutex_t aMutex[3]; - pthread_cond_t aCond[1]; - pthread_t aHolder[3]; -} primitives = { - { PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER - } , { - PTHREAD_COND_INITIALIZER - } , { 0, 0, 0 } -}; - -static void async_mutex_enter(int eMutex){ - assert( eMutex==0 || eMutex==1 || eMutex==2 ); - assert( eMutex!=2 || (!mutex_held(0) && !mutex_held(1) && !mutex_held(2)) ); - assert( eMutex!=1 || (!mutex_held(0) && !mutex_held(1)) ); - assert( eMutex!=0 || (!mutex_held(0)) ); - pthread_mutex_lock(&primitives.aMutex[eMutex]); - TESTONLY( primitives.aHolder[eMutex] = pthread_self(); ) -} -static void async_mutex_leave(int eMutex){ - assert( eMutex==0 || eMutex==1 || eMutex==2 ); - assert( mutex_held(eMutex) ); - TESTONLY( primitives.aHolder[eMutex] = 0; ) - pthread_mutex_unlock(&primitives.aMutex[eMutex]); -} -static void async_cond_wait(int eCond, int eMutex){ - assert( eMutex==0 || eMutex==1 || eMutex==2 ); - assert( mutex_held(eMutex) ); - TESTONLY( primitives.aHolder[eMutex] = 0; ) - pthread_cond_wait(&primitives.aCond[eCond], &primitives.aMutex[eMutex]); - TESTONLY( primitives.aHolder[eMutex] = pthread_self(); ) -} -static void async_cond_signal(int eCond){ - assert( mutex_held(ASYNC_MUTEX_QUEUE) ); - pthread_cond_signal(&primitives.aCond[eCond]); -} -static void async_sched_yield(void){ - sched_yield(); -} -#endif -/* -** End of OS specific code. -*************************************************************************/ - -#define assert_mutex_is_held(X) assert( mutex_held(X) ) - - -#ifndef SQLITE_ASYNC_TWO_FILEHANDLES -/* #define SQLITE_ASYNC_TWO_FILEHANDLES 0 */ -#define SQLITE_ASYNC_TWO_FILEHANDLES 1 -#endif - -/* -** State information is held in the static variable "async" defined -** as the following structure. -** -** Both async.ioError and async.nFile are protected by async.queueMutex. -*/ -static struct TestAsyncStaticData { - AsyncWrite *pQueueFirst; /* Next write operation to be processed */ - AsyncWrite *pQueueLast; /* Last write operation on the list */ - AsyncLock *pLock; /* Linked list of all AsyncLock structures */ - volatile int ioDelay; /* Extra delay between write operations */ - volatile int eHalt; /* One of the SQLITEASYNC_HALT_XXX values */ - volatile int bLockFiles; /* Current value of "lockfiles" parameter */ - int ioError; /* True if an IO error has occurred */ - int nFile; /* Number of open files (from sqlite pov) */ -} async = { 0,0,0,0,0,1,0,0 }; - -/* Possible values of AsyncWrite.op */ -#define ASYNC_NOOP 0 -#define ASYNC_WRITE 1 -#define ASYNC_SYNC 2 -#define ASYNC_TRUNCATE 3 -#define ASYNC_CLOSE 4 -#define ASYNC_DELETE 5 -#define ASYNC_OPENEXCLUSIVE 6 -#define ASYNC_UNLOCK 7 - -/* Names of opcodes. Used for debugging only. -** Make sure these stay in sync with the macros above! -*/ -static const char *azOpcodeName[] = { - "NOOP", "WRITE", "SYNC", "TRUNCATE", "CLOSE", "DELETE", "OPENEX", "UNLOCK" -}; - -/* -** Entries on the write-op queue are instances of the AsyncWrite -** structure, defined here. -** -** The interpretation of the iOffset and nByte variables varies depending -** on the value of AsyncWrite.op: -** -** ASYNC_NOOP: -** No values used. -** -** ASYNC_WRITE: -** iOffset -> Offset in file to write to. -** nByte -> Number of bytes of data to write (pointed to by zBuf). -** -** ASYNC_SYNC: -** nByte -> flags to pass to sqlite3OsSync(). -** -** ASYNC_TRUNCATE: -** iOffset -> Size to truncate file to. -** nByte -> Unused. -** -** ASYNC_CLOSE: -** iOffset -> Unused. -** nByte -> Unused. -** -** ASYNC_DELETE: -** iOffset -> Contains the "syncDir" flag. -** nByte -> Number of bytes of zBuf points to (file name). -** -** ASYNC_OPENEXCLUSIVE: -** iOffset -> Value of "delflag". -** nByte -> Number of bytes of zBuf points to (file name). -** -** ASYNC_UNLOCK: -** nByte -> Argument to sqlite3OsUnlock(). -** -** -** For an ASYNC_WRITE operation, zBuf points to the data to write to the file. -** This space is sqlite3_malloc()d along with the AsyncWrite structure in a -** single blob, so is deleted when sqlite3_free() is called on the parent -** structure. -*/ -struct AsyncWrite { - AsyncFileData *pFileData; /* File to write data to or sync */ - int op; /* One of ASYNC_xxx etc. */ - sqlite_int64 iOffset; /* See above */ - int nByte; /* See above */ - char *zBuf; /* Data to write to file (or NULL if op!=ASYNC_WRITE) */ - AsyncWrite *pNext; /* Next write operation (to any file) */ -}; - -/* -** An instance of this structure is created for each distinct open file -** (i.e. if two handles are opened on the one file, only one of these -** structures is allocated) and stored in the async.aLock hash table. The -** keys for async.aLock are the full pathnames of the opened files. -** -** AsyncLock.pList points to the head of a linked list of AsyncFileLock -** structures, one for each handle currently open on the file. -** -** If the opened file is not a main-database (the SQLITE_OPEN_MAIN_DB is -** not passed to the sqlite3OsOpen() call), or if async.bLockFiles is -** false, variables AsyncLock.pFile and AsyncLock.eLock are never used. -** Otherwise, pFile is a file handle opened on the file in question and -** used to obtain the file-system locks required by database connections -** within this process. -** -** See comments above the asyncLock() function for more details on -** the implementation of database locking used by this backend. -*/ -struct AsyncLock { - char *zFile; - int nFile; - sqlite3_file *pFile; - int eLock; - AsyncFileLock *pList; - AsyncLock *pNext; /* Next in linked list headed by async.pLock */ -}; - -/* -** An instance of the following structure is allocated along with each -** AsyncFileData structure (see AsyncFileData.lock), but is only used if the -** file was opened with the SQLITE_OPEN_MAIN_DB. -*/ -struct AsyncFileLock { - int eLock; /* Internally visible lock state (sqlite pov) */ - int eAsyncLock; /* Lock-state with write-queue unlock */ - AsyncFileLock *pNext; -}; - -/* -** The AsyncFile structure is a subclass of sqlite3_file used for -** asynchronous IO. -** -** All of the actual data for the structure is stored in the structure -** pointed to by AsyncFile.pData, which is allocated as part of the -** sqlite3OsOpen() using sqlite3_malloc(). The reason for this is that the -** lifetime of the AsyncFile structure is ended by the caller after OsClose() -** is called, but the data in AsyncFileData may be required by the -** writer thread after that point. -*/ -struct AsyncFile { - sqlite3_io_methods *pMethod; - AsyncFileData *pData; -}; -struct AsyncFileData { - char *zName; /* Underlying OS filename - used for debugging */ - int nName; /* Number of characters in zName */ - sqlite3_file *pBaseRead; /* Read handle to the underlying Os file */ - sqlite3_file *pBaseWrite; /* Write handle to the underlying Os file */ - AsyncFileLock lock; /* Lock state for this handle */ - AsyncLock *pLock; /* AsyncLock object for this file system entry */ - AsyncWrite closeOp; /* Preallocated close operation */ -}; - -/* -** Add an entry to the end of the global write-op list. pWrite should point -** to an AsyncWrite structure allocated using sqlite3_malloc(). The writer -** thread will call sqlite3_free() to free the structure after the specified -** operation has been completed. -** -** Once an AsyncWrite structure has been added to the list, it becomes the -** property of the writer thread and must not be read or modified by the -** caller. -*/ -static void addAsyncWrite(AsyncWrite *pWrite){ - /* We must hold the queue mutex in order to modify the queue pointers */ - if( pWrite->op!=ASYNC_UNLOCK ){ - async_mutex_enter(ASYNC_MUTEX_QUEUE); - } - - /* Add the record to the end of the write-op queue */ - assert( !pWrite->pNext ); - if( async.pQueueLast ){ - assert( async.pQueueFirst ); - async.pQueueLast->pNext = pWrite; - }else{ - async.pQueueFirst = pWrite; - } - async.pQueueLast = pWrite; - ASYNC_TRACE(("PUSH %p (%s %s %d)\n", pWrite, azOpcodeName[pWrite->op], - pWrite->pFileData ? pWrite->pFileData->zName : "-", pWrite->iOffset)); - - if( pWrite->op==ASYNC_CLOSE ){ - async.nFile--; - } - - /* The writer thread might have been idle because there was nothing - ** on the write-op queue for it to do. So wake it up. */ - async_cond_signal(ASYNC_COND_QUEUE); - - /* Drop the queue mutex */ - if( pWrite->op!=ASYNC_UNLOCK ){ - async_mutex_leave(ASYNC_MUTEX_QUEUE); - } -} - -/* -** Increment async.nFile in a thread-safe manner. -*/ -static void incrOpenFileCount(void){ - /* We must hold the queue mutex in order to modify async.nFile */ - async_mutex_enter(ASYNC_MUTEX_QUEUE); - if( async.nFile==0 ){ - async.ioError = SQLITE_OK; - } - async.nFile++; - async_mutex_leave(ASYNC_MUTEX_QUEUE); -} - -/* -** This is a utility function to allocate and populate a new AsyncWrite -** structure and insert it (via addAsyncWrite() ) into the global list. -*/ -static int addNewAsyncWrite( - AsyncFileData *pFileData, - int op, - sqlite3_int64 iOffset, - int nByte, - const char *zByte -){ - AsyncWrite *p; - if( op!=ASYNC_CLOSE && async.ioError ){ - return async.ioError; - } - p = sqlite3_malloc(sizeof(AsyncWrite) + (zByte?nByte:0)); - if( !p ){ - /* The upper layer does not expect operations like OsWrite() to - ** return SQLITE_NOMEM. This is partly because under normal conditions - ** SQLite is required to do rollback without calling malloc(). So - ** if malloc() fails here, treat it as an I/O error. The above - ** layer knows how to handle that. - */ - return SQLITE_IOERR; - } - p->op = op; - p->iOffset = iOffset; - p->nByte = nByte; - p->pFileData = pFileData; - p->pNext = 0; - if( zByte ){ - p->zBuf = (char *)&p[1]; - memcpy(p->zBuf, zByte, nByte); - }else{ - p->zBuf = 0; - } - addAsyncWrite(p); - return SQLITE_OK; -} - -/* -** Close the file. This just adds an entry to the write-op list, the file is -** not actually closed. -*/ -static int asyncClose(sqlite3_file *pFile){ - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - - /* Unlock the file, if it is locked */ - async_mutex_enter(ASYNC_MUTEX_LOCK); - p->lock.eLock = 0; - async_mutex_leave(ASYNC_MUTEX_LOCK); - - addAsyncWrite(&p->closeOp); - return SQLITE_OK; -} - -/* -** Implementation of sqlite3OsWrite() for asynchronous files. Instead of -** writing to the underlying file, this function adds an entry to the end of -** the global AsyncWrite list. Either SQLITE_OK or SQLITE_NOMEM may be -** returned. -*/ -static int asyncWrite( - sqlite3_file *pFile, - const void *pBuf, - int amt, - sqlite3_int64 iOff -){ - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - return addNewAsyncWrite(p, ASYNC_WRITE, iOff, amt, pBuf); -} - -/* -** Read data from the file. First we read from the filesystem, then adjust -** the contents of the buffer based on ASYNC_WRITE operations in the -** write-op queue. -** -** This method holds the mutex from start to finish. -*/ -static int asyncRead( - sqlite3_file *pFile, - void *zOut, - int iAmt, - sqlite3_int64 iOffset -){ - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - int rc = SQLITE_OK; - sqlite3_int64 filesize = 0; - sqlite3_file *pBase = p->pBaseRead; - sqlite3_int64 iAmt64 = (sqlite3_int64)iAmt; - - /* Grab the write queue mutex for the duration of the call */ - async_mutex_enter(ASYNC_MUTEX_QUEUE); - - /* If an I/O error has previously occurred in this virtual file - ** system, then all subsequent operations fail. - */ - if( async.ioError!=SQLITE_OK ){ - rc = async.ioError; - goto asyncread_out; - } - - if( pBase->pMethods ){ - sqlite3_int64 nRead; - rc = pBase->pMethods->xFileSize(pBase, &filesize); - if( rc!=SQLITE_OK ){ - goto asyncread_out; - } - nRead = MIN(filesize - iOffset, iAmt64); - if( nRead>0 ){ - rc = pBase->pMethods->xRead(pBase, zOut, (int)nRead, iOffset); - ASYNC_TRACE(("READ %s %d bytes at %d\n", p->zName, nRead, iOffset)); - } - } - - if( rc==SQLITE_OK ){ - AsyncWrite *pWrite; - char *zName = p->zName; - - for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){ - if( pWrite->op==ASYNC_WRITE && ( - (pWrite->pFileData==p) || - (zName && pWrite->pFileData->zName==zName) - )){ - sqlite3_int64 nCopy; - sqlite3_int64 nByte64 = (sqlite3_int64)pWrite->nByte; - - /* Set variable iBeginIn to the offset in buffer pWrite->zBuf[] from - ** which data should be copied. Set iBeginOut to the offset within - ** the output buffer to which data should be copied. If either of - ** these offsets is a negative number, set them to 0. - */ - sqlite3_int64 iBeginOut = (pWrite->iOffset-iOffset); - sqlite3_int64 iBeginIn = -iBeginOut; - if( iBeginIn<0 ) iBeginIn = 0; - if( iBeginOut<0 ) iBeginOut = 0; - - filesize = MAX(filesize, pWrite->iOffset+nByte64); - - nCopy = MIN(nByte64-iBeginIn, iAmt64-iBeginOut); - if( nCopy>0 ){ - memcpy(&((char *)zOut)[iBeginOut], &pWrite->zBuf[iBeginIn], (size_t)nCopy); - ASYNC_TRACE(("OVERREAD %d bytes at %d\n", nCopy, iBeginOut+iOffset)); - } - } - } - } - -asyncread_out: - async_mutex_leave(ASYNC_MUTEX_QUEUE); - if( rc==SQLITE_OK && filesize<(iOffset+iAmt) ){ - rc = SQLITE_IOERR_SHORT_READ; - } - return rc; -} - -/* -** Truncate the file to nByte bytes in length. This just adds an entry to -** the write-op list, no IO actually takes place. -*/ -static int asyncTruncate(sqlite3_file *pFile, sqlite3_int64 nByte){ - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - return addNewAsyncWrite(p, ASYNC_TRUNCATE, nByte, 0, 0); -} - -/* -** Sync the file. This just adds an entry to the write-op list, the -** sync() is done later by sqlite3_async_flush(). -*/ -static int asyncSync(sqlite3_file *pFile, int flags){ - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - return addNewAsyncWrite(p, ASYNC_SYNC, 0, flags, 0); -} - -/* -** Read the size of the file. First we read the size of the file system -** entry, then adjust for any ASYNC_WRITE or ASYNC_TRUNCATE operations -** currently in the write-op list. -** -** This method holds the mutex from start to finish. -*/ -int asyncFileSize(sqlite3_file *pFile, sqlite3_int64 *piSize){ - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - int rc = SQLITE_OK; - sqlite3_int64 s = 0; - sqlite3_file *pBase; - - async_mutex_enter(ASYNC_MUTEX_QUEUE); - - /* Read the filesystem size from the base file. If pMethods is NULL, this - ** means the file hasn't been opened yet. In this case all relevant data - ** must be in the write-op queue anyway, so we can omit reading from the - ** file-system. - */ - pBase = p->pBaseRead; - if( pBase->pMethods ){ - rc = pBase->pMethods->xFileSize(pBase, &s); - } - - if( rc==SQLITE_OK ){ - AsyncWrite *pWrite; - for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){ - if( pWrite->op==ASYNC_DELETE - && p->zName - && strcmp(p->zName, pWrite->zBuf)==0 - ){ - s = 0; - }else if( pWrite->pFileData && ( - (pWrite->pFileData==p) - || (p->zName && pWrite->pFileData->zName==p->zName) - )){ - switch( pWrite->op ){ - case ASYNC_WRITE: - s = MAX(pWrite->iOffset + (sqlite3_int64)(pWrite->nByte), s); - break; - case ASYNC_TRUNCATE: - s = MIN(s, pWrite->iOffset); - break; - } - } - } - *piSize = s; - } - async_mutex_leave(ASYNC_MUTEX_QUEUE); - return rc; -} - -/* -** Lock or unlock the actual file-system entry. -*/ -static int getFileLock(AsyncLock *pLock){ - int rc = SQLITE_OK; - AsyncFileLock *pIter; - int eRequired = 0; - - if( pLock->pFile ){ - for(pIter=pLock->pList; pIter; pIter=pIter->pNext){ - assert(pIter->eAsyncLock>=pIter->eLock); - if( pIter->eAsyncLock>eRequired ){ - eRequired = pIter->eAsyncLock; - assert(eRequired>=0 && eRequired<=SQLITE_LOCK_EXCLUSIVE); - } - } - - if( eRequired>pLock->eLock ){ - rc = pLock->pFile->pMethods->xLock(pLock->pFile, eRequired); - if( rc==SQLITE_OK ){ - pLock->eLock = eRequired; - } - } - else if( eRequiredeLock && eRequired<=SQLITE_LOCK_SHARED ){ - rc = pLock->pFile->pMethods->xUnlock(pLock->pFile, eRequired); - if( rc==SQLITE_OK ){ - pLock->eLock = eRequired; - } - } - } - - return rc; -} - -/* -** Return the AsyncLock structure from the global async.pLock list -** associated with the file-system entry identified by path zName -** (a string of nName bytes). If no such structure exists, return 0. -*/ -static AsyncLock *findLock(const char *zName, int nName){ - AsyncLock *p = async.pLock; - while( p && (p->nFile!=nName || memcmp(p->zFile, zName, nName)) ){ - p = p->pNext; - } - return p; -} - -/* -** The following two methods - asyncLock() and asyncUnlock() - are used -** to obtain and release locks on database files opened with the -** asynchronous backend. -*/ -static int asyncLock(sqlite3_file *pFile, int eLock){ - int rc = SQLITE_OK; - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - - if( p->zName ){ - async_mutex_enter(ASYNC_MUTEX_LOCK); - if( p->lock.eLockpLock; - AsyncFileLock *pIter; - assert(pLock && pLock->pList); - for(pIter=pLock->pList; pIter; pIter=pIter->pNext){ - if( pIter!=&p->lock && ( - (eLock==SQLITE_LOCK_EXCLUSIVE && pIter->eLock>=SQLITE_LOCK_SHARED) || - (eLock==SQLITE_LOCK_PENDING && pIter->eLock>=SQLITE_LOCK_RESERVED) || - (eLock==SQLITE_LOCK_RESERVED && pIter->eLock>=SQLITE_LOCK_RESERVED) || - (eLock==SQLITE_LOCK_SHARED && pIter->eLock>=SQLITE_LOCK_PENDING) - )){ - rc = SQLITE_BUSY; - } - } - if( rc==SQLITE_OK ){ - p->lock.eLock = eLock; - p->lock.eAsyncLock = MAX(p->lock.eAsyncLock, eLock); - } - assert(p->lock.eAsyncLock>=p->lock.eLock); - if( rc==SQLITE_OK ){ - rc = getFileLock(pLock); - } - } - async_mutex_leave(ASYNC_MUTEX_LOCK); - } - - ASYNC_TRACE(("LOCK %d (%s) rc=%d\n", eLock, p->zName, rc)); - return rc; -} -static int asyncUnlock(sqlite3_file *pFile, int eLock){ - int rc = SQLITE_OK; - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - if( p->zName ){ - AsyncFileLock *pLock = &p->lock; - async_mutex_enter(ASYNC_MUTEX_QUEUE); - async_mutex_enter(ASYNC_MUTEX_LOCK); - pLock->eLock = MIN(pLock->eLock, eLock); - rc = addNewAsyncWrite(p, ASYNC_UNLOCK, 0, eLock, 0); - async_mutex_leave(ASYNC_MUTEX_LOCK); - async_mutex_leave(ASYNC_MUTEX_QUEUE); - } - return rc; -} - -/* -** This function is called when the pager layer first opens a database file -** and is checking for a hot-journal. -*/ -static int asyncCheckReservedLock(sqlite3_file *pFile, int *pResOut){ - int ret = 0; - AsyncFileLock *pIter; - AsyncFileData *p = ((AsyncFile *)pFile)->pData; - - async_mutex_enter(ASYNC_MUTEX_LOCK); - for(pIter=p->pLock->pList; pIter; pIter=pIter->pNext){ - if( pIter->eLock>=SQLITE_LOCK_RESERVED ){ - ret = 1; - break; - } - } - async_mutex_leave(ASYNC_MUTEX_LOCK); - - ASYNC_TRACE(("CHECK-LOCK %d (%s)\n", ret, p->zName)); - *pResOut = ret; - return SQLITE_OK; -} - -/* -** sqlite3_file_control() implementation. -*/ -static int asyncFileControl(sqlite3_file *id, int op, void *pArg){ - switch( op ){ - case SQLITE_FCNTL_LOCKSTATE: { - async_mutex_enter(ASYNC_MUTEX_LOCK); - *(int*)pArg = ((AsyncFile*)id)->pData->lock.eLock; - async_mutex_leave(ASYNC_MUTEX_LOCK); - return SQLITE_OK; - } - } - return SQLITE_NOTFOUND; -} - -/* -** Return the device characteristics and sector-size of the device. It -** is tricky to implement these correctly, as this backend might -** not have an open file handle at this point. -*/ -static int asyncSectorSize(sqlite3_file *pFile){ - UNUSED_PARAMETER(pFile); - return 512; -} -static int asyncDeviceCharacteristics(sqlite3_file *pFile){ - UNUSED_PARAMETER(pFile); - return 0; -} - -static int unlinkAsyncFile(AsyncFileData *pData){ - AsyncFileLock **ppIter; - int rc = SQLITE_OK; - - if( pData->zName ){ - AsyncLock *pLock = pData->pLock; - for(ppIter=&pLock->pList; *ppIter; ppIter=&((*ppIter)->pNext)){ - if( (*ppIter)==&pData->lock ){ - *ppIter = pData->lock.pNext; - break; - } - } - if( !pLock->pList ){ - AsyncLock **pp; - if( pLock->pFile ){ - pLock->pFile->pMethods->xClose(pLock->pFile); - } - for(pp=&async.pLock; *pp!=pLock; pp=&((*pp)->pNext)); - *pp = pLock->pNext; - sqlite3_free(pLock); - }else{ - rc = getFileLock(pLock); - } - } - - return rc; -} - -/* -** The parameter passed to this function is a copy of a 'flags' parameter -** passed to this modules xOpen() method. This function returns true -** if the file should be opened asynchronously, or false if it should -** be opened immediately. -** -** If the file is to be opened asynchronously, then asyncOpen() will add -** an entry to the event queue and the file will not actually be opened -** until the event is processed. Otherwise, the file is opened directly -** by the caller. -*/ -static int doAsynchronousOpen(int flags){ - return (flags&SQLITE_OPEN_CREATE) && ( - (flags&SQLITE_OPEN_MAIN_JOURNAL) || - (flags&SQLITE_OPEN_TEMP_JOURNAL) || - (flags&SQLITE_OPEN_DELETEONCLOSE) - ); -} - -/* -** Open a file. -*/ -static int asyncOpen( - sqlite3_vfs *pAsyncVfs, - const char *zName, - sqlite3_file *pFile, - int flags, - int *pOutFlags -){ - static sqlite3_io_methods async_methods = { - 1, /* iVersion */ - asyncClose, /* xClose */ - asyncRead, /* xRead */ - asyncWrite, /* xWrite */ - asyncTruncate, /* xTruncate */ - asyncSync, /* xSync */ - asyncFileSize, /* xFileSize */ - asyncLock, /* xLock */ - asyncUnlock, /* xUnlock */ - asyncCheckReservedLock, /* xCheckReservedLock */ - asyncFileControl, /* xFileControl */ - asyncSectorSize, /* xSectorSize */ - asyncDeviceCharacteristics /* xDeviceCharacteristics */ - }; - - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - AsyncFile *p = (AsyncFile *)pFile; - int nName = 0; - int rc = SQLITE_OK; - int nByte; - AsyncFileData *pData; - AsyncLock *pLock = 0; - char *z; - int isAsyncOpen = doAsynchronousOpen(flags); - - /* If zName is NULL, then the upper layer is requesting an anonymous file. - ** Otherwise, allocate enough space to make a copy of the file name (along - ** with the second nul-terminator byte required by xOpen). - */ - if( zName ){ - nName = (int)strlen(zName); - } - - nByte = ( - sizeof(AsyncFileData) + /* AsyncFileData structure */ - 2 * pVfs->szOsFile + /* AsyncFileData.pBaseRead and pBaseWrite */ - nName + 2 /* AsyncFileData.zName */ - ); - z = sqlite3_malloc(nByte); - if( !z ){ - return SQLITE_NOMEM; - } - memset(z, 0, nByte); - pData = (AsyncFileData*)z; - z += sizeof(pData[0]); - pData->pBaseRead = (sqlite3_file*)z; - z += pVfs->szOsFile; - pData->pBaseWrite = (sqlite3_file*)z; - pData->closeOp.pFileData = pData; - pData->closeOp.op = ASYNC_CLOSE; - - if( zName ){ - z += pVfs->szOsFile; - pData->zName = z; - pData->nName = nName; - memcpy(pData->zName, zName, nName); - } - - if( !isAsyncOpen ){ - int flagsout; - rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseRead, flags, &flagsout); - if( rc==SQLITE_OK - && (flagsout&SQLITE_OPEN_READWRITE) - && (flags&SQLITE_OPEN_EXCLUSIVE)==0 - ){ - rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseWrite, flags, 0); - } - if( pOutFlags ){ - *pOutFlags = flagsout; - } - } - - async_mutex_enter(ASYNC_MUTEX_LOCK); - - if( zName && rc==SQLITE_OK ){ - pLock = findLock(pData->zName, pData->nName); - if( !pLock ){ - int nByte = pVfs->szOsFile + sizeof(AsyncLock) + pData->nName + 1; - pLock = (AsyncLock *)sqlite3_malloc(nByte); - if( pLock ){ - memset(pLock, 0, nByte); - if( async.bLockFiles && (flags&SQLITE_OPEN_MAIN_DB) ){ - pLock->pFile = (sqlite3_file *)&pLock[1]; - rc = pVfs->xOpen(pVfs, pData->zName, pLock->pFile, flags, 0); - if( rc!=SQLITE_OK ){ - sqlite3_free(pLock); - pLock = 0; - } - } - if( pLock ){ - pLock->nFile = pData->nName; - pLock->zFile = &((char *)(&pLock[1]))[pVfs->szOsFile]; - memcpy(pLock->zFile, pData->zName, pLock->nFile); - pLock->pNext = async.pLock; - async.pLock = pLock; - } - }else{ - rc = SQLITE_NOMEM; - } - } - } - - if( rc==SQLITE_OK ){ - p->pMethod = &async_methods; - p->pData = pData; - - /* Link AsyncFileData.lock into the linked list of - ** AsyncFileLock structures for this file. - */ - if( zName ){ - pData->lock.pNext = pLock->pList; - pLock->pList = &pData->lock; - pData->zName = pLock->zFile; - } - }else{ - if( pData->pBaseRead->pMethods ){ - pData->pBaseRead->pMethods->xClose(pData->pBaseRead); - } - if( pData->pBaseWrite->pMethods ){ - pData->pBaseWrite->pMethods->xClose(pData->pBaseWrite); - } - sqlite3_free(pData); - } - - async_mutex_leave(ASYNC_MUTEX_LOCK); - - if( rc==SQLITE_OK ){ - pData->pLock = pLock; - } - - if( rc==SQLITE_OK && isAsyncOpen ){ - rc = addNewAsyncWrite(pData, ASYNC_OPENEXCLUSIVE, (sqlite3_int64)flags,0,0); - if( rc==SQLITE_OK ){ - if( pOutFlags ) *pOutFlags = flags; - }else{ - async_mutex_enter(ASYNC_MUTEX_LOCK); - unlinkAsyncFile(pData); - async_mutex_leave(ASYNC_MUTEX_LOCK); - sqlite3_free(pData); - } - } - if( rc!=SQLITE_OK ){ - p->pMethod = 0; - }else{ - incrOpenFileCount(); - } - - return rc; -} - -/* -** Implementation of sqlite3OsDelete. Add an entry to the end of the -** write-op queue to perform the delete. -*/ -static int asyncDelete(sqlite3_vfs *pAsyncVfs, const char *z, int syncDir){ - UNUSED_PARAMETER(pAsyncVfs); - return addNewAsyncWrite(0, ASYNC_DELETE, syncDir, (int)strlen(z)+1, z); -} - -/* -** Implementation of sqlite3OsAccess. This method holds the mutex from -** start to finish. -*/ -static int asyncAccess( - sqlite3_vfs *pAsyncVfs, - const char *zName, - int flags, - int *pResOut -){ - int rc; - int ret; - AsyncWrite *p; - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - - assert(flags==SQLITE_ACCESS_READWRITE - || flags==SQLITE_ACCESS_READ - || flags==SQLITE_ACCESS_EXISTS - ); - - async_mutex_enter(ASYNC_MUTEX_QUEUE); - rc = pVfs->xAccess(pVfs, zName, flags, &ret); - if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ - for(p=async.pQueueFirst; p; p = p->pNext){ - if( p->op==ASYNC_DELETE && 0==strcmp(p->zBuf, zName) ){ - ret = 0; - }else if( p->op==ASYNC_OPENEXCLUSIVE - && p->pFileData->zName - && 0==strcmp(p->pFileData->zName, zName) - ){ - ret = 1; - } - } - } - ASYNC_TRACE(("ACCESS(%s): %s = %d\n", - flags==SQLITE_ACCESS_READWRITE?"read-write": - flags==SQLITE_ACCESS_READ?"read":"exists" - , zName, ret) - ); - async_mutex_leave(ASYNC_MUTEX_QUEUE); - *pResOut = ret; - return rc; -} - -/* -** Fill in zPathOut with the full path to the file identified by zPath. -*/ -static int asyncFullPathname( - sqlite3_vfs *pAsyncVfs, - const char *zPath, - int nPathOut, - char *zPathOut -){ - int rc; - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - rc = pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); - - /* Because of the way intra-process file locking works, this backend - ** needs to return a canonical path. The following block assumes the - ** file-system uses unix style paths. - */ - if( rc==SQLITE_OK ){ - int i, j; - char *z = zPathOut; - int n = (int)strlen(z); - while( n>1 && z[n-1]=='/' ){ n--; } - for(i=j=0; i0 && z[j-1]!='/' ){ j--; } - if( j>0 ){ j--; } - i += 2; - continue; - } - } - z[j++] = z[i]; - } - z[j] = 0; - } - - return rc; -} -static void *asyncDlOpen(sqlite3_vfs *pAsyncVfs, const char *zPath){ - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - return pVfs->xDlOpen(pVfs, zPath); -} -static void asyncDlError(sqlite3_vfs *pAsyncVfs, int nByte, char *zErrMsg){ - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - pVfs->xDlError(pVfs, nByte, zErrMsg); -} -static void (*asyncDlSym( - sqlite3_vfs *pAsyncVfs, - void *pHandle, - const char *zSymbol -))(void){ - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - return pVfs->xDlSym(pVfs, pHandle, zSymbol); -} -static void asyncDlClose(sqlite3_vfs *pAsyncVfs, void *pHandle){ - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - pVfs->xDlClose(pVfs, pHandle); -} -static int asyncRandomness(sqlite3_vfs *pAsyncVfs, int nByte, char *zBufOut){ - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - return pVfs->xRandomness(pVfs, nByte, zBufOut); -} -static int asyncSleep(sqlite3_vfs *pAsyncVfs, int nMicro){ - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - return pVfs->xSleep(pVfs, nMicro); -} -static int asyncCurrentTime(sqlite3_vfs *pAsyncVfs, double *pTimeOut){ - sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - return pVfs->xCurrentTime(pVfs, pTimeOut); -} - -static sqlite3_vfs async_vfs = { - 1, /* iVersion */ - sizeof(AsyncFile), /* szOsFile */ - 0, /* mxPathname */ - 0, /* pNext */ - SQLITEASYNC_VFSNAME, /* zName */ - 0, /* pAppData */ - asyncOpen, /* xOpen */ - asyncDelete, /* xDelete */ - asyncAccess, /* xAccess */ - asyncFullPathname, /* xFullPathname */ - asyncDlOpen, /* xDlOpen */ - asyncDlError, /* xDlError */ - asyncDlSym, /* xDlSym */ - asyncDlClose, /* xDlClose */ - asyncRandomness, /* xDlError */ - asyncSleep, /* xDlSym */ - asyncCurrentTime /* xDlClose */ -}; - -/* -** This procedure runs in a separate thread, reading messages off of the -** write queue and processing them one by one. -** -** If async.writerHaltNow is true, then this procedure exits -** after processing a single message. -** -** If async.writerHaltWhenIdle is true, then this procedure exits when -** the write queue is empty. -** -** If both of the above variables are false, this procedure runs -** indefinately, waiting for operations to be added to the write queue -** and processing them in the order in which they arrive. -** -** An artifical delay of async.ioDelay milliseconds is inserted before -** each write operation in order to simulate the effect of a slow disk. -** -** Only one instance of this procedure may be running at a time. -*/ -static void asyncWriterThread(void){ - sqlite3_vfs *pVfs = (sqlite3_vfs *)(async_vfs.pAppData); - AsyncWrite *p = 0; - int rc = SQLITE_OK; - int holdingMutex = 0; - - async_mutex_enter(ASYNC_MUTEX_WRITER); - - while( async.eHalt!=SQLITEASYNC_HALT_NOW ){ - int doNotFree = 0; - sqlite3_file *pBase = 0; - - if( !holdingMutex ){ - async_mutex_enter(ASYNC_MUTEX_QUEUE); - } - while( (p = async.pQueueFirst)==0 ){ - if( async.eHalt!=SQLITEASYNC_HALT_NEVER ){ - async_mutex_leave(ASYNC_MUTEX_QUEUE); - break; - }else{ - ASYNC_TRACE(("IDLE\n")); - async_cond_wait(ASYNC_COND_QUEUE, ASYNC_MUTEX_QUEUE); - ASYNC_TRACE(("WAKEUP\n")); - } - } - if( p==0 ) break; - holdingMutex = 1; - - /* Right now this thread is holding the mutex on the write-op queue. - ** Variable 'p' points to the first entry in the write-op queue. In - ** the general case, we hold on to the mutex for the entire body of - ** the loop. - ** - ** However in the cases enumerated below, we relinquish the mutex, - ** perform the IO, and then re-request the mutex before removing 'p' from - ** the head of the write-op queue. The idea is to increase concurrency with - ** sqlite threads. - ** - ** * An ASYNC_CLOSE operation. - ** * An ASYNC_OPENEXCLUSIVE operation. For this one, we relinquish - ** the mutex, call the underlying xOpenExclusive() function, then - ** re-aquire the mutex before seting the AsyncFile.pBaseRead - ** variable. - ** * ASYNC_SYNC and ASYNC_WRITE operations, if - ** SQLITE_ASYNC_TWO_FILEHANDLES was set at compile time and two - ** file-handles are open for the particular file being "synced". - */ - if( async.ioError!=SQLITE_OK && p->op!=ASYNC_CLOSE ){ - p->op = ASYNC_NOOP; - } - if( p->pFileData ){ - pBase = p->pFileData->pBaseWrite; - if( - p->op==ASYNC_CLOSE || - p->op==ASYNC_OPENEXCLUSIVE || - (pBase->pMethods && (p->op==ASYNC_SYNC || p->op==ASYNC_WRITE) ) - ){ - async_mutex_leave(ASYNC_MUTEX_QUEUE); - holdingMutex = 0; - } - if( !pBase->pMethods ){ - pBase = p->pFileData->pBaseRead; - } - } - - switch( p->op ){ - case ASYNC_NOOP: - break; - - case ASYNC_WRITE: - assert( pBase ); - ASYNC_TRACE(("WRITE %s %d bytes at %d\n", - p->pFileData->zName, p->nByte, p->iOffset)); - rc = pBase->pMethods->xWrite(pBase, (void *)(p->zBuf), p->nByte, p->iOffset); - break; - - case ASYNC_SYNC: - assert( pBase ); - ASYNC_TRACE(("SYNC %s\n", p->pFileData->zName)); - rc = pBase->pMethods->xSync(pBase, p->nByte); - break; - - case ASYNC_TRUNCATE: - assert( pBase ); - ASYNC_TRACE(("TRUNCATE %s to %d bytes\n", - p->pFileData->zName, p->iOffset)); - rc = pBase->pMethods->xTruncate(pBase, p->iOffset); - break; - - case ASYNC_CLOSE: { - AsyncFileData *pData = p->pFileData; - ASYNC_TRACE(("CLOSE %s\n", p->pFileData->zName)); - if( pData->pBaseWrite->pMethods ){ - pData->pBaseWrite->pMethods->xClose(pData->pBaseWrite); - } - if( pData->pBaseRead->pMethods ){ - pData->pBaseRead->pMethods->xClose(pData->pBaseRead); - } - - /* Unlink AsyncFileData.lock from the linked list of AsyncFileLock - ** structures for this file. Obtain the async.lockMutex mutex - ** before doing so. - */ - async_mutex_enter(ASYNC_MUTEX_LOCK); - rc = unlinkAsyncFile(pData); - async_mutex_leave(ASYNC_MUTEX_LOCK); - - if( !holdingMutex ){ - async_mutex_enter(ASYNC_MUTEX_QUEUE); - holdingMutex = 1; - } - assert_mutex_is_held(ASYNC_MUTEX_QUEUE); - async.pQueueFirst = p->pNext; - sqlite3_free(pData); - doNotFree = 1; - break; - } - - case ASYNC_UNLOCK: { - AsyncWrite *pIter; - AsyncFileData *pData = p->pFileData; - int eLock = p->nByte; - - /* When a file is locked by SQLite using the async backend, it is - ** locked within the 'real' file-system synchronously. When it is - ** unlocked, an ASYNC_UNLOCK event is added to the write-queue to - ** unlock the file asynchronously. The design of the async backend - ** requires that the 'real' file-system file be locked from the - ** time that SQLite first locks it (and probably reads from it) - ** until all asynchronous write events that were scheduled before - ** SQLite unlocked the file have been processed. - ** - ** This is more complex if SQLite locks and unlocks the file multiple - ** times in quick succession. For example, if SQLite does: - ** - ** lock, write, unlock, lock, write, unlock - ** - ** Each "lock" operation locks the file immediately. Each "write" - ** and "unlock" operation adds an event to the event queue. If the - ** second "lock" operation is performed before the first "unlock" - ** operation has been processed asynchronously, then the first - ** "unlock" cannot be safely processed as is, since this would mean - ** the file was unlocked when the second "write" operation is - ** processed. To work around this, when processing an ASYNC_UNLOCK - ** operation, SQLite: - ** - ** 1) Unlocks the file to the minimum of the argument passed to - ** the xUnlock() call and the current lock from SQLite's point - ** of view, and - ** - ** 2) Only unlocks the file at all if this event is the last - ** ASYNC_UNLOCK event on this file in the write-queue. - */ - assert( holdingMutex==1 ); - assert( async.pQueueFirst==p ); - for(pIter=async.pQueueFirst->pNext; pIter; pIter=pIter->pNext){ - if( pIter->pFileData==pData && pIter->op==ASYNC_UNLOCK ) break; - } - if( !pIter ){ - async_mutex_enter(ASYNC_MUTEX_LOCK); - pData->lock.eAsyncLock = MIN( - pData->lock.eAsyncLock, MAX(pData->lock.eLock, eLock) - ); - assert(pData->lock.eAsyncLock>=pData->lock.eLock); - rc = getFileLock(pData->pLock); - async_mutex_leave(ASYNC_MUTEX_LOCK); - } - break; - } - - case ASYNC_DELETE: - ASYNC_TRACE(("DELETE %s\n", p->zBuf)); - rc = pVfs->xDelete(pVfs, p->zBuf, (int)p->iOffset); - if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK; - break; - - case ASYNC_OPENEXCLUSIVE: { - int flags = (int)p->iOffset; - AsyncFileData *pData = p->pFileData; - ASYNC_TRACE(("OPEN %s flags=%d\n", p->zBuf, (int)p->iOffset)); - assert(pData->pBaseRead->pMethods==0 && pData->pBaseWrite->pMethods==0); - rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseRead, flags, 0); - assert( holdingMutex==0 ); - async_mutex_enter(ASYNC_MUTEX_QUEUE); - holdingMutex = 1; - break; - } - - default: assert(!"Illegal value for AsyncWrite.op"); - } - - /* If we didn't hang on to the mutex during the IO op, obtain it now - ** so that the AsyncWrite structure can be safely removed from the - ** global write-op queue. - */ - if( !holdingMutex ){ - async_mutex_enter(ASYNC_MUTEX_QUEUE); - holdingMutex = 1; - } - /* ASYNC_TRACE(("UNLINK %p\n", p)); */ - if( p==async.pQueueLast ){ - async.pQueueLast = 0; - } - if( !doNotFree ){ - assert_mutex_is_held(ASYNC_MUTEX_QUEUE); - async.pQueueFirst = p->pNext; - sqlite3_free(p); - } - assert( holdingMutex ); - - /* An IO error has occurred. We cannot report the error back to the - ** connection that requested the I/O since the error happened - ** asynchronously. The connection has already moved on. There - ** really is nobody to report the error to. - ** - ** The file for which the error occurred may have been a database or - ** journal file. Regardless, none of the currently queued operations - ** associated with the same database should now be performed. Nor should - ** any subsequently requested IO on either a database or journal file - ** handle for the same database be accepted until the main database - ** file handle has been closed and reopened. - ** - ** Furthermore, no further IO should be queued or performed on any file - ** handle associated with a database that may have been part of a - ** multi-file transaction that included the database associated with - ** the IO error (i.e. a database ATTACHed to the same handle at some - ** point in time). - */ - if( rc!=SQLITE_OK ){ - async.ioError = rc; - } - - if( async.ioError && !async.pQueueFirst ){ - async_mutex_enter(ASYNC_MUTEX_LOCK); - if( 0==async.pLock ){ - async.ioError = SQLITE_OK; - } - async_mutex_leave(ASYNC_MUTEX_LOCK); - } - - /* Drop the queue mutex before continuing to the next write operation - ** in order to give other threads a chance to work with the write queue. - */ - if( !async.pQueueFirst || !async.ioError ){ - async_mutex_leave(ASYNC_MUTEX_QUEUE); - holdingMutex = 0; - if( async.ioDelay>0 ){ - pVfs->xSleep(pVfs, async.ioDelay*1000); - }else{ - async_sched_yield(); - } - } - } - - async_mutex_leave(ASYNC_MUTEX_WRITER); - return; -} - -/* -** Install the asynchronous VFS. -*/ -int sqlite3async_initialize(const char *zParent, int isDefault){ - int rc = SQLITE_OK; - if( async_vfs.pAppData==0 ){ - sqlite3_vfs *pParent = sqlite3_vfs_find(zParent); - if( !pParent || async_os_initialize() ){ - rc = SQLITE_ERROR; - }else if( SQLITE_OK!=(rc = sqlite3_vfs_register(&async_vfs, isDefault)) ){ - async_os_shutdown(); - }else{ - async_vfs.pAppData = (void *)pParent; - async_vfs.mxPathname = ((sqlite3_vfs *)async_vfs.pAppData)->mxPathname; - } - } - return rc; -} - -/* -** Uninstall the asynchronous VFS. -*/ -void sqlite3async_shutdown(void){ - if( async_vfs.pAppData ){ - async_os_shutdown(); - sqlite3_vfs_unregister((sqlite3_vfs *)&async_vfs); - async_vfs.pAppData = 0; - } -} - -/* -** Process events on the write-queue. -*/ -void sqlite3async_run(void){ - asyncWriterThread(); -} - -/* -** Control/configure the asynchronous IO system. -*/ -int sqlite3async_control(int op, ...){ - int rc = SQLITE_OK; - va_list ap; - va_start(ap, op); - switch( op ){ - case SQLITEASYNC_HALT: { - int eWhen = va_arg(ap, int); - if( eWhen!=SQLITEASYNC_HALT_NEVER - && eWhen!=SQLITEASYNC_HALT_NOW - && eWhen!=SQLITEASYNC_HALT_IDLE - ){ - rc = SQLITE_MISUSE; - break; - } - async.eHalt = eWhen; - async_mutex_enter(ASYNC_MUTEX_QUEUE); - async_cond_signal(ASYNC_COND_QUEUE); - async_mutex_leave(ASYNC_MUTEX_QUEUE); - break; - } - - case SQLITEASYNC_DELAY: { - int iDelay = va_arg(ap, int); - if( iDelay<0 ){ - rc = SQLITE_MISUSE; - break; - } - async.ioDelay = iDelay; - break; - } - - case SQLITEASYNC_LOCKFILES: { - int bLock = va_arg(ap, int); - async_mutex_enter(ASYNC_MUTEX_QUEUE); - if( async.nFile || async.pQueueFirst ){ - async_mutex_leave(ASYNC_MUTEX_QUEUE); - rc = SQLITE_MISUSE; - break; - } - async.bLockFiles = bLock; - async_mutex_leave(ASYNC_MUTEX_QUEUE); - break; - } - - case SQLITEASYNC_GET_HALT: { - int *peWhen = va_arg(ap, int *); - *peWhen = async.eHalt; - break; - } - case SQLITEASYNC_GET_DELAY: { - int *piDelay = va_arg(ap, int *); - *piDelay = async.ioDelay; - break; - } - case SQLITEASYNC_GET_LOCKFILES: { - int *piDelay = va_arg(ap, int *); - *piDelay = async.bLockFiles; - break; - } - - default: - rc = SQLITE_ERROR; - break; - } - va_end(ap); - return rc; -} - -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ASYNCIO) */ diff --git a/ext/async/sqlite3async.h b/ext/async/sqlite3async.h deleted file mode 100644 index 13b23bc6a2..0000000000 --- a/ext/async/sqlite3async.h +++ /dev/null @@ -1,222 +0,0 @@ - -#ifndef __SQLITEASYNC_H_ -#define __SQLITEASYNC_H_ 1 - -/* -** Make sure we can call this stuff from C++. -*/ -#ifdef __cplusplus -extern "C" { -#endif - -#define SQLITEASYNC_VFSNAME "sqlite3async" - -/* -** THREAD SAFETY NOTES: -** -** Of the four API functions in this file, the following are not threadsafe: -** -** sqlite3async_initialize() -** sqlite3async_shutdown() -** -** Care must be taken that neither of these functions is called while -** another thread may be calling either any sqlite3async_XXX() function -** or an sqlite3_XXX() API function related to a database handle that -** is using the asynchronous IO VFS. -** -** These functions: -** -** sqlite3async_run() -** sqlite3async_control() -** -** are threadsafe. It is quite safe to call either of these functions even -** if another thread may also be calling one of them or an sqlite3_XXX() -** function related to a database handle that uses the asynchronous IO VFS. -*/ - -/* -** Initialize the asynchronous IO VFS and register it with SQLite using -** sqlite3_vfs_register(). If the asynchronous VFS is already initialized -** and registered, this function is a no-op. The asynchronous IO VFS -** is registered as "sqlite3async". -** -** The asynchronous IO VFS does not make operating system IO requests -** directly. Instead, it uses an existing VFS implementation for all -** required file-system operations. If the first parameter to this function -** is NULL, then the current default VFS is used for IO. If it is not -** NULL, then it must be the name of an existing VFS. In other words, the -** first argument to this function is passed to sqlite3_vfs_find() to -** locate the VFS to use for all real IO operations. This VFS is known -** as the "parent VFS". -** -** If the second parameter to this function is non-zero, then the -** asynchronous IO VFS is registered as the default VFS for all SQLite -** database connections within the process. Otherwise, the asynchronous IO -** VFS is only used by connections opened using sqlite3_open_v2() that -** specifically request VFS "sqlite3async". -** -** If a parent VFS cannot be located, then SQLITE_ERROR is returned. -** In the unlikely event that operating system specific initialization -** fails (win32 systems create the required critical section and event -** objects within this function), then SQLITE_ERROR is also returned. -** Finally, if the call to sqlite3_vfs_register() returns an error, then -** the error code is returned to the user by this function. In all three -** of these cases, intialization has failed and the asynchronous IO VFS -** is not registered with SQLite. -** -** Otherwise, if no error occurs, SQLITE_OK is returned. -*/ -int sqlite3async_initialize(const char *zParent, int isDefault); - -/* -** This function unregisters the asynchronous IO VFS using -** sqlite3_vfs_unregister(). -** -** On win32 platforms, this function also releases the small number of -** critical section and event objects created by sqlite3async_initialize(). -*/ -void sqlite3async_shutdown(void); - -/* -** This function may only be called when the asynchronous IO VFS is -** installed (after a call to sqlite3async_initialize()). It processes -** zero or more queued write operations before returning. It is expected -** (but not required) that this function will be called by a different -** thread than those threads that use SQLite. The "background thread" -** that performs IO. -** -** How many queued write operations are performed before returning -** depends on the global setting configured by passing the SQLITEASYNC_HALT -** verb to sqlite3async_control() (see below for details). By default -** this function never returns - it processes all pending operations and -** then blocks waiting for new ones. -** -** If multiple simultaneous calls are made to sqlite3async_run() from two -** or more threads, then the calls are serialized internally. -*/ -void sqlite3async_run(void); - -/* -** This function may only be called when the asynchronous IO VFS is -** installed (after a call to sqlite3async_initialize()). It is used -** to query or configure various parameters that affect the operation -** of the asynchronous IO VFS. At present there are three parameters -** supported: -** -** * The "halt" parameter, which configures the circumstances under -** which the sqlite3async_run() parameter is configured. -** -** * The "delay" parameter. Setting the delay parameter to a non-zero -** value causes the sqlite3async_run() function to sleep for the -** configured number of milliseconds between each queued write -** operation. -** -** * The "lockfiles" parameter. This parameter determines whether or -** not the asynchronous IO VFS locks the database files it operates -** on. Disabling file locking can improve throughput. -** -** This function is always passed two arguments. When setting the value -** of a parameter, the first argument must be one of SQLITEASYNC_HALT, -** SQLITEASYNC_DELAY or SQLITEASYNC_LOCKFILES. The second argument must -** be passed the new value for the parameter as type "int". -** -** When querying the current value of a paramter, the first argument must -** be one of SQLITEASYNC_GET_HALT, GET_DELAY or GET_LOCKFILES. The second -** argument to this function must be of type (int *). The current value -** of the queried parameter is copied to the memory pointed to by the -** second argument. For example: -** -** int eCurrentHalt; -** int eNewHalt = SQLITEASYNC_HALT_IDLE; -** -** sqlite3async_control(SQLITEASYNC_HALT, eNewHalt); -** sqlite3async_control(SQLITEASYNC_GET_HALT, &eCurrentHalt); -** assert( eNewHalt==eCurrentHalt ); -** -** See below for more detail on each configuration parameter. -** -** SQLITEASYNC_HALT: -** -** This is used to set the value of the "halt" parameter. The second -** argument must be one of the SQLITEASYNC_HALT_XXX symbols defined -** below (either NEVER, IDLE and NOW). -** -** If the parameter is set to NEVER, then calls to sqlite3async_run() -** never return. This is the default setting. If the parameter is set -** to IDLE, then calls to sqlite3async_run() return as soon as the -** queue of pending write operations is empty. If the parameter is set -** to NOW, then calls to sqlite3async_run() return as quickly as -** possible, without processing any pending write requests. -** -** If an attempt is made to set this parameter to an integer value other -** than SQLITEASYNC_HALT_NEVER, IDLE or NOW, then sqlite3async_control() -** returns SQLITE_MISUSE and the current value of the parameter is not -** modified. -** -** Modifying the "halt" parameter affects calls to sqlite3async_run() -** made by other threads that are currently in progress. -** -** SQLITEASYNC_DELAY: -** -** This is used to set the value of the "delay" parameter. If set to -** a non-zero value, then after completing a pending write request, the -** sqlite3async_run() function sleeps for the configured number of -** milliseconds. -** -** If an attempt is made to set this parameter to a negative value, -** sqlite3async_control() returns SQLITE_MISUSE and the current value -** of the parameter is not modified. -** -** Modifying the "delay" parameter affects calls to sqlite3async_run() -** made by other threads that are currently in progress. -** -** SQLITEASYNC_LOCKFILES: -** -** This is used to set the value of the "lockfiles" parameter. This -** parameter must be set to either 0 or 1. If set to 1, then the -** asynchronous IO VFS uses the xLock() and xUnlock() methods of the -** parent VFS to lock database files being read and/or written. If -** the parameter is set to 0, then these locks are omitted. -** -** This parameter may only be set when there are no open database -** connections using the VFS and the queue of pending write requests -** is empty. Attempting to set it when this is not true, or to set it -** to a value other than 0 or 1 causes sqlite3async_control() to return -** SQLITE_MISUSE and the value of the parameter to remain unchanged. -** -** If this parameter is set to zero, then it is only safe to access the -** database via the asynchronous IO VFS from within a single process. If -** while writing to the database via the asynchronous IO VFS the database -** is also read or written from within another process, or via another -** connection that does not use the asynchronous IO VFS within the same -** process, the results are undefined (and may include crashes or database -** corruption). -** -** Alternatively, if this parameter is set to 1, then it is safe to access -** the database from multiple connections within multiple processes using -** either the asynchronous IO VFS or the parent VFS directly. -*/ -int sqlite3async_control(int op, ...); - -/* -** Values that can be used as the first argument to sqlite3async_control(). -*/ -#define SQLITEASYNC_HALT 1 -#define SQLITEASYNC_GET_HALT 2 -#define SQLITEASYNC_DELAY 3 -#define SQLITEASYNC_GET_DELAY 4 -#define SQLITEASYNC_LOCKFILES 5 -#define SQLITEASYNC_GET_LOCKFILES 6 - -/* -** If the first argument to sqlite3async_control() is SQLITEASYNC_HALT, -** the second argument should be one of the following. -*/ -#define SQLITEASYNC_HALT_NEVER 0 /* Never halt (default value) */ -#define SQLITEASYNC_HALT_NOW 1 /* Halt as soon as possible */ -#define SQLITEASYNC_HALT_IDLE 2 /* Halt when write-queue is empty */ - -#ifdef __cplusplus -} /* End of the 'extern "C"' block */ -#endif -#endif /* ifndef __SQLITEASYNC_H_ */ diff --git a/main.mk b/main.mk index 1502b05c7e..3469381bd6 100644 --- a/main.mk +++ b/main.mk @@ -307,7 +307,7 @@ T.cc.sqlite ?= $(T.cc) # CFLAGS.intree_includes = \ -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \ - -I$(TOP)/ext/fts3 -I$(TOP)/ext/async -I$(TOP)/ext/session \ + -I$(TOP)/ext/fts3 -I$(TOP)/ext/session \ -I$(TOP)/ext/misc -I$(TOP)/ext/userauth T.cc.sqlite += $(CFLAGS.intree_includes) @@ -627,7 +627,6 @@ TESTSRC = \ $(TOP)/src/test8.c \ $(TOP)/src/test9.c \ $(TOP)/src/test_autoext.c \ - $(TOP)/src/test_async.c \ $(TOP)/src/test_backup.c \ $(TOP)/src/test_bestindex.c \ $(TOP)/src/test_blob.c \ @@ -764,7 +763,6 @@ TESTSRC2 = \ $(TOP)/ext/fts3/fts3_term.c \ $(TOP)/ext/fts3/fts3_tokenizer.c \ $(TOP)/ext/fts3/fts3_write.c \ - $(TOP)/ext/async/sqlite3async.c \ $(TOP)/ext/session/sqlite3session.c \ $(TOP)/ext/misc/stmt.c \ fts5.c diff --git a/manifest b/manifest index 383228d3e0..2a8ee27a47 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Omit\sext/consio\sfrom\sthe\stree.\s\sNo\slonger\sneeded\sor\ssupported. -D 2024-10-28T14:53:45.379 +C Omit\sthe\santiquated\sand\slong-unsupport\sasync\sextension\ssince\sit\shas\sbeen\nsuperseded\sby\sWAL\smode\sfor\sover\sa\sdecade. +D 2024-10-28T15:38:53.409 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 F Makefile.in 02ea00ff433902dba369d4a55b3aeb6bb1ffe2d82f777194984b8cdd7ed7c3ad F Makefile.linux-generic 69b54c58ab2424a0d30f340d9defd7e87c25690a55b77acb9bdc657bd9a223f1 -F Makefile.msc d2d927177660945599ba88ea32f1ab5c261a96a8797380b99766e27f3aea7e4f +F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -68,9 +68,6 @@ F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc1404 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F doc/wal-lock.md 781726aaba20bafeceb7ba9f91d5c98c6731691b30c954e37cf0b49a053d461d F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd -F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 -F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94 -F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 F ext/expert/expert1.test 1d2da6606623b57bb47064e02140823ce1daecd4cacbf402c73ad3473d7f000c @@ -705,7 +702,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ed437c3fb9ef480a534aa3205fff1f380ce776c1aa1069e3623b692770f86404 +F main.mk c5e17513c0f68b514d0f1b5afabcc0aabfedf8ebba0e6314435df1edcb7e8fd4 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -804,7 +801,6 @@ F src/test5.c bb87279ed12e199486894e6c83e58dc8cd1de9524ace171d59219d3ab696a0c1 F src/test6.c 763b92489f11f4a77b773f0d3b8369ab0edd5292ac794043062c337019f12d8a F src/test8.c 206d8f3cc73950d252906656e2646b5de0d580b07187b635fcb3edd8c2c5fbc0 F src/test9.c 7a708ad27f8fda79113e5e15de66632710958c401e64c2f22bc04e2f5a7a1b62 -F src/test_async.c 0101173cf8137ba5473a84a695281fa9dedc2a1d155998c68623f2978017ad98 F src/test_autoext.c 14d4bbd3d0bd1eec0f6d16b29e28cf1e2d0b020d454835f0721a5f68121ac10f F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d9719a7 F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6 @@ -837,7 +833,7 @@ F src/test_schema.c b06d3ddc3edc173c143878f3edb869dd200d57d918ae2f38820534f9a5e3 F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a F src/test_superlock.c 18355ca274746aa6909e3744163e5deb1196a85d5bc64b9cd377273cef626da7 F src/test_syscall.c 9ad7ab39910c16d29411678d91b0d27a7a996a718df5ee93dcd635e846d0275c -F src/test_tclsh.c 6077f2bdc6b4ea2bace2a0cd6ea48e0a4651007ae7382c13efc0c495eb0c6956 +F src/test_tclsh.c c01706ac60bd3176754d3ccd37da74c6ad97c2e14489f8ed71b497c1c0ac0dd4 F src/test_tclvar.c ae873248a0188459b1c16ca7cc431265dacce524399e8b46725c2b3b7e048424 F src/test_thread.c d7a8bcea7445f37cc2a1f7f81dd6059634f45e0c61bfe80182b02872fb0328bb F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3 @@ -919,11 +915,6 @@ F test/analyzeE.test d2ec7921c162cdc33ac8e7eb01f9ebf78100610af7c94c8552bbf551de1 F test/analyzeF.test 40b5cc3ad7b10e81020d7ca86f1417647ecfae7477cfd88acc5aa7ae1068f949 F test/analyzeG.test 623be33038c49648872746c8dd8b23b5792c08fef173c55e82f1b12fca259852 F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49 -F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b -F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b -F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 -F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a -F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 F test/atof1.test 7ec56debc04b32e8f9dc87239f4bbb07d84550fb83dd7475b0ead9e83beb35da F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061 F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da @@ -1417,7 +1408,7 @@ F test/literal2.tcl 1499037beaf661aeecdbe48801220a181d805372a64c6128d5f26bb6a4a8 F test/literal2.test b149e16b5fc9ee6249069a8858ed41052f222014fe0ba7ad43c2fb989c2dada2 F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 -F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db +F test/lock.test 05f346b65040b9a27c032c984e1e509dfef1661135b4f26a3ab6d21358277803 F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 F test/lock4.test 27143363eda1622f03c133efc8db808fc331afd973486cb571ea71cd717d37b8 @@ -1426,7 +1417,7 @@ F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5 F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431 F test/lock_common.tcl 2f3f7f2e9637f93ccf609df48ef5b27a50278b6b1cd752b445d52262e5841413 F test/lookaside.test 5a828e7256f1ee4da8e1bdaa03373a3ccdb0f1ff98dfa82e9b76cb41a45b1083 -F test/main.test 1b07447e484d3a3ca8c620c6551258fa51f9cc9fdd56648e8949ea8c836be961 +F test/main.test e8752d76233b1c8906cd2c98ad920dba868bd63c87d51d8a2ea5e9cba55dd496 F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/malloc.test 18dd1c4188c81ca79cf123527c71b19ee0c31feb9947fdffb0dc6ceb1436816a F test/malloc3.test 6e88bae6312854a4adb4ecc2a6a5ea8c59b4db778b724ba718e1c43fc8c3c136 @@ -1459,7 +1450,7 @@ F test/memdb1.test c737ac9aa5895092332b1dde24fae7ae494b7fcbcd346d22d600891096a38 F test/memdb2.test 4ba1fc09e2f51df80d148a540e4a3fa66d0462e91167b27497084de4d1f6b5b4 F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c F test/memjournal2.test dbc2c5cb5f7b38950f4f6dc3e73fcecf0fcbed3fc32c7ce913bba164d288da1e -F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 +F test/memleak.test c7478f1195d64887dd1c677edc39fa03b5bf29024e6dcc5b5cc554d7ed00b01f F test/memsubsys1.test 86b8158752af9188ed5b32a30674a1ef71183e6bc4e6808e815cd658ca9058a6 F test/memsubsys2.test 774b93cb09ca50d1b759bb7c645baa2a9ce172edc3a3da67d5150a26a9fc2a08 F test/merge1.test 7dd9dc6838bcd0623a069485fe3a8dd498a051c16e1877cf84f506c0d6a29b43 @@ -1538,7 +1529,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463 F test/percentile.test 52ba89d6ee6b65f770972b67dace358bab7cdbd532803d3db157845268e789cd -F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80 +F test/permutations.test 37650c5286f7d6f322af95cad876b69c6c2c79c28dc649f09de07d3312b1213c F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f @@ -1784,7 +1775,6 @@ F test/tkt-8454a207b9.test ead80b7a01438ca1436cee029694a96c821346cf1e24f06de12f8 F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356 F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5 -F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223 F test/tkt-99378177930f87bd.test 9d6cff39b50d062c813ae1cb0ebbd1b7acf81ecc23ae5d5215e5bb05667dc137 F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667 F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6 @@ -2214,8 +2204,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6cb7cb7e33835d42cbab2e5468d73de7bb3b01971da078ce1c1344edc11ab1b3 -R 00f0377d2b4f46d55243305df3135edf +P 1ce8507f732a26508a9b336cb27756a0a8638e14395efdd59b5faef40526ede5 +R b9b93d2e2084015bc7fa1134ed3eba38 +T *branch * omit-async +T *sym-omit-async * +T -sym-trunk * U drh -Z 05dc840cebf23762b49de298db68f9dc +Z e51dfe59488ba774ddcef48ab38dfbd3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1592140732..97058526f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ce8507f732a26508a9b336cb27756a0a8638e14395efdd59b5faef40526ede5 +10b1b86821bfc21377e7ccceb31146ab01aa6eaf418b85a204abcab5b793958e diff --git a/src/test_async.c b/src/test_async.c deleted file mode 100644 index afe401ac69..0000000000 --- a/src/test_async.c +++ /dev/null @@ -1,241 +0,0 @@ -/* -** 2005 December 14 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains a binding of the asynchronous IO extension interface -** (defined in ext/async/sqlite3async.h) to Tcl. -*/ - -#define TCL_THREADS -#include "tclsqlite.h" - -#ifdef SQLITE_ENABLE_ASYNCIO - -#include "sqlite3async.h" -#include "sqlite3.h" -#include - -/* From main.c */ -extern const char *sqlite3ErrName(int); - - -struct TestAsyncGlobal { - int isInstalled; /* True when async VFS is installed */ -} testasync_g = { 0 }; - -TCL_DECLARE_MUTEX(testasync_g_writerMutex); - -/* -** sqlite3async_initialize PARENT-VFS ISDEFAULT -*/ -static int SQLITE_TCLAPI testAsyncInit( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - const char *zParent; - int isDefault; - int rc; - - if( objc!=3 ){ - Tcl_WrongNumArgs(interp, 1, objv, "PARENT-VFS ISDEFAULT"); - return TCL_ERROR; - } - zParent = Tcl_GetString(objv[1]); - if( !*zParent ) { - zParent = 0; - } - if( Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){ - return TCL_ERROR; - } - - rc = sqlite3async_initialize(zParent, isDefault); - if( rc!=SQLITE_OK ){ - Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** sqlite3async_shutdown -*/ -static int SQLITE_TCLAPI testAsyncShutdown( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - sqlite3async_shutdown(); - return TCL_OK; -} - -static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){ - Tcl_MutexLock(&testasync_g_writerMutex); - *((int *)pIsStarted) = 1; - sqlite3async_run(); - Tcl_MutexUnlock(&testasync_g_writerMutex); - Tcl_ExitThread(0); - TCL_THREAD_CREATE_RETURN; -} - -/* -** sqlite3async_start -** -** Start a new writer thread. -*/ -static int SQLITE_TCLAPI testAsyncStart( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - volatile int isStarted = 0; - ClientData threadData = (ClientData)&isStarted; - - Tcl_ThreadId x; - const int nStack = TCL_THREAD_STACK_DEFAULT; - const int flags = TCL_THREAD_NOFLAGS; - int rc; - - rc = Tcl_CreateThread(&x, tclWriterThread, threadData, nStack, flags); - if( rc!=TCL_OK ){ - Tcl_AppendResult(interp, "Tcl_CreateThread() failed", 0); - return TCL_ERROR; - } - - while( isStarted==0 ) { /* Busy loop */ } - return TCL_OK; -} - -/* -** sqlite3async_wait -** -** Wait for the current writer thread to terminate. -** -** If the current writer thread is set to run forever then this -** command would block forever. To prevent that, an error is returned. -*/ -static int SQLITE_TCLAPI testAsyncWait( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - int eCond; - if( objc!=1 ){ - Tcl_WrongNumArgs(interp, 1, objv, ""); - return TCL_ERROR; - } - - sqlite3async_control(SQLITEASYNC_GET_HALT, &eCond); - if( eCond==SQLITEASYNC_HALT_NEVER ){ - Tcl_AppendResult(interp, "would block forever", (char*)0); - return TCL_ERROR; - } - - Tcl_MutexLock(&testasync_g_writerMutex); - Tcl_MutexUnlock(&testasync_g_writerMutex); - return TCL_OK; -} - -/* -** sqlite3async_control OPTION ?VALUE? -*/ -static int SQLITE_TCLAPI testAsyncControl( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - int rc = SQLITE_OK; - int aeOpt[] = { SQLITEASYNC_HALT, SQLITEASYNC_DELAY, SQLITEASYNC_LOCKFILES }; - const char *azOpt[] = { "halt", "delay", "lockfiles", 0 }; - const char *az[] = { "never", "now", "idle", 0 }; - int iVal; - int eOpt; - - if( objc!=2 && objc!=3 ){ - Tcl_WrongNumArgs(interp, 1, objv, "OPTION ?VALUE?"); - return TCL_ERROR; - } - if( Tcl_GetIndexFromObj(interp, objv[1], azOpt, "option", 0, &eOpt) ){ - return TCL_ERROR; - } - eOpt = aeOpt[eOpt]; - - if( objc==3 ){ - switch( eOpt ){ - case SQLITEASYNC_HALT: { - assert( SQLITEASYNC_HALT_NEVER==0 ); - assert( SQLITEASYNC_HALT_NOW==1 ); - assert( SQLITEASYNC_HALT_IDLE==2 ); - if( Tcl_GetIndexFromObj(interp, objv[2], az, "value", 0, &iVal) ){ - return TCL_ERROR; - } - break; - } - case SQLITEASYNC_DELAY: - if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ){ - return TCL_ERROR; - } - break; - - case SQLITEASYNC_LOCKFILES: - if( Tcl_GetBooleanFromObj(interp, objv[2], &iVal) ){ - return TCL_ERROR; - } - break; - } - - rc = sqlite3async_control(eOpt, iVal); - } - - if( rc==SQLITE_OK ){ - rc = sqlite3async_control( - eOpt==SQLITEASYNC_HALT ? SQLITEASYNC_GET_HALT : - eOpt==SQLITEASYNC_DELAY ? SQLITEASYNC_GET_DELAY : - SQLITEASYNC_GET_LOCKFILES, &iVal); - } - - if( rc!=SQLITE_OK ){ - Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); - return TCL_ERROR; - } - - if( eOpt==SQLITEASYNC_HALT ){ - Tcl_SetObjResult(interp, Tcl_NewStringObj(az[iVal], -1)); - }else{ - Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal)); - } - - return TCL_OK; -} - -#endif /* SQLITE_ENABLE_ASYNCIO */ - -/* -** This routine registers the custom TCL commands defined in this -** module. This should be the only procedure visible from outside -** of this module. -*/ -int Sqlitetestasync_Init(Tcl_Interp *interp){ -#ifdef SQLITE_ENABLE_ASYNCIO - Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0); - Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0); - - Tcl_CreateObjCommand(interp,"sqlite3async_control",testAsyncControl,0,0); - Tcl_CreateObjCommand(interp,"sqlite3async_initialize",testAsyncInit,0,0); - Tcl_CreateObjCommand(interp,"sqlite3async_shutdown",testAsyncShutdown,0,0); -#endif /* SQLITE_ENABLE_ASYNCIO */ - return TCL_OK; -} diff --git a/src/test_tclsh.c b/src/test_tclsh.c index db362049e7..989cb97a62 100644 --- a/src/test_tclsh.c +++ b/src/test_tclsh.c @@ -59,7 +59,6 @@ const char *sqlite3TestInit(Tcl_Interp *interp){ extern int Sqlitetest6_Init(Tcl_Interp*); extern int Sqlitetest8_Init(Tcl_Interp*); extern int Sqlitetest9_Init(Tcl_Interp*); - extern int Sqlitetestasync_Init(Tcl_Interp*); extern int Sqlitetest_autoext_Init(Tcl_Interp*); extern int Sqlitetest_blob_Init(Tcl_Interp*); extern int Sqlitetest_demovfs_Init(Tcl_Interp *); @@ -131,7 +130,6 @@ const char *sqlite3TestInit(Tcl_Interp *interp){ Sqlitetest6_Init(interp); Sqlitetest8_Init(interp); Sqlitetest9_Init(interp); - Sqlitetestasync_Init(interp); Sqlitetest_autoext_Init(interp); Sqlitetest_blob_Init(interp); Sqlitetest_demovfs_Init(interp); diff --git a/test/async.test b/test/async.test deleted file mode 100644 index e1bc08642e..0000000000 --- a/test/async.test +++ /dev/null @@ -1,90 +0,0 @@ -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file runs all tests. -# -# $Id: async.test,v 1.21 2009/06/05 17:09:12 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if {[info commands sqlite3async_initialize] eq ""} { - # The async logic is not built into this system - finish_test - return -} - -rename finish_test async_really_finish_test -proc finish_test {} { - catch {db close} - catch {db2 close} - catch {db3 close} -} -if {[info exists G(isquick)]} { set ASYNC_SAVE_ISQUICK $G(isquick) } -set G(isquick) 1 - -set ASYNC_INCLUDE { - insert.test - insert2.test - insert3.test - lock.test - lock2.test - lock3.test - select1.test - select2.test - select3.test - select4.test - trans.test -} - -# Enable asynchronous IO. -sqlite3async_initialize "" 1 - -# This proc flushes the contents of the async-IO queue through to the -# underlying VFS. A couple of the test scripts identified in $ASYNC_INCLUDE -# above contain lines like "catch flush_async_queue" in places where -# this is required for the tests to work in async mode. -# -proc flush_async_queue {} { - sqlite3async_control halt idle - sqlite3async_start - sqlite3async_wait - sqlite3async_control halt never -} - -rename do_test async_really_do_test -proc do_test {name args} { - uplevel async_really_do_test async_io-$name $args - flush_async_queue -} - -foreach testfile [lsort -dictionary [glob $testdir/*.test]] { - set tail [file tail $testfile] - if {[lsearch -exact $ASYNC_INCLUDE $tail]<0} continue - source $testfile - - # Make sure everything is flushed through. This is because [source]ing - # the next test file will delete the database file on disk (using - # [delete_file]). If the asynchronous backend still has the file - # open, it will become confused. - # - flush_async_queue -} - -# Flush the write-queue and disable asynchronous IO. This should ensure -# all allocated memory is cleaned up. -set sqlite3async_trace 1 -flush_async_queue -sqlite3async_shutdown -set sqlite3async_trace 0 - -rename do_test {} -rename async_really_do_test do_test -rename finish_test {} -rename async_really_finish_test finish_test - -if {[info exists ASYNC_SAVE_ISQUICK]} { set G(isquick) $ASYNC_SAVE_ISQUICK } -finish_test diff --git a/test/async2.test b/test/async2.test deleted file mode 100644 index 7994a7219d..0000000000 --- a/test/async2.test +++ /dev/null @@ -1,126 +0,0 @@ -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# -# $Id: async2.test,v 1.12 2009/04/25 08:39:15 danielk1977 Exp $ - - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if { - [info commands sqlite3async_initialize]=="" || - [info command sqlite3_memdebug_fail]=="" -} { - # The async logic is not built into this system - puts "Skipping async2 tests: not compiled with required features" - finish_test - return -} - -# Enable asynchronous IO. - -set setup_script { - CREATE TABLE counter(c); - INSERT INTO counter(c) VALUES (1); -} - -set sql_script { - BEGIN; - UPDATE counter SET c = 2; - CREATE TABLE t1(a PRIMARY KEY, b, c); - CREATE TABLE t2(a PRIMARY KEY, b, c); - COMMIT; - - BEGIN; - UPDATE counter SET c = 3; - INSERT INTO t1 VALUES('abcdefghij', 'four', 'score'); - INSERT INTO t2 VALUES('klmnopqrst', 'and', 'seven'); - COMMIT; - - UPDATE counter SET c = 'FIN'; -} - -db close - -foreach err [list ioerr malloc-transient malloc-persistent] { - set ::go 10 - for {set n 1} {$::go} {incr n} { - set ::sqlite_io_error_pending 0 - sqlite3_memdebug_fail -1 - forcedelete test.db test.db-journal - sqlite3 db test.db - execsql $::setup_script - db close - - sqlite3async_initialize "" 1 - sqlite3 db test.db - sqlite3_db_config_lookaside db 0 0 0 - - switch -- $err { - ioerr { set ::sqlite_io_error_pending $n } - malloc-persistent { sqlite3_memdebug_fail $n -repeat 1 } - malloc-transient { sqlite3_memdebug_fail $n -repeat 0 } - } - - catchsql $::sql_script - db close - - sqlite3async_control halt idle - sqlite3async_start - sqlite3async_wait - sqlite3async_control halt never - sqlite3async_shutdown - - set ::sqlite_io_error_pending 0 - sqlite3_memdebug_fail -1 - - sqlite3 db test.db - set c [db one {SELECT c FROM counter LIMIT 1}] - switch -- $c { - 1 { - do_test async-$err-1.1.$n { - execsql { - SELECT name FROM sqlite_master; - } - } {counter} - } - 2 { - do_test async-$err-1.2.$n.1 { - execsql { - SELECT * FROM t1; - } - } {} - do_test async-$err-1.2.$n.2 { - execsql { - SELECT * FROM t2; - } - } {} - } - 3 { - do_test async-$err-1.3.$n.1 { - execsql { - SELECT * FROM t1; - } - } {abcdefghij four score} - do_test async-$err-1.3.$n.2 { - execsql { - SELECT * FROM t2; - } - } {klmnopqrst and seven} - } - FIN { - incr ::go -1 - } - } - - db close - } -} - -catch {db close} - -finish_test diff --git a/test/async3.test b/test/async3.test deleted file mode 100644 index 9336b66058..0000000000 --- a/test/async3.test +++ /dev/null @@ -1,76 +0,0 @@ -# 2007 September 5 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# -# The focus of this file is testing the code in test_async.c. -# Specifically, it tests that the xFullPathname() method of -# of the asynchronous vfs works correctly. -# -# $Id: async3.test,v 1.5 2009/04/25 08:39:15 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if { [info commands sqlite3async_initialize]=="" } { - # The async logic is not built into this system - puts "Skipping async3 tests: not compiled with required features" - finish_test - return -} - -db close -sqlite3async_initialize "" 1 -#set sqlite3async_trace 1 -sqlite3async_start - -set paths { - chocolate/banana/vanilla/file.db - chocolate//banana/vanilla/file.db - chocolate/./banana//vanilla/file.db - chocolate/banana/./vanilla/file.db - chocolate/banana/../banana/vanilla/file.db - chocolate/banana/./vanilla/extra_bit/../file.db -} - -do_test async3-1.0 { - file mkdir [file join chocolate banana vanilla] - forcedelete chocolate/banana/vanilla/file.db - forcedelete chocolate/banana/vanilla/file.db-journal -} {} - -do_test async3-1.1 { - sqlite3 db chocolate/banana/vanilla/file.db - execsql { - CREATE TABLE abc(a, b, c); - BEGIN; - INSERT INTO abc VALUES(1, 2, 3); - } -} {} - -set N 2 -foreach p $paths { - sqlite3 db2 $p - do_test async3-1.$N.1 { - execsql {SELECT * FROM abc} db2 - } {} - do_test async3-1.$N.2 { - catchsql {INSERT INTO abc VALUES(4, 5, 6)} db2 - } {1 {database is locked}} - db2 close - incr N -} - -db close - -sqlite3async_control halt idle -sqlite3async_wait -sqlite3async_control halt never -sqlite3async_shutdown -finish_test diff --git a/test/async4.test b/test/async4.test deleted file mode 100644 index 92a820173e..0000000000 --- a/test/async4.test +++ /dev/null @@ -1,168 +0,0 @@ -# 2009 April 25 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# -# $Id: async4.test,v 1.4 2009/06/05 17:09:12 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Do not use a codec for tests in this file, as the database file is -# manipulated directly using tcl scripts (using the [hexio_write] command). -# -do_not_use_codec - -# These tests only work for Tcl version 8.5 and later on Windows (for now) -# -if {$tcl_platform(platform)=="windows"} { - scan $::tcl_version %f vx - if {$vx<8.5} { - finish_test - return - } -} - -if {[info commands sqlite3async_initialize] eq ""} { - # The async logic is not built into this system - finish_test - return -} -db close - -# Test layout: -# -# async4.1.*: Test the lockfiles parameter. -# async4.2.*: Test the delay parameter. - -do_test async4.1.1 { - sqlite3async_initialize {} 0 - sqlite3async_control lockfiles -} {1} -do_test async4.1.2 { - sqlite3async_control lockfiles false -} {0} -do_test async4.1.3 { - sqlite3async_control lockfiles -} {0} -do_test async4.1.4 { - sqlite3async_control lockfiles true -} {1} - -do_test async4.1.5 { - sqlite3 db test.db -vfs sqlite3async - execsql { CREATE TABLE t1(a, b, c) } -} {} -do_test async4.1.6 { - list [file exists test.db] [file size test.db] -} {1 0} -do_test async4.1.7 { - sqlite3 db2 test.db - catchsql { CREATE TABLE t2(a, b, c) } db2 -} {1 {database is locked}} -do_test async4.1.8 { - sqlite3async_control halt idle - sqlite3async_start - sqlite3async_wait -} {} -do_test async4.1.9 { - catchsql { CREATE TABLE t2(a, b, c) } db2 -} {0 {}} -do_test async4.1.10 { - list [catch {sqlite3async_control lockfiles false} msg] $msg -} {1 SQLITE_MISUSE} -do_test async4.1.11 { - db close - list [catch {sqlite3async_control lockfiles false} msg] $msg -} {1 SQLITE_MISUSE} -do_test async4.1.12 { - sqlite3async_start - sqlite3async_wait - sqlite3async_control lockfiles false -} {0} -do_test async4.1.13 { - sqlite3 db test.db -vfs sqlite3async - execsql { CREATE TABLE t3(a, b, c) } db -} {} -do_test async4.1.14 { - execsql { - CREATE INDEX i1 ON t2(a); - CREATE INDEX i2 ON t1(a); - } db2 -} {} -do_test async4.1.15 { - sqlite3async_start - sqlite3async_wait - hexio_write test.db 28 00000000 - execsql { pragma integrity_check } db2 -} {{*** in database main *** -Page 5 is never used}} -do_test async4.1.16 { - db close - db2 close - sqlite3async_start - sqlite3async_wait -} {} -do_test async4.1.17 { - sqlite3async_control lockfiles true -} {1} - -do_test async4.2.1 { - sqlite3async_control delay -} {0} -do_test async4.2.2 { - sqlite3async_control delay 23 -} {23} -do_test async4.2.3 { - sqlite3async_control delay -} {23} -do_test async4.2.4 { - sqlite3async_control delay 0 -} {0} -do_test async4.2.5 { - sqlite3 db test.db -vfs sqlite3async - - execsql { CREATE TABLE t4(a, b) } - set T1 [lindex [time { - sqlite3async_start - sqlite3async_wait - }] 0] - - sqlite3async_control delay 100 - execsql { CREATE TABLE t5(a, b) } - set T2 [lindex [time { - sqlite3async_start - sqlite3async_wait - }] 0] - - expr {($T1+1000000) < $T2} -} {1} - -do_test async4.2.6 { - sqlite3async_control delay 0 - execsql { CREATE TABLE t6(a, b) } - set T1 [lindex [time { - sqlite3async_start - sqlite3async_wait - }] 0] - - expr {($T1+1000000) < $T2} -} {1} - -do_test async4.2.7 { - list [catch { sqlite3async_control delay -1 } msg] $msg -} {1 SQLITE_MISUSE} - -do_test async4.2.8 { - db close - sqlite3async_start - sqlite3async_wait -} {} - -finish_test diff --git a/test/async5.test b/test/async5.test deleted file mode 100644 index abac11f750..0000000000 --- a/test/async5.test +++ /dev/null @@ -1,68 +0,0 @@ -# 2009 July 19 -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file tests that asynchronous IO is compatible with multi-file -# transactions. -# -# $Id: async5.test,v 1.1 2009/07/18 11:52:04 danielk1977 Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if {[info commands sqlite3async_initialize] eq ""} { - # The async logic is not built into this system - finish_test - return -} - -db close -forcedelete test2.db -sqlite3async_initialize "" 1 -sqlite3async_control halt never -sqlite3 db test.db - -do_test async5-1.1 { - execsql { - ATTACH 'test2.db' AS next; - CREATE TABLE main.t1(a, b); - CREATE TABLE next.t2(a, b); - BEGIN; - INSERT INTO t1 VALUES(1, 2); - INSERT INTO t2 VALUES(3, 4); - COMMIT; - } -} {} -do_test async5-1.2 { - execsql { SELECT * FROM t1 } -} {1 2} -do_test async5-1.3 { - execsql { SELECT * FROM t2 } -} {3 4} -do_test async5-1.4 { - execsql { - BEGIN; - INSERT INTO t1 VALUES('a', 'b'); - INSERT INTO t2 VALUES('c', 'd'); - COMMIT; - } -} {} -do_test async5-1.5 { - execsql { SELECT * FROM t1 } -} {1 2 a b} -do_test async5-1.6 { - execsql { SELECT * FROM t2 } -} {3 4 c d} - -db close - -sqlite3async_control halt idle -sqlite3async_start -sqlite3async_wait -sqlite3async_control halt never -sqlite3async_shutdown -set sqlite3async_trace 0 -finish_test diff --git a/test/lock.test b/test/lock.test index 534aa3b9a4..cacb6d3ff1 100644 --- a/test/lock.test +++ b/test/lock.test @@ -21,7 +21,7 @@ source $testdir/tester.tcl # do_test lock-1.0 { # Give a complex pathname to stress the path simplification logic in - # the vxworks driver and in test_async. + # the vxworks driver. file mkdir tempdir/t1/t2 sqlite3 db2 ./tempdir/../tempdir/t1/.//t2/../../..//test.db set dummy {} diff --git a/test/main.test b/test/main.test index cdf9fb99e0..556a8bdfcc 100644 --- a/test/main.test +++ b/test/main.test @@ -472,49 +472,6 @@ do_test main-3.6 { catchsql {SELECT 'abc' + #9} } {1 {near "#9": syntax error}} -# The following test-case tests the linked list code used to manage -# sqlite3_vfs structures. -if {$::tcl_platform(platform)=="unix" - && [info command sqlite3async_initialize]!=""} { - ifcapable threadsafe { - do_test main-4.1 { - sqlite3_crash_enable 1 - sqlite3_crash_enable 0 - - sqlite3async_initialize "" 1 - sqlite3async_shutdown - - sqlite3_crash_enable 1 - sqlite3async_initialize "" 1 - sqlite3_crash_enable 0 - sqlite3async_shutdown - - sqlite3_crash_enable 1 - sqlite3async_initialize "" 1 - sqlite3async_shutdown - sqlite3_crash_enable 0 - - sqlite3async_initialize "" 1 - sqlite3_crash_enable 1 - sqlite3_crash_enable 0 - sqlite3async_shutdown - - sqlite3async_initialize "" 1 - sqlite3_crash_enable 1 - sqlite3async_shutdown - sqlite3_crash_enable 0 - } {} - do_test main-4.2 { - set rc [catch {sqlite3 db test.db -vfs crash} msg] - list $rc $msg - } {1 {no such vfs: crash}} - do_test main-4.3 { - set rc [catch {sqlite3 db test.db -vfs async} msg] - list $rc $msg - } {1 {no such vfs: async}} - } -} - # Print the version number so that it can be picked up by releasetest.tcl. # puts [db one {SELECT 'VERSION: ' || diff --git a/test/memleak.test b/test/memleak.test index a24a901f50..8443162ed6 100644 --- a/test/memleak.test +++ b/test/memleak.test @@ -38,8 +38,6 @@ set EXCLUDE { misuse.test memleak.test btree2.test - async.test - async2.test trans.test crash.test autovacuum_crash.test diff --git a/test/permutations.test b/test/permutations.test index c26d6ead14..5bbef184c7 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -108,14 +108,14 @@ if {$::tcl_platform(platform)!="unix"} { set alltests [test_set $alltests -exclude crash.test crash2.test] } set alltests [test_set $alltests -exclude { - all.test async.test quick.test veryquick.test + all.test quick.test veryquick.test memleak.test permutations.test soak.test fts3.test mallocAll.test rtree.test full.test extraquick.test session.test rbu.test }] set allquicktests [test_set $alltests -exclude { - async2.test async3.test backup_ioerr.test corrupt.test + backup_ioerr.test corrupt.test corruptC.test crash.test crash2.test crash3.test crash4.test crash5.test crash6.test crash7.test delete3.test e_fts3.test fts3rnd.test fkey_malloc.test fuzz.test fuzz3.test fuzz_malloc.test in2.test loadext.test @@ -790,7 +790,7 @@ test_suite "inmemory_journal" -description { journal3.test 8_3_names.test shmlock.test pendingrace.test - pager1.test async4.test corrupt.test filefmt.test pager2.test + pager1.test corrupt.test filefmt.test pager2.test corrupt5.test corruptA.test pageropt.test # Exclude stmt.test, which expects sub-journals to use temporary files. @@ -951,12 +951,11 @@ test_suite "safe_append" -description { set ::G(perm:sqlite3_args) [list -vfs devsym] sqlite3_simulate_device -char safe_append } -files [ - test_set $::allquicktests shared_err.test -exclude async3.test + test_set $::allquicktests shared_err.test ] # The set of tests to run on the alternative-pcache set perm-alt-pcache-testset { - async.test attach.test delete.test delete2.test index.test @@ -997,7 +996,7 @@ test_suite "journaltest" -description { unregister_jt_vfs } -files [test_set $::allquicktests -exclude { wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test - async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test + bigfile.test backcompat.test e_wal* fstat.test mmap2.test pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock* pager2.test *fault* rowal* snapshot* superlock* symlink.test delete_db.test shmlock.test chunksize.test diff --git a/test/tkt-94c04eaadb.test b/test/tkt-94c04eaadb.test deleted file mode 100644 index 9de8aea28d..0000000000 --- a/test/tkt-94c04eaadb.test +++ /dev/null @@ -1,72 +0,0 @@ -# 2009 October 19 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# This file implements regression tests for SQLite library. -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -if {[info commands sqlite3async_initialize] eq ""} { - # The async logic is not built into this system - finish_test - return -} - -# Create a database. -do_test tkt-94c94-1.1 { - execsql { CREATE TABLE t1(a, b) } -} {} - -# Grow the file to larger than 4096MB (2^32 bytes) -db close -if {[catch {fake_big_file 4096 [get_pwd]/test.db} msg]} { - puts "**** Unable to create a file larger than 4096 MB. *****" - finish_test - return -} - -# Switch to async mode. -sqlite3async_initialize "" 1 -sqlite3 db test.db -sqlite3 db2 test.db - -# Read from and write to the db just past the 4096MB mark. -# -do_test tkt-94c94-2.1 { - execsql { CREATE TABLE t2(x, y) } db -} {} -do_test tkt-94c94-2.2 { - execsql { INSERT INTO t2 VALUES(1, 2) } db2 -} {} -do_test tkt-94c94-2.3 { - execsql { SELECT * FROM t2 } db -} {1 2} -do_test tkt-94c94-2.4 { - sqlite3async_control halt idle - sqlite3async_start - sqlite3async_wait -} {} -do_test tkt-94c94-2.5 { - execsql { SELECT * FROM t2 } db -} {1 2} -do_test tkt-94c94-2.6 { - sqlite3async_start - sqlite3async_wait -} {} - -db close -db2 close -sqlite3async_start -sqlite3async_wait -sqlite3async_control halt never -sqlite3async_shutdown - -finish_test From 19afe7ffd1e3c3f9014d6c10807ee5d5c6de9969 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 28 Oct 2024 16:28:43 +0000 Subject: [PATCH 204/522] Have sqlite3_rsync avoid write-locking the origin database. FossilOrigin-Name: b7eb6530505bf774cf3fa5de6ec4bc40f217796d4fa9a149372bd47488ed470f --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/sqlite3_rsync.c | 19 +++++++++++++++++-- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 383228d3e0..7c4ef8d307 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sext/consio\sfrom\sthe\stree.\s\sNo\slonger\sneeded\sor\ssupported. -D 2024-10-28T14:53:45.379 +C Have\ssqlite3_rsync\savoid\swrite-locking\sthe\sorigin\sdatabase. +D 2024-10-28T16:28:43.849 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -2196,7 +2196,7 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b F tool/sqlite3_analyzer.c.in 348ba349bbdc93c9866439f9f935d7284866a2a4e6898bc906ae1204ade56918 -F tool/sqlite3_rsync.c 6c9cac5a9197f591985b271aeff803ec4fb4db36c8eab97e1331ff64aa1b8d94 +F tool/sqlite3_rsync.c 9a1cca2ab1271c59b37a6493c15dc1bcd0ab9149197a9125926bc08dd26b83fb F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c d00f93263aa2fa6ba0cba0106d95458e6effb94fdb5fc634f56834f90c05bbb4 @@ -2214,8 +2214,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6cb7cb7e33835d42cbab2e5468d73de7bb3b01971da078ce1c1344edc11ab1b3 -R 00f0377d2b4f46d55243305df3135edf -U drh -Z 05dc840cebf23762b49de298db68f9dc +P 1ce8507f732a26508a9b336cb27756a0a8638e14395efdd59b5faef40526ede5 +R 49f8f2fbecb9d9f2f7002e9a5c677568 +U dan +Z a23c9b99fd9fb556a69898d6ec82974f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1592140732..99fb8586fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ce8507f732a26508a9b336cb27756a0a8638e14395efdd59b5faef40526ede5 +b7eb6530505bf774cf3fa5de6ec4bc40f217796d4fa9a149372bd47488ed470f diff --git a/tool/sqlite3_rsync.c b/tool/sqlite3_rsync.c index 7a453b6cc3..01dcbed050 100644 --- a/tool/sqlite3_rsync.c +++ b/tool/sqlite3_rsync.c @@ -1217,6 +1217,7 @@ static void originSide(SQLiteRsync *p){ unsigned int lockBytePage = 0; unsigned int szPg = 0; sqlite3_stmt *pCkHash = 0; + sqlite3_stmt *pInsHash = 0; char buf[200]; p->isReplica = 0; @@ -1281,10 +1282,12 @@ static void originSide(SQLiteRsync *p){ if( pCkHash==0 ){ runSql(p, "CREATE TEMP TABLE badHash(pgno INTEGER PRIMARY KEY)"); pCkHash = prepareStmt(p, - "INSERT INTO badHash SELECT pgno FROM sqlite_dbpage('main')" + "SELECT pgno FROM sqlite_dbpage('main')" " WHERE pgno=?1 AND hash(data)!=?2" ); if( pCkHash==0 ) break; + pInsHash = prepareStmt(p, "INSERT INTO badHash VALUES(?)"); + if( pInsHash==0 ) break; } p->nHashSent++; iPage++; @@ -1292,7 +1295,16 @@ static void originSide(SQLiteRsync *p){ readBytes(p, 20, buf); sqlite3_bind_blob(pCkHash, 2, buf, 20, SQLITE_STATIC); rc = sqlite3_step(pCkHash); - if( rc!=SQLITE_DONE ){ + if( rc==SQLITE_ROW ){ + sqlite3_bind_int64(pInsHash, 1, sqlite3_column_int64(pCkHash, 0)); + rc = sqlite3_step(pInsHash); + if( rc!=SQLITE_DONE ){ + reportError(p, "SQL statement [%s] failed: %s", + sqlite3_sql(pInsHash), sqlite3_errmsg(p->db)); + } + sqlite3_reset(pInsHash); + } + else if( rc!=SQLITE_DONE ){ reportError(p, "SQL statement [%s] failed: %s", sqlite3_sql(pCkHash), sqlite3_errmsg(p->db)); } @@ -1302,7 +1314,9 @@ static void originSide(SQLiteRsync *p){ case REPLICA_READY: { sqlite3_stmt *pStmt; sqlite3_finalize(pCkHash); + sqlite3_finalize(pInsHash); pCkHash = 0; + pInsHash = 0; if( iPage+1nPage ){ runSql(p, "WITH RECURSIVE c(n) AS" " (VALUES(%d) UNION ALL SELECT n+1 FROM c WHERE n<%d)" @@ -1338,6 +1352,7 @@ static void originSide(SQLiteRsync *p){ } if( pCkHash ) sqlite3_finalize(pCkHash); + if( pInsHash ) sqlite3_finalize(pInsHash); closeDb(p); } From fe5602ffd9d1f7fb6d05047b9065b3fe52218cca Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 17:20:18 +0000 Subject: [PATCH 205/522] Perform some makefile acrobatics to get the tclConfig.sh state applied for static makefiles. FossilOrigin-Name: 9b141d108b64c8f4e1103de6f142d972b5151eed0f07988fea308fc71cec45b8 --- Makefile.in | 15 ++++--- autosetup/proj.tcl | 2 + main.mk | 82 +++++++++++++++++++++++++++------------ manifest | 20 +++++----- manifest.uuid | 2 +- tool/tclConfigShToMake.sh | 31 +++++++++++++++ 6 files changed, 110 insertions(+), 42 deletions(-) create mode 100755 tool/tclConfigShToMake.sh diff --git a/Makefile.in b/Makefile.in index 67cc9ac453..688b3ff062 100644 --- a/Makefile.in +++ b/Makefile.in @@ -202,12 +202,15 @@ TCL_CONFIG_SH = @TCL_CONFIG_SH@ # # TCL config info from tclConfig.sh # -TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ -TCL_LIB_SPEC = @TCL_LIB_SPEC@ -TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ -TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@ -TCL_VERSION = @TCL_VERSION@ -TCLLIB_RPATH = @TCLLIB_RPATH@ +# We have to inject this differently in main.mk to accommodate static +# makefiles: +# +#TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +#TCL_LIB_SPEC = @TCL_LIB_SPEC@ +#TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +#TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@ +#TCL_VERSION = @TCL_VERSION@ +#TCLLIB_RPATH = @TCLLIB_RPATH@ # # Where do we want to install the tcl plugin # diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 5fdf94d2d2..0b1613430c 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -804,6 +804,8 @@ proc proj-check-rpath {} { cc-with {} { if {[cc-check-flags "-rpath $lp"]} { define LDFLAGS_RPATH "-rpath $lp" + } elseif {[cc-check-flags "-Wl,-rpath,$lp"]} { + define LDFLAGS_RPATH "-Wl,-rpath,$lp" } elseif {[cc-check-flags "-Wl,-rpath -Wl,$lp"]} { define LDFLAGS_RPATH "-Wl,-rpath -Wl,$lp" } elseif {[cc-check-flags -Wl,-R$lp]} { diff --git a/main.mk b/main.mk index 3469381bd6..3d23215a44 100644 --- a/main.mk +++ b/main.mk @@ -212,17 +212,14 @@ OPT_FEATURE_FLAGS ?= # SHELL_OPT ?= # -# The following TCL_vars come from tclConfig.sh +# TCL_CONFIG_SH must, for some of the build targets, refer to a valid +# tclConfig.sh. That script will be used to populate most of the other +# TCL-related vars the build needs, the one exception being: # -# Potential TODO: a shell script, similar tool/tclConfigShToTcl.sh, -# which emits these vars in a format which we can include from this -# makefile. +# TCLLIBDIR is required for installing (but not building) the TCL +# deliverables. It must currently be set by the makefile which +# imports this one or as an argument to it from the user. # -TCL_INCLUDE_SPEC ?= -TCL_LIB_SPEC ?= -TCL_STUB_LIB_SPEC ?= -TCL_EXEC_PREFIX ?= -TCL_VERSION ?= TCLLIBDIR ?= TCL_CONFIG_SH ?= # @@ -911,6 +908,36 @@ has_tclsh85: sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) touch has_tclsh85 +# +# .tclconfig.make has the config info from tclConfig.sh, but in +# makefile form. If TCL_CONFIG_SH is empty then it will emit +# empty config state (which is harmless). +# +# Alas, it turns out that POSIX make cannot both generate a makefile +# and import it in the same make invocation (GNU make can), so this +# approach, while simple to implement and non-intrusive on the targets +# which require the config state, is not portable. +# +# An alternative is $(SOURCE_TCLCONFIG), defined below, but this impl +# is retained as a reminder of why we cannot portably use this +# otherwise trivial approach. +# +#.tclconfig.make: +# sh $(TOP)/tool/tclConfigShToMake.sh $(TCL_CONFIG_SH) > .tclconfig.make +#distclean-tclconfig: +# rm -f .tclconfig.make +#distclean: distclean-tclconfig +#-include .tclconfig.make + +# +# SOURCE_TCLCONFIG is shell code to be run as part of any compilation +# or link step which requires vars from $(TCL_CONFIG_SH). All targets +# which use this should also have a dependency on has_tclconfig. +# +SOURCE_TCLCONFIG = . $(TCL_CONFIG_SH) || exit $$? +T.compile.tcl = $(SOURCE_TCLCONFIG); $(T.compile) +T.link.tcl = $(SOURCE_TCLCONFIG); $(T.link) + has_tclconfig: @if [ x = "x$(TCL_CONFIG_SH)" ]; then \ echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ @@ -1230,19 +1257,19 @@ whereexpr.o: $(TOP)/src/whereexpr.c $(DEPS_OBJ_COMMON) window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON) $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/window.c -tclsqlite.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(T.compile) -DUSE_TCL_STUBS=1 $(TCL_INCLUDE_SPEC) $(CFLAGS.intree_includes) \ +tclsqlite.o: has_tclconfig $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) + $(T.compile.tcl) -DUSE_TCL_STUBS=1 $$TCL_INCLUDE_SPEC $(CFLAGS.intree_includes) \ -c $(TOP)/src/tclsqlite.c -tclsqlite-shell.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(T.compile) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) +tclsqlite-shell.o: has_tclconfig $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) + $(T.compile.tcl) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c $$TCL_INCLUDE_SPEC -tclsqlite-stubs.o: $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(T.compile) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c $(TCL_INCLUDE_SPEC) +tclsqlite-stubs.o: has_tclconfig $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) + $(T.compile.tcl) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c $$TCL_INCLUDE_SPEC tclsqlite3$(T.exe): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) - $(T.link) -o $@ tclsqlite-shell.o \ - $(libsqlite3.LIB) $(TCL_INCLUDE_SPEC) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) + $(T.link.tcl) -o $@ tclsqlite-shell.o \ + $(libsqlite3.LIB) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) # Rules to build opcodes.c and opcodes.h # @@ -1378,10 +1405,15 @@ install: install-includes pkgIndex.tcl: echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(T.dll) -$(libtclsqlite3.SO): tclsqlite.o $(libsqlite3.SO) +$(libtclsqlite3.SO): has_tclconfig tclsqlite.o $(libsqlite3.SO) + libdir=`echo "puts stdout [lindex \\$$auto_path 0]" | $(TCLSH_CMD)` || exit $$?; \ + $(SOURCE_TCLCONFIG); \ $(T.link.shared) -o $@ tclsqlite.o \ - $(TCL_INCLUDE_SPEC) $(TCL_STUB_LIB_SPEC) $(LDFLAGS.libsqlite3) \ - $(libsqlite3.SO) $(TCLLIB_RPATH) + $$TCL_INCLUDE_SPEC $$TCL_STUB_LIB_SPEC $(LDFLAGS.libsqlite3) \ + $(libsqlite3.SO) -Wl,-rpath,$$libdir/sqlite3 +# ^^^ that rpath bit is defined as TCL_LD_SEARCH_FLAGS in +# tclConfig.sh, but it's defined in such a way as to be useless for a +# _static_ makefile. $(libtclsqlite3.SO)-1: $(libtclsqlite3.SO) $(libtclsqlite3.SO)-0 $(libtclsqlite3.SO)-: libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL) @@ -1497,9 +1529,9 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) testfixture$(T.exe): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) - $(T.link) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ + $(T.link.tcl) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -o $@ $(TESTFIXTURE_SRC) \ - $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) \ + $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC \ $(CFLAGS.libsqlite3) $(LDFLAGS.libsqlite3) coretestprogs: testfixture$(B.exe) sqlite3$(B.exe) @@ -1617,7 +1649,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(T.exe): has_tclconfig sqlite3_analyzer.c - $(T.link) sqlite3_analyzer.c -o $@ $(TCL_LIB_SPEC) $(TCL_INCLUDE_SPEC) $(LDFLAGS.libsqlite3) + $(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC $(LDFLAGS.libsqlite3) sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl \ @@ -1625,7 +1657,7 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(T.exe): has_tclconfig sqltclsh.c - $(T.link) sqltclsh.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS.libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) + $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. xbin: sqltclsh$(T.exe) @@ -1650,7 +1682,7 @@ sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ sqlite3_checker$(T.exe): has_tclconfig sqlite3_checker.c - $(T.link) sqlite3_checker.c -o $@ $(TCL_INCLUDE_SPEC) $(CFLAGS.libsqlite3) $(TCL_LIB_SPEC) $(LDFLAGS.libsqlite3) + $(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) xbin: sqlite3_checker$(T.exe) dbdump$(T.exe): $(TOP)/ext/misc/dbdump.c sqlite3.o diff --git a/manifest b/manifest index a4e0015ad0..0f5b18c42a 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C The\sasync\sextension\swas\ssuperseded\sby\sWAL\smode\sabout\s11\syears\sago,\sand\shas\nlong\sbeen\sdeprecated.\s\sRemove\sit\sfrom\sthe\ssource\stree.\s\s(Anybody\swho\sreally\nneeds\sit\scan\sstill\sdig\sit\sout\sof\sthe\shistorical\srecords.) -D 2024-10-28T16:31:20.697 +C Perform\ssome\smakefile\sacrobatics\sto\sget\sthe\stclConfig.sh\sstate\sapplied\sfor\sstatic\smakefiles. +D 2024-10-28T17:20:18.788 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 -F Makefile.in 02ea00ff433902dba369d4a55b3aeb6bb1ffe2d82f777194984b8cdd7ed7c3ad +F Makefile.in e4a6a12767fd297b5359ca4190141ec6f925e64dd8d5a1067a220e41b7dbf7a8 F Makefile.linux-generic 69b54c58ab2424a0d30f340d9defd7e87c25690a55b77acb9bdc657bd9a223f1 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl b01940e6b2e9c24f2c50f0e180d308a0a4f88d2e2b00c6902edd5980d221becf +F autosetup/proj.tcl 8167786ff3c20d6a14e9b0b747996e91cabfe85ac49dcc5d0a0aa35d4167dd91 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -702,7 +702,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk c5e17513c0f68b514d0f1b5afabcc0aabfedf8ebba0e6314435df1edcb7e8fd4 +F main.mk e9ff755b0d6f2ab6a95fab7bb11f742485de6ad1606822932d24bbfa14a9884a F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2196,6 +2196,7 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9 +F tool/tclConfigShToMake.sh 7c065d81c2d178e15e45a77372c6e5a38b5a1b08755301cd6f20a3a862db7312 x F tool/tclConfigShToTcl.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl fa2f37ab39b2a0087fafb6a7f3ce19503e25e624ffa8ed9951717ab72920c088 @@ -2204,9 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b7eb6530505bf774cf3fa5de6ec4bc40f217796d4fa9a149372bd47488ed470f 10b1b86821bfc21377e7ccceb31146ab01aa6eaf418b85a204abcab5b793958e -R c0dab2d05721f7a4961535e333dd9173 -T +closed 10b1b86821bfc21377e7ccceb31146ab01aa6eaf418b85a204abcab5b793958e -U drh -Z 5e2ff8c2159e64c6bedc8f4dcf3a85b5 +P f98da150a9c18dfaf9d5178ceee227caf7fce9c9c9194a7a4291abb40de832fa +R e203eb86dfdd2daea7dd35f993a3ed58 +U stephan +Z ba3f561a89835f0184bfa691acd0be76 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e4336995a5..41798faaa6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f98da150a9c18dfaf9d5178ceee227caf7fce9c9c9194a7a4291abb40de832fa +9b141d108b64c8f4e1103de6f142d972b5151eed0f07988fea308fc71cec45b8 diff --git a/tool/tclConfigShToMake.sh b/tool/tclConfigShToMake.sh new file mode 100755 index 0000000000..89ca15ad5b --- /dev/null +++ b/tool/tclConfigShToMake.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# A level of indirection for use soley by main.mk to extract info +# from tclConfig.sh if it's not provided by the configure script. +# +# Expects to be passed a full path to a tclConfig.sh. It sources it +# and emits TCL code which sets some vars which are exported by +# tclConfig.sh. +# +# This script expects that the caller has already validated that the +# file exists, is not a directory, and is readable. +# +# If passed no filename, or an empty one, then it emits config code +# suitable for the "config not found" case. +if test x = "x$1"; then + TCL_INCLUDE_SPEC= + TCL_LIB_SPEC= + TCL_STUB_LIB_SPEC= + TCL_EXEC_PREFIX= + TCL_VERSION= +else + . "$1" +fi + +cat < Date: Mon, 28 Oct 2024 17:27:15 +0000 Subject: [PATCH 206/522] Remove the never-used and never-documented and long-ago deprecated user-authentication feature option. FossilOrigin-Name: 3a3f7bf4307c27e56546e51da06ecc9a262cdf155fda2dd359aa2326d207a147 --- ext/userauth/sqlite3userauth.h | 96 --------- ext/userauth/user-auth.txt | 176 ---------------- ext/userauth/userauth.c | 355 --------------------------------- main.mk | 13 +- manifest | 44 ++-- manifest.uuid | 2 +- src/attach.c | 9 - src/auth.c | 12 +- src/build.c | 31 --- src/ctime.c | 3 - src/func.c | 3 - src/main.c | 4 - src/pragma.c | 6 - src/shell.c.in | 66 ------ src/sqliteInt.h | 43 +--- src/tclsqlite.c | 6 - src/test1.c | 131 ------------ src/test_config.c | 6 - test/userauth01.test | 257 ------------------------ tool/mkctimec.tcl | 1 - 20 files changed, 27 insertions(+), 1237 deletions(-) delete mode 100644 ext/userauth/sqlite3userauth.h delete mode 100644 ext/userauth/user-auth.txt delete mode 100644 ext/userauth/userauth.c delete mode 100644 test/userauth01.test diff --git a/ext/userauth/sqlite3userauth.h b/ext/userauth/sqlite3userauth.h deleted file mode 100644 index c7d23b9399..0000000000 --- a/ext/userauth/sqlite3userauth.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -** 2014-09-08 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains the application interface definitions for the -** user-authentication extension feature. -** -** To compile with the user-authentication feature, append this file to -** end of an SQLite amalgamation header file ("sqlite3.h"), then add -** the SQLITE_USER_AUTHENTICATION compile-time option. See the -** user-auth.txt file in the same source directory as this file for -** additional information. -*/ -#ifdef SQLITE_USER_AUTHENTICATION - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** If a database contains the SQLITE_USER table, then the -** sqlite3_user_authenticate() interface must be invoked with an -** appropriate username and password prior to enable read and write -** access to the database. -** -** Return SQLITE_OK on success or SQLITE_ERROR if the username/password -** combination is incorrect or unknown. -** -** If the SQLITE_USER table is not present in the database file, then -** this interface is a harmless no-op returnning SQLITE_OK. -*/ -int sqlite3_user_authenticate( - sqlite3 *db, /* The database connection */ - const char *zUsername, /* Username */ - const char *aPW, /* Password or credentials */ - int nPW /* Number of bytes in aPW[] */ -); - -/* -** The sqlite3_user_add() interface can be used (by an admin user only) -** to create a new user. When called on a no-authentication-required -** database, this routine converts the database into an authentication- -** required database, automatically makes the added user an -** administrator, and logs in the current connection as that user. -** The sqlite3_user_add() interface only works for the "main" database, not -** for any ATTACH-ed databases. Any call to sqlite3_user_add() by a -** non-admin user results in an error. -*/ -int sqlite3_user_add( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to be added */ - const char *aPW, /* Password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* True to give new user admin privilege */ -); - -/* -** The sqlite3_user_change() interface can be used to change a users -** login credentials or admin privilege. Any user can change their own -** login credentials. Only an admin user can change another users login -** credentials or admin privilege setting. No user may change their own -** admin privilege setting. -*/ -int sqlite3_user_change( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to change */ - const char *aPW, /* New password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* Modified admin privilege for the user */ -); - -/* -** The sqlite3_user_delete() interface can be used (by an admin user only) -** to delete a user. The currently logged-in user cannot be deleted, -** which guarantees that there is always an admin user and hence that -** the database cannot be converted into a no-authentication-required -** database. -*/ -int sqlite3_user_delete( - sqlite3 *db, /* Database connection */ - const char *zUsername /* Username to remove */ -); - -#ifdef __cplusplus -} /* end of the 'extern "C"' block */ -#endif - -#endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/ext/userauth/user-auth.txt b/ext/userauth/user-auth.txt deleted file mode 100644 index 9d6ba23336..0000000000 --- a/ext/userauth/user-auth.txt +++ /dev/null @@ -1,176 +0,0 @@ -*********************************** NOTICE ************************************ -* This extension is deprecated. The SQLite developers do not maintain this * -* extension. At some point in the future, it might disappear from the source * -* tree. * -* * -* If you are using this extension and think it should be supported moving * -* forward, visit the SQLite Forum (https://sqlite.org/forum) and argue your * -* case there. * -* * -* This deprecation notice was added on 2024-01-22. * -******************************************************************************* - -Activate the user authentication logic by including the -ext/userauth/userauth.c source code file in the build and -adding the -DSQLITE_USER_AUTHENTICATION compile-time option. -The ext/userauth/sqlite3userauth.h header file is available to -applications to define the interface. - -When using the SQLite amalgamation, it is sufficient to append -the ext/userauth/userauth.c source file onto the end of the -amalgamation. - -The following new APIs are available when user authentication is -activated: - - int sqlite3_user_authenticate( - sqlite3 *db, /* The database connection */ - const char *zUsername, /* Username */ - const char *aPW, /* Password or credentials */ - int nPW /* Number of bytes in aPW[] */ - ); - - int sqlite3_user_add( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to be added */ - const char *aPW, /* Password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* True to give new user admin privilege */ - ); - - int sqlite3_user_change( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to change */ - const void *aPW, /* Modified password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* Modified admin privilege for the user */ - ); - - int sqlite3_user_delete( - sqlite3 *db, /* Database connection */ - const char *zUsername /* Username to remove */ - ); - -With this extension, a database can be marked as requiring authentication. -By default a database does not require authentication. - -The sqlite3_open(), sqlite3_open16(), and sqlite3_open_v2() interfaces -work as before: they open a new database connection. However, if the -database being opened requires authentication, then attempts to read -or write from the database will fail with an SQLITE_AUTH error until -after sqlite3_user_authenticate() has been called successfully. The -sqlite3_user_authenticate() call will return SQLITE_OK if the -authentication credentials are accepted and SQLITE_ERROR if not. - -Calling sqlite3_user_authenticate() on a no-authentication-required -database connection is a harmless no-op. - -If the database is encrypted, then sqlite3_key_v2() must be called first, -with the correct decryption key, prior to invoking sqlite3_user_authenticate(). - -To recapitulate: When opening an existing unencrypted authentication- -required database, the call sequence is: - - sqlite3_open_v2() - sqlite3_user_authenticate(); - /* Database is now usable */ - -To open an existing, encrypted, authentication-required database, the -call sequence is: - - sqlite3_open_v2(); - sqlite3_key_v2(); - sqlite3_user_authenticate(); - /* Database is now usable */ - -When opening a no-authentication-required database, the database -connection is treated as if it was authenticated as an admin user. - -When ATTACH-ing new database files to a connection, each newly attached -database that is an authentication-required database is checked using -the same username and password as supplied to the main database. If that -check fails, then the ATTACH command fails with an SQLITE_AUTH error. - -The sqlite3_user_add() interface can be used (by an admin user only) -to create a new user. When called on a no-authentication-required -database and when A is true, the sqlite3_user_add(D,U,P,N,A) routine -converts the database into an authentication-required database and -logs in the database connection D as user U with password P,N. -To convert a no-authentication-required database into an authentication- -required database, the isAdmin parameter must be true. If -sqlite3_user_add(D,U,P,N,A) is called on a no-authentication-required -database and A is false, then the call fails with an SQLITE_AUTH error. - -Any call to sqlite3_user_add() by a non-admin user results in an error. - -Hence, to create a new, unencrypted, authentication-required database, -the call sequence is: - - sqlite3_open_v2(); - sqlite3_user_add(); - -And to create a new, encrypted, authentication-required database, the call -sequence is: - - sqlite3_open_v2(); - sqlite3_key_v2(); - sqlite3_user_add(); - -The sqlite3_user_delete() interface can be used (by an admin user only) -to delete a user. The currently logged-in user cannot be deleted, -which guarantees that there is always an admin user and hence that -the database cannot be converted into a no-authentication-required -database. - -The sqlite3_user_change() interface can be used to change a users -login credentials or admin privilege. Any user can change their own -password. Only an admin user can change another users login -credentials or admin privilege setting. No user may change their own -admin privilege setting. - -The sqlite3_set_authorizer() callback is modified to take a 7th parameter -which is the username of the currently logged in user, or NULL for a -no-authentication-required database. - ------------------------------------------------------------------------------ -Implementation notes: - -An authentication-required database is identified by the presence of a -new table: - - CREATE TABLE sqlite_user( - uname TEXT PRIMARY KEY, - isAdmin BOOLEAN, - pw BLOB - ) WITHOUT ROWID; - -The sqlite_user table is inaccessible (unreadable and unwriteable) to -non-admin users and is read-only for admin users. However, if the same -database file is opened by a version of SQLite that omits -the -DSQLITE_USER_AUTHENTICATION compile-time option, then the sqlite_user -table will be readable by anybody and writeable by anybody if -the "PRAGMA writable_schema=ON" statement is run first. - -The sqlite_user.pw field is encoded by a built-in SQL function -"sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument -is the plaintext password supplied to the sqlite3_user_authenticate() -interface. The second argument is the sqlite_user.pw value and is supplied -so that the function can extract the "salt" used by the password encoder. -The result of sqlite_crypt(X,Y) is another blob which is the value that -ends up being stored in sqlite_user.pw. To verify credentials X supplied -by the sqlite3_user_authenticate() routine, SQLite runs: - - sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw) - -To compute an appropriate sqlite_user.pw value from a new or modified -password X, sqlite_crypt(X,NULL) is run. A new random salt is selected -when the second argument is NULL. - -The built-in version of of sqlite_crypt() uses a simple Ceasar-cypher -which prevents passwords from being revealed by searching the raw database -for ASCII text, but is otherwise trivally broken. For better password -security, the database should be encrypted using the SQLite Encryption -Extension or similar technology. Or, the application can use the -sqlite3_create_function() interface to provide an alternative -implementation of sqlite_crypt() that computes a stronger password hash, -perhaps using a cryptographic hash function like SHA1. diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c deleted file mode 100644 index fa708516ee..0000000000 --- a/ext/userauth/userauth.c +++ /dev/null @@ -1,355 +0,0 @@ -/* -** 2014-09-08 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains the bulk of the implementation of the -** user-authentication extension feature. Some parts of the user- -** authentication code are contained within the SQLite core (in the -** src/ subdirectory of the main source code tree) but those parts -** that could reasonable be separated out are moved into this file. -** -** To compile with the user-authentication feature, append this file to -** end of an SQLite amalgamation, then add the SQLITE_USER_AUTHENTICATION -** compile-time option. See the user-auth.txt file in the same source -** directory as this file for additional information. -*/ -#ifdef SQLITE_USER_AUTHENTICATION -#ifndef SQLITEINT_H -# include "sqliteInt.h" -#endif - -/* -** Prepare an SQL statement for use by the user authentication logic. -** Return a pointer to the prepared statement on success. Return a -** NULL pointer if there is an error of any kind. -*/ -static sqlite3_stmt *sqlite3UserAuthPrepare( - sqlite3 *db, - const char *zFormat, - ... -){ - sqlite3_stmt *pStmt; - char *zSql; - int rc; - va_list ap; - u64 savedFlags = db->flags; - - va_start(ap, zFormat); - zSql = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - if( zSql==0 ) return 0; - db->flags |= SQLITE_WriteSchema; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - db->flags = savedFlags; - sqlite3_free(zSql); - if( rc ){ - sqlite3_finalize(pStmt); - pStmt = 0; - } - return pStmt; -} - -/* -** Check to see if the sqlite_user table exists in database zDb. -*/ -static int userTableExists(sqlite3 *db, const char *zDb){ - int rc; - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); - if( db->init.busy==0 ){ - char *zErr = 0; - sqlite3Init(db, &zErr); - sqlite3DbFree(db, zErr); - } - rc = sqlite3FindTable(db, "sqlite_user", zDb)!=0; - sqlite3BtreeLeaveAll(db); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Check to see if database zDb has a "sqlite_user" table and if it does -** whether that table can authenticate zUser with nPw,zPw. Write one of -** the UAUTH_* user authorization level codes into *peAuth and return a -** result code. -*/ -static int userAuthCheckLogin( - sqlite3 *db, /* The database connection to check */ - const char *zDb, /* Name of specific database to check */ - u8 *peAuth /* OUT: One of UAUTH_* constants */ -){ - sqlite3_stmt *pStmt; - int rc; - - *peAuth = UAUTH_Unknown; - if( !userTableExists(db, "main") ){ - *peAuth = UAUTH_Admin; /* No sqlite_user table. Everybody is admin. */ - return SQLITE_OK; - } - if( db->auth.zAuthUser==0 ){ - *peAuth = UAUTH_Fail; - return SQLITE_OK; - } - pStmt = sqlite3UserAuthPrepare(db, - "SELECT pw=sqlite_crypt(?1,pw), isAdmin FROM \"%w\".sqlite_user" - " WHERE uname=?2", zDb); - if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_bind_blob(pStmt, 1, db->auth.zAuthPW, db->auth.nAuthPW,SQLITE_STATIC); - sqlite3_bind_text(pStmt, 2, db->auth.zAuthUser, -1, SQLITE_STATIC); - rc = sqlite3_step(pStmt); - if( rc==SQLITE_ROW && sqlite3_column_int(pStmt,0) ){ - *peAuth = sqlite3_column_int(pStmt, 1) + UAUTH_User; - }else{ - *peAuth = UAUTH_Fail; - } - return sqlite3_finalize(pStmt); -} -int sqlite3UserAuthCheckLogin( - sqlite3 *db, /* The database connection to check */ - const char *zDb, /* Name of specific database to check */ - u8 *peAuth /* OUT: One of UAUTH_* constants */ -){ - int rc; - u8 savedAuthLevel; - assert( zDb!=0 ); - assert( peAuth!=0 ); - savedAuthLevel = db->auth.authLevel; - db->auth.authLevel = UAUTH_Admin; - rc = userAuthCheckLogin(db, zDb, peAuth); - db->auth.authLevel = savedAuthLevel; - return rc; -} - -/* -** If the current authLevel is UAUTH_Unknown, the take actions to figure -** out what authLevel should be -*/ -void sqlite3UserAuthInit(sqlite3 *db){ - if( db->auth.authLevel==UAUTH_Unknown ){ - u8 authLevel = UAUTH_Fail; - sqlite3UserAuthCheckLogin(db, "main", &authLevel); - db->auth.authLevel = authLevel; - if( authLevelflags &= ~SQLITE_WriteSchema; - } -} - -/* -** Implementation of the sqlite_crypt(X,Y) function. -** -** If Y is NULL then generate a new hash for password X and return that -** hash. If Y is not null, then generate a hash for password X using the -** same salt as the previous hash Y and return the new hash. -*/ -void sqlite3CryptFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - const char *zIn; - int nIn, ii; - u8 *zOut; - char zSalt[8]; - zIn = sqlite3_value_blob(argv[0]); - nIn = sqlite3_value_bytes(argv[0]); - if( sqlite3_value_type(argv[1])==SQLITE_BLOB - && sqlite3_value_bytes(argv[1])==nIn+sizeof(zSalt) - ){ - memcpy(zSalt, sqlite3_value_blob(argv[1]), sizeof(zSalt)); - }else{ - sqlite3_randomness(sizeof(zSalt), zSalt); - } - zOut = sqlite3_malloc( nIn+sizeof(zSalt) ); - if( zOut==0 ){ - sqlite3_result_error_nomem(context); - }else{ - memcpy(zOut, zSalt, sizeof(zSalt)); - for(ii=0; iiauth.authLevel = UAUTH_Unknown; - sqlite3_free(db->auth.zAuthUser); - sqlite3_free(db->auth.zAuthPW); - memset(&db->auth, 0, sizeof(db->auth)); - db->auth.zAuthUser = sqlite3_mprintf("%s", zUsername); - if( db->auth.zAuthUser==0 ) return SQLITE_NOMEM; - db->auth.zAuthPW = sqlite3_malloc( nPW+1 ); - if( db->auth.zAuthPW==0 ) return SQLITE_NOMEM; - memcpy(db->auth.zAuthPW,zPW,nPW); - db->auth.nAuthPW = nPW; - rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel); - db->auth.authLevel = authLevel; - sqlite3ExpirePreparedStatements(db, 0); - if( rc ){ - return rc; /* OOM error, I/O error, etc. */ - } - if( authLevelauth.authLevelauth.zAuthUser==0 ){ - assert( isAdmin!=0 ); - sqlite3_user_authenticate(db, zUsername, aPW, nPW); - } - return SQLITE_OK; -} - -/* -** The sqlite3_user_change() interface can be used to change a users -** login credentials or admin privilege. Any user can change their own -** login credentials. Only an admin user can change another users login -** credentials or admin privilege setting. No user may change their own -** admin privilege setting. -*/ -int sqlite3_user_change( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to change */ - const char *aPW, /* Modified password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* Modified admin privilege for the user */ -){ - sqlite3_stmt *pStmt; - int rc; - u8 authLevel; - - authLevel = db->auth.authLevel; - if( authLevelauth.zAuthUser, zUsername)!=0 ){ - if( db->auth.authLevelauth.authLevel = UAUTH_Admin; - if( !userTableExists(db, "main") ){ - /* This routine is a no-op if the user to be modified does not exist */ - }else{ - pStmt = sqlite3UserAuthPrepare(db, - "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)" - " WHERE uname=%Q", isAdmin, zUsername); - if( pStmt==0 ){ - rc = SQLITE_NOMEM; - }else{ - sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); - sqlite3_step(pStmt); - rc = sqlite3_finalize(pStmt); - } - } - db->auth.authLevel = authLevel; - return rc; -} - -/* -** The sqlite3_user_delete() interface can be used (by an admin user only) -** to delete a user. The currently logged-in user cannot be deleted, -** which guarantees that there is always an admin user and hence that -** the database cannot be converted into a no-authentication-required -** database. -*/ -int sqlite3_user_delete( - sqlite3 *db, /* Database connection */ - const char *zUsername /* Username to remove */ -){ - sqlite3_stmt *pStmt; - if( db->auth.authLevelauth.zAuthUser, zUsername)==0 ){ - /* Cannot delete self */ - return SQLITE_AUTH; - } - if( !userTableExists(db, "main") ){ - /* This routine is a no-op if the user to be deleted does not exist */ - return SQLITE_OK; - } - pStmt = sqlite3UserAuthPrepare(db, - "DELETE FROM sqlite_user WHERE uname=%Q", zUsername); - if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_step(pStmt); - return sqlite3_finalize(pStmt); -} - -#endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/main.mk b/main.mk index 3d23215a44..139245830f 100644 --- a/main.mk +++ b/main.mk @@ -305,7 +305,7 @@ T.cc.sqlite ?= $(T.cc) CFLAGS.intree_includes = \ -I. -I$(TOP)/src -I$(TOP)/ext/rtree -I$(TOP)/ext/icu \ -I$(TOP)/ext/fts3 -I$(TOP)/ext/session \ - -I$(TOP)/ext/misc -I$(TOP)/ext/userauth + -I$(TOP)/ext/misc T.cc.sqlite += $(CFLAGS.intree_includes) # @@ -433,7 +433,7 @@ LIBOBJS0 = alter.o analyze.o attach.o auth.o \ random.o resolve.o rowset.o rtree.o \ sqlite3session.o select.o sqlite3rbu.o status.o stmt.o \ table.o threads.o tokenize.o treeview.o trigger.o \ - update.o upsert.o userauth.o utf.o util.o vacuum.o \ + update.o upsert.o utf.o util.o vacuum.o \ vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ vdbetrace.o vdbevtab.o vtab.o \ wal.o walker.o where.o wherecode.o whereexpr.o \ @@ -591,9 +591,6 @@ SRC += \ SRC += \ $(TOP)/ext/session/sqlite3session.c \ $(TOP)/ext/session/sqlite3session.h -SRC += \ - $(TOP)/ext/userauth/userauth.c \ - $(TOP)/ext/userauth/sqlite3userauth.h SRC += \ $(TOP)/ext/rbu/sqlite3rbu.h \ $(TOP)/ext/rbu/sqlite3rbu.c @@ -705,7 +702,6 @@ TESTSRC += \ $(TOP)/ext/misc/unionvtab.c \ $(TOP)/ext/misc/wholenumber.c \ $(TOP)/ext/misc/zipfile.c \ - $(TOP)/ext/userauth/userauth.c \ $(TOP)/ext/rtree/test_rtreedoc.c # Source code to the library files needed by the test fixture @@ -808,8 +804,6 @@ EXTHDR += \ $(TOP)/ext/icu/sqliteicu.h EXTHDR += \ $(TOP)/ext/rtree/sqlite3rtree.h -EXTHDR += \ - $(TOP)/ext/userauth/sqlite3userauth.h # # Executables needed for testing @@ -2081,9 +2075,6 @@ fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(DEPS_EXT_COMMON) rtree.o: $(TOP)/ext/rtree/rtree.c $(DEPS_EXT_COMMON) $(T.cc.extension) -c $(TOP)/ext/rtree/rtree.c -userauth.o: $(TOP)/ext/userauth/userauth.c $(DEPS_EXT_COMMON) - $(T.cc.extension) -c $(TOP)/ext/userauth/userauth.c - sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(DEPS_EXT_COMMON) $(T.cc.extension) -c $(TOP)/ext/session/sqlite3session.c diff --git a/manifest b/manifest index 0f5b18c42a..cae8108738 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Perform\ssome\smakefile\sacrobatics\sto\sget\sthe\stclConfig.sh\sstate\sapplied\sfor\sstatic\smakefiles. -D 2024-10-28T17:20:18.788 +C Remove\sthe\snever-used\sand\snever-documented\sand\slong-ago\sdeprecated\nuser-authentication\sfeature\soption. +D 2024-10-28T17:27:15.255 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -614,9 +614,6 @@ F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009e F ext/session/sqlite3session.c 3d0a7f0f7a1c946e01818c716a55a40ae30542a29a9045cb05daf7fb658cdafa F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b F ext/session/test_session.c aa29abdcc9011ac02f4fa38e8ede226106eaeee7c3ea7d8b2b999a124e0c368c -F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 -F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c -F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c F ext/wasm/GNUmakefile 311aa0d5edc7006409962cc77cc26560d92f9be69c2c4302e8bbc68189fd02db F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 @@ -702,7 +699,7 @@ F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk e9ff755b0d6f2ab6a95fab7bb11f742485de6ad1606822932d24bbfa14a9884a +F main.mk 79392fb2e964f1359518d71df364182d7e53cc26a8fc4b25362ded9aeb4a17f7 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -716,18 +713,18 @@ F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb -F src/attach.c 08235ab62ed5ccc93c22bf36e640d19effcd632319615851bccf724ec9341333 -F src/auth.c 4c1ea890e0069ad73bead5d17a5b12c34cfa4f1a24175c8147ea439b64be271c +F src/attach.c f35bb8cc1fcdde8f6815a7ef09ae413bcac71821d530796800ba24b3c7da1e80 +F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645 F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 F src/btree.c 63ca6b647342e8cef643863cd0962a542f133e1069460725ba4461dcda92b03c F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6 -F src/build.c 3a1840d9d171ce2d24f4c1f7acda7266ab796c664290c1acba65ff98ce2bd01e +F src/build.c c6b09342d870a509529244ed8e19b4175a261f2e3163c199241d69e1d8a57607 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c b224d3db0f28c4a5f1407c50107a0a8133bd244ff3c7f6f8cedeb896a8cf1b64 +F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c @@ -735,7 +732,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c a9d9f5fdfbdd3b2c94d7af1b11f181464b8a641736cf32cb92fa3c5e7ecb30df F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f -F src/func.c 1d093b93b8f097665721e59a1c404d7db4dc591e1a777a7a1022dfbda21e108b +F src/func.c fa138d44348e189817542f6efa6232420b3e0081c835ced65883adc7fd777d65 F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 @@ -745,7 +742,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70 F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 -F src/main.c d55d27db5a3b7bb12e1b723e350efd833586f22baa4b15ca2c0b4bde9a44ae29 +F src/main.c f6daba376adac080fe9287c6746fb15e12c7e47d022f2e9f2986ed364b7e0329 F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 @@ -775,7 +772,7 @@ F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 -F src/pragma.c cd613126f7cdd0c2ded4648c3c7b7b0239e678d7f3489e88c4b6d6858372fd07 +F src/pragma.c a2ec3657a953fa7dea7c1e680e4358b6ce6ae570b6c5234e0f5ef219d308d223 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 3ba0ad907b7773ed642f66cea8a2c9c8edc18841aa1050b6218dbb3479e86225 F src/printf.c 6a87534ebfb9e5346011191b1f3a7ebc457f5938c7e4feeea478ecf53f6a41b2 @@ -783,17 +780,17 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 2fb0947424944f8baa1b4efdfd9eca70dc0691bbc1cb4d283db7fc142937fa3a +F src/shell.c.in b6b7944fc076c2fd29d38edb61e3da978e838e3f79e1cf2c96a1342c423b3892 F src/sqlite.h.in 29fc900a58f394c7488d093fd7a8dcb14d3fa6399d5178cb20adcf88dbedfe39 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h baae24292817e13e7fe748851c62efc381dcc4dac241b1182eac3d2f05eae52c +F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1 F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 47d4bb6eb06aab48d643eeb8c4f65b5fa9529fa5526fdcbf223ea32277ed1b56 +F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 -F src/test1.c 370668f1832dc7bc2ab0212d807d880b6cdb0d5949550489593ce0cdb4a61012 +F src/test1.c 9df74d1d8c0513b0f906942d004b7d7aff5c6f47320a921a0b890748bac0e34d F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d @@ -806,7 +803,7 @@ F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d97 F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6 F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5 F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5 -F src/test_config.c e8d041a84151cbaee4dd82eb32e4153abe06856bcfab4771968a8cf930a86332 +F src/test_config.c bff5e1625c007f14a9ea4d346b6a741149b5e1f885c1c7ae69bb28a8ddade151 F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383 F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86 @@ -1948,7 +1945,6 @@ F test/upsert5.test 9953b180d02d1369cdbb6c73c900834e5fef8cb78e98e07511c8762ec21c F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35 F test/uri.test c1abaaaa28e9422d61e5f3f9cbc8ef993ec49fe802f581520731708561d49384 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 -F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 F test/utf16align.test 9fde0bb5d3a821594aa68c6829ab9c5453a084384137ebb9f6153e2d678039da F test/vacuum-into.test 77845cee98770c416dae9b0da6bb3229753861f2da65c11b4f9715d081712d8a F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d @@ -2143,7 +2139,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a F tool/mkccode.tcl 4cb8ad7e7330aaed052b0657a1bfacbc67103c400e41860aff643a482cfc2d3e x -F tool/mkctimec.tcl e3af51acc2ef92062fe6d622de010a27a34b497258a248dada04388b916c61c6 x +F tool/mkctimec.tcl ef6a67ec82e5b6fc19152a4c79f237227b18bf67ff16d155bac7adb94355d9cf x F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559 F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef @@ -2205,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f98da150a9c18dfaf9d5178ceee227caf7fce9c9c9194a7a4291abb40de832fa -R e203eb86dfdd2daea7dd35f993a3ed58 -U stephan -Z ba3f561a89835f0184bfa691acd0be76 +P 9b141d108b64c8f4e1103de6f142d972b5151eed0f07988fea308fc71cec45b8 +R 9407a62c47c06c3fbba4fc768b189643 +U drh +Z 30f01ab7792d4b857d7e101ce9a3bf79 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 41798faaa6..dd84b8f505 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b141d108b64c8f4e1103de6f142d972b5151eed0f07988fea308fc71cec45b8 +3a3f7bf4307c27e56546e51da06ecc9a262cdf155fda2dd359aa2326d207a147 diff --git a/src/attach.c b/src/attach.c index 76476685fb..9f23dce1ed 100644 --- a/src/attach.c +++ b/src/attach.c @@ -227,15 +227,6 @@ static void attachFunc( sqlite3BtreeLeaveAll(db); assert( zErrDyn==0 || rc!=SQLITE_OK ); } -#ifdef SQLITE_USER_AUTHENTICATION - if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){ - u8 newAuth = 0; - rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); - if( newAuthauth.authLevel ){ - rc = SQLITE_AUTH_USER; - } - } -#endif if( rc ){ if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ int iDb = db->nDb - 1; diff --git a/src/auth.c b/src/auth.c index fba2c09905..9ec2e7d046 100644 --- a/src/auth.c +++ b/src/auth.c @@ -112,11 +112,7 @@ int sqlite3AuthReadCol( int rc; /* Auth callback return code */ if( db->init.busy ) return SQLITE_OK; - rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext); if( rc==SQLITE_DENY ){ char *z = sqlite3_mprintf("%s.%s", zTab, zCol); if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); @@ -223,11 +219,7 @@ int sqlite3AuthCheck( testcase( zArg3==0 ); testcase( pParse->zAuthContext==0 ); - rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); + rc = db->xAuth(db->pAuthArg,code,zArg1,zArg2,zArg3,pParse->zAuthContext); if( rc==SQLITE_DENY ){ sqlite3ErrorMsg(pParse, "not authorized"); pParse->rc = SQLITE_AUTH; diff --git a/src/build.c b/src/build.c index 943d862e97..a5deb54fc6 100644 --- a/src/build.c +++ b/src/build.c @@ -189,17 +189,6 @@ void sqlite3FinishCoding(Parse *pParse){ } sqlite3VdbeAddOp0(v, OP_Halt); -#if SQLITE_USER_AUTHENTICATION && !defined(SQLITE_OMIT_SHARED_CACHE) - if( pParse->nTableLock>0 && db->init.busy==0 ){ - sqlite3UserAuthInit(db); - if( db->auth.authLevelrc = SQLITE_AUTH_USER; - return; - } - } -#endif - /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a @@ -328,16 +317,6 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ pParse->nested--; } -#if SQLITE_USER_AUTHENTICATION -/* -** Return TRUE if zTable is the name of the system table that stores the -** list of users and their access credentials. -*/ -int sqlite3UserAuthTable(const char *zTable){ - return sqlite3_stricmp(zTable, "sqlite_user")==0; -} -#endif - /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -356,13 +335,6 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ /* All mutexes are required for schema access. Make sure we hold them. */ assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); -#if SQLITE_USER_AUTHENTICATION - /* Only the admin user is allowed to know that the sqlite_user table - ** exists */ - if( db->auth.authLevelnDb; i++){ if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break; @@ -4021,9 +3993,6 @@ void sqlite3CreateIndex( if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && db->init.busy==0 && pTblName!=0 -#if SQLITE_USER_AUTHENTICATION - && sqlite3UserAuthTable(pTab->zName)==0 -#endif ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; diff --git a/src/ctime.c b/src/ctime.c index fe7849fec7..9f358bd27f 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -767,9 +767,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_UNTESTABLE "UNTESTABLE", #endif -#ifdef SQLITE_USER_AUTHENTICATION - "USER_AUTHENTICATION", -#endif #ifdef SQLITE_USE_ALLOCA "USE_ALLOCA", #endif diff --git a/src/func.c b/src/func.c index 2de16b8aa9..419ce24c62 100644 --- a/src/func.c +++ b/src/func.c @@ -2678,9 +2678,6 @@ void sqlite3RegisterBuiltinFunctions(void){ SFUNCTION(load_extension, 1, 0, 0, loadExt ), SFUNCTION(load_extension, 2, 0, 0, loadExt ), #endif -#if SQLITE_USER_AUTHENTICATION - FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), -#endif #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), diff --git a/src/main.c b/src/main.c index a6935fb0f3..2dbd8dce19 100644 --- a/src/main.c +++ b/src/main.c @@ -1423,10 +1423,6 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ sqlite3ValueFree(db->pErr); sqlite3CloseExtensions(db); -#if SQLITE_USER_AUTHENTICATION - sqlite3_free(db->auth.zAuthUser); - sqlite3_free(db->auth.zAuthPW); -#endif db->eOpenState = SQLITE_STATE_ERROR; diff --git a/src/pragma.c b/src/pragma.c index 07139015f9..785676e04e 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1144,12 +1144,6 @@ void sqlite3Pragma( ** in auto-commit mode. */ mask &= ~(SQLITE_ForeignKeys); } -#if SQLITE_USER_AUTHENTICATION - if( db->auth.authLevel==UAUTH_User ){ - /* Do not allow non-admin users to modify the schema arbitrarily */ - mask &= ~(SQLITE_WriteSchema); - } -#endif if( sqlite3GetBoolean(zRight, 0) ){ if( (mask & SQLITE_WriteSchema)==0 diff --git a/src/shell.c.in b/src/shell.c.in index df0c3500de..50f1c5bfea 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -104,9 +104,6 @@ typedef unsigned short int u16; typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; typedef unsigned char u8; -#if SQLITE_USER_AUTHENTICATION -# include "sqlite3userauth.h" -#endif #include #include @@ -11758,69 +11755,6 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif -#if SQLITE_USER_AUTHENTICATION - if( c=='u' && cli_strncmp(azArg[0], "user", n)==0 ){ - if( nArg<2 ){ - eputz("Usage: .user SUBCOMMAND ...\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); - if( cli_strcmp(azArg[1],"login")==0 ){ - if( nArg!=4 ){ - eputz("Usage: .user login USER PASSWORD\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], - strlen30(azArg[3])); - if( rc ){ - sqlite3_fprintf(stderr,"Authentication failed for user %s\n", azArg[2]); - rc = 1; - } - }else if( cli_strcmp(azArg[1],"add")==0 ){ - if( nArg!=5 ){ - eputz("Usage: .user add USER PASSWORD ISADMIN\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - sqlite3_fprintf(stderr,"User-Add failed: %d\n", rc); - rc = 1; - } - }else if( cli_strcmp(azArg[1],"edit")==0 ){ - if( nArg!=5 ){ - eputz("Usage: .user edit USER PASSWORD ISADMIN\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - sqlite3_fprintf(stderr,"User-Edit failed: %d\n", rc); - rc = 1; - } - }else if( cli_strcmp(azArg[1],"delete")==0 ){ - if( nArg!=3 ){ - eputz("Usage: .user delete USER\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_delete(p->db, azArg[2]); - if( rc ){ - sqlite3_fprintf(stderr,"User-Delete failed: %d\n", rc); - rc = 1; - } - }else{ - eputz("Usage: .user login|add|edit|delete ...\n"); - rc = 1; - goto meta_command_exit; - } - }else -#endif /* SQLITE_USER_AUTHENTICATION */ - if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){ char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit"; sqlite3_fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7a8d8a5df9..dbdf36200d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1602,47 +1602,11 @@ struct FuncDefHash { }; #define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) -#if defined(SQLITE_USER_AUTHENTICATION) -# warning "The SQLITE_USER_AUTHENTICATION extension is deprecated. \ - See ext/userauth/user-auth.txt for details." -#endif -#ifdef SQLITE_USER_AUTHENTICATION -/* -** Information held in the "sqlite3" database connection object and used -** to manage user authentication. -*/ -typedef struct sqlite3_userauth sqlite3_userauth; -struct sqlite3_userauth { - u8 authLevel; /* Current authentication level */ - int nAuthPW; /* Size of the zAuthPW in bytes */ - char *zAuthPW; /* Password used to authenticate */ - char *zAuthUser; /* User name used to authenticate */ -}; - -/* Allowed values for sqlite3_userauth.authLevel */ -#define UAUTH_Unknown 0 /* Authentication not yet checked */ -#define UAUTH_Fail 1 /* User authentication failed */ -#define UAUTH_User 2 /* Authenticated as a normal user */ -#define UAUTH_Admin 3 /* Authenticated as an administrator */ - -/* Functions used only by user authorization logic */ -int sqlite3UserAuthTable(const char*); -int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); -void sqlite3UserAuthInit(sqlite3*); -void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); - -#endif /* SQLITE_USER_AUTHENTICATION */ - /* ** typedef for the authorization callback function. */ -#ifdef SQLITE_USER_AUTHENTICATION - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*, const char*); -#else - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*); -#endif +typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*); #ifndef SQLITE_OMIT_DEPRECATED /* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing @@ -1803,9 +1767,6 @@ struct sqlite3 { void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif -#ifdef SQLITE_USER_AUTHENTICATION - sqlite3_userauth auth; /* User authentication information */ -#endif }; /* diff --git a/src/tclsqlite.c b/src/tclsqlite.c index e572d1d6c0..af0d27b1fe 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1155,9 +1155,6 @@ static int auth_callback( const char *zArg2, const char *zArg3, const char *zArg4 -#ifdef SQLITE_USER_AUTHENTICATION - ,const char *zArg5 -#endif ){ const char *zCode; Tcl_DString str; @@ -1217,9 +1214,6 @@ static int auth_callback( Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); -#ifdef SQLITE_USER_AUTHENTICATION - Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); -#endif rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; diff --git a/src/test1.c b/src/test1.c index 5d05667476..b124faa0c4 100644 --- a/src/test1.c +++ b/src/test1.c @@ -8324,131 +8324,6 @@ static int SQLITE_TCLAPI sorter_test_sort4_helper( } -#ifdef SQLITE_USER_AUTHENTICATION -#include "sqlite3userauth.h" -/* -** tclcmd: sqlite3_user_authenticate DB USERNAME PASSWORD -*/ -static int SQLITE_TCLAPI test_user_authenticate( - ClientData clientData, /* Unused */ - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[] /* Command arguments */ -){ - char *zUser = 0; - char *zPasswd = 0; - Tcl_Size nPasswd = 0; - sqlite3 *db; - int rc; - - if( objc!=4 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD"); - return TCL_ERROR; - } - if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ - return TCL_ERROR; - } - zUser = Tcl_GetString(objv[2]); - zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); - rc = sqlite3_user_authenticate(db, zUser, zPasswd, (int)nPasswd); - Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); - return TCL_OK; -} -#endif /* SQLITE_USER_AUTHENTICATION */ - -#ifdef SQLITE_USER_AUTHENTICATION -/* -** tclcmd: sqlite3_user_add DB USERNAME PASSWORD ISADMIN -*/ -static int SQLITE_TCLAPI test_user_add( - ClientData clientData, /* Unused */ - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[] /* Command arguments */ -){ - char *zUser = 0; - char *zPasswd = 0; - Tcl_Size nPasswd = 0; - int isAdmin = 0; - sqlite3 *db; - int rc; - - if( objc!=5 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN"); - return TCL_ERROR; - } - if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ - return TCL_ERROR; - } - zUser = Tcl_GetString(objv[2]); - zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); - Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin); - rc = sqlite3_user_add(db, zUser, zPasswd, (int)nPasswd, isAdmin); - Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); - return TCL_OK; -} -#endif /* SQLITE_USER_AUTHENTICATION */ - -#ifdef SQLITE_USER_AUTHENTICATION -/* -** tclcmd: sqlite3_user_change DB USERNAME PASSWORD ISADMIN -*/ -static int SQLITE_TCLAPI test_user_change( - ClientData clientData, /* Unused */ - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[] /* Command arguments */ -){ - char *zUser = 0; - char *zPasswd = 0; - Tcl_Size nPasswd = 0; - int isAdmin = 0; - sqlite3 *db; - int rc; - - if( objc!=5 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN"); - return TCL_ERROR; - } - if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ - return TCL_ERROR; - } - zUser = Tcl_GetString(objv[2]); - zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); - Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin); - rc = sqlite3_user_change(db, zUser, zPasswd, (int)nPasswd, isAdmin); - Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); - return TCL_OK; -} -#endif /* SQLITE_USER_AUTHENTICATION */ - -#ifdef SQLITE_USER_AUTHENTICATION -/* -** tclcmd: sqlite3_user_delete DB USERNAME -*/ -static int SQLITE_TCLAPI test_user_delete( - ClientData clientData, /* Unused */ - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[] /* Command arguments */ -){ - char *zUser = 0; - sqlite3 *db; - int rc; - - if( objc!=3 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME"); - return TCL_ERROR; - } - if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ - return TCL_ERROR; - } - zUser = Tcl_GetString(objv[2]); - rc = sqlite3_user_delete(db, zUser); - Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); - return TCL_OK; -} -#endif /* SQLITE_USER_AUTHENTICATION */ /* ** tclcmd: register_dbstat_vtab DB @@ -9169,12 +9044,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "load_static_extension", tclLoadStaticExtensionCmd }, { "sorter_test_fakeheap", sorter_test_fakeheap }, { "sorter_test_sort4_helper", sorter_test_sort4_helper }, -#ifdef SQLITE_USER_AUTHENTICATION - { "sqlite3_user_authenticate", test_user_authenticate, 0 }, - { "sqlite3_user_add", test_user_add, 0 }, - { "sqlite3_user_change", test_user_change, 0 }, - { "sqlite3_user_delete", test_user_delete, 0 }, -#endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS { "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 }, { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 }, diff --git a/src/test_config.c b/src/test_config.c index ad315c723c..c8ce2ab88a 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -745,12 +745,6 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "0", TCL_GLOBAL_ONLY); #endif -#ifdef SQLITE_USER_AUTHENTICATION - Tcl_SetVar2(interp, "sqlite_options", "userauth", "1", TCL_GLOBAL_ONLY); -#else - Tcl_SetVar2(interp, "sqlite_options", "userauth", "0", TCL_GLOBAL_ONLY); -#endif - #ifdef SQLITE_MULTIPLEX_EXT_OVWR Tcl_SetVar2(interp, "sqlite_options", "multiplex_ext_overwrite", "1", TCL_GLOBAL_ONLY); #else diff --git a/test/userauth01.test b/test/userauth01.test deleted file mode 100644 index 644937b192..0000000000 --- a/test/userauth01.test +++ /dev/null @@ -1,257 +0,0 @@ -# 2014-09-10 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#*********************************************************************** -# -# This file implements tests of the SQLITE_USER_AUTHENTICATION extension. -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -set testprefix userauth01 - -ifcapable !userauth { - finish_test - return -} - -# Create a no-authentication-required database -# -do_execsql_test userauth01-1.0 { - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(1),(2.5),('three'),(x'4444'),(NULL); - SELECT quote(x) FROM t1 ORDER BY x; - SELECT name FROM sqlite_master; -} {NULL 1 2.5 'three' X'4444' t1} - -# Calling sqlite3_user_authenticate() on a no-authentication-required -# database connection is a harmless no-op. -# -do_test userauth01-1.1 { - sqlite3_user_authenticate db alice pw-4-alice - execsql { - SELECT quote(x) FROM t1 ORDER BY x; - SELECT name FROM sqlite_master; - } -} {NULL 1 2.5 'three' X'4444' t1} - -# If sqlite3_user_add(D,U,P,N,A) is called on a no-authentication-required -# database and A is false, then the call fails with an SQLITE_AUTH error. -# -do_test userauth01-1.2 { - sqlite3_user_add db bob pw-4-bob 0 -} {SQLITE_AUTH} -do_test userauth01-1.3 { - execsql { - SELECT quote(x) FROM t1 ORDER BY x; - SELECT name FROM sqlite_master; - } -} {NULL 1 2.5 'three' X'4444' t1} - -# When called on a no-authentication-required -# database and when A is true, the sqlite3_user_add(D,U,P,N,A) routine -# converts the database into an authentication-required database and -# logs the database connection D in using user U with password P,N. -# -do_test userauth01-1.4 { - sqlite3_user_add db alice pw-4-alice 1 -} {SQLITE_OK} -do_test userauth01-1.5 { - execsql { - SELECT quote(x) FROM t1 ORDER BY x; - SELECT uname, isadmin FROM sqlite_user ORDER BY uname; - SELECT name FROM sqlite_master ORDER BY name; - } -} {NULL 1 2.5 'three' X'4444' alice 1 sqlite_user t1} - -# The sqlite3_user_add() interface can be used (by an admin user only) -# to create a new user. -# -do_test userauth01-1.6 { - sqlite3_user_add db bob pw-4-bob 0 - sqlite3_user_add db cindy pw-4-cindy 0 - sqlite3_user_add db david pw-4-david 0 - execsql { - SELECT uname, isadmin FROM sqlite_user ORDER BY uname; - } -} {alice 1 bob 0 cindy 0 david 0} - -# The sqlite_user table is inaccessible (unreadable and unwriteable) to -# non-admin users and is read-only for admin users. However, if the same -# -do_test userauth01-1.7 { - sqlite3 db2 test.db - sqlite3_user_authenticate db2 cindy pw-4-cindy - db2 eval { - SELECT quote(x) FROM t1 ORDER BY x; - SELECT name FROM sqlite_master ORDER BY name; - } -} {NULL 1 2.5 'three' X'4444' sqlite_user t1} -do_test userauth01-1.8 { - catchsql { - SELECT uname, isadmin FROM sqlite_user ORDER BY uname; - } db2 -} {1 {no such table: sqlite_user}} - -# Any user can change their own password. -# -do_test userauth01-1.9 { - sqlite3_user_change db2 cindy xyzzy-cindy 0 -} {SQLITE_OK} -do_test userauth01-1.10 { - sqlite3_user_authenticate db2 cindy pw-4-cindy -} {SQLITE_AUTH} -do_test userauth01-1.11 { - sqlite3_user_authenticate db2 cindy xyzzy-cindy -} {SQLITE_OK} -do_test userauth01-1.12 { - sqlite3_user_change db alice xyzzy-alice 1 -} {SQLITE_OK} -do_test userauth01-1.13 { - sqlite3_user_authenticate db alice pw-4-alice -} {SQLITE_AUTH} -do_test userauth01-1.14 { - sqlite3_user_authenticate db alice xyzzy-alice -} {SQLITE_OK} - -# No user may change their own admin privilege setting. -# -do_test userauth01-1.15 { - sqlite3_user_change db alice xyzzy-alice 0 -} {SQLITE_AUTH} -do_test userauth01-1.16 { - db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 bob 0 cindy 0 david 0} -do_test userauth01-1.17 { - sqlite3_user_change db2 cindy xyzzy-cindy 1 -} {SQLITE_AUTH} -do_test userauth01-1.18 { - db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 bob 0 cindy 0 david 0} - -# The sqlite3_user_change() interface can be used to change a users -# login credentials or admin privilege. -# -do_test userauth01-1.20 { - sqlite3_user_change db david xyzzy-david 1 -} {SQLITE_OK} -do_test userauth01-1.21 { - db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 bob 0 cindy 0 david 1} -do_test userauth01-1.22 { - sqlite3_user_authenticate db2 david xyzzy-david -} {SQLITE_OK} -do_test userauth01-1.23 { - db2 eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 bob 0 cindy 0 david 1} -do_test userauth01-1.24 { - sqlite3_user_change db david pw-4-david 0 -} {SQLITE_OK} -do_test userauth01-1.25 { - sqlite3_user_authenticate db2 david pw-4-david -} {SQLITE_OK} -do_test userauth01-1.26 { - db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 bob 0 cindy 0 david 0} -do_test userauth01-1.27 { - catchsql {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} db2 -} {1 {no such table: sqlite_user}} - -# Only an admin user can change another users login -# credentials or admin privilege setting. -# -do_test userauth01-1.30 { - sqlite3_user_change db2 bob xyzzy-bob 1 -} {SQLITE_AUTH} -do_test userauth01-1.31 { - db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 bob 0 cindy 0 david 0} - -# The sqlite3_user_delete() interface can be used (by an admin user only) -# to delete a user. -# -do_test userauth01-1.40 { - sqlite3_user_delete db bob -} {SQLITE_OK} -do_test userauth01-1.41 { - db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 cindy 0 david 0} -do_test userauth01-1.42 { - sqlite3_user_delete db2 cindy -} {SQLITE_AUTH} -do_test userauth01-1.43 { - sqlite3_user_delete db2 alice -} {SQLITE_AUTH} -do_test userauth01-1.44 { - db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 cindy 0 david 0} - -# The currently logged-in user cannot be deleted -# -do_test userauth01-1.50 { - sqlite3_user_delete db alice -} {SQLITE_AUTH} -do_test userauth01-1.51 { - db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} -} {alice 1 cindy 0 david 0} - -# When ATTACH-ing new database files to a connection, each newly attached -# database that is an authentication-required database is checked using -# the same username and password as supplied to the main database. If that -# check fails, then the ATTACH command fails with an SQLITE_AUTH error. -# -do_test userauth01-1.60 { - forcedelete test3.db - sqlite3 db3 test3.db - sqlite3_user_add db3 alice xyzzy-alice 1 -} {SQLITE_OK} -do_test userauth01-1.61 { - db3 eval { - CREATE TABLE t3(a,b,c); INSERT INTO t3 VALUES(1,2,3); - SELECT * FROM t3; - } -} {1 2 3} -do_test userauth01-1.62 { - db eval { - ATTACH 'test3.db' AS aux; - SELECT * FROM t1, t3 ORDER BY x LIMIT 1; - DETACH aux; - } -} {{} 1 2 3} -do_test userauth01-1.63 { - sqlite3_user_change db alice pw-4-alice 1 - sqlite3_user_authenticate db alice pw-4-alice - catchsql { - ATTACH 'test3.db' AS aux; - } -} {1 {unable to open database: test3.db}} -do_test userauth01-1.64 { - sqlite3_extended_errcode db -} {SQLITE_AUTH} -do_test userauth01-1.65 { - db eval {PRAGMA database_list} -} {~/test3.db/} - -# The sqlite3_set_authorizer() callback is modified to take a 7th parameter -# which is the username of the currently logged in user, or NULL for a -# no-authentication-required database. -# -proc auth {args} { - lappend ::authargs $args - return SQLITE_OK -} -do_test authuser01-2.1 { - unset -nocomplain ::authargs - db auth auth - db eval {SELECT x FROM t1} - set ::authargs -} {/SQLITE_SELECT {} {} {} {} alice/} - - -finish_test diff --git a/tool/mkctimec.tcl b/tool/mkctimec.tcl index a7e897a596..69d25c678e 100755 --- a/tool/mkctimec.tcl +++ b/tool/mkctimec.tcl @@ -279,7 +279,6 @@ set boolean_defnil_options { SQLITE_UNTESTABLE SQLITE_USE_ALLOCA SQLITE_USE_FCNTL_TRACE - SQLITE_USER_AUTHENTICATION SQLITE_USE_URI SQLITE_VDBE_COVERAGE SQLITE_WIN32_MALLOC From 54a282830f3d6baa8b46f57d15ed9057c8aab35f Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 17:30:11 +0000 Subject: [PATCH 207/522] Remove the ltmain.sh autotools remnant. FossilOrigin-Name: dad5eb9393e87403b932ddfb9da6db0ce1d6ed75c4771f22e87fbce1b0c206c2 --- ltmain.sh | 8461 ------------------------------------------------- manifest | 13 +- manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 8469 deletions(-) delete mode 100644 ltmain.sh diff --git a/ltmain.sh b/ltmain.sh deleted file mode 100644 index 0634c4bccc..0000000000 --- a/ltmain.sh +++ /dev/null @@ -1,8461 +0,0 @@ -# Generated from ltmain.m4sh. - -# ltmain.sh (GNU libtool) 2.2.6 -# Written by Gordon Matzigkeit , 1996 - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# Usage: $progname [OPTION]... [MODE-ARG]... -# -# Provide generalized library-building support services. -# -# --config show all configuration variables -# --debug enable verbose shell tracing -# -n, --dry-run display commands without modifying any files -# --features display basic configuration information and exit -# --mode=MODE use operation mode MODE -# --preserve-dup-deps don't remove duplicate dependency libraries -# --quiet, --silent don't print informational messages -# --tag=TAG use configuration variables from tag TAG -# -v, --verbose print informational messages (default) -# --version print version information -# -h, --help print short or long help message -# -# MODE must be one of the following: -# -# clean remove files from the build directory -# compile compile a source file into a libtool object -# execute automatically set library path, then run a program -# finish complete the installation of libtool libraries -# install install libraries or executables -# link create a library or an executable -# uninstall remove libraries from an installed directory -# -# MODE-ARGS vary depending on the MODE. -# Try `$progname --help --mode=MODE' for a more detailed description of MODE. -# -# When reporting a bug, please describe a test case to reproduce it and -# include the following information: -# -# host-triplet: $host -# shell: $SHELL -# compiler: $LTCC -# compiler flags: $LTCFLAGS -# linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.2.6 -# automake: $automake_version -# autoconf: $autoconf_version -# -# Report bugs to . - -PROGRAM=ltmain.sh -PACKAGE=libtool -VERSION=2.2.6 -TIMESTAMP="" -package_revision=1.3012 - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# NLS nuisances: We save the old values to restore during execute mode. -# Only set LANG and LC_ALL to C if already set. -# These must not be set unconditionally because not all systems understand -# e.g. LANG=C (notably SCO). -lt_user_locale= -lt_safe_locale= -for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES -do - eval "if test \"\${$lt_var+set}\" = set; then - save_$lt_var=\$$lt_var - $lt_var=C - export $lt_var - lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" - lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" - fi" -done - -$lt_unset CDPATH - - - - - -: ${CP="cp -f"} -: ${ECHO="echo"} -: ${EGREP="/usr/bin/grep -E"} -: ${FGREP="/usr/bin/grep -F"} -: ${GREP="/usr/bin/grep"} -: ${LN_S="ln -s"} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SED="/opt/local/bin/gsed"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} -: ${Xsed="$SED -e 1s/^X//"} - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -exit_status=$EXIT_SUCCESS - -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" - -dirname="s,/[^/]*$,," -basename="s,^.*/,," - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi - func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` -} - -# Generated shell functions inserted here. - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - -# The name of this program: -# In the unlikely event $progname began with a '-', it would play havoc with -# func_echo (imagine progname=-n), so we prepend ./ in that case: -func_dirname_and_basename "$progpath" -progname=$func_basename_result -case $progname in - -*) progname=./$progname ;; -esac - -# Make sure we have an absolute path for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=$func_dirname_result - progdir=`cd "$progdir" && pwd` - progpath="$progdir/$progname" - ;; - *) - save_IFS="$IFS" - IFS=: - for progdir in $PATH; do - IFS="$save_IFS" - test -x "$progdir/$progname" && break - done - IFS="$save_IFS" - test -n "$progdir" || progdir=`pwd` - progpath="$progdir/$progname" - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Re-`\' parameter expansions in output of double_quote_subst that were -# `\'-ed in input to the same. If an odd number of `\' preceded a '$' -# in input to double_quote_subst, that '$' was protected from expansion. -# Since each input `\' is now two `\'s, look for any number of runs of -# four `\'s followed by two `\'s and then a '$'. `\' that '$'. -bs='\\' -bs2='\\\\' -bs4='\\\\\\\\' -dollar='\$' -sed_double_backslash="\ - s/$bs4/&\\ -/g - s/^$bs2$dollar/$bs&/ - s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g - s/\n//g" - -# Standard options: -opt_dry_run=false -opt_help=false -opt_quiet=false -opt_verbose=false -opt_warning=: - -# func_echo arg... -# Echo program name prefixed message, along with the current mode -# name if it has been set yet. -func_echo () -{ - $ECHO "$progname${mode+: }$mode: $*" -} - -# func_verbose arg... -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $opt_verbose && func_echo ${1+"$@"} - - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : -} - -# func_error arg... -# Echo program name prefixed message to standard error. -func_error () -{ - $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 -} - -# func_warning arg... -# Echo program name prefixed warning message to standard error. -func_warning () -{ - $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 - - # bash bug again: - : -} - -# func_fatal_error arg... -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - func_error ${1+"$@"} - exit $EXIT_FAILURE -} - -# func_fatal_help arg... -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - func_error ${1+"$@"} - func_fatal_error "$help" -} -help="Try \`$progname --help' for more information." ## default - - -# func_grep expression filename -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_mkdir_p directory-path -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - my_directory_path="$1" - my_dir_list= - - if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then - - # Protect directory names starting with `-' - case $my_directory_path in - -*) my_directory_path="./$my_directory_path" ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$my_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - my_dir_list="$my_directory_path:$my_dir_list" - - # If the last portion added has no slash in it, the list is done - case $my_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` - done - my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` - - save_mkdir_p_IFS="$IFS"; IFS=':' - for my_dir in $my_dir_list; do - IFS="$save_mkdir_p_IFS" - # mkdir can fail with a `File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$my_dir" 2>/dev/null || : - done - IFS="$save_mkdir_p_IFS" - - # Bail out if we (or some other process) failed to create a directory. - test -d "$my_directory_path" || \ - func_fatal_error "Failed to create \`$1'" - fi -} - - -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () -{ - my_template="${TMPDIR-/tmp}/${1-$progname}" - - if test "$opt_dry_run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else - - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` - - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" - - save_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$my_tmpdir" - umask $save_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || \ - func_fatal_error "cannot create temporary directory \`$my_tmpdir'" - fi - - $ECHO "X$my_tmpdir" | $Xsed -} - - -# func_quote_for_eval arg -# Aesthetically quote ARG to be evaled later. -# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT -# is double-quoted, suitable for a subsequent eval, whereas -# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters -# which are still active within double quotes backslashified. -func_quote_for_eval () -{ - case $1 in - *[\\\`\"\$]*) - func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; - *) - func_quote_for_eval_unquoted_result="$1" ;; - esac - - case $func_quote_for_eval_unquoted_result in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and and variable - # expansion for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" - ;; - *) - func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" - esac -} - - -# func_quote_for_expand arg -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - case $1 in - *[\\\`\"]*) - my_arg=`$ECHO "X$1" | $Xsed \ - -e "$double_quote_subst" -e "$sed_double_backslash"` ;; - *) - my_arg="$1" ;; - esac - - case $my_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - my_arg="\"$my_arg\"" - ;; - esac - - func_quote_for_expand_result="$my_arg" -} - - -# func_show_eval cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$my_cmd" - my_status=$? - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - - -# func_show_eval_locale cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$lt_user_locale - $my_cmd" - my_status=$? - eval "$lt_safe_locale" - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - - - - - -# func_version -# Echo version message to standard output and exit. -func_version () -{ - $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { - s/^# // - s/^# *$// - s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ - p - }' < "$progpath" - exit $? -} - -# func_usage -# Echo short help message to standard output and exit. -func_usage () -{ - $SED -n '/^# Usage:/,/# -h/ { - s/^# // - s/^# *$// - s/\$progname/'$progname'/ - p - }' < "$progpath" - $ECHO - $ECHO "run \`$progname --help | more' for full usage" - exit $? -} - -# func_help -# Echo long help message to standard output and exit. -func_help () -{ - $SED -n '/^# Usage:/,/# Report bugs to/ { - s/^# // - s/^# *$// - s*\$progname*'$progname'* - s*\$host*'"$host"'* - s*\$SHELL*'"$SHELL"'* - s*\$LTCC*'"$LTCC"'* - s*\$LTCFLAGS*'"$LTCFLAGS"'* - s*\$LD*'"$LD"'* - s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ - p - }' < "$progpath" - exit $? -} - -# func_missing_arg argname -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () -{ - func_error "missing argument for $1" - exit_cmd=exit -} - -exit_cmd=: - - - - - -# Check that we have a working $ECHO. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then - # Yippee, $ECHO works! - : -else - # Restart under the correct shell, and then maybe $ECHO will work. - exec $SHELL "$progpath" --no-reexec ${1+"$@"} -fi -# Same for EGREP, and just to be sure, do LTCC as well -if test "x$EGREP" = x ; then - EGREP=egrep -fi -if test "x$LTCC" = x ; then - LTCC=${CC-gcc} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac -} - -# Parse options once, thoroughly. This comes as soon as possible in -# the script to make things like `libtool --version' happen quickly. -{ - - # Shorthand for --mode=foo, only valid as the first argument - case $1 in - clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; - compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; - execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; - finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; - install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; - link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; - uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; - esac - - # Parse non-mode specific arguments: - while test "$#" -gt 0; do - opt="$1" - shift - - case $opt in - --config) func_config ;; - - --debug) preserve_args="$preserve_args $opt" - func_echo "enabling shell trace mode" - opt_debug='set -x' - $opt_debug - ;; - - -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break - execute_dlfiles="$execute_dlfiles $1" - shift - ;; - - --dry-run | -n) opt_dry_run=: ;; - --features) func_features ;; - --finish) mode="finish" ;; - - --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break - case $1 in - # Valid mode arguments: - clean) ;; - compile) ;; - execute) ;; - finish) ;; - install) ;; - link) ;; - relink) ;; - uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; - esac - - mode="$1" - shift - ;; - - --preserve-dup-deps) - opt_duplicate_deps=: ;; - - --quiet|--silent) preserve_args="$preserve_args $opt" - opt_silent=: - ;; - - --verbose| -v) preserve_args="$preserve_args $opt" - opt_silent=false - ;; - - --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break - preserve_args="$preserve_args $opt $1" - func_enable_tag "$1" # tagname is set here - shift - ;; - - # Separate optargs to long options: - -dlopen=*|--mode=*|--tag=*) - func_opt_split "$opt" - set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} - shift - ;; - - -\?|-h) func_usage ;; - --help) opt_help=: ;; - --version) func_version ;; - - -*) func_fatal_help "unrecognized option \`$opt'" ;; - - *) nonopt="$opt" - break - ;; - esac - done - - - case $host in - *cygwin* | *mingw* | *pw32* | *cegcc*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_duplicate_deps - ;; - esac - - # Having warned about all mis-specified options, bail out if - # anything was wrong. - $exit_cmd $EXIT_FAILURE -} - -# func_check_version_match -# Ensure that we are using m4 macros, and libtool script from the same -# release of libtool. -func_check_version_match () -{ - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from an older release. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - fi - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, -$progname: but the definition of this LT_INIT comes from revision $macro_revision. -$progname: You should recreate aclocal.m4 with macros from revision $package_revision -$progname: of $PACKAGE $VERSION and run autoconf again. -_LT_EOF - fi - - exit $EXIT_MISMATCH - fi -} - - -## ----------- ## -## Main. ## -## ----------- ## - -$opt_help || { - # Sanity checks first: - func_check_version_match - - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi - - test -z "$mode" && func_fatal_error "error: you must specify a MODE." - - - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" - - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$mode' for more information." -} - - -# func_lalib_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_lalib_p () -{ - test -f "$1" && - $SED -e 4q "$1" 2>/dev/null \ - | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 -} - -# func_lalib_unsafe_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function implements the same check as func_lalib_p without -# resorting to external programs. To this end, it redirects stdin and -# closes it afterwards, without saving the original file descriptor. -# As a safety measure, use it only where a negative result would be -# fatal anyway. Works if `file' does not exist. -func_lalib_unsafe_p () -{ - lalib_p=no - if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then - for lalib_p_l in 1 2 3 4 - do - read lalib_p_line - case "$lalib_p_line" in - \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; - esac - done - exec 0<&5 5<&- - fi - test "$lalib_p" = yes -} - -# func_ltwrapper_script_p file -# True iff FILE is a libtool wrapper script -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_script_p () -{ - func_lalib_p "$1" -} - -# func_ltwrapper_executable_p file -# True iff FILE is a libtool wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_executable_p () -{ - func_ltwrapper_exec_suffix= - case $1 in - *.exe) ;; - *) func_ltwrapper_exec_suffix=.exe ;; - esac - $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 -} - -# func_ltwrapper_scriptname file -# Assumes file is an ltwrapper_executable -# uses $file to determine the appropriate filename for a -# temporary ltwrapper_script. -func_ltwrapper_scriptname () -{ - func_ltwrapper_scriptname_result="" - if func_ltwrapper_executable_p "$1"; then - func_dirname_and_basename "$1" "" "." - func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" - fi -} - -# func_ltwrapper_p file -# True iff FILE is a libtool wrapper script or wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_p () -{ - func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" -} - - -# func_execute_cmds commands fail_cmd -# Execute tilde-delimited COMMANDS. -# If FAIL_CMD is given, eval that upon failure. -# FAIL_CMD may read-access the current command in variable CMD! -func_execute_cmds () -{ - $opt_debug - save_ifs=$IFS; IFS='~' - for cmd in $1; do - IFS=$save_ifs - eval cmd=\"$cmd\" - func_show_eval "$cmd" "${2-:}" - done - IFS=$save_ifs -} - - -# func_source file -# Source FILE, adding directory component if necessary. -# Note that it is not necessary on cygwin/mingw to append a dot to -# FILE even if both FILE and FILE.exe exist: automatic-append-.exe -# behavior happens only for exec(3), not for open(2)! Also, sourcing -# `FILE.' does not work on cygwin managed mounts. -func_source () -{ - $opt_debug - case $1 in - */* | *\\*) . "$1" ;; - *) . "./$1" ;; - esac -} - - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - $opt_debug - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - func_quote_for_eval "$arg" - CC_quoted="$CC_quoted $func_quote_for_eval_result" - done - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - func_quote_for_eval "$arg" - CC_quoted="$CC_quoted $func_quote_for_eval_result" - done - case "$@ " in - " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with \`--tag'" -# else -# func_verbose "using $tagname tagged configuration" - fi - ;; - esac - fi -} - - - -# func_write_libtool_object output_name pic_name nonpic_name -# Create a libtool object file (analogous to a ".la" file), -# but don't create it if we're doing a dry run. -func_write_libtool_object () -{ - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' - else - write_lobj=none - fi - - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' - else - write_oldobj=none - fi - - $opt_dry_run || { - cat >${write_libobj}T <?"'"'"' &()|`$[]' \ - && func_warning "libobj name \`$libobj' may not contain shell special characters." - func_dirname_and_basename "$obj" "/" "" - objname="$func_basename_result" - xdir="$func_dirname_result" - lobj=${xdir}$objdir/$objname - - test -z "$base_compile" && \ - func_fatal_help "you must specify a compilation command" - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $ECHO "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - removelist="$removelist $output_obj" - $ECHO "$srcfile" > "$lockfile" - fi - - $opt_dry_run || $RM $removelist - removelist="$removelist $lockfile" - trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - command="$base_compile $qsrcfile $pic_flag" - else - # Don't build PIC code - command="$base_compile $qsrcfile" - fi - - func_mkdir_p "$xdir$objdir" - - if test -z "$output_obj"; then - # Place PIC objects in $objdir - command="$command -o $lobj" - fi - - func_show_eval_locale "$command" \ - 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - func_show_eval '$MV "$output_obj" "$lobj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - - # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then - suppress_output=' >/dev/null 2>&1' - fi - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $qsrcfile$pie_flag" - else - command="$base_compile $qsrcfile $pic_flag" - fi - if test "$compiler_c_o" = yes; then - command="$command -o $obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - command="$command$suppress_output" - func_show_eval_locale "$command" \ - '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - func_show_eval '$MV "$output_obj" "$obj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - fi - - $opt_dry_run || { - func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - removelist=$lockfile - $RM "$lockfile" - fi - } - - exit $EXIT_SUCCESS -} - -$opt_help || { -test "$mode" = compile && func_mode_compile ${1+"$@"} -} - -func_mode_help () -{ - # We need to display help for each of the modes. - case $mode in - "") - # Generic help is extracted from the usage comments - # at the start of this file. - func_help - ;; - - clean) - $ECHO \ -"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - - compile) - $ECHO \ -"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -no-suppress do not suppress compiler output for multiple passes - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -shared do not build a \`.o' file suitable for static linking - -static only build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - - execute) - $ECHO \ -"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - - finish) - $ECHO \ -"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - - install) - $ECHO \ -"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The following components of INSTALL-COMMAND are treated specially: - - -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - - link) - $ECHO \ -"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -shared only do dynamic linking of libtool libraries - -shrext SUFFIX override the standard shared library file extension - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -weak LIBNAME declare that the target provides the LIBNAME interface - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - - uninstall) - $ECHO \ -"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - - *) - func_fatal_help "invalid operation mode \`$mode'" - ;; - esac - - $ECHO - $ECHO "Try \`$progname --help' for more information about other modes." - - exit $? -} - - # Now that we've collected a possible --mode arg, show help if necessary - $opt_help && func_mode_help - - -# func_mode_execute arg... -func_mode_execute () -{ - $opt_debug - # The first argument is the command name. - cmd="$nonopt" - test -z "$cmd" && \ - func_fatal_help "you must specify a COMMAND" - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - test -f "$file" \ - || func_fatal_help "\`$file' is not a file" - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$lib' is not a valid libtool archive" - - # Read the libtool library. - dlname= - library_names= - func_source "$file" - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && \ - func_warning "\`$file' was not linked with \`-export-dynamic'" - continue - fi - - func_dirname "$file" "" "." - dir="$func_dirname_result" - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" - fi - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - func_dirname "$file" "" "." - dir="$func_dirname_result" - ;; - - *) - func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if func_ltwrapper_script_p "$file"; then - func_source "$file" - # Transform arg to wrapped name. - file="$progdir/$program" - elif func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - func_source "$func_ltwrapper_scriptname_result" - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - func_quote_for_eval "$file" - args="$args $func_quote_for_eval_result" - done - - if test "X$opt_dry_run" = Xfalse; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - else - $lt_unset $lt_var - fi" - done - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - $ECHO "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS - fi -} - -test "$mode" = execute && func_mode_execute ${1+"$@"} - - -# func_mode_finish arg... -func_mode_finish () -{ - $opt_debug - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - func_execute_cmds "$finish_cmds" 'admincmds="$admincmds -'"$cmd"'"' - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $opt_dry_run || eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - $opt_silent && exit $EXIT_SUCCESS - - $ECHO "X----------------------------------------------------------------------" | $Xsed - $ECHO "Libraries have been installed in:" - for libdir in $libdirs; do - $ECHO " $libdir" - done - $ECHO - $ECHO "If you ever happen to want to link against installed libraries" - $ECHO "in a given directory, LIBDIR, you must either use libtool, and" - $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" - $ECHO "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" - $ECHO " during execution" - fi - if test -n "$runpath_var"; then - $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" - $ECHO " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $ECHO " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $ECHO " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - $ECHO - - $ECHO "See any operating system documentation about shared libraries for" - case $host in - solaris2.[6789]|solaris2.1[0-9]) - $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" - $ECHO "pages." - ;; - *) - $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." - ;; - esac - $ECHO "X----------------------------------------------------------------------" | $Xsed - exit $EXIT_SUCCESS -} - -test "$mode" = finish && func_mode_finish ${1+"$@"} - - -# func_mode_install arg... -func_mode_install () -{ - $opt_debug - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $ECHO "X$nonopt" | $GREP shtool >/dev/null; then - # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " - arg=$1 - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - func_quote_for_eval "$arg" - install_prog="$install_prog$func_quote_for_eval_result" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - case " $install_prog " in - *[\\\ /]cp\ *) ;; - *) prev=$arg ;; - esac - ;; - -g | -m | -o) - prev=$arg - ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - func_quote_for_eval "$arg" - install_prog="$install_prog $func_quote_for_eval_result" - done - - test -z "$install_prog" && \ - func_fatal_help "you must specify an install program" - - test -n "$prev" && \ - func_fatal_help "the \`$prev' option requires an argument" - - if test -z "$files"; then - if test -z "$dest"; then - func_fatal_help "no file or destination specified" - else - func_fatal_help "you must specify a destination" - fi - fi - - # Strip any trailing slash from the destination. - func_stripname '' '/' "$dest" - dest=$func_stripname_result - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - func_dirname_and_basename "$dest" "" "." - destdir="$func_dirname_result" - destname="$func_basename_result" - - # Not a directory, so check to see that there is only one file specified. - set dummy $files; shift - test "$#" -gt 1 && \ - func_fatal_help "\`$dest' is not a directory" - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - func_fatal_help "\`$destdir' must be an absolute directory name" - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$file' is not a valid libtool archive" - - library_names= - old_library= - relink_command= - func_source "$file" - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - func_dirname "$file" "/" "" - dir="$func_dirname_result" - dir="$dir$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` - fi - - func_warning "relinking \`$file'" - func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' - fi - - # See the names of the shared library. - set dummy $library_names; shift - if test -n "$1"; then - realname="$1" - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ - 'exit $?' - tstripme="$stripme" - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - case $realname in - *.dll.a) - tstripme="" - ;; - esac - ;; - esac - if test -n "$tstripme" && test -n "$striplib"; then - func_show_eval "$striplib $destdir/$realname" 'exit $?' - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - test "$linkname" != "$realname" \ - && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - func_execute_cmds "$postinstall_cmds" 'exit $?' - fi - - # Install the pseudo-library for information purposes. - func_basename "$file" - name="$func_basename_result" - instname="$dir/$name"i - func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - func_lo2o "$destfile" - staticdest=$func_lo2o_result - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - func_fatal_help "cannot copy a libtool object to \`$destfile'" - ;; - esac - - # Install the libtool object if requested. - test -n "$destfile" && \ - func_show_eval "$install_prog $file $destfile" 'exit $?' - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - func_lo2o "$file" - staticobj=$func_lo2o_result - func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - func_stripname '' '.exe' "$file" - file=$func_stripname_result - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin* | *mingw*) - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - wrapper=$func_ltwrapper_scriptname_result - else - func_stripname '' '.exe' "$file" - wrapper=$func_stripname_result - fi - ;; - *) - wrapper=$file - ;; - esac - if func_ltwrapper_script_p "$wrapper"; then - notinst_deplibs= - relink_command= - - func_source "$wrapper" - - # Check the variables that should have been set. - test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script \`$wrapper'" - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - func_source "$lib" - fi - libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "\`$lib' has not been installed in \`$libdir'" - finalize=no - fi - done - - relink_command= - func_source "$wrapper" - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - $opt_dry_run || { - if test "$finalize" = yes; then - tmpdir=`func_mktempdir` - func_basename "$file$stripped_ext" - file="$func_basename_result" - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` - - $opt_silent || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" - } - if eval "$relink_command"; then : - else - func_error "error: relink \`$file' with the above command before installing it" - $opt_dry_run || ${RM}r "$tmpdir" - continue - fi - file="$outputname" - else - func_warning "cannot relink \`$file'" - fi - } - else - # Install the binary that we compiled earlier. - file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - func_stripname '' '.exe' "$destfile" - destfile=$func_stripname_result - ;; - esac - ;; - esac - func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' - $opt_dry_run || if test -n "$outputname"; then - ${RM}r "$tmpdir" - fi - ;; - esac - done - - for file in $staticlibs; do - func_basename "$file" - name="$func_basename_result" - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - func_show_eval "$install_prog \$file \$oldlib" 'exit $?' - - if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $oldlib" 'exit $?' - fi - - # Do each command in the postinstall commands. - func_execute_cmds "$old_postinstall_cmds" 'exit $?' - done - - test -n "$future_libdirs" && \ - func_warning "remember to run \`$progname --finish$future_libdirs'" - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi -} - -test "$mode" = install && func_mode_install ${1+"$@"} - - -# func_generate_dlsyms outputname originator pic_p -# Extract symbols from dlprefiles and create ${outputname}S.o with -# a dlpreopen symbol table. -func_generate_dlsyms () -{ - $opt_debug - my_outputname="$1" - my_originator="$2" - my_pic_p="${3-no}" - my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` - my_dlsyms= - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms="${my_outputname}S.c" - else - func_error "not configured to extract global symbols from dlpreopened files" - fi - fi - - if test -n "$my_dlsyms"; then - case $my_dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${my_outputname}.nm" - - func_show_eval "$RM $nlist ${nlist}S ${nlist}T" - - # Parse the name list into a source file. - func_verbose "creating $output_objdir/$my_dlsyms" - - $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - func_verbose "generating symbol list for \`$output'" - - $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for progfile in $progfiles; do - func_verbose "extracting global C symbols from \`$progfile'" - $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $opt_dry_run || { - eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - if test -n "$export_symbols_regex"; then - $opt_dry_run || { - eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $opt_dry_run || { - $RM $export_symbols - eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - } - else - $opt_dry_run || { - eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - case $host in - *cygwin | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - } - fi - fi - - for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from \`$dlprefile'" - func_basename "$dlprefile" - name="$func_basename_result" - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - done - - $opt_dry_run || { - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $MV "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if $GREP -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - $GREP -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' - else - $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" - fi - - $ECHO >> "$output_objdir/$my_dlsyms" "\ - -/* The mapping between symbol names and symbols. */ -typedef struct { - const char *name; - void *address; -} lt_dlsymlist; -" - case $host in - *cygwin* | *mingw* | *cegcc* ) - $ECHO >> "$output_objdir/$my_dlsyms" "\ -/* DATA imports from DLLs on WIN32 con't be const, because - runtime relocations are performed -- see ld's documentation - on pseudo-relocs. */" - lt_dlsym_const= ;; - *osf5*) - echo >> "$output_objdir/$my_dlsyms" "\ -/* This system does not cope well with relocations in const data */" - lt_dlsym_const= ;; - *) - lt_dlsym_const=const ;; - esac - - $ECHO >> "$output_objdir/$my_dlsyms" "\ -extern $lt_dlsym_const lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[]; -$lt_dlsym_const lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[] = -{\ - { \"$my_originator\", (void *) 0 }," - - case $need_lib_prefix in - no) - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - *) - eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - esac - $ECHO >> "$output_objdir/$my_dlsyms" "\ - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_${my_prefix}_LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - } # !$opt_dry_run - - pic_flag_for_symtable= - case "$compile_command " in - *" -static "*) ;; - *) - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; - *-*-hpux*) - pic_flag_for_symtable=" $pic_flag" ;; - *) - if test "X$my_pic_p" != Xno; then - pic_flag_for_symtable=" $pic_flag" - fi - ;; - esac - ;; - esac - symtab_cflags= - for arg in $LTCFLAGS; do - case $arg in - -pie | -fpie | -fPIE) ;; - *) symtab_cflags="$symtab_cflags $arg" ;; - esac - done - - # Now compile the dynamic symbol file. - func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' - - # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' - - # Transform the symbol file into the correct name. - symfileobj="$output_objdir/${my_outputname}S.$objext" - case $host in - *cygwin* | *mingw* | *cegcc* ) - if test -f "$output_objdir/$my_outputname.def"; then - compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - else - compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` - fi - ;; - *) - compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` - ;; - esac - ;; - *) - func_fatal_error "unknown suffix for \`$my_dlsyms'" - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` - finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` - fi -} - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -func_win32_libid () -{ - $opt_debug - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then - win32_nmres=`eval $NM -f posix -A $1 | - $SED -n -e ' - 1,100{ - / I /{ - s,.*,import, - p - q - } - }'` - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $ECHO "$win32_libid_type" -} - - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - $opt_debug - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" - fi -} - - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - $opt_debug - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - func_basename "$my_xlib" - my_xlib="$func_basename_result" - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - func_arith $extracted_serial + 1 - extracted_serial=$func_arith_result - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" - - func_mkdir_p "$my_xdir" - - case $host in - *-darwin*) - func_verbose "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - $opt_dry_run || { - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`basename "$darwin_archive"` - darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` - if test -n "$darwin_arches"; then - darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we've a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` - $LIPO -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - $RM -rf unfat-$$ - cd "$darwin_orig_dir" - else - cd $darwin_orig_dir - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - } # !$opt_dry_run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` - done - - func_extract_archives_result="$my_oldobjs" -} - - - -# func_emit_wrapper_part1 [arg=no] -# -# Emit the first part of a libtool wrapper script on stdout. -# For more information, see the description associated with -# func_emit_wrapper(), below. -func_emit_wrapper_part1 () -{ - func_emit_wrapper_part1_arg1=no - if test -n "$1" ; then - func_emit_wrapper_part1_arg1=$1 - fi - - $ECHO "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='${SED} -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variables: - generated_by_libtool_version='$macro_version' - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$ECHO are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - ECHO=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$ECHO works! - : - else - # Restart under the correct shell, and then maybe \$ECHO will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $ECHO "\ - - # Find the directory that this script lives in. - thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` - done -" -} -# end: func_emit_wrapper_part1 - -# func_emit_wrapper_part2 [arg=no] -# -# Emit the second part of a libtool wrapper script on stdout. -# For more information, see the description associated with -# func_emit_wrapper(), below. -func_emit_wrapper_part2 () -{ - func_emit_wrapper_part2_arg1=no - if test -n "$1" ; then - func_emit_wrapper_part2_arg1=$1 - fi - - $ECHO "\ - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 - if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then - # special case for '.' - if test \"\$thisdir\" = \".\"; then - thisdir=\`pwd\` - fi - # remove .libs from thisdir - case \"\$thisdir\" in - *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; - $objdir ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $ECHO "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $MKDIR \"\$progdir\" - else - $RM \"\$progdir/\$file\" - fi" - - $ECHO "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $ECHO \"\$relink_command_output\" >&2 - $RM \"\$progdir/\$file\" - exit 1 - fi - fi - - $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $RM \"\$progdir/\$program\"; - $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $RM \"\$progdir/\$file\" - fi" - else - $ECHO "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $ECHO "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $ECHO "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $ECHO "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $ECHO "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) - $ECHO "\ - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $ECHO "\ - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $ECHO "\ - \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 - exit 1 - fi - else - # The program doesn't exist. - \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 - $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" -} -# end: func_emit_wrapper_part2 - - -# func_emit_wrapper [arg=no] -# -# Emit a libtool wrapper script on stdout. -# Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw -# wrapper executable. Must ONLY be called from within -# func_mode_link because it depends on a number of variables -# set therein. -# -# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR -# variable will take. If 'yes', then the emitted script -# will assume that the directory in which it is stored is -# the $objdir directory. This is a cygwin/mingw-specific -# behavior. -func_emit_wrapper () -{ - func_emit_wrapper_arg1=no - if test -n "$1" ; then - func_emit_wrapper_arg1=$1 - fi - - # split this up so that func_emit_cwrapperexe_src - # can call each part independently. - func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" - func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" -} - - -# func_to_host_path arg -# -# Convert paths to host format when used with build tools. -# Intended for use with "native" mingw (where libtool itself -# is running under the msys shell), or in the following cross- -# build environments: -# $build $host -# mingw (msys) mingw [e.g. native] -# cygwin mingw -# *nix + wine mingw -# where wine is equipped with the `winepath' executable. -# In the native mingw case, the (msys) shell automatically -# converts paths for any non-msys applications it launches, -# but that facility isn't available from inside the cwrapper. -# Similar accommodations are necessary for $host mingw and -# $build cygwin. Calling this function does no harm for other -# $host/$build combinations not listed above. -# -# ARG is the path (on $build) that should be converted to -# the proper representation for $host. The result is stored -# in $func_to_host_path_result. -func_to_host_path () -{ - func_to_host_path_result="$1" - if test -n "$1" ; then - case $host in - *mingw* ) - lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - case $build in - *mingw* ) # actually, msys - # awkward: cmd appends spaces to result - lt_sed_strip_trailing_spaces="s/[ ]*\$//" - func_to_host_path_tmp1=`( cmd //c echo "$1" |\ - $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` - func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ - $SED -e "$lt_sed_naive_backslashify"` - ;; - *cygwin* ) - func_to_host_path_tmp1=`cygpath -w "$1"` - func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ - $SED -e "$lt_sed_naive_backslashify"` - ;; - * ) - # Unfortunately, winepath does not exit with a non-zero - # error code, so we are forced to check the contents of - # stdout. On the other hand, if the command is not - # found, the shell will set an exit code of 127 and print - # *an error message* to stdout. So we must check for both - # error code of zero AND non-empty stdout, which explains - # the odd construction: - func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` - if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then - func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ - $SED -e "$lt_sed_naive_backslashify"` - else - # Allow warning below. - func_to_host_path_result="" - fi - ;; - esac - if test -z "$func_to_host_path_result" ; then - func_error "Could not determine host path corresponding to" - func_error " '$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback: - func_to_host_path_result="$1" - fi - ;; - esac - fi -} -# end: func_to_host_path - -# func_to_host_pathlist arg -# -# Convert pathlists to host format when used with build tools. -# See func_to_host_path(), above. This function supports the -# following $build/$host combinations (but does no harm for -# combinations not listed here): -# $build $host -# mingw (msys) mingw [e.g. native] -# cygwin mingw -# *nix + wine mingw -# -# Path separators are also converted from $build format to -# $host format. If ARG begins or ends with a path separator -# character, it is preserved (but converted to $host format) -# on output. -# -# ARG is a pathlist (on $build) that should be converted to -# the proper representation on $host. The result is stored -# in $func_to_host_pathlist_result. -func_to_host_pathlist () -{ - func_to_host_pathlist_result="$1" - if test -n "$1" ; then - case $host in - *mingw* ) - lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - # Remove leading and trailing path separator characters from - # ARG. msys behavior is inconsistent here, cygpath turns them - # into '.;' and ';.', and winepath ignores them completely. - func_to_host_pathlist_tmp2="$1" - # Once set for this call, this variable should not be - # reassigned. It is used in tha fallback case. - func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ - $SED -e 's|^:*||' -e 's|:*$||'` - case $build in - *mingw* ) # Actually, msys. - # Awkward: cmd appends spaces to result. - lt_sed_strip_trailing_spaces="s/[ ]*\$//" - func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ - $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` - func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ - $SED -e "$lt_sed_naive_backslashify"` - ;; - *cygwin* ) - func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` - func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ - $SED -e "$lt_sed_naive_backslashify"` - ;; - * ) - # unfortunately, winepath doesn't convert pathlists - func_to_host_pathlist_result="" - func_to_host_pathlist_oldIFS=$IFS - IFS=: - for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do - IFS=$func_to_host_pathlist_oldIFS - if test -n "$func_to_host_pathlist_f" ; then - func_to_host_path "$func_to_host_pathlist_f" - if test -n "$func_to_host_path_result" ; then - if test -z "$func_to_host_pathlist_result" ; then - func_to_host_pathlist_result="$func_to_host_path_result" - else - func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" - fi - fi - fi - IFS=: - done - IFS=$func_to_host_pathlist_oldIFS - ;; - esac - if test -z "$func_to_host_pathlist_result" ; then - func_error "Could not determine the host path(s) corresponding to" - func_error " '$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback. This may break if $1 contains DOS-style drive - # specifications. The fix is not to complicate the expression - # below, but for the user to provide a working wine installation - # with winepath so that path translation in the cross-to-mingw - # case works properly. - lt_replace_pathsep_nix_to_dos="s|:|;|g" - func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ - $SED -e "$lt_replace_pathsep_nix_to_dos"` - fi - # Now, add the leading and trailing path separators back - case "$1" in - :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" - ;; - esac - case "$1" in - *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" - ;; - esac - ;; - esac - fi -} -# end: func_to_host_pathlist - -# func_emit_cwrapperexe_src -# emit the source code for a wrapper executable on stdout -# Must ONLY be called from within func_mode_link because -# it depends on a number of variable set therein. -func_emit_cwrapperexe_src () -{ - cat < -#include -#ifdef _MSC_VER -# include -# include -# include -# define setmode _setmode -#else -# include -# include -# ifdef __CYGWIN__ -# include -# define HAVE_SETENV -# ifdef __STRICT_ANSI__ -char *realpath (const char *, char *); -int putenv (char *); -int setenv (const char *, const char *, int); -# endif -# endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef S_IXOTH -# define S_IXOTH 0 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0 -#endif - -#ifdef _MSC_VER -# define S_IXUSR _S_IEXEC -# define stat _stat -# ifndef _INTPTR_T_DEFINED -# define intptr_t int -# endif -#endif - -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -# define HAVE_DOS_BASED_FILE_SYSTEM -# define FOPEN_WB "wb" -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#ifdef __CYGWIN__ -# define FOPEN_WB "wb" -#endif - -#ifndef FOPEN_WB -# define FOPEN_WB "w" -#endif -#ifndef _O_BINARY -# define _O_BINARY 0 -#endif - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -#undef LTWRAPPER_DEBUGPRINTF -#if defined DEBUGWRAPPER -# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args -static void -ltwrapper_debugprintf (const char *fmt, ...) -{ - va_list args; - va_start (args, fmt); - (void) vfprintf (stderr, fmt, args); - va_end (args); -} -#else -# define LTWRAPPER_DEBUGPRINTF(args) -#endif - -const char *program_name = NULL; - -void *xmalloc (size_t num); -char *xstrdup (const char *string); -const char *base_name (const char *name); -char *find_executable (const char *wrapper); -char *chase_symlinks (const char *pathspec); -int make_executable (const char *path); -int check_executable (const char *path); -char *strendzap (char *str, const char *pat); -void lt_fatal (const char *message, ...); -void lt_setenv (const char *name, const char *value); -char *lt_extend_str (const char *orig_value, const char *add, int to_end); -void lt_opt_process_env_set (const char *arg); -void lt_opt_process_env_prepend (const char *arg); -void lt_opt_process_env_append (const char *arg); -int lt_split_name_value (const char *arg, char** name, char** value); -void lt_update_exe_path (const char *name, const char *value); -void lt_update_lib_path (const char *name, const char *value); - -static const char *script_text_part1 = -EOF - - func_emit_wrapper_part1 yes | - $SED -e 's/\([\\"]\)/\\\1/g' \ - -e 's/^/ "/' -e 's/$/\\n"/' - echo ";" - cat <"))); - for (i = 0; i < newargc; i++) - { - LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); - } - -EOF - - case $host_os in - mingw*) - cat <<"EOF" - /* execv doesn't actually work on mingw as expected on unix */ - rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); - if (rval == -1) - { - /* failed to start process */ - LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); - return 127; - } - return rval; -EOF - ;; - *) - cat <<"EOF" - execv (lt_argv_zero, newargz); - return rval; /* =127, but avoids unused variable warning */ -EOF - ;; - esac - - cat <<"EOF" -} - -void * -xmalloc (size_t num) -{ - void *p = (void *) malloc (num); - if (!p) - lt_fatal ("Memory exhausted"); - - return p; -} - -char * -xstrdup (const char *string) -{ - return string ? strcpy ((char *) xmalloc (strlen (string) + 1), - string) : NULL; -} - -const char * -base_name (const char *name) -{ - const char *base; - -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - /* Skip over the disk name in MSDOS pathnames. */ - if (isalpha ((unsigned char) name[0]) && name[1] == ':') - name += 2; -#endif - - for (base = name; *name; name++) - if (IS_DIR_SEPARATOR (*name)) - base = name + 1; - return base; -} - -int -check_executable (const char *path) -{ - struct stat st; - - LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", - path ? (*path ? path : "EMPTY!") : "NULL!")); - if ((!path) || (!*path)) - return 0; - - if ((stat (path, &st) >= 0) - && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - return 1; - else - return 0; -} - -int -make_executable (const char *path) -{ - int rval = 0; - struct stat st; - - LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", - path ? (*path ? path : "EMPTY!") : "NULL!")); - if ((!path) || (!*path)) - return 0; - - if (stat (path, &st) >= 0) - { - rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); - } - return rval; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise - Does not chase symlinks, even on platforms that support them. -*/ -char * -find_executable (const char *wrapper) -{ - int has_slash = 0; - const char *p; - const char *p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - int tmp_len; - char *concat_name; - - LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", - wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char *path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char *q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR (*q)) - break; - p_len = q - p; - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - tmp_len = strlen (tmp); - concat_name = - XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = - XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - tmp_len = strlen (tmp); - concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - return NULL; -} - -char * -chase_symlinks (const char *pathspec) -{ -#ifndef S_ISLNK - return xstrdup (pathspec); -#else - char buf[LT_PATHMAX]; - struct stat s; - char *tmp_pathspec = xstrdup (pathspec); - char *p; - int has_symlinks = 0; - while (strlen (tmp_pathspec) && !has_symlinks) - { - LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", - tmp_pathspec)); - if (lstat (tmp_pathspec, &s) == 0) - { - if (S_ISLNK (s.st_mode) != 0) - { - has_symlinks = 1; - break; - } - - /* search backwards for last DIR_SEPARATOR */ - p = tmp_pathspec + strlen (tmp_pathspec) - 1; - while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - p--; - if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - { - /* no more DIR_SEPARATORS left */ - break; - } - *p = '\0'; - } - else - { - char *errstr = strerror (errno); - lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); - } - } - XFREE (tmp_pathspec); - - if (!has_symlinks) - { - return xstrdup (pathspec); - } - - tmp_pathspec = realpath (pathspec, buf); - if (tmp_pathspec == 0) - { - lt_fatal ("Could not follow symlinks for %s", pathspec); - } - return xstrdup (tmp_pathspec); -#endif -} - -char * -strendzap (char *str, const char *pat) -{ - size_t len, patlen; - - assert (str != NULL); - assert (pat != NULL); - - len = strlen (str); - patlen = strlen (pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp (str, pat) == 0) - *str = '\0'; - } - return str; -} - -static void -lt_error_core (int exit_status, const char *mode, - const char *message, va_list ap) -{ - fprintf (stderr, "%s: %s: ", program_name, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, "FATAL", message, ap); - va_end (ap); -} - -void -lt_setenv (const char *name, const char *value) -{ - LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", - (name ? name : ""), - (value ? value : ""))); - { -#ifdef HAVE_SETENV - /* always make a copy, for consistency with !HAVE_SETENV */ - char *str = xstrdup (value); - setenv (name, str, 1); -#else - int len = strlen (name) + 1 + strlen (value) + 1; - char *str = XMALLOC (char, len); - sprintf (str, "%s=%s", name, value); - if (putenv (str) != EXIT_SUCCESS) - { - XFREE (str); - } -#endif - } -} - -char * -lt_extend_str (const char *orig_value, const char *add, int to_end) -{ - char *new_value; - if (orig_value && *orig_value) - { - int orig_value_len = strlen (orig_value); - int add_len = strlen (add); - new_value = XMALLOC (char, add_len + orig_value_len + 1); - if (to_end) - { - strcpy (new_value, orig_value); - strcpy (new_value + orig_value_len, add); - } - else - { - strcpy (new_value, add); - strcpy (new_value + add_len, orig_value); - } - } - else - { - new_value = xstrdup (add); - } - return new_value; -} - -int -lt_split_name_value (const char *arg, char** name, char** value) -{ - const char *p; - int len; - if (!arg || !*arg) - return 1; - - p = strchr (arg, (int)'='); - - if (!p) - return 1; - - *value = xstrdup (++p); - - len = strlen (arg) - strlen (*value); - *name = XMALLOC (char, len); - strncpy (*name, arg, len-1); - (*name)[len - 1] = '\0'; - - return 0; -} - -void -lt_opt_process_env_set (const char *arg) -{ - char *name = NULL; - char *value = NULL; - - if (lt_split_name_value (arg, &name, &value) != 0) - { - XFREE (name); - XFREE (value); - lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); - } - - lt_setenv (name, value); - XFREE (name); - XFREE (value); -} - -void -lt_opt_process_env_prepend (const char *arg) -{ - char *name = NULL; - char *value = NULL; - char *new_value = NULL; - - if (lt_split_name_value (arg, &name, &value) != 0) - { - XFREE (name); - XFREE (value); - lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); - } - - new_value = lt_extend_str (getenv (name), value, 0); - lt_setenv (name, new_value); - XFREE (new_value); - XFREE (name); - XFREE (value); -} - -void -lt_opt_process_env_append (const char *arg) -{ - char *name = NULL; - char *value = NULL; - char *new_value = NULL; - - if (lt_split_name_value (arg, &name, &value) != 0) - { - XFREE (name); - XFREE (value); - lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); - } - - new_value = lt_extend_str (getenv (name), value, 1); - lt_setenv (name, new_value); - XFREE (new_value); - XFREE (name); - XFREE (value); -} - -void -lt_update_exe_path (const char *name, const char *value) -{ - LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", - (name ? name : ""), - (value ? value : ""))); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - /* some systems can't cope with a ':'-terminated path #' */ - int len = strlen (new_value); - while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) - { - new_value[len-1] = '\0'; - } - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -void -lt_update_lib_path (const char *name, const char *value) -{ - LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", - (name ? name : ""), - (value ? value : ""))); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - lt_setenv (name, new_value); - XFREE (new_value); - } -} - - -EOF -} -# end: func_emit_cwrapperexe_src - -# func_mode_link arg... -func_mode_link () -{ - $opt_debug - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invocation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args=$nonopt - base_compile="$nonopt $@" - compile_command=$nonopt - finalize_command=$nonopt - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - new_inherited_linker_flags= - - avoid_version=no - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - non_pic_objects= - precious_files_regex= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - vinfo_number=no - weak_libs= - single_module="${wl}-single_module" - func_infer_tag $base_compile - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - break - ;; - -all-static | -static | -static-libtool-libs) - case $arg in - -all-static) - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - func_warning "complete static linking is impossible in this configuration" - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - func_append compile_command " @OUTPUT@" - func_append finalize_command " @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - func_append compile_command " @SYMFILE@" - func_append finalize_command " @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - test -f "$arg" \ - || func_fatal_error "symbol file \`$arg' does not exist" - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - framework) - case $host in - *-*-darwin*) - case "$deplibs " in - *" $qarg.ltframework "*) ;; - *) deplibs="$deplibs $qarg.ltframework" # this is fixed later - ;; - esac - ;; - esac - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat "$save_arg"` - do -# moreargs="$moreargs $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - done - else - func_fatal_error "link input file \`$arg' does not exist" - fi - arg=$save_arg - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - weak) - weak_libs="$weak_libs $arg" - prev= - continue - ;; - xcclinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - func_append compile_command " $wl$qarg" - func_append finalize_command " $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - # See comment for -static flag below, for more details. - func_append compile_command " $link_static_flag" - func_append finalize_command " $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - func_fatal_error "\`-allow-undefined' must not be used because it is the default" - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - func_fatal_error "more than one -exported-symbols argument is not allowed" - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework) - prev=framework - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - func_append compile_command " $arg" - func_append finalize_command " $arg" - ;; - esac - continue - ;; - - -L*) - func_stripname '-L' '' "$arg" - dir=$func_stripname_result - if test -z "$dir"; then - if test "$#" -gt 0; then - func_fatal_error "require no space between \`-L' and \`$1'" - else - func_fatal_error "need path for \`-L' option" - fi - fi - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of \`$dir'" - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - ::) dllsearchpath=$dir;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) dllsearchpath="$dllsearchpath:$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - deplibs="$deplibs System.ltframework" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test "X$arg" = "X-lc" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot) - compiler_flags="$compiler_flags $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) - compiler_flags="$compiler_flags $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case "$new_inherited_linker_flags " in - *" $arg "*) ;; - * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; - esac - continue - ;; - - -multi_module) - single_module="${wl}-multi_module" - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) - # The PATH hackery in wrapper scripts is required on Windows - # and Darwin in order for the loader to find any dlls it needs. - func_warning "\`-no-install' is ignored for $host" - func_warning "assuming \`-no-fast-install' instead" - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - func_stripname '-R' '' "$arg" - dir=$func_stripname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -shared) - # The effects of -shared are defined in a previous loop. - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -weak) - prev=weak - continue - ;; - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - arg="$arg $wl$func_quote_for_eval_result" - compiler_flags="$compiler_flags $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Wl,*) - func_stripname '-Wl,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - arg="$arg $wl$func_quote_for_eval_result" - compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" - linker_flags="$linker_flags $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # -msg_* for osf cc - -msg_*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - # -64, -mips[0-9] enable 64-bit mode on the SGI compiler - # -r[0-9][0-9]* specifies the processor on the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler - # +DA*, +DD* enable 64-bit mode on the HP compiler - # -q* pass through compiler args for the IBM compiler - # -m*, -t[45]*, -txscale* pass through architecture-specific - # compiler args for GCC - # -F/path gives path to uninstalled frameworks, gcc on darwin - # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC - # @file GCC response files - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ - -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - func_append compile_command " $arg" - func_append finalize_command " $arg" - compiler_flags="$compiler_flags $arg" - continue - ;; - - # Some other compiler flag. - -* | +*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - *.$objext) - # A standard object. - objs="$objs $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - done # argument parsing loop - - test -n "$prev" && \ - func_fatal_help "the \`$prevarg' option requires an argument" - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - func_basename "$output" - outputname="$func_basename_result" - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - func_dirname "$output" "/" "" - output_objdir="$func_dirname_result$objdir" - # Create the object directory. - func_mkdir_p "$output_objdir" - - # Determine the type of output - case $output in - "") - func_fatal_help "you must specify an output file" - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if $opt_duplicate_deps ; then - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - libs="$libs $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if $opt_duplicate_compiler_generated_deps; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; - esac - pre_post_deps="$pre_post_deps $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - - case $linkmode in - lib) - passes="conv dlpreopen link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - - for pass in $passes; do - # The preopen pass in lib mode reverses $deplibs; put it back here - # so that -L comes before libs that need it for instance... - if test "$linkmode,$pass" = "lib,link"; then - ## FIXME: Find the place where the list is rebuilt in the wrong - ## order, and fix it there properly - tmp_deplibs= - for deplib in $deplibs; do - tmp_deplibs="$deplib $tmp_deplibs" - done - deplibs="$tmp_deplibs" - fi - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - if test "$linkmode,$pass" = "lib,dlpreopen"; then - # Collect and forward deplibs of preopened libtool libs - for lib in $dlprefiles; do - # Ignore non-libtool-libs - dependency_libs= - case $lib in - *.la) func_source "$lib" ;; - esac - - # Collect preopened libtool deplibs, except any this library - # has declared as weak libs - for deplib in $dependency_libs; do - deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` - case " $weak_libs " in - *" $deplib_base "*) ;; - *) deplibs="$deplibs $deplib" ;; - esac - done - done - libs="$dlprefiles" - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - compiler_flags="$compiler_flags $deplib" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; - esac - fi - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - func_warning "\`-l' is ignored for archives/objects" - continue - fi - func_stripname '-l' '' "$deplib" - name=$func_stripname_result - if test "$linkmode" = lib; then - searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" - else - searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" - fi - for searchdir in $searchdirs; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if func_lalib_p "$lib"; then - library_names= - old_library= - func_source "$lib" - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - *.ltframework) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; - esac - fi - fi - continue - ;; - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - func_stripname '-L' '' "$deplib" - newlib_search_path="$newlib_search_path $func_stripname_result" - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - func_stripname '-L' '' "$deplib" - newlib_search_path="$newlib_search_path $func_stripname_result" - ;; - *) - func_warning "\`-L' is ignored for archives/objects" - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - func_stripname '-R' '' "$deplib" - dir=$func_stripname_result - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - # Linking convenience modules into shared libraries is allowed, - # but linking other static libraries is non-portable. - case " $dlpreconveniencelibs " in - *" $deplib "*) ;; - *) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - $ECHO - $ECHO "*** Warning: Trying to link with static lib archive $deplib." - $ECHO "*** I have the capability to make that library automatically link in when" - $ECHO "*** you link to this library. But I can only do this if you have a" - $ECHO "*** shared version of the library, which you do not appear to have" - $ECHO "*** because the file extensions .$libext of this argument makes me believe" - $ECHO "*** that it is just a static archive that I should not use here." - else - $ECHO - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - ;; - esac - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - - if test "$found" = yes || test -f "$lib"; then : - else - func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" - fi - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$lib" \ - || func_fatal_error "\`$lib' is not a valid libtool archive" - - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - inherited_linker_flags= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - func_source "$lib" - - # Convert "-framework foo" to "foo.ltframework" - if test -n "$inherited_linker_flags"; then - tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` - for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do - case " $new_inherited_linker_flags " in - *" $tmp_inherited_linker_flag "*) ;; - *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; - esac - done - fi - dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - elif test "$linkmode" != prog && test "$linkmode" != lib; then - func_fatal_error "\`$lib' is not a convenience library" - fi - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_duplicate_deps ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - func_fatal_error "cannot -dlopen a convenience library: \`$lib'" - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - dlprefiles="$dlprefiles $lib $dependency_libs" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of \`$ladir'" - func_warning "passing it literally to the linker, although it might fail" - abs_ladir="$ladir" - fi - ;; - esac - func_basename "$lib" - laname="$func_basename_result" - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library \`$lib' was moved." - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi - fi # $installed = yes - func_stripname 'lib' '.la' "$laname" - name=$func_stripname_result - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir" && test "$linkmode" = prog; then - func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - newlib_search_path="$newlib_search_path $func_stripname_result" - ;; - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if $opt_duplicate_deps ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath:" in - *"$absdir:"*) ;; - *) temp_rpath="$temp_rpath$absdir:" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes; then - use_static_libs=no - fi - if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then - case $host in - *cygwin* | *mingw* | *cegcc*) - # No point in relinking DLLs because paths are not encoded - notinst_deplibs="$notinst_deplibs $lib" - need_relink=no - ;; - *) - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - ;; - esac - # This is a shared library - - # Warn about portability, can't link against -module's on some - # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule="" - for dlpremoduletest in $dlprefiles; do - if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule="$dlpremoduletest" - break - fi - done - if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then - $ECHO - if test "$linkmode" = prog; then - $ECHO "*** Warning: Linking the executable $output against the loadable module" - else - $ECHO "*** Warning: Linking the shared library $output against the loadable module" - fi - $ECHO "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - shift - realname="$1" - shift - libname=`eval "\\$ECHO \"$libname_spec\""` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw* | *cegcc*) - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - func_basename "$soroot" - soname="$func_basename_result" - func_stripname 'lib' '.dll' "$soname" - newlib=libimp-$func_stripname_result.a - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - func_verbose "extracting exported symbol list from \`$soname'" - func_execute_cmds "$extract_expsyms_cmds" 'exit $?' - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for \`$soname'" - func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a (non-dlopened) module then we can not - # link against it, someone is ignoring the earlier warnings - if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null ; then - if test "X$dlopenmodule" != "X$lib"; then - $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - $ECHO - $ECHO "*** And there doesn't seem to be a static archive available" - $ECHO "*** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - elif test -n "$old_library"; then - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - func_fatal_configuration "unsupported hardcode properties" - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && - test "$hardcode_minus_L" != yes && - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - $ECHO - $ECHO "*** Warning: This system can not link to static lib archive $lib." - $ECHO "*** I have the capability to make that library automatically link in when" - $ECHO "*** you link to this library. But I can only do this if you have a" - $ECHO "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - $ECHO "*** But as you try to build a module library, libtool will still create " - $ECHO "*** a static module, that should work as long as the dlopening application" - $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - $ECHO - $ECHO "*** However, this would only work if libtool was able to extract symbol" - $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" - $ECHO "*** not find such a program. So, this module is probably useless." - $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) func_stripname '-R' '' "$libdir" - temp_xrpath=$func_stripname_result - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - if $opt_duplicate_deps ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - func_dirname "$deplib" "" "." - dir="$func_dirname_result" - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of \`$dir'" - absdir="$dir" - fi - ;; - esac - if $GREP "^installed=no" $deplib > /dev/null; then - case $host in - *-*-darwin*) - depdepl= - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$absdir/$objdir/$depdepl" ; then - depdepl="$absdir/$objdir/$depdepl" - darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - if test -z "$darwin_install_name"; then - darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - fi - compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" - linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" - path= - fi - fi - ;; - *) - path="-L$absdir/$objdir" - ;; - esac - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - test "$absdir" != "$libdir" && \ - func_warning "\`$deplib' seems to be moved" - - path="-L$absdir" - fi - ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test "$pass" = link; then - if test "$linkmode" = "prog"; then - compile_deplibs="$new_inherited_linker_flags $compile_deplibs" - finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" - else - compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` - fi - fi - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - tmp_libs="$tmp_libs $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - fi - if test "$linkmode" = prog || test "$linkmode" = lib; then - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for archives" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for archives" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for archives" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for archives" - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for archives" - - test -n "$release" && \ - func_warning "\`-release' is ignored for archives" - - test -n "$export_symbols$export_symbols_regex" && \ - func_warning "\`-export-symbols' is ignored for archives" - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - func_stripname 'lib' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - test "$module" = no && \ - func_fatal_help "libtool library \`$output' must begin with \`lib'" - - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - func_stripname '' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - func_stripname '' '.la' "$outputname" - libname=$func_stripname_result - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" - else - $ECHO - $ECHO "*** Warning: Linking the shared library $output against the non-libtool" - $ECHO "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - test "$dlself" != no && \ - func_warning "\`-dlopen self' is ignored for libtool libraries" - - set dummy $rpath - shift - test "$#" -gt 1 && \ - func_warning "ignoring multiple \`-rpath's for a libtool library" - - install_libdir="$1" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for convenience libraries" - - test -n "$release" && \ - func_warning "\`-release' is ignored for convenience libraries" - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - shift - IFS="$save_ifs" - - test -n "$7" && \ - func_fatal_help "too many parameters to \`-version-info'" - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$1" - number_minor="$2" - number_revision="$3" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - darwin|linux|osf|windows|none) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_minor" - lt_irix_increment=no - ;; - esac - ;; - no) - current="$1" - revision="$2" - age="$3" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "CURRENT \`$current' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "REVISION \`$revision' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "AGE \`$age' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - if test "$age" -gt "$current"; then - func_error "AGE \`$age' is greater than the current interface number \`$current'" - func_fatal_error "\`$vinfo' is not valid version information" - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - func_arith $current + 1 - minor_current=$func_arith_result - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current" - ;; - - irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then - func_arith $current - $age - else - func_arith $current - $age + 1 - fi - major=$func_arith_result - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - func_arith $revision - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - ;; - - osf) - func_arith $current - $age - major=.$func_arith_result - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - func_arith $current - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - qnx) - major=".$current" - versuffix=".$current" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - - *) - func_fatal_configuration "unknown library version type \`$version_type'" - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - func_warning "undefined symbols not allowed in $host shared libraries" - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - - fi - - func_generate_dlsyms "$libname" "$libname" "yes" - libobjs="$libobjs $symfileobj" - test "X$libobjs" = "X " && libobjs= - - if test "$mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$ECHO "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext | *.gcno) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - removelist="$removelist $p" - ;; - *) ;; - esac - done - test -n "$removelist" && \ - func_show_eval "${RM}r \$removelist" - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - #for path in $notinst_path; do - # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` - # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` - # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` - #done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs System.ltframework" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $opt_dry_run || $RM conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null | - $GREP " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | - $SED -e 10q | - $EGREP "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $ECHO - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - $ECHO "*** I have the capability to make that library automatically link in when" - $ECHO "*** you link to this library. But I can only do this if you have a" - $ECHO "*** shared version of the library, which you do not appear to have" - $ECHO "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for file magic test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a file magic. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - for a_deplib in $deplibs; do - case $a_deplib in - -l*) - func_stripname -l '' "$a_deplib" - name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval "\\$ECHO \"$libname_spec\""` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ - $EGREP "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $ECHO - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - $ECHO "*** I have the capability to make that library automatically link in when" - $ECHO "*** you link to this library. But I can only do this if you have a" - $ECHO "*** shared version of the library, which you do not appear to have" - $ECHO "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a regex pattern. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ - -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` - done - fi - if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | - $GREP . >/dev/null; then - $ECHO - if test "X$deplibs_check_method" = "Xnone"; then - $ECHO "*** Warning: inter-library dependencies are not supported in this platform." - else - $ECHO "*** Warning: inter-library dependencies are not known to be supported." - fi - $ECHO "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library with the System framework - newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - $ECHO - $ECHO "*** Warning: libtool could not satisfy all declared inter-library" - $ECHO "*** dependencies of module $libname. Therefore, libtool will create" - $ECHO "*** a static module, that should work as long as the dlopening" - $ECHO "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - $ECHO - $ECHO "*** However, this would only work if libtool was able to extract symbol" - $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" - $ECHO "*** not find such a program. So, this module is probably useless." - $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - $ECHO "*** The inter-library dependencies that have been dropped here will be" - $ECHO "*** automatically added whenever a program is linked with this library" - $ECHO "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - $ECHO - $ECHO "*** Since this library must not contain undefined symbols," - $ECHO "*** because either the platform does not support them or" - $ECHO "*** it was explicitly requested with -no-undefined," - $ECHO "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - case $host in - *-*-darwin*) - newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` - new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` - deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - new_libs="$new_libs -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$new_libs $deplib" ;; - esac - ;; - *) new_libs="$new_libs $deplib" ;; - esac - done - deplibs="$new_libs" - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - shift - realname="$1" - shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - linknames= - for link - do - linknames="$linknames $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - test "X$libobjs" = "X " && libobjs= - - delfiles= - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols="$output_objdir/$libname.uexp" - delfiles="$delfiles $export_symbols" - fi - - orig_export_symbols= - case $host_os in - cygwin* | mingw* | cegcc*) - if test -n "$export_symbols" && test -z "$export_symbols_regex"; then - # exporting using user supplied symfile - if test "x`$SED 1q $export_symbols`" != xEXPORTS; then - # and it's NOT already a .def file. Must figure out - # which of the given symbols are data symbols and tag - # them as such. So, trigger use of export_symbols_cmds. - # export_symbols gets reassigned inside the "prepare - # the list of exported symbols" if statement, so the - # include_expsyms logic still works. - orig_export_symbols="$export_symbols" - export_symbols= - always_export_symbols=yes - fi - fi - ;; - esac - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - func_len " $cmd" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - func_show_eval "$cmd" 'exit $?' - skipped_export=false - else - # The command line is too long to execute in one step. - func_verbose "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' - fi - - if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - tmp_deplibs="$tmp_deplibs $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec" && - test "$compiler_needs_object" = yes && - test -z "$libobjs"; then - # extract the archives, so we have objects to list. - # TODO: could optimize this to just extract one archive. - whole_archive_flag_spec= - fi - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - else - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - libobjs="$libobjs $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - func_len " $test_cmds" && - len=$func_len_result && - test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise - # or, if using GNU ld and skipped_export is not :, use a linker - # script. - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - output_la=`$ECHO "X$output" | $Xsed -e "$basename"` - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - last_robj= - k=1 - - if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then - output=${output_objdir}/${output_la}.lnkscript - func_verbose "creating GNU ld script: $output" - $ECHO 'INPUT (' > $output - for obj in $save_libobjs - do - $ECHO "$obj" >> $output - done - $ECHO ')' >> $output - delfiles="$delfiles $output" - elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then - output=${output_objdir}/${output_la}.lnk - func_verbose "creating linker input file list: $output" - : > $output - set x $save_libobjs - shift - firstobj= - if test "$compiler_needs_object" = yes; then - firstobj="$1 " - shift - fi - for obj - do - $ECHO "$obj" >> $output - done - delfiles="$delfiles $output" - output=$firstobj\"$file_list_spec$output\" - else - if test -n "$save_libobjs"; then - func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext - eval test_cmds=\"$reload_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - if test "X$objlist" = X || - test "$len" -lt "$max_cmd_len"; then - func_append objlist " $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - eval concat_cmds=\"$reload_cmds $objlist $last_robj\" - else - # All subsequent reloadable object files will link in - # the last one created. - eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - func_arith $k + 1 - k=$func_arith_result - output=$output_objdir/$output_la-${k}.$objext - objlist=$obj - func_len " $last_robj" - func_arith $len0 + $func_len_result - len=$func_arith_result - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" - if test -n "$last_robj"; then - eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" - fi - delfiles="$delfiles $output" - - else - output= - fi - - if ${skipped_export-false}; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - libobjs=$output - # Append the command to create the export file. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - fi - - test -n "$save_libobjs" && - func_verbose "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - if test -n "$export_symbols_regex" && ${skipped_export-false}; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - - if ${skipped_export-false}; then - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' - fi - - if test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - fi - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - fi - - if test -n "$delfiles"; then - # Append the command to remove temporary files to $cmds. - eval cmds=\"\$cmds~\$RM $delfiles\" - fi - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $dlprefiles - libobjs="$libobjs $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - func_show_eval '${RM}r "$gentop"' - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for objects" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for objects" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for objects" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for objects" - - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for objects" - - test -n "$release" && \ - func_warning "\`-release' is ignored for objects" - - case $output in - *.lo) - test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object \`$output' from non-libtool objects" - - libobj=$output - func_lo2o "$libobj" - obj=$func_lo2o_result - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $opt_dry_run || $RM $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec and hope we can get by with - # turning comma into space.. - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` - else - gentop="$output_objdir/${obj}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - func_execute_cmds "$reload_cmds" 'exit $?' - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - func_execute_cmds "$reload_cmds" 'exit $?' - fi - - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) func_stripname '' '.exe' "$output" - output=$func_stripname_result.exe;; - esac - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for programs" - - test -n "$release" && \ - func_warning "\`-release' is ignored for programs" - - test "$preload" = yes \ - && test "$dlopen_support" = unknown \ - && test "$dlopen_self" = unknown \ - && test "$dlopen_self_static" = unknown && \ - func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` - finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` - ;; - esac - - case $host in - *-*-darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - # But is supposedly fixed on 10.4 or later (yay!). - if test "$tagname" = CXX ; then - case ${MACOSX_DEPLOYMENT_TARGET-10.0} in - 10.[0123]) - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" - ;; - esac - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` - finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - new_libs="$new_libs -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$new_libs $deplib" ;; - esac - ;; - *) new_libs="$new_libs $deplib" ;; - esac - done - compile_deplibs="$new_libs" - - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - ::) dllsearchpath=$libdir;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) dllsearchpath="$dllsearchpath:$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - func_generate_dlsyms "$outputname" "@PROGRAM@" "no" - - # template prelinking step - if test -n "$prelink_cmds"; then - func_execute_cmds "$prelink_cmds" 'exit $?' - fi - - wrappers_required=yes - case $host in - *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - *cegcc) - # Disable wrappers for cegcc, we are cross compiling anyway. - wrappers_required=no - ;; - *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - esac - if test "$wrappers_required" = no; then - # Replace the output file specification. - compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - exit_status=0 - func_show_eval "$link_command" 'exit_status=$?' - - # Delete the generated files. - if test -f "$output_objdir/${outputname}S.${objext}"; then - func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' - fi - - exit $exit_status - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $opt_dry_run || $RM $output - # Link the executable and exit - func_show_eval "$link_command" 'exit $?' - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - func_warning "this platform does not like uninstalled shared libraries" - func_warning "\`$output' will be relinked during installation" - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname - - func_show_eval "$link_command" 'exit $?' - - # Now create the wrapper script. - func_verbose "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` - fi - - # Quote $ECHO for shipping. - if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then - case $progpath in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; - *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; - esac - qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if not in dry run mode. - $opt_dry_run || { - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) func_stripname '' '.exe' "$output" - output=$func_stripname_result ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - func_stripname '' '.exe' "$outputname" - outputname=$func_stripname_result ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - func_dirname_and_basename "$output" "" "." - output_name=$func_basename_result - output_path=$func_dirname_result - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" - $RM $cwrappersource $cwrapper - trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - func_emit_cwrapperexe_src > $cwrappersource - - # The wrapper executable is built using the $host compiler, - # because it contains $host paths and files. If cross- - # compiling, it, like the target executable, must be - # executed on the $host or under an emulation environment. - $opt_dry_run || { - $LTCC $LTCFLAGS -o $cwrapper $cwrappersource - $STRIP $cwrapper - } - - # Now, create the wrapper script for func_source use: - func_ltwrapper_scriptname $cwrapper - $RM $func_ltwrapper_scriptname_result - trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 - $opt_dry_run || { - # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host" ; then - $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result - else - func_emit_wrapper no > $func_ltwrapper_scriptname_result - fi - } - ;; - * ) - $RM $output - trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 - - func_emit_wrapper no > $output - chmod +x $output - ;; - esac - } - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save $symfileobj" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - if test "$preload" = yes && test -f "$symfileobj"; then - oldobjs="$oldobjs $symfileobj" - fi - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $addlibs - oldobjs="$oldobjs $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $dlprefiles - oldobjs="$oldobjs $func_extract_archives_result" - fi - - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - func_basename "$obj" - $ECHO "$func_basename_result" - done | sort | sort -uc >/dev/null 2>&1); then - : - else - $ECHO "copying selected object files to avoid basename conflicts..." - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - func_mkdir_p "$gentop" - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - func_basename "$obj" - objbase="$func_basename_result" - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - func_arith $counter + 1 - counter=$func_arith_result - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - oldobjs="$oldobjs $gentop/$newobj" - ;; - *) oldobjs="$oldobjs $obj" ;; - esac - done - fi - eval cmds=\"$old_archive_cmds\" - - func_len " $cmds" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - func_verbose "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - oldobjs= - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - eval test_cmds=\"$old_archive_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - for obj in $save_oldobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - func_append objlist " $obj" - if test "$len" -lt "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - len=$len0 - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - func_execute_cmds "$cmds" 'exit $?' - done - - test -n "$generated" && \ - func_show_eval "${RM}r$generated" - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - func_verbose "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - # Only create the output if not a dry run. - $opt_dry_run || { - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - func_basename "$deplib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - if test "x$EGREP" = x ; then - EGREP=egrep - fi - # We do not want portage's install root ($D) present. Check only for - # this if the .la is being installed. - if test "$installed" = yes && test "$D"; then - eval mynewdependency_lib=`echo "$libdir/$name" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` - else - mynewdependency_lib="$libdir/$name" - fi - # Do not add duplicates - if test "$mynewdependency_lib"; then - my_little_ninja_foo_1=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"` - if test -z "$my_little_ninja_foo_1"; then - newdependency_libs="$newdependency_libs $mynewdependency_lib" - fi - fi - ;; - *) - if test "$installed" = yes; then - # Rather use S=WORKDIR if our version of portage supports it. - # This is because some ebuild (gcc) do not use $S as buildroot. - if test "$PWORKDIR"; then - S="$PWORKDIR" - fi - # We do not want portage's build root ($S) present. - my_little_ninja_foo_2=`echo $deplib |$EGREP -e "$S"` - # We do not want portage's install root ($D) present. - my_little_ninja_foo_3=`echo $deplib |$EGREP -e "$D"` - if test -n "$my_little_ninja_foo_2" && test "$S"; then - mynewdependency_lib="" - elif test -n "$my_little_ninja_foo_3" && test "$D"; then - eval mynewdependency_lib=`echo "$deplib" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` - else - mynewdependency_lib="$deplib" - fi - else - mynewdependency_lib="$deplib" - fi - # Do not add duplicates - if test "$mynewdependency_lib"; then - my_little_ninja_foo_4=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"` - if test -z "$my_little_ninja_foo_4"; then - newdependency_libs="$newdependency_libs $mynewdependency_lib" - fi - fi - ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - - for lib in $dlfiles; do - case $lib in - *.la) - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - newdlfiles="$newdlfiles $libdir/$name" - ;; - *) newdlfiles="$newdlfiles $lib" ;; - esac - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - *.la) - # Only pass preopened files to the pseudo-archive (for - # eventual linking with the app. that links it) if we - # didn't already link the preopened objects directly into - # the library: - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - newdlprefiles="$newdlprefiles $libdir/$name" - ;; - esac - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlfiles="$newdlfiles $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlprefiles="$newdlprefiles $abs" - done - dlprefiles="$newdlprefiles" - fi - $RM $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - # Do not add duplicates - if test "$installed" = yes && test "$D"; then - install_libdir=`echo "$install_libdir" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` - fi - $ECHO > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Linker flags that can not go in dependency_libs. -inherited_linker_flags='$new_inherited_linker_flags' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Names of additional weak libraries provided by this library -weak_library_names='$weak_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $ECHO >> $output "\ -relink_command=\"$relink_command\"" - fi - done - } - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' - ;; - esac - exit $EXIT_SUCCESS -} - -{ test "$mode" = link || test "$mode" = relink; } && - func_mode_link ${1+"$@"} - - -# func_mode_uninstall arg... -func_mode_uninstall () -{ - $opt_debug - RM="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) RM="$RM $arg"; rmforce=yes ;; - -*) RM="$RM $arg" ;; - *) files="$files $arg" ;; - esac - done - - test -z "$RM" && \ - func_fatal_help "you must specify an RM program" - - rmdirs= - - origobjdir="$objdir" - for file in $files; do - func_dirname "$file" "" "." - dir="$func_dirname_result" - if test "X$dir" = X.; then - objdir="$origobjdir" - else - objdir="$dir/$origobjdir" - fi - func_basename "$file" - name="$func_basename_result" - test "$mode" = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test "$mode" = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if { test -L "$file"; } >/dev/null 2>&1 || - { test -h "$file"; } >/dev/null 2>&1 || - test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if func_lalib_p "$file"; then - func_source $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - - case "$mode" in - clean) - case " $library_names " in - # " " in the beginning catches empty $dlname - *" $dlname "*) ;; - *) rmfiles="$rmfiles $objdir/$dlname" ;; - esac - test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if func_lalib_p "$file"; then - - # Read the .lo file - func_source $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" && - test "$pic_object" != none; then - rmfiles="$rmfiles $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && - test "$non_pic_object" != none; then - rmfiles="$rmfiles $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$mode" = clean ; then - noexename=$name - case $file in - *.exe) - func_stripname '' '.exe' "$file" - file=$func_stripname_result - func_stripname '' '.exe' "$name" - noexename=$func_stripname_result - # $file with .exe has already been added to rmfiles, - # add $file without .exe - rmfiles="$rmfiles $file" - ;; - esac - # Do a test to see if this is a libtool program. - if func_ltwrapper_p "$file"; then - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - relink_command= - func_source $func_ltwrapper_scriptname_result - rmfiles="$rmfiles $func_ltwrapper_scriptname_result" - else - relink_command= - func_source $dir/$noexename - fi - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - rmfiles="$rmfiles $objdir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - func_show_eval "$RM $rmfiles" 'exit_status=1' - done - objdir="$origobjdir" - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - func_show_eval "rmdir $dir >/dev/null 2>&1" - fi - done - - exit $exit_status -} - -{ test "$mode" = uninstall || test "$mode" = clean; } && - func_mode_uninstall ${1+"$@"} - -test -z "$mode" && { - help="$generic_help" - func_fatal_help "you must specify a MODE" -} - -test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$mode'" - -if test -n "$exec_cmd"; then - eval exec "$exec_cmd" - exit $EXIT_FAILURE -fi - -exit $exit_status - - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -# vi:sw=2 - diff --git a/manifest b/manifest index cae8108738..d2fe1f68f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\snever-used\sand\snever-documented\sand\slong-ago\sdeprecated\nuser-authentication\sfeature\soption. -D 2024-10-28T17:27:15.255 +C Remove\sthe\sltmain.sh\sautotools\sremnant. +D 2024-10-28T17:30:11.295 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -697,7 +697,6 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x -F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 F main.mk 79392fb2e964f1359518d71df364182d7e53cc26a8fc4b25362ded9aeb4a17f7 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 @@ -2201,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9b141d108b64c8f4e1103de6f142d972b5151eed0f07988fea308fc71cec45b8 -R 9407a62c47c06c3fbba4fc768b189643 -U drh -Z 30f01ab7792d4b857d7e101ce9a3bf79 +P 3a3f7bf4307c27e56546e51da06ecc9a262cdf155fda2dd359aa2326d207a147 +R cd9b1bec596be837269b2e695c7b5245 +U stephan +Z 92ad112c447ec4600daf66fcdd05b35c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dd84b8f505..4794168bfe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a3f7bf4307c27e56546e51da06ecc9a262cdf155fda2dd359aa2326d207a147 +dad5eb9393e87403b932ddfb9da6db0ce1d6ed75c4771f22e87fbce1b0c206c2 From 51d5aa0915fcc759ef01ada8f694faa4d0d62c87 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 18:30:46 +0000 Subject: [PATCH 208/522] Calculate TCLLIBDIR in the makefile targets which use it, rather than via the configure script. This enables its use in static makefiles. FossilOrigin-Name: 6b1494cecb48535b909f8a48ccb56e147221601380a1457ff85ab861fa576ea1 --- Makefile.in | 2 +- auto.def | 66 ++++++++++++++++++++++++++++----------------------- main.mk | 40 ++++++++++++++++++++----------- manifest | 16 ++++++------- manifest.uuid | 2 +- 5 files changed, 72 insertions(+), 54 deletions(-) diff --git a/Makefile.in b/Makefile.in index 688b3ff062..c705318113 100644 --- a/Makefile.in +++ b/Makefile.in @@ -214,7 +214,7 @@ TCL_CONFIG_SH = @TCL_CONFIG_SH@ # # Where do we want to install the tcl plugin # -TCLLIBDIR = @TCLLIBDIR@ +#TCLLIBDIR = @TCLLIBDIR@ # # Additional options when running tests using testrunner.tcl diff --git a/auto.def b/auto.def index 042656ff3c..d246a84086 100644 --- a/auto.def +++ b/auto.def @@ -580,40 +580,46 @@ proc sqlite-check-tcl {} { } define TCLSH_CMD $with_tclsh - if {$use_tcl} { - # Set up the TCLLIBDIR and TCLLIB_RPATH - set tcllibdir [get-env TCLLIBDIR ""] - if {"" eq $tcllibdir} { - if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { - foreach i $result { - if {[file isdir $i]} { - set tcllibdir $i - break + if {0} { + # 2024-10-28: calculation of TCLLIBDIR is now done via the shell + # in the makefile rules which need it (search main.mk for + # T.tcllibdir). This code block is kept around as a basis for + # comparison while the new makefile-side rules get battle-tested. + if {$use_tcl} { + # Set up the TCLLIBDIR and TCLLIB_RPATH + set tcllibdir [get-env TCLLIBDIR ""] + if {"" eq $tcllibdir} { + if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { + foreach i $result { + if {[file isdir $i]} { + set tcllibdir $i + break + } } + } else { + proj-warn "Cannot determine TCLLIBDIR" } - } else { - proj-warn "Cannot determine TCLLIBDIR" } + set tclrpath "" + if {"" ne $tcllibdir} { + set tcllibdir "${tcllibdir}/sqlite3" + set rp [get-define SH_LINKRPATH] + set tclrpath [string map [list "%s" $tcllibdir] $rp] + # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the + # rpath but (A) it includes an unexpand var ref to + # ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B) + # that flag is inherently compiler-dependent so it's not as + # portable as tclConfig.sh assumes. We'll instead use the rpath + # flag which autosetup determines for the current compiler. + } + define TCLLIBDIR $tcllibdir + define TCLLIB_RPATH $tclrpath + #proj-fatal "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" + } else { + define TCLLIBDIR "" + define TCLLIB_RPATH "" } - set tclrpath "" - if {"" ne $tcllibdir} { - set tcllibdir "${tcllibdir}/sqlite3" - set rp [get-define SH_LINKRPATH] - set tclrpath [string map [list "%s" $tcllibdir] $rp] - # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the - # rpath but (A) it includes an unexpand var ref to - # ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B) - # that flag is inherently compiler-dependent so it's not as - # portable as tclConfig.sh assumes. We'll instead use the rpath - # flag which autosetup determines for the current compiler. - } - define TCLLIBDIR $tcllibdir - define TCLLIB_RPATH $tclrpath - #proj-fatal "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" - } else { - define TCLLIBDIR "" - define TCLLIB_RPATH "" - } + }; # find TCLLIBDIR if {[file exists $with_tclsh]} { msg-result "Using tclsh: $with_tclsh" diff --git a/main.mk b/main.mk index 139245830f..38f92af360 100644 --- a/main.mk +++ b/main.mk @@ -214,13 +214,8 @@ SHELL_OPT ?= # # TCL_CONFIG_SH must, for some of the build targets, refer to a valid # tclConfig.sh. That script will be used to populate most of the other -# TCL-related vars the build needs, the one exception being: +# TCL-related vars the build needs. # -# TCLLIBDIR is required for installing (but not building) the TCL -# deliverables. It must currently be set by the makefile which -# imports this one or as an argument to it from the user. -# -TCLLIBDIR ?= TCL_CONFIG_SH ?= # # $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not @@ -929,6 +924,24 @@ has_tclsh85: # which use this should also have a dependency on has_tclconfig. # SOURCE_TCLCONFIG = . $(TCL_CONFIG_SH) || exit $$? +# +# T.tcllibdir = shell code to extract the TCLLIBDIR to the tcllibdir +# shell var and exit with !0 if it cannot be determined. It must be +# part of a chained series of commands so that the var survives for +# the following rules in the same recipe. +# +# Algo: tcllibdir = the first entry from TCL's $auto_path which refers +# to an existing dir, then append /sqlite3 to it. +# +T.tcllibdir = \ + for tcllibdir in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \ + [ -d "$$tcllibdir" ] && break; done; \ + if [ x = "x$$tcllibdir" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ + tcllibdir="$$tcllibdir/sqlite3"; echo "TCLLIBDIR=$$tcllibdir" +# +# $(T.compile.tcl) and $(T.link.tcl) are TCL-specific counterparts for $(T.compile) +# and $(T.link) which first invoke $(SOURCE_TCLCONFIG). +# T.compile.tcl = $(SOURCE_TCLCONFIG); $(T.compile) T.link.tcl = $(SOURCE_TCLCONFIG); $(T.link) @@ -1400,11 +1413,11 @@ pkgIndex.tcl: echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(T.dll) $(libtclsqlite3.SO): has_tclconfig tclsqlite.o $(libsqlite3.SO) - libdir=`echo "puts stdout [lindex \\$$auto_path 0]" | $(TCLSH_CMD)` || exit $$?; \ - $(SOURCE_TCLCONFIG); \ + @$(T.tcllibdir); \ + $(SOURCE_TCLCONFIG); set -x; \ $(T.link.shared) -o $@ tclsqlite.o \ $$TCL_INCLUDE_SPEC $$TCL_STUB_LIB_SPEC $(LDFLAGS.libsqlite3) \ - $(libsqlite3.SO) -Wl,-rpath,$$libdir/sqlite3 + $(libsqlite3.SO) -Wl,-rpath,$$tcllibdir # ^^^ that rpath bit is defined as TCL_LD_SEARCH_FLAGS in # tclConfig.sh, but it's defined in such a way as to be useless for a # _static_ makefile. @@ -1413,12 +1426,11 @@ $(libtclsqlite3.SO)-0 $(libtclsqlite3.SO)-: libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL) all: libtcl -install.tcldir = $(DESTDIR)$(TCLLIBDIR) install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl - @if [ "x$(DESTDIR)" = "x$(install.tcldir)" ]; then echo "TCLLIBDIR is not set." 1>&2; exit 1; fi - $(INSTALL) -d $(install.tcldir) - $(INSTALL) $(libtclsqlite3.SO) $(install.tcldir) - $(INSTALL.noexec) pkgIndex.tcl $(install.tcldir) + @$(T.tcllibdir); set -x; dest="$(DESTDIR)$$tcllibdir"; \ + $(INSTALL) -d $$dest; \ + $(INSTALL) $(libtclsqlite3.SO) $$dest; \ + $(INSTALL.noexec) pkgIndex.tcl $$dest install-tcl-0 install-tcl-: install-tcl: install-tcl-$(HAVE_TCL) install: install-tcl diff --git a/manifest b/manifest index d2fe1f68f2..0044c55208 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Remove\sthe\sltmain.sh\sautotools\sremnant. -D 2024-10-28T17:30:11.295 +C Calculate\sTCLLIBDIR\sin\sthe\smakefile\stargets\swhich\suse\sit,\srather\sthan\svia\sthe\sconfigure\sscript.\sThis\senables\sits\suse\sin\sstatic\smakefiles. +D 2024-10-28T18:30:46.768 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 -F Makefile.in e4a6a12767fd297b5359ca4190141ec6f925e64dd8d5a1067a220e41b7dbf7a8 +F Makefile.in cdf1c8db0b33fa83f400bcd63742113a727517adc55b322d2e004339c012cac2 F Makefile.linux-generic 69b54c58ab2424a0d30f340d9defd7e87c25690a55b77acb9bdc657bd9a223f1 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 537d9e3cd85ed5a454ee6055585a4eadedde921fbb686fcb40c8446933be2b5a +F auto.def cf550c649ffa1d6ed383e627b3f5cdbd98e04708cf3b27632483caccd6b55cab F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -698,7 +698,7 @@ F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 79392fb2e964f1359518d71df364182d7e53cc26a8fc4b25362ded9aeb4a17f7 +F main.mk aba8a5877a848898c309862d6d19d80a0ccad4459641017dc377ca23c640aaad F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3a3f7bf4307c27e56546e51da06ecc9a262cdf155fda2dd359aa2326d207a147 -R cd9b1bec596be837269b2e695c7b5245 +P dad5eb9393e87403b932ddfb9da6db0ce1d6ed75c4771f22e87fbce1b0c206c2 +R 20ebbf6e3d71220bc2b3e267520cf726 U stephan -Z 92ad112c447ec4600daf66fcdd05b35c +Z 3602e361ae1b37fbb57c835a7dbf6ec8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4794168bfe..5dac689438 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dad5eb9393e87403b932ddfb9da6db0ce1d6ed75c4771f22e87fbce1b0c206c2 +6b1494cecb48535b909f8a48ccb56e147221601380a1457ff85ab861fa576ea1 From 4824b9c6641de3d6767996d235394a2f2ab7d1b4 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 28 Oct 2024 18:41:42 +0000 Subject: [PATCH 209/522] Minor makefile formatting cleanups. No functional changes. FossilOrigin-Name: 10b2cfdccd06553752baf684ccd7f4f85a697e3f0f6dfc5e5dda6b231fa4352d --- main.mk | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/main.mk b/main.mk index 38f92af360..f1b2941dfb 100644 --- a/main.mk +++ b/main.mk @@ -935,9 +935,9 @@ SOURCE_TCLCONFIG = . $(TCL_CONFIG_SH) || exit $$? # T.tcllibdir = \ for tcllibdir in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \ - [ -d "$$tcllibdir" ] && break; done; \ - if [ x = "x$$tcllibdir" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ - tcllibdir="$$tcllibdir/sqlite3"; echo "TCLLIBDIR=$$tcllibdir" + [ -d "$$tcllibdir" ] && break; done; \ + if [ x = "x$$tcllibdir" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ + tcllibdir="$$tcllibdir/sqlite3"; echo "TCLLIBDIR=$$tcllibdir" # # $(T.compile.tcl) and $(T.link.tcl) are TCL-specific counterparts for $(T.compile) # and $(T.link) which first invoke $(SOURCE_TCLCONFIG). diff --git a/manifest b/manifest index 0044c55208..977d99460b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Calculate\sTCLLIBDIR\sin\sthe\smakefile\stargets\swhich\suse\sit,\srather\sthan\svia\sthe\sconfigure\sscript.\sThis\senables\sits\suse\sin\sstatic\smakefiles. -D 2024-10-28T18:30:46.768 +C Minor\smakefile\sformatting\scleanups.\sNo\sfunctional\schanges. +D 2024-10-28T18:41:42.261 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -698,7 +698,7 @@ F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk aba8a5877a848898c309862d6d19d80a0ccad4459641017dc377ca23c640aaad +F main.mk 380707675b0912eecfc3961af468be8d9f4410c889e55bc12711f43f1fa88141 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P dad5eb9393e87403b932ddfb9da6db0ce1d6ed75c4771f22e87fbce1b0c206c2 -R 20ebbf6e3d71220bc2b3e267520cf726 +P 6b1494cecb48535b909f8a48ccb56e147221601380a1457ff85ab861fa576ea1 +R bcd550df0bf0a415ddd053fc701fba21 U stephan -Z 3602e361ae1b37fbb57c835a7dbf6ec8 +Z d7a68d90ac7d9032db43fb1f51be9bce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5dac689438..6aba159eaf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b1494cecb48535b909f8a48ccb56e147221601380a1457ff85ab861fa576ea1 +10b2cfdccd06553752baf684ccd7f4f85a697e3f0f6dfc5e5dda6b231fa4352d From 173c113c5f12249e17155a6262601486d009cffa Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Oct 2024 19:19:58 +0000 Subject: [PATCH 210/522] Remove unnecessary install-sh and spec.template files. FossilOrigin-Name: 3acb6d789eecd05010e6949b77b58f71cd39446ddf1a66ab89fae6757ccacd31 --- install-sh | 251 -------------------------------------------------- manifest | 14 ++- manifest.uuid | 2 +- spec.template | 67 -------------- 4 files changed, 7 insertions(+), 327 deletions(-) delete mode 100755 install-sh delete mode 100644 spec.template diff --git a/install-sh b/install-sh deleted file mode 100755 index e9de23842d..0000000000 --- a/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/manifest b/manifest index 977d99460b..b253111ccf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\smakefile\sformatting\scleanups.\sNo\sfunctional\schanges. -D 2024-10-28T18:41:42.261 +C Remove\sunnecessary\sinstall-sh\sand\sspec.template\sfiles. +D 2024-10-28T19:19:58.197 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -696,7 +696,6 @@ F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471 F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 F main.mk 380707675b0912eecfc3961af468be8d9f4410c889e55bc12711f43f1fa88141 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 @@ -705,7 +704,6 @@ F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8 F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0 F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d -F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 @@ -2200,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6b1494cecb48535b909f8a48ccb56e147221601380a1457ff85ab861fa576ea1 -R bcd550df0bf0a415ddd053fc701fba21 -U stephan -Z d7a68d90ac7d9032db43fb1f51be9bce +P 10b2cfdccd06553752baf684ccd7f4f85a697e3f0f6dfc5e5dda6b231fa4352d +R 7b6b0ba3ac02267225ed992d43293488 +U drh +Z f4dc6a11590d68ff496d681b045d1315 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6aba159eaf..039a6a3741 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -10b2cfdccd06553752baf684ccd7f4f85a697e3f0f6dfc5e5dda6b231fa4352d +3acb6d789eecd05010e6949b77b58f71cd39446ddf1a66ab89fae6757ccacd31 diff --git a/spec.template b/spec.template deleted file mode 100644 index 6cc7ab2eab..0000000000 --- a/spec.template +++ /dev/null @@ -1,67 +0,0 @@ -%define name sqlite -%define version SQLITE_VERSION -%define release 1 - -Name: %{name} -Summary: SQLite is a C library that implements an embeddable SQL database engine -Version: %{version} -Release: %{release} -Source: %{name}-%{version}.tar.gz -Group: System/Libraries -URL: http://www.sqlite.org/ -License: Public Domain -BuildRoot: %{_tmppath}/%{name}-%{version}-root - -%description -SQLite is a software library that implements a self-contained, serverless, -zero-configuration, transactional SQL database engine. -Programs that link with the SQLite library can have SQL database access -without running a separate RDBMS process. The distribution comes with a -standalone command-line access program (sqlite) that can be used to -administer an SQLite database and which serves as an example of how to -use the SQLite library. - -%package -n %{name}-devel -Summary: Header files and libraries for developing apps which will use sqlite -Group: Development/C -Requires: %{name} = %{version}-%{release} - -%description -n %{name}-devel -The sqlite-devel package contains the header files and libraries needed -to develop programs that use the SQLite database library. - -%prep -%setup -q -n %{name} - -%build -CFLAGS="%optflags -DNDEBUG=1" CXXFLAGS="%optflags -DNDEBUG=1" ./configure --prefix=%{_prefix} - -make -make doc - -%install -install -d $RPM_BUILD_ROOT/%{_prefix} -install -d $RPM_BUILD_ROOT/%{_prefix}/bin -install -d $RPM_BUILD_ROOT/%{_prefix}/include -install -d $RPM_BUILD_ROOT/%{_prefix}/lib -make install prefix=$RPM_BUILD_ROOT/%{_prefix} - -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig - -%clean -rm -fr $RPM_BUILD_ROOT - -%files -%defattr(-, root, root) -%{_libdir}/*.so* -%{_bindir}/* - -%files -n %{name}-devel -%defattr(-, root, root) -%{_libdir}/pkgconfig/sqlite3.pc -%{_libdir}/*.a -%{_libdir}/*.la -%{_includedir}/* -%doc doc/* From 8b3ba8eb5a87058363288aa31dd5e01dd8804356 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Oct 2024 22:35:32 +0000 Subject: [PATCH 211/522] Enclose the generated "sqlite3.c" and "sqlite3.h" in a single big #ifdef so that if they get truncated by more than a little whitespace, they will not compile and the truncation can be easily detected. FossilOrigin-Name: c3b624e2a903f0c975bc8b7288b98616a4a22b2a574738d1f578bfad1d6d8b91 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- tool/mksqlite3c.tcl | 4 +++- tool/mksqlite3h.tcl | 1 + 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b253111ccf..89e996686c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\sinstall-sh\sand\sspec.template\sfiles. -D 2024-10-28T19:19:58.197 +C Enclose\sthe\sgenerated\s"sqlite3.c"\sand\s"sqlite3.h"\sin\sa\ssingle\sbig\s#ifdef\sso\nthat\sif\sthey\sget\struncated\sby\smore\sthan\sa\slittle\swhitespace,\sthey\swill\snot\ncompile\sand\sthe\struncation\scan\sbe\seasily\sdetected. +D 2024-10-28T22:35:32.189 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -778,7 +778,7 @@ F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe F src/shell.c.in b6b7944fc076c2fd29d38edb61e3da978e838e3f79e1cf2c96a1342c423b3892 -F src/sqlite.h.in 29fc900a58f394c7488d093fd7a8dcb14d3fa6399d5178cb20adcf88dbedfe39 +F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1 @@ -2147,8 +2147,8 @@ F tool/mkshellc.tcl 2bc29c201933ae72a16a79070fe80aded80c24ea487ecd2f8df20c2973c8 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f -F tool/mksqlite3c.tcl 98a250d6f2ea60343268e32e2997790e678205ce128aa0d0a67a3f70811615af -F tool/mksqlite3h.tcl 2a6ba8955adf9cfabd0617ee5949760e531e0b75b703b5faf8d1150657b5628f +F tool/mksqlite3c.tcl 9e88a30981280e33489fe4782f4ab1e5349ba1866603fba7f1a948d5599b9124 +F tool/mksqlite3h.tcl 7a4648fef5efb33308d575c7775eb242855d71d5bf89065df3f006b9a634a0a1 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c7a27c F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 10b2cfdccd06553752baf684ccd7f4f85a697e3f0f6dfc5e5dda6b231fa4352d -R 7b6b0ba3ac02267225ed992d43293488 +P 3acb6d789eecd05010e6949b77b58f71cd39446ddf1a66ab89fae6757ccacd31 +R f66773bb544e46054d9e87ac9724855e U drh -Z f4dc6a11590d68ff496d681b045d1315 +Z 723f18082ce3d486045ce4be59f235ec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 039a6a3741..af7eafeb8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3acb6d789eecd05010e6949b77b58f71cd39446ddf1a66ab89fae6757ccacd31 +c3b624e2a903f0c975bc8b7288b98616a4a22b2a574738d1f578bfad1d6d8b91 diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f91088a772..77d928024d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -10889,4 +10889,4 @@ int sqlite3_deserialize( #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif -#endif /* SQLITE3_H */ +/* #endif for SQLITE3_H will be added by mksqlite3.tcl */ diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index dd0ce380b4..1b3958f460 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -138,6 +138,7 @@ if {[file executable $vsrcprog] && [file readable $srcroot/manifest]} { puts $out "** is unknown." } puts $out [subst {*/ +#ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1}] if {$addstatic} { @@ -509,6 +510,7 @@ puts $out \ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }" puts $out \ -"/************************** End of sqlite3.c ******************************/" +"#endif /* SQLITE_AMALGAMATION */ +/************************** End of sqlite3.c ******************************/" close $out diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index c02b80044a..c242005a07 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -168,3 +168,4 @@ foreach file $filelist { puts "/******** End of [file tail $file] *********/" } } +puts "#endif /* SQLITE3_H */" From a94ca1d37c073a9a981ed6dbab92cb4e47a00bef Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 03:29:45 +0000 Subject: [PATCH 212/522] Remove some dead auto.def code. Link tclsqlite3 shell against the .so instead of .a, analog to [45315f8f275d]. Move some header file tests which are only needed for jimsh into the jimsh compilability check block. FossilOrigin-Name: 9a259026ae2dce5d60b80bd7d662a6e73734e51056f4a4226c3fa5ac636b5e3a --- auto.def | 125 +++++++++++++++++--------------------- autosetup/proj.tcl | 146 +++------------------------------------------ main.mk | 4 +- manifest | 18 +++--- manifest.uuid | 2 +- 5 files changed, 76 insertions(+), 219 deletions(-) diff --git a/auto.def b/auto.def index d246a84086..97a3179ae1 100644 --- a/auto.def +++ b/auto.def @@ -231,7 +231,6 @@ foreach arg $::autosetup(argv) { define-append SQLITE_AUTORECONFIG '$arg' } - # Are we cross-compiling? set cross_compiling [proj-is-cross-compiling] if {![file exists sqlite3.pc.in]} { @@ -246,7 +245,7 @@ define OPT_SHELL {} ; # CFLAGS for the sqlite3 CLI app # Adds $args, if not empty, to OPT_FEATURE_FLAGS. # If the first arg is -shell then it strips that arg # and passes the remaining args th sqlite-add-shell-opt -# before adding them to OPF_FEATURE_FLAGS. +# in addition to adding them to OPT_FEATURE_FLAGS. proc sqlite-add-feature-flag {args} { set shell "" if {"-shell" eq [lindex $args 0]} { @@ -379,38 +378,23 @@ cc-check-includes \ string.h strings.h \ inttypes.h -# These are optional for JimTCL but necessary if we want to use it for -# code generation: -cc-check-includes dirent.h sys/time.h - if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { # TODO: port over the more sophisticated zlib search from the fossil auto.def - define HAVE_ZLIB 1; # "-DSQLITE_HAVE_ZLIB=1" + define HAVE_ZLIB 1 define LDFLAGS_ZLIB -lz - # Note that -DSQLITE_HAVE_ZLIB=1 is handled separately from the - # other feature flags in the autotools build. Do we need to emulate - # that? sqlite-add-shell-opt -DSQLITE_HAVE_ZLIB=1 } else { define HAVE_ZLIB 0 define LDFLAGS_ZLIB "" } -# -# Determine proper rpath-handling flags. -# -proj-check-rpath +proj-check-rpath; # Determine proper rpath-handling flags. -proj-define-if-opt-truthy shared ENABLE_SHARED \ - "Build shared library?" +proj-define-if-opt-truthy shared ENABLE_SHARED "Build shared library?" -if {![proj-define-if-opt-truthy static ENABLE_STATIC \ - "Build static library?"]} { - proj-warn "static lib build may be implicitly re-activated by other components, e.g. libtclsqlite3." -} +proj-define-if-opt-truthy static ENABLE_STATIC "Build static library?" -proj-define-if-opt-truthy amalgamation USE_AMALGAMATION \ - "Use amalgamation for builds?" +proj-define-if-opt-truthy amalgamation USE_AMALGAMATION "Use amalgamation for builds?" proj-define-if-opt-truthy gcov USE_GCOV "Use gcov?" @@ -420,8 +404,7 @@ proj-define-if-opt-truthy test-status TSTRNNR_OPTS \ proj-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \ "Use #line macros in the amalgamation:" -msg-checking "Debug build? " - +msg-checking "SQLITE_DEBUG build? " proj-if-opt-truthy with-debug { define SQLITE_DEBUG 1 define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} @@ -633,57 +616,59 @@ sqlite-check-tcl ######################################################################## # Check which TCL to use as a code generator. Prefer jimsh simply -# because we have it in-tree (it's part of autosetup). -# -# Building jimsh0.c with -DJIM_COMPAT changes certain behavior to be -# compatible with canonical TCL. Specifically: jim's [expr] only -# accepts one arg unless JIM_COMPAT is defined. As of 2024-10-23, -# jimsh0.c defines JIM_COMPAT automatically (prior to that it intended -# to but a typo of JIM_TCL_COMPAT made it a no-op). -define CFLAGS_JIMSH {} -msg-result "Which TCL to use for code generation... " -set cgtcl [opt-val with-tclsh jimsh] -if {"jimsh" ne $cgtcl} { - # When --with-tclsh=X is used, use that for all TCL purposes, - # including in-tree code generation, per developer request. - define BTCLSH "\$(TCLSH_CMD)" -} else { - if {[cc-check-functions realpath]} { - define-append CFLAGS_JIMSH -DHAVE_REALPATH - define BTCLSH "\$(JIMSH)" - } elseif {[cc-check-functions _fullpath]} { - # _fullpath() is a Windows API - define-append CFLAGS_JIMSH -DHAVE__FULLPATH - define BTCLSH "\$(JIMSH)" - } elseif {[file exists [get-define TCLSH_CMD]]} { - set cgtcl [get-define TCLSH_CMD] +# because we have it in-tree (it's part of autosetup), unless +# --with-tclsh=X is used, in which case prefix X. +# +# Returns the name of the TCL it selects. Fails fatally if it cannot +# detect a TCL appropriate for code generation. +proc sqlite-check-which-tcl {} { + msg-result "Checking for TCL to use for code generation... " + define CFLAGS_JIMSH {} + set cgtcl [opt-val with-tclsh jimsh] + if {"jimsh" ne $cgtcl} { + # When --with-tclsh=X is used, use that for all TCL purposes, + # including in-tree code generation, per developer request. define BTCLSH "\$(TCLSH_CMD)" } else { - # One last-ditch effort to find TCLSH_CMD: use info from - # tclConfig.sh to try to find a tclsh - if {"" eq [get-define TCLSH_CMD]} { - set tpre [get-define TCL_EXEC_PREFIX] - if {"" ne $tpre} { - set tv [get-define TCL_VERSION] - if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { - define TCLSH_CMD "${tpre}/bin/tclsh${tv}" - } elseif {[file-isexec "${tpre}/bin/tclsh"]} { - define TCLSH_CMD "${tpre}/bin/tclsh" + # These headers are technically optional for JimTCL but necessary if + # we want to use it for code generation: + set sysh [cc-check-includes dirent.h sys/time.h] + if {$sysh && [cc-check-functions realpath]} { + define-append CFLAGS_JIMSH -DHAVE_REALPATH + define BTCLSH "\$(JIMSH)" + } elseif {$sysh && [cc-check-functions _fullpath]} { + # _fullpath() is a Windows API + define-append CFLAGS_JIMSH -DHAVE__FULLPATH + define BTCLSH "\$(JIMSH)" + } elseif {[file exists [get-define TCLSH_CMD]]} { + set cgtcl [get-define TCLSH_CMD] + define BTCLSH "\$(TCLSH_CMD)" + } else { + # One last-ditch effort to find TCLSH_CMD: use info from + # tclConfig.sh to try to find a tclsh + if {"" eq [get-define TCLSH_CMD]} { + set tpre [get-define TCL_EXEC_PREFIX] + if {"" ne $tpre} { + set tv [get-define TCL_VERSION] + if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { + define TCLSH_CMD "${tpre}/bin/tclsh${tv}" + } elseif {[file-isexec "${tpre}/bin/tclsh"]} { + define TCLSH_CMD "${tpre}/bin/tclsh" + } + unset tv } - unset tv + unset tpre } - unset tpre - } - set cgtcl [get-define TCLSH_CMD] - if {![file exists $cgtcl]} { - proj-fatal "Cannot find a tclsh to use for code generation." + set cgtcl [get-define TCLSH_CMD] + if {![file exists $cgtcl]} { + proj-fatal "Cannot find a tclsh to use for code generation." + } + define BTCLSH "\$(TCLSH_CMD)" } - define BTCLSH "\$(TCLSH_CMD)" } -} -msg-result "TCL for code generation: $cgtcl" -unset cgtcl -#define CFLAGS_JIMSH {-DJUST_TESTING} + return $cgtcl +}; # sqlite-check-which-tcl +msg-result "TCL for code generation: [sqlite-check-which-tcl]" # /TCL ######################################################################## @@ -739,7 +724,7 @@ if {1} { # # - LDFLAGS_READLINE = linker flags or empty string # -# - CFLAGS_READLINE = compilation flags for clients or empty string +# - CFLAGS_READLINE = compilation flags for clients or empty string. # # Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to # linenoise or editline, not necessarily libreadline. diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 0b1613430c..e966b872e9 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -15,7 +15,7 @@ # This file was initially derived from one used in the libfossil # project, authored by the same person who ported it here, and this is # noted here only as an indication that there are no licensing issues -# despite this code having at least two near-twins running around a +# despite this code having a handful of near-twins running around a # handful of third-party source trees. # ######################################################################## @@ -80,8 +80,8 @@ proc proj-bold {str} { # immediately and then exits. proc proj-indented-notice {args} { set fErr "" - switch -exact -- [lindex $args 0] { - -error { set args [lassign $args fErr] } + if {"-error" eq [lindex $args 0]} { + set args [lassign $args fErr] } set lines [split [join $args] \n] foreach line $lines { @@ -177,14 +177,6 @@ proc proj-search-for-header-dir {header args} { return "" } -######################################################################## -# If $v is true, [puts $msg] is called, else puts is not called. -#proc proj-maybe-verbose {v msg} { -# if {$v} { -# puts $msg -# } -#} - ######################################################################## # Usage: proj-find-executable-path ?-v? binaryName # @@ -241,31 +233,19 @@ proc proj-bin-define {binName {defName {}}} { # caller has no sensible way of knowing which result it was unless # they pass only a single argument). proc proj-first-bin-of {args} { + set rc "" foreach b $args { + set u [string toupper $b] + # Note that cc-path-progs defines $u to false if it finds no match. if {[cc-path-progs $b]} { - set u [string toupper $b] - set x [get-define $u] - undefine $u - return $x + set rc [get-define $u] } + undefine $u + if {"" ne $rc} break } return "" } -######################################################################## -# Looks for `bash` binary and dies if not found. On success, defines -# BIN_BASH to the full path to bash and returns that value. -# -# TODO: move this out of this file and back into the 1 or 2 downstream -# trees which use it. -proc proj-require-bash {} { - set bash [proj-bin-define bash] - if {"" eq $bash} { - user-error "Cannot find required bash shell" - } - return $bash -} - ######################################################################## # Returns 1 if the user specifically provided the given configure # flag, else 0. This can be used to distinguish between options which @@ -818,114 +798,6 @@ proc proj-check-rpath {} { return $rc } -######################################################################## -# Check for availability of libreadline. Linking in readline varies -# wildly by platform and this check does not cover all known options. -# This detection is known to fail under the following conditions: -# -# - (pkg-config readline) info is either unavailable for libreadline or -# simply misbehaves. -# -# - Either of readline.h or libreadline are in an exotic place. -# -# Defines the following vars: -# -# - HAVE_READLINE: 0 or 1 -# - LDFLAGS_READLINE: "" or linker flags -# - CFLAGS_READLINE: "" or c-flags -# -# Quirks: -# -# - If readline.h is found in a directory name matching *line then the -# resulting -I... flag points one directory _up_ from that, under -# the assumption that client-side code will #include -# . -# -# Returns the value of HAVE_READLINE. -proc proj-check-readline {} { - define HAVE_READLINE 0 - define LDFLAGS_READLINE "" - define CFLAGS_READLINE "" - if {![opt-bool readline]} { - msg-result "libreadline disabled via --disable-readline." - return 0 - } - - if {[pkg-config-init 0] && [pkg-config readline]} { - define HAVE_READLINE 1 - define LDFLAGS_READLINE [get-define PKG_READLINE_LDFLAGS] - define-append LDFLAGS_READLINE [get-define PKG_READLINE_LIBS] - define CFLAGS_READLINE [get-define PKG_READLINE_CFLAGS] - return 1 - } - - # On OpenBSD on a Raspberry pi 4: - # - # $ pkg-config readline; echo $? - # 0 - # $ pkg-config --cflags readline - # Package termcap was not found in the pkg-config search path - # $ echo $? - # 1 - # $ pkg-config --print-requires readline; echo $? - # 1 - # - # i.e. there's apparently no way to find out that readline requires - # termcap beyond parsing the error message. It turns out it doesn't - # want termcap, it wants -lcurses, but we don't get that info from - # pkg-config either. - - # Look for readline.h - set rlInc "" - if {![proj-is-cross-compiling]} { - # ^^^ this check is derived from SQLite's legacy configure script - set rlInc [proj-search-for-header-dir readline.h \ - -subdirs {include/readline include}] - if {"" ne $rlInc} { - if {[string match */*line $rlInc]} { - # Special case: if the path includes .../*line/readline.h", set - # the -I to one dir up from that because our sources include - # or . Reminder: if - # auto.def is being run by jimsh0 then [file normalize] will not - # work! - set rlInc [file dirname $v] - } - set rlInc "-I${rlInc}" - } - } - - # If readline.h was found/specified, look for libreadline... - set rlLib "" - if {"" ne $rlInc} { - set libTerm "" - if {[proj-check-function-in-lib tgetent {readline ncurses curses termcap}]} { - # ^^^ check extracted from an ancient autotools configure script. - set libTerm [get-define lib_tgetent] - undefine lib_tgetent - } - if {"readline" eq $libTerm} { - set rlLib $libTerm - } elseif {[proj-check-function-in-lib readline readline $libTerm]} { - set rlLib [get-define lib_readline] - lappend rlLib $libTerm - undefine lib_readline - } - } - - if {"" ne $rlLib} { - set rlLib [join $rlLib] - define LDFLAGS_READLINE $rlLib - define CFLAGS_READLINE $rlInc - define HAVE_READLINE 1 - msg-result "Using readline with flags: $rlInc $rlLib" - return 1 - } - - msg-result "libreadline not found." - return 0 -} - - ######################################################################## # Internal helper for proj-dump-defs-json. Expects to be passed a # [define] name and the variadic $args which are passed to diff --git a/main.mk b/main.mk index f1b2941dfb..75dbd7e728 100644 --- a/main.mk +++ b/main.mk @@ -1274,9 +1274,9 @@ tclsqlite-shell.o: has_tclconfig $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) tclsqlite-stubs.o: has_tclconfig $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) $(T.compile.tcl) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c $$TCL_INCLUDE_SPEC -tclsqlite3$(T.exe): has_tclconfig tclsqlite-shell.o $(libsqlite3.LIB) +tclsqlite3$(T.exe): has_tclconfig tclsqlite-shell.o $(libsqlite3.SO) $(T.link.tcl) -o $@ tclsqlite-shell.o \ - $(libsqlite3.LIB) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) + $(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) # Rules to build opcodes.c and opcodes.h # diff --git a/manifest b/manifest index 89e996686c..88d0db9088 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enclose\sthe\sgenerated\s"sqlite3.c"\sand\s"sqlite3.h"\sin\sa\ssingle\sbig\s#ifdef\sso\nthat\sif\sthey\sget\struncated\sby\smore\sthan\sa\slittle\swhitespace,\sthey\swill\snot\ncompile\sand\sthe\struncation\scan\sbe\seasily\sdetected. -D 2024-10-28T22:35:32.189 +C Remove\ssome\sdead\sauto.def\scode.\sLink\stclsqlite3\sshell\sagainst\sthe\s.so\sinstead\sof\s.a,\sanalog\sto\s[45315f8f275d].\sMove\ssome\sheader\sfile\stests\swhich\sare\sonly\sneeded\sfor\sjimsh\sinto\sthe\sjimsh\scompilability\scheck\sblock. +D 2024-10-29T03:29:45.408 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def cf550c649ffa1d6ed383e627b3f5cdbd98e04708cf3b27632483caccd6b55cab +F auto.def 30e263662f55d045994aae89b9e8d2afd3476edba679165dec776d96ed5d7e21 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 8167786ff3c20d6a14e9b0b747996e91cabfe85ac49dcc5d0a0aa35d4167dd91 +F autosetup/proj.tcl 986cad77e63672eb910aa2a040185f0ecf3590b5c4ff4d2a033cb791edb9445f F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 380707675b0912eecfc3961af468be8d9f4410c889e55bc12711f43f1fa88141 +F main.mk f1a7ddc6e41c08bc3d61fe7ec50a669ca5688bfab7e8b747e1150b54bccaf8cb F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3acb6d789eecd05010e6949b77b58f71cd39446ddf1a66ab89fae6757ccacd31 -R f66773bb544e46054d9e87ac9724855e -U drh -Z 723f18082ce3d486045ce4be59f235ec +P c3b624e2a903f0c975bc8b7288b98616a4a22b2a574738d1f578bfad1d6d8b91 +R 1fbe3bfca5dee7f1b439640106ed2db7 +U stephan +Z 39268a9790bf3e3d8cfe8a98d615a386 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index af7eafeb8c..b5a800f0ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3b624e2a903f0c975bc8b7288b98616a4a22b2a574738d1f578bfad1d6d8b91 +9a259026ae2dce5d60b80bd7d662a6e73734e51056f4a4226c3fa5ac636b5e3a From 7097105beace6b4d25dcfd9ad8c064815865b556 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 04:21:11 +0000 Subject: [PATCH 213/522] Remove LDFLAGS_LIBZ from sqlite3.pc.in (pkg-config) because it's not needed by the library, only the shell. Re-enable the notice about --disable-static only being partially true. FossilOrigin-Name: e03c564aff6e3ac558f17670bfdd5fc129a8d33ec50975af843973152483e3fa --- auto.def | 9 ++++++--- main.mk | 3 ++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- sqlite3.pc.in | 2 +- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/auto.def b/auto.def index 97a3179ae1..0f914a4138 100644 --- a/auto.def +++ b/auto.def @@ -139,7 +139,6 @@ set flags { load-extension=1 => {Disable loading of external extensions} math=1 => {Disable math functions} json=1 => {Disable JSON functions} - all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} memsys5 => {Enable MEMSYS5} memsys3 => {Enable MEMSYS3} fts3 => {Enable the FTS3 extension} @@ -149,6 +148,7 @@ set flags { geopoly => {Enable the GEOPOLY extension} rtree => {Enable the RTREE extension} session => {Enable the SESSION extension} + all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} # # with-tclsh:PATH => {Full pathname of tclsh to use} @@ -392,7 +392,10 @@ proj-check-rpath; # Determine proper rpath-handling flags. proj-define-if-opt-truthy shared ENABLE_SHARED "Build shared library?" -proj-define-if-opt-truthy static ENABLE_STATIC "Build static library?" +if {![proj-define-if-opt-truthy static ENABLE_STATIC \ + "Build static library?"]} { + proj-warn "Static lib build may be implicitly re-activated by other components, e.g. some test apps." +} proj-define-if-opt-truthy amalgamation USE_AMALGAMATION "Use amalgamation for builds?" @@ -474,7 +477,7 @@ proc sqlite-check-tcl {} { proj-fatal "TCL shell $with_tclsh is not executable" } else { define TCLSH_CMD $with_tclsh - msg-result "Using tclsh: $with_tclsh" + #msg-result "Using tclsh: $with_tclsh" } if {$use_tcl} { if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { diff --git a/main.mk b/main.mk index 75dbd7e728..409f9ac8f1 100644 --- a/main.mk +++ b/main.mk @@ -326,7 +326,8 @@ T.link.shared = $(T.link) $(LDFLAGS.shobj) # results in building libsqlite3.so, compiles sqlite3.c directly, or # links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these # flags are for the target build platform, not necessarily localhost. -# i.e. it should be used with $(T.cc.sqlite) or $(T.link) but not $(B.cc). +# i.e. it should be used with $(T.cc.sqlite) or $(T.link) but not +# $(B.cc). # LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ diff --git a/manifest b/manifest index 88d0db9088..40810f458f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sdead\sauto.def\scode.\sLink\stclsqlite3\sshell\sagainst\sthe\s.so\sinstead\sof\s.a,\sanalog\sto\s[45315f8f275d].\sMove\ssome\sheader\sfile\stests\swhich\sare\sonly\sneeded\sfor\sjimsh\sinto\sthe\sjimsh\scompilability\scheck\sblock. -D 2024-10-29T03:29:45.408 +C Remove\sLDFLAGS_LIBZ\sfrom\ssqlite3.pc.in\s(pkg-config)\sbecause\sit's\snot\sneeded\sby\sthe\slibrary,\sonly\sthe\sshell.\sRe-enable\sthe\snotice\sabout\s--disable-static\sonly\sbeing\spartially\strue. +D 2024-10-29T04:21:11.440 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 30e263662f55d045994aae89b9e8d2afd3476edba679165dec776d96ed5d7e21 +F auto.def 7f3da911883d21c53462b9a79259c9551d971a8cdc9bbbd11a7e79efaa7b758b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk f1a7ddc6e41c08bc3d61fe7ec50a669ca5688bfab7e8b747e1150b54bccaf8cb +F main.mk 35c8565133e6afc4219654a8339cf617f8d9f40b3e9b6a598a2e9782b8a4eee5 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -706,7 +706,7 @@ F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0 F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc -F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 +F sqlite3.pc.in 2d5c88643679fc199dafc9afb6ea8868ea3192d941c2e57dbe06395149d892ba F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c3b624e2a903f0c975bc8b7288b98616a4a22b2a574738d1f578bfad1d6d8b91 -R 1fbe3bfca5dee7f1b439640106ed2db7 +P 9a259026ae2dce5d60b80bd7d662a6e73734e51056f4a4226c3fa5ac636b5e3a +R faa87ee569d92cfc3e69ecb8ae88e292 U stephan -Z 39268a9790bf3e3d8cfe8a98d615a386 +Z 1c510488e46aaa36e3e65a77adda5034 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b5a800f0ab..4c7174f142 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a259026ae2dce5d60b80bd7d662a6e73734e51056f4a4226c3fa5ac636b5e3a +e03c564aff6e3ac558f17670bfdd5fc129a8d33ec50975af843973152483e3fa diff --git a/sqlite3.pc.in b/sqlite3.pc.in index a9f941b1e4..97f3c1a60d 100644 --- a/sqlite3.pc.in +++ b/sqlite3.pc.in @@ -9,5 +9,5 @@ Name: SQLite Description: SQL database engine Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lsqlite3 -Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ZLIB@ @LDFLAGS_ICU@ +Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ICU@ Cflags: -I${includedir} From e32a50a02590a1a48c5e4152cdb2bba9fd976fc6 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 08:01:56 +0000 Subject: [PATCH 214/522] Teach configure --editline to report itself to shell.c as either HAVE_EDITLINE or HAVE_READLINE, depending on which headers are available (editline/readline.h or readline/readline.h, both of which work and some systems only have the latter), but then link against libedit regardless of which one shell.c thinks it is using. FossilOrigin-Name: 85077b20e69ed269f8840bb900e823981bebd82063853fbf178b1af44a6951ba --- auto.def | 123 +++++++++++++++++++++++--------------------------- main.mk | 17 ++++--- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 75 insertions(+), 81 deletions(-) diff --git a/auto.def b/auto.def index 0f914a4138..c3d895aa22 100644 --- a/auto.def +++ b/auto.def @@ -741,7 +741,10 @@ proc sqlite-check-line-editing {} { define HAVE_EDITLINE 0 define LDFLAGS_READLINE "" define CFLAGS_READLINE "" + set libsForReadline {readline edit} ; # -l names to check for readline() set check [opt-val with-linenoise] + set editLibName "readline" ; # "readline" or "editline" + set editLibDef "HAVE_READLINE" ; # "HAVE_READLINE" or "HAVE_EDITLINE" if {"" ne $check} { # Use linenoise... set dirLn $check @@ -758,33 +761,18 @@ proc sqlite-check-line-editing {} { sqlite-add-shell-opt -DHAVE_LINENOISE=1 return "linenoise" } elseif {[opt-bool editline]} { - # --enable-editline. The problem is finding a system which has it - # available to test on. The man pages for it on OpenBSD do not - # match how shell.c uses it. OpenBSD has a lib named libedit but - # no headers to go with it. The legacy configure script looked for - # readline() in libedit (and libedit.a indeed has the - # readline/history functions used by shell.c) but shell.c expects - # to find when HAVE_EDITLINE=1, and that - # file is nowhere to be found. + # libedit mimics of libreadline and on some systems does not + # have its own header installed (instead, that of libreadline is used). + # We treat --editline as, for purposes of this tree, readline except + # that we'll link against libedit if it's available (and fail if + # it's not). We will use either API's header file # - # However, a workaround which works on the available systems is: - # - # --with-readline-ldflags=-ledit - # - # And then let it detect readline.h. We "could" re-map - # --enable-editline to do exactly that but it seems likely to - # break on systems for which which HAVE_EDITLINE=1 previously - # worked. - proj-indented-notice -error { - ERROR: the --enable-editline flag is not supported due to - non-availability of systems which have it in a form which the - sqlite3 CLI shell expects to see. On some systems this can be - worked around by passing --with-readline-ldflags=-ledit instead - of --enable-editline, which will attempt to use the readline.h - supplied by libreadline but link against -ledit. On systems - tested so far, that works. - } - return "none" + # shell.c historically expects HAVE_EDITLINE to be set for + # libedit, but it then expects to see , which + # some system's don't actually have, despite having libedit. Thus + # we trick shell.c into using editline by posing as readline. + set libsForReadline {edit} + set editLibName editline } elseif {![opt-bool readline]} { msg-result "Readline support explicitly disabled with --disable-readline" return "none" @@ -798,8 +786,8 @@ proc sqlite-check-line-editing {} { proj-opt-set with-readline-cflags auto } else { set v [file dirname $v] - if {[string match */*line $v]} { - # Special case: if the path includes .../*line/readline.h", set + if {[string match */readline $v]} { + # Special case: if the path includes .../readline/readline.h, set # the -I to one dir up from that because our sources include # or . Reminder: if # auto.def is being run by jimsh0 then [file normalize] will not @@ -814,16 +802,28 @@ proc sqlite-check-line-editing {} { set rlInc [opt-val with-readline-cflags auto] if {"auto" eq $rlInc} { set rlInc "" - if {!$::cross_compiling} { + if {$::cross_compiling} { # ^^^ this check is derived from the legacy configure script + proj-warn "Skipping check for readline.h because we're cross-compiling." + } else { + set dirs "[get-define prefix] /usr /usr/local /usr/local/readline /usr/contrib /mingw" + set subdirs "include/$editLibName" + if {"readline" ne $editLibName} { + lappend subdirs include/readline + # ^^^ editline, on some systems, does not have its own header, + # and uses libreadline's header. + } + lappend subdirs include + # ^^^ The dirs and subdirs lists are, except for the inclusion + # of $prefix and editline, from the legacy configure script set rlInc [proj-search-for-header-dir readline.h \ - -dirs {/usr /usr/local /usr/local/readline /usr/contrib /mingw} \ - -subdirs {include/readline include}] - # ^^^ The -dirs and -subdirs lists are from the legacy configure script + -dirs $dirs -subdirs $subdirs] if {"" ne $rlInc} { - if {[string match */*line $rlInc]} { - # See notes above for --with-readline-header - set rlInc [file dirname $rlInc] + if {[string match */readline $rlInc]} { + set rlInc [file dirname $rlInc]; # shell #include's + } elseif {[string match */editline $rlInc]} { + set editLibDef HAVE_EDITLINE + set rlInc [file dirname $rlInc]; # shell #include's } set rlInc "-I${rlInc}" } @@ -837,14 +837,14 @@ proc sqlite-check-line-editing {} { if {"" eq $rlLib || "auto" eq $rlLib} { set rlLib "" set libTerm "" - if {[proj-check-function-in-lib tgetent {readline ncurses curses termcap}]} { + if {[proj-check-function-in-lib tgetent "$editLibName ncurses curses termcap"]} { # ^^^ that libs list comes from the legacy configure script ^^^ set libTerm [get-define lib_tgetent] undefine lib_tgetent } - if {"readline" eq $libTerm} { + if {$editLibName eq $libTerm} { set rlLib $libTerm - } elseif {[proj-check-function-in-lib readline readline $libTerm]} { + } elseif {[proj-check-function-in-lib readline $libsForReadline $libTerm]} { set rlLib [get-define lib_readline] lappend rlLib $libTerm undefine lib_readline @@ -853,54 +853,43 @@ proc sqlite-check-line-editing {} { } if {"" ne $rlLib} { + if {"editline" eq $editLibName && "HAVE_READLINE" eq $editLibDef} { + proj-indented-notice { + NOTE: this is libedit but using , + so will be compiled using -DHAVE_READLINE=1 but linked with + libedit. + } + } set rlLib [join $rlLib] set rlInc [join $rlInc] define LDFLAGS_READLINE $rlLib define CFLAGS_READLINE $rlInc - define HAVE_READLINE 1 - sqlite-add-shell-opt -DHAVE_READLINE=1 - msg-result "Using readline flags: $rlInc $rlLib" - + define $editLibDef 1 + sqlite-add-shell-opt -D${editLibDef}=1 + msg-result "Using $editLibName flags: $rlInc $rlLib" # Now check whether rl_completion_matches() has a signature we can use. # cctest is producing unexpected test output when using: # -includes {stdio.h readline/readline.h} # so we have to use -source instead and write the whole test app inline - if {[cctest \ - -cflags $rlInc -libs $rlLib -nooutput 1 -source { + if {![cctest \ + -cflags "$rlInc -D${editLibDef}" -libs $rlLib -nooutput 1 -source { #include + #ifdef HAVE_EDITLINE + #include + #else #include + #endif static char * rcg(const char *z, int i){return 0;} int main(void) { char ** x = rl_completion_matches("one", rcg); return 0; } }]} { - } else { - user-notice "WARNING: readline completion disabled due to rl_completion_matches() signature mismatch" + user-notice "WARNING: readline-style completion disabled due to rl_completion_matches() signature mismatch" show-notices sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION } - - # Now check whether rl_completion_matches() has a signature we can use. - # cctest is producing unexpected test output when using: - # -includes {stdio.h readline/readline.h} - # so we have to use -source instead and write the whole test app inline - if {[cctest \ - -cflags $rlInc -libs $rlLib -nooutput 1 -source { - #include - #include - static char * rcg(const char *z, int i){return 0;} - int main(void) { - char ** x = rl_completion_matches("one", rcg); - return 0; - } - }]} { - user-notice "Readline completion enabled" - } else { - user-notice "WARNING: readline completion disabled due to rl_completion_matches() signature mismatch" - sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION - } - return "readline" + return $editLibName } return "none" diff --git a/main.mk b/main.mk index 409f9ac8f1..626b297d48 100644 --- a/main.mk +++ b/main.mk @@ -322,12 +322,17 @@ T.link = $(T.cc.sqlite) $(T.link.extras) T.link.shared = $(T.link) $(LDFLAGS.shobj) # -# LDFLAGS.libsqlite3 should be used with any target which either -# results in building libsqlite3.so, compiles sqlite3.c directly, or -# links in either of $(LIBOBJSO) or $(LIBOBJS1). Note that these -# flags are for the target build platform, not necessarily localhost. -# i.e. it should be used with $(T.cc.sqlite) or $(T.link) but not -# $(B.cc). +# LDFLAGS.libsqlite3 should be used with any deliverable for which any +# of the following apply: +# +# - Results in building libsqlite3.so +# - Compiles sqlite3.c in to an application +# - Links with libsqlite3.a +# - Links in either of $(LIBOBJSO) or $(LIBOBJS1) +# +# Note that these flags are for the target build platform, not +# necessarily localhost. i.e. it should be used with $(T.cc.sqlite) +# or $(T.link) but not $(B.cc). # LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ diff --git a/manifest b/manifest index 40810f458f..5e66a9acec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sLDFLAGS_LIBZ\sfrom\ssqlite3.pc.in\s(pkg-config)\sbecause\sit's\snot\sneeded\sby\sthe\slibrary,\sonly\sthe\sshell.\sRe-enable\sthe\snotice\sabout\s--disable-static\sonly\sbeing\spartially\strue. -D 2024-10-29T04:21:11.440 +C Teach\sconfigure\s--editline\sto\sreport\sitself\sto\sshell.c\sas\seither\sHAVE_EDITLINE\sor\sHAVE_READLINE,\sdepending\son\swhich\sheaders\sare\savailable\s(editline/readline.h\sor\sreadline/readline.h,\sboth\sof\swhich\swork\sand\ssome\ssystems\sonly\shave\sthe\slatter),\sbut\sthen\slink\sagainst\slibedit\sregardless\sof\swhich\sone\sshell.c\sthinks\sit\sis\susing. +D 2024-10-29T08:01:56.226 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 7f3da911883d21c53462b9a79259c9551d971a8cdc9bbbd11a7e79efaa7b758b +F auto.def 446169b97de3492b54e2282f22cd0364a5579ec620617273c3b6e371650700ff F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 35c8565133e6afc4219654a8339cf617f8d9f40b3e9b6a598a2e9782b8a4eee5 +F main.mk 46f98320780c72a025bed1a5f8af3355fb2186691617f2b8d41221f9aa564494 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9a259026ae2dce5d60b80bd7d662a6e73734e51056f4a4226c3fa5ac636b5e3a -R faa87ee569d92cfc3e69ecb8ae88e292 +P e03c564aff6e3ac558f17670bfdd5fc129a8d33ec50975af843973152483e3fa +R d3a68de2e78347c35dd06cc7c4f435ff U stephan -Z 1c510488e46aaa36e3e65a77adda5034 +Z 03d95568b8712aa0747a4210f93cda01 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4c7174f142..0869312b92 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e03c564aff6e3ac558f17670bfdd5fc129a8d33ec50975af843973152483e3fa +85077b20e69ed269f8840bb900e823981bebd82063853fbf178b1af44a6951ba From 13e735a5b5b6c2722d22349f51548db00ee4e9b2 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 08:14:34 +0000 Subject: [PATCH 215/522] Add proj-assert proc and add a couple of asserts to the editline/readline checks. FossilOrigin-Name: db9870caa806c902cae033a96fec48db1b2d78b96b124e568479c5326e006c9b --- auto.def | 10 +++++++--- autosetup/proj.tcl | 9 +++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/auto.def b/auto.def index c3d895aa22..f25de85bb7 100644 --- a/auto.def +++ b/auto.def @@ -742,9 +742,9 @@ proc sqlite-check-line-editing {} { define LDFLAGS_READLINE "" define CFLAGS_READLINE "" set libsForReadline {readline edit} ; # -l names to check for readline() - set check [opt-val with-linenoise] set editLibName "readline" ; # "readline" or "editline" set editLibDef "HAVE_READLINE" ; # "HAVE_READLINE" or "HAVE_EDITLINE" + set check [opt-val with-linenoise] if {"" ne $check} { # Use linenoise... set dirLn $check @@ -769,8 +769,10 @@ proc sqlite-check-line-editing {} { # # shell.c historically expects HAVE_EDITLINE to be set for # libedit, but it then expects to see , which - # some system's don't actually have, despite having libedit. Thus - # we trick shell.c into using editline by posing as readline. + # some system's don't actually have, despite having libedit. If we + # end up finding below, we will use + # -DHAVE_EDITLINE=1, else we will use -DHAVE_READLINE=1. In either + # case, we will link against libedit. set libsForReadline {edit} set editLibName editline } elseif {![opt-bool readline]} { @@ -864,6 +866,8 @@ proc sqlite-check-line-editing {} { set rlInc [join $rlInc] define LDFLAGS_READLINE $rlLib define CFLAGS_READLINE $rlInc + proj-assert {expr {$editLibDef in {HAVE_READLINE HAVE_EDITLINE}}} + proj-assert {expr {$editLibName in {readline editline}}} define $editLibDef 1 sqlite-add-shell-opt -D${editLibDef}=1 msg-result "Using $editLibName flags: $rlInc $rlLib" diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index e966b872e9..8f5335f77e 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -59,6 +59,15 @@ proc proj-fatal {msg} { exit 1 } +######################################################################## +# Kind of like a C assert if uplevel (eval) of $script is false, +# triggers a fatal error. +proc proj-assert {script} { + if {![uplevel 1 $script]} { + proj-fatal "Affirmation failed: $script" + } +} + ######################################################################## # If this function believes that the current console might support # ANSI escape sequences then this returns $str wrapped in a sequence diff --git a/manifest b/manifest index 5e66a9acec..1f94aa5d6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Teach\sconfigure\s--editline\sto\sreport\sitself\sto\sshell.c\sas\seither\sHAVE_EDITLINE\sor\sHAVE_READLINE,\sdepending\son\swhich\sheaders\sare\savailable\s(editline/readline.h\sor\sreadline/readline.h,\sboth\sof\swhich\swork\sand\ssome\ssystems\sonly\shave\sthe\slatter),\sbut\sthen\slink\sagainst\slibedit\sregardless\sof\swhich\sone\sshell.c\sthinks\sit\sis\susing. -D 2024-10-29T08:01:56.226 +C Add\sproj-assert\sproc\sand\sadd\sa\scouple\sof\sasserts\sto\sthe\seditline/readline\schecks. +D 2024-10-29T08:14:34.309 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 446169b97de3492b54e2282f22cd0364a5579ec620617273c3b6e371650700ff +F auto.def 3ff5ee963e46a86cab5a56bfabefd95e9caa9dffbaf6c6fe76f0ff30510fc475 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 986cad77e63672eb910aa2a040185f0ecf3590b5c4ff4d2a033cb791edb9445f +F autosetup/proj.tcl 2fcaa8ee431a72df5cd5c1122df356d67ab2c892ef613cff6ffeb86a7b7da8f3 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e03c564aff6e3ac558f17670bfdd5fc129a8d33ec50975af843973152483e3fa -R d3a68de2e78347c35dd06cc7c4f435ff +P 85077b20e69ed269f8840bb900e823981bebd82063853fbf178b1af44a6951ba +R b5b0e6d951eff454ba00abe04bd51ebc U stephan -Z 03d95568b8712aa0747a4210f93cda01 +Z aa2a20cde06aa54503780a7e22fdad3b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0869312b92..70a6796c73 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85077b20e69ed269f8840bb900e823981bebd82063853fbf178b1af44a6951ba +db9870caa806c902cae033a96fec48db1b2d78b96b124e568479c5326e006c9b From 4cbc413a2580c02922e111348cb72ebb97222e37 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 08:18:45 +0000 Subject: [PATCH 216/522] Minor --help text tweak. FossilOrigin-Name: 80ac10ed8d0ee9eaf83a6c43608098c631f5f9535c8b125da5bfe2d6a4d23bec --- auto.def | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index f25de85bb7..cd64578c8b 100644 --- a/auto.def +++ b/auto.def @@ -175,8 +175,8 @@ set flags { # with-icu-ldflags:LDFLAGS => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} - icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...} with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU and fetch linker flags from the given icu-config binary} + icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=... or --with-icu-config} # # with-wasi-sdk:=/opt/wasi-sdk diff --git a/manifest b/manifest index 1f94aa5d6b..d1fce51c5d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sproj-assert\sproc\sand\sadd\sa\scouple\sof\sasserts\sto\sthe\seditline/readline\schecks. -D 2024-10-29T08:14:34.309 +C Minor\s--help\stext\stweak. +D 2024-10-29T08:18:45.075 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 3ff5ee963e46a86cab5a56bfabefd95e9caa9dffbaf6c6fe76f0ff30510fc475 +F auto.def 668d8f3b131c77a4ed3cba4b657ca39bbc674480542c63cda3c0a69f07fbb71b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 85077b20e69ed269f8840bb900e823981bebd82063853fbf178b1af44a6951ba -R b5b0e6d951eff454ba00abe04bd51ebc +P db9870caa806c902cae033a96fec48db1b2d78b96b124e568479c5326e006c9b +R 64e0dc3cdfa9939ef91bb975c4e5bc84 U stephan -Z aa2a20cde06aa54503780a7e22fdad3b +Z 4b590d1a39e9d5937dc34e5d02b161d2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 70a6796c73..db300dabe7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db9870caa806c902cae033a96fec48db1b2d78b96b124e568479c5326e006c9b +80ac10ed8d0ee9eaf83a6c43608098c631f5f9535c8b125da5bfe2d6a4d23bec From 02834a9a3d1ed69e3d787a59eb46bf0b1070f85d Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 08:42:06 +0000 Subject: [PATCH 217/522] When either --readline or --editline are explicitly provided but the corresponding feature is not found, fail fatally. If not explicitly requested, simply disable that feature if the lib is not found. FossilOrigin-Name: 1d24a29c6ef05185950ba5c45f2a60a92f12a8e5c57026b599f716c9f2f6cf84 --- auto.def | 24 ++++++++++++++++++++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/auto.def b/auto.def index cd64578c8b..8dbe301a86 100644 --- a/auto.def +++ b/auto.def @@ -734,6 +734,20 @@ if {1} { # # Returns a string describing which line-editing approach to use, or # "none" if no option is available. +# +# Order of checks: +# +# 1) --with-linenoise trumps all others +# +# 2) --editline trumps --readline +# +# 3) --disable-readline trumps --readline +# +# 4) Default to automatic search for optional readline +# +# 5) Try to find readline resp. editline. If it's not found AND the +# corresponding --FEATURE flag was explicitly given, fail fatally, +# else fail silently. proc sqlite-check-line-editing {} { msg-result "Checking for line-editing capability..." define HAVE_READLINE 0 @@ -741,6 +755,7 @@ proc sqlite-check-line-editing {} { define HAVE_EDITLINE 0 define LDFLAGS_READLINE "" define CFLAGS_READLINE "" + set failIfNotFound 0 ; # Set to 1 for explicit --FEATURE requests when FEATURE is not found set libsForReadline {readline edit} ; # -l names to check for readline() set editLibName "readline" ; # "readline" or "editline" set editLibDef "HAVE_READLINE" ; # "HAVE_READLINE" or "HAVE_EDITLINE" @@ -773,11 +788,16 @@ proc sqlite-check-line-editing {} { # end up finding below, we will use # -DHAVE_EDITLINE=1, else we will use -DHAVE_READLINE=1. In either # case, we will link against libedit. + set failIfNotFound 1 set libsForReadline {edit} set editLibName editline } elseif {![opt-bool readline]} { msg-result "Readline support explicitly disabled with --disable-readline" return "none" + } elseif {[proj-opt-was-provided readline]} { + # If an explicit --enable-readline was used, fail if it's not found, + # else treat the feature as optional. + set failIfNotFound 1 } # Transform with-readline-header=X to with-readline-cflags=-I... @@ -896,6 +916,10 @@ proc sqlite-check-line-editing {} { return $editLibName } + if {$failIfNotFound} { + proj-fatal "Explicit --$editLibName failed to find a matching library." + } + return "none" }; # sqlite-check-line-editing msg-result "Line-editing support for the sqlite3 shell: [sqlite-check-line-editing]" diff --git a/manifest b/manifest index d1fce51c5d..a47e0eb473 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\s--help\stext\stweak. -D 2024-10-29T08:18:45.075 +C When\seither\s--readline\sor\s--editline\sare\sexplicitly\sprovided\sbut\sthe\scorresponding\sfeature\sis\snot\sfound,\sfail\sfatally.\sIf\snot\sexplicitly\srequested,\ssimply\sdisable\sthat\sfeature\sif\sthe\slib\sis\snot\sfound. +D 2024-10-29T08:42:06.048 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 668d8f3b131c77a4ed3cba4b657ca39bbc674480542c63cda3c0a69f07fbb71b +F auto.def 416110aed3a3fe50fa6902ff82bccb24243f0b2a20d7f2bc83b6cea519c90b18 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P db9870caa806c902cae033a96fec48db1b2d78b96b124e568479c5326e006c9b -R 64e0dc3cdfa9939ef91bb975c4e5bc84 +P 80ac10ed8d0ee9eaf83a6c43608098c631f5f9535c8b125da5bfe2d6a4d23bec +R db8a68fd2e53d23ef8f48e7caeaffa7c U stephan -Z 4b590d1a39e9d5937dc34e5d02b161d2 +Z 7e16d1fa4c3f0d8fad8a4fd41d97e038 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index db300dabe7..45d294f26a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80ac10ed8d0ee9eaf83a6c43608098c631f5f9535c8b125da5bfe2d6a4d23bec +1d24a29c6ef05185950ba5c45f2a60a92f12a8e5c57026b599f716c9f2f6cf84 From ffddcb725f752d71179f8c354ac7ddd185255de6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 29 Oct 2024 14:22:12 +0000 Subject: [PATCH 218/522] Fix a typo in LICENSE.md FossilOrigin-Name: decc60034849c232a05c8eb93ff0c6a5d6a48336d960771ed096d89633a9d0e2 --- LICENSE.md | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 6a1f19246a..5382a66842 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -56,7 +56,7 @@ words, there are some non-public-domain files used to implement: In all cases, the non-public-domain files included with this repository have generous BSD-style licenses. So anyone is free to use any of the code in this source repository for any purpose, though -attribution my be required to reuse or republish the configure and +attribution may be required to reuse or republish the configure and build scripts. None of the non-public-domain code ever actually reaches the build products, such as "sqlite3.c", however, so no attribution is required to use SQLite itself. The non-public-domain code consists of diff --git a/manifest b/manifest index a47e0eb473..3c1add3939 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C When\seither\s--readline\sor\s--editline\sare\sexplicitly\sprovided\sbut\sthe\scorresponding\sfeature\sis\snot\sfound,\sfail\sfatally.\sIf\snot\sexplicitly\srequested,\ssimply\sdisable\sthat\sfeature\sif\sthe\slib\sis\snot\sfound. -D 2024-10-29T08:42:06.048 +C Fix\sa\stypo\sin\sLICENSE.md +D 2024-10-29T14:22:12.268 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea -F LICENSE.md b6e6c1baf38e4339bd3f1e0e5e5bfd0a9a93d133360691b2785c2d4b2f2dcec2 +F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 F Makefile.in cdf1c8db0b33fa83f400bcd63742113a727517adc55b322d2e004339c012cac2 F Makefile.linux-generic 69b54c58ab2424a0d30f340d9defd7e87c25690a55b77acb9bdc657bd9a223f1 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 80ac10ed8d0ee9eaf83a6c43608098c631f5f9535c8b125da5bfe2d6a4d23bec -R db8a68fd2e53d23ef8f48e7caeaffa7c -U stephan -Z 7e16d1fa4c3f0d8fad8a4fd41d97e038 +P 1d24a29c6ef05185950ba5c45f2a60a92f12a8e5c57026b599f716c9f2f6cf84 +R 39666de7648cff00f94d62d8ecd9d6d5 +U drh +Z 98e5f326f4e37c32b0833374f38b52df # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 45d294f26a..7b7b320a05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d24a29c6ef05185950ba5c45f2a60a92f12a8e5c57026b599f716c9f2f6cf84 +decc60034849c232a05c8eb93ff0c6a5d6a48336d960771ed096d89633a9d0e2 From d3335a79709d45b6a30a8754e443cc2eb625f8ec Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 17:55:12 +0000 Subject: [PATCH 219/522] Remove some extraneous configure output. FossilOrigin-Name: 2234569edb15bb8b229e1b785aea08dd515798419ffe39c50f8399ce984258ac --- auto.def | 2 -- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/auto.def b/auto.def index 8dbe301a86..e4462ef5cd 100644 --- a/auto.def +++ b/auto.def @@ -1190,5 +1190,3 @@ proj-if-opt-truthy dump-defines { } } } - -msg-result [proj-bold "Source tree is configured! Run make to build it."] diff --git a/manifest b/manifest index 3c1add3939..08323c75f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sLICENSE.md -D 2024-10-29T14:22:12.268 +C Remove\ssome\sextraneous\sconfigure\soutput. +D 2024-10-29T17:55:12.324 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 416110aed3a3fe50fa6902ff82bccb24243f0b2a20d7f2bc83b6cea519c90b18 +F auto.def d9bb91d7ad13283870f4bbaba875a578a6738372957535280e0fdbcae5fb5860 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1d24a29c6ef05185950ba5c45f2a60a92f12a8e5c57026b599f716c9f2f6cf84 -R 39666de7648cff00f94d62d8ecd9d6d5 -U drh -Z 98e5f326f4e37c32b0833374f38b52df +P decc60034849c232a05c8eb93ff0c6a5d6a48336d960771ed096d89633a9d0e2 +R 8da872de86ba96cb7075df2df6b3ca7e +U stephan +Z cba6c8632d422ce92a5eebc93c684f66 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7b7b320a05..8891d875a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -decc60034849c232a05c8eb93ff0c6a5d6a48336d960771ed096d89633a9d0e2 +2234569edb15bb8b229e1b785aea08dd515798419ffe39c50f8399ce984258ac From 47f4bb3f2d81928177cf533e71585c63a2e12549 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 18:50:25 +0000 Subject: [PATCH 220/522] Rename an almost-name-colliding auto.def function. Fix a refactoring-induced change which broke implicit lookup of tclConfig.sh. Add msg-debug proc to enable toggling of developer-level debug messages via a configure argument. FossilOrigin-Name: 265ba15df1e64a50722118ac6d84667b0abd35fe8f4db28facf7788c50ac6cde --- auto.def | 25 ++++++++++++++++++------- autosetup/proj.tcl | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/auto.def b/auto.def index e4462ef5cd..91daf6d86f 100644 --- a/auto.def +++ b/auto.def @@ -189,12 +189,14 @@ set flags { linemacros => {Enable #line macros in the amalgamation.} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} # + } if {"" ne $DUMP_DEFINES_JSON} { lappend flags \ defines-json-include-lowercase=0 \ => {Include lower-case defines (primarily system paths) in $DUMP_DEFINES_JSON} } + options [subst $flags] unset flags @@ -265,6 +267,15 @@ proc sqlite-add-shell-opt {args} { } } +# Pass msg-debug=1 to configure to enable obnoxiously loud output from +# msg-debug. +set msgDebugEnabled [proj-val-truthy [get-env msg-debug 0]] +proc msg-debug {msg} { + if {$::msgDebugEnabled} { + puts stderr [proj-bold "** DEBUG: $msg"] + } +} + proj-file-extensions if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_UNIX 0 @@ -462,13 +473,13 @@ proc sqlite-check-tcl {} { set use_tcl $optTcl set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] - #puts "sqlite-check-tcl: use_tcl ${use_tcl}" - #puts "sqlite-check-tcl: with_tclsh=${with_tclsh}" - #puts "sqlite-check-tcl: with_tcl=$with_tcl" + msg-debug "sqlite-check-tcl: use_tcl ${use_tcl}" + msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" + msg-debug "sqlite-check-tcl: with_tcl=$with_tcl" if {"" eq $with_tclsh && "" eq $with_tcl} { set with_tclsh [proj-first-bin-of tclsh9.0 tclsh8.6 tclsh] + msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" } - #puts "sqlite-check-tcl: with_tclsh=${with_tclsh}" if {"" ne $with_tclsh} { if {![file isfile $with_tclsh]} { @@ -624,7 +635,7 @@ sqlite-check-tcl # # Returns the name of the TCL it selects. Fails fatally if it cannot # detect a TCL appropriate for code generation. -proc sqlite-check-which-tcl {} { +proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " define CFLAGS_JIMSH {} set cgtcl [opt-val with-tclsh jimsh] @@ -670,8 +681,8 @@ proc sqlite-check-which-tcl {} { } } return $cgtcl -}; # sqlite-check-which-tcl -msg-result "TCL for code generation: [sqlite-check-which-tcl]" +}; # sqlite-determine-codegen-tcl +msg-result "TCL for code generation: [sqlite-determine-codegen-tcl]" # /TCL ######################################################################## diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 8f5335f77e..698385630e 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -252,7 +252,7 @@ proc proj-first-bin-of {args} { undefine $u if {"" ne $rc} break } - return "" + return $rc } ######################################################################## diff --git a/manifest b/manifest index 08323c75f0..49154e9f62 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sextraneous\sconfigure\soutput. -D 2024-10-29T17:55:12.324 +C Rename\san\salmost-name-colliding\sauto.def\sfunction.\sFix\sa\srefactoring-induced\schange\swhich\sbroke\simplicit\slookup\sof\stclConfig.sh.\sAdd\smsg-debug\sproc\sto\senable\stoggling\sof\sdeveloper-level\sdebug\smessages\svia\sa\sconfigure\sargument. +D 2024-10-29T18:50:25.758 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d9bb91d7ad13283870f4bbaba875a578a6738372957535280e0fdbcae5fb5860 +F auto.def 20dec7b20f2eebc50a93608ea544bbfc3dfeee6b26da5f96760aae95e382f560 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 2fcaa8ee431a72df5cd5c1122df356d67ab2c892ef613cff6ffeb86a7b7da8f3 +F autosetup/proj.tcl c37063118b4c2556bd6e9c1b1b6a96e325415ea5ff0b6c56921aed6165ccd332 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P decc60034849c232a05c8eb93ff0c6a5d6a48336d960771ed096d89633a9d0e2 -R 8da872de86ba96cb7075df2df6b3ca7e +P 2234569edb15bb8b229e1b785aea08dd515798419ffe39c50f8399ce984258ac +R e3f5199dad0ffa18056f027428bdd0e9 U stephan -Z cba6c8632d422ce92a5eebc93c684f66 +Z 1eb45bfbd7096c53e58d39982f0c271f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8891d875a7..f25d99ad3b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2234569edb15bb8b229e1b785aea08dd515798419ffe39c50f8399ce984258ac +265ba15df1e64a50722118ac6d84667b0abd35fe8f4db28facf7788c50ac6cde From ca698abb5a8623c3cd3682c57a9fc97f4d4d54cb Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 19:03:22 +0000 Subject: [PATCH 221/522] Reformulate the readline completion signature compatibility test so that -Wunused-variable in the CFLAGS does not cause it to fail. Problem reported via email. FossilOrigin-Name: 3891669a3fdd71f7095cf464f6e4e2b870d6c23e79b9f796b1125b2040f05519 --- auto.def | 3 ++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index 91daf6d86f..ce2f590f31 100644 --- a/auto.def +++ b/auto.def @@ -914,9 +914,10 @@ proc sqlite-check-line-editing {} { #else #include #endif - static char * rcg(const char *z, int i){return 0;} + static char * rcg(const char *z, int i){(void)z; (void)i; return 0;} int main(void) { char ** x = rl_completion_matches("one", rcg); + (void)x; return 0; } }]} { diff --git a/manifest b/manifest index 49154e9f62..1c1ec9b24b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\san\salmost-name-colliding\sauto.def\sfunction.\sFix\sa\srefactoring-induced\schange\swhich\sbroke\simplicit\slookup\sof\stclConfig.sh.\sAdd\smsg-debug\sproc\sto\senable\stoggling\sof\sdeveloper-level\sdebug\smessages\svia\sa\sconfigure\sargument. -D 2024-10-29T18:50:25.758 +C Reformulate\sthe\sreadline\scompletion\ssignature\scompatibility\stest\sso\sthat\s-Wunused-variable\sin\sthe\sCFLAGS\sdoes\snot\scause\sit\sto\sfail.\sProblem\sreported\svia\semail. +D 2024-10-29T19:03:22.644 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 20dec7b20f2eebc50a93608ea544bbfc3dfeee6b26da5f96760aae95e382f560 +F auto.def 1e6852f218b4d74fa79b2c85bbb19b3cf3b2c7c8e89225c8d639df2f0fd5a68f F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2234569edb15bb8b229e1b785aea08dd515798419ffe39c50f8399ce984258ac -R e3f5199dad0ffa18056f027428bdd0e9 +P 265ba15df1e64a50722118ac6d84667b0abd35fe8f4db28facf7788c50ac6cde +R e4fa5cb9421ab06b93f3a08ca998b3a0 U stephan -Z 1eb45bfbd7096c53e58d39982f0c271f +Z af5ebb66ac586f10a87182e001c0a012 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f25d99ad3b..697d2e3417 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -265ba15df1e64a50722118ac6d84667b0abd35fe8f4db28facf7788c50ac6cde +3891669a3fdd71f7095cf464f6e4e2b870d6c23e79b9f796b1125b2040f05519 From e034c18591ac5f924313e36a95ad3c3bbd755840 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 20:27:36 +0000 Subject: [PATCH 222/522] General auto.def cleanups and docs. FossilOrigin-Name: e2f41c2540d8ff7686bfe22336598896de9083d139fc5a291c0f19896b9c1d20 --- Makefile.in | 2 +- auto.def | 155 ++++++++++++++++++++++++-------------------------- manifest | 14 ++--- manifest.uuid | 2 +- 4 files changed, 83 insertions(+), 90 deletions(-) diff --git a/Makefile.in b/Makefile.in index c705318113..44a0f62932 100644 --- a/Makefile.in +++ b/Makefile.in @@ -95,7 +95,7 @@ INSTALL = @BIN_INSTALL@ AR = @AR@ AR.flags = cr # TODO? Add a configure test to determine this? CC = @CC@ -B.cc = @BUILD_CC@ @BUILD_CFLAGS@ +B.cc = @CC_FOR_BUILD@ @BUILD_CFLAGS@ T.cc = @CC@ CFLAGS = @CPPFLAGS@ @CFLAGS@ @SH_CFLAGS@ diff --git a/auto.def b/auto.def index ce2f590f31..e5da690c24 100644 --- a/auto.def +++ b/auto.def @@ -19,14 +19,10 @@ use cc cc-db cc-shared cc-lib proj pkg-config set DUMP_DEFINES_TXT ./config.defines.txt # $DUMP_DEFINES_JSON is the autosetup counterpart of the historical # "DEFS" var which was generated by the autotools in the pre-processed -# autotools builds (but not in the canonical tree). This is used by at -# least one high-profile client to extract build config info for use -# in compiling a scripting-language binding, so its name should not be -# arbitrarily changed. -# -# 2024-10-26: generation of this file is disabled (via an empty file -# name) until/unless someone voices a specific interest in it. The -# original motivating use case is handled fine by sqlite_cfg.h. +# autotools builds (but not in the canonical tree). Generation of this +# file is disabled (via an empty file name) until/unless someone +# voices a specific interest in it. The original motivating use case +# is handled fine by sqlite_cfg.h. set DUMP_DEFINES_JSON ""; #./config.defines.json ######################################################################## @@ -291,27 +287,15 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { # Programs needed if {"" eq [proj-bin-define install]} { proj-warn "Cannot find install binary, so 'make install' will not work." - # Reminder: we historically have ./install-sh in the source tree. - # Can we not simply use that? - # - # define BIN_INSTALL "$top_srcdir/install-sh" - # - # Nope: it MOVES its source files over the target, which breaks the - # installation in some cases, e.g. when libtclsqlite3.so is built in - # response to 'make install' and libsqlite3.a is moved before - # libtclsqlite3.so is linked. It's easy to hack to use cp instead - # of mv (simply replace the instcmd=... bit) but that won't retain - # the source timestamp and permissions unless we use cp's -p flag, - # which may not be portable enough. } ######################################################################## # We differentiate between two C compilers: the one used for binaries -# which are to run on the build system (BUILD_CC, a.k.a. BCC) and the -# one used for compiling binaries for the target system (CC, -# a.k.a. TCC). Normally they're the same, but they will differ when +# which are to run on the build system (in autosetup it's called +# CC_FOR_BUILD and in Makefile.in it's $(B.cc)) and the one used for +# compiling binaries for the target system (CC a.k.a. $(T.cc)). +# Normally they're the same, but they will differ when # cross-compiling. -define BUILD_CC [get-define CC_FOR_BUILD] define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] ######################################################################## @@ -457,8 +441,8 @@ proj-if-opt-truthy with-debug { # be empty - this tree requires TCL to generated numerous # components. # -define TCLSH_CMD {exit 1} -define HAVE_TCL 0 +define TCLSH_CMD false ; # Significant is that it exits with non-0 +define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search proc sqlite-check-tcl {} { # TODO: document the steps this is taking. if {![opt-bool tcl]} { @@ -629,12 +613,21 @@ proc sqlite-check-tcl {} { sqlite-check-tcl ######################################################################## -# Check which TCL to use as a code generator. Prefer jimsh simply -# because we have it in-tree (it's part of autosetup), unless -# --with-tclsh=X is used, in which case prefix X. +# sqlite-determine-codegen-tcl checks which TCL to use as a code +# generator. By default, prefer jimsh simply because we have it +# in-tree (it's part of autosetup) unless --with-tclsh=X is used, in +# which case prefix X. # # Returns the name of the TCL it selects. Fails fatally if it cannot # detect a TCL appropriate for code generation. +# +# Defines: +# +# - BTCLSH = the TCL shell used for code generation. It may set this +# to an unexpanded makefile var name. +# +# - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible +# jimsh. proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " define CFLAGS_JIMSH {} @@ -669,9 +662,7 @@ proc sqlite-determine-codegen-tcl {} { } elseif {[file-isexec "${tpre}/bin/tclsh"]} { define TCLSH_CMD "${tpre}/bin/tclsh" } - unset tv } - unset tpre } set cgtcl [get-define TCLSH_CMD] if {![file exists $cgtcl]} { @@ -683,7 +674,6 @@ proc sqlite-determine-codegen-tcl {} { return $cgtcl }; # sqlite-determine-codegen-tcl msg-result "TCL for code generation: [sqlite-determine-codegen-tcl]" - # /TCL ######################################################################## @@ -741,7 +731,9 @@ if {1} { # - CFLAGS_READLINE = compilation flags for clients or empty string. # # Note that LDFLAGS_READLINE and CFLAGS_READLINE may refer to -# linenoise or editline, not necessarily libreadline. +# linenoise or editline, not necessarily libreadline. In some cases +# it will set HAVE_READLINE=1 when it's really using editline, for +# reasons described in this function's comments. # # Returns a string describing which line-editing approach to use, or # "none" if no option is available. @@ -766,14 +758,14 @@ proc sqlite-check-line-editing {} { define HAVE_EDITLINE 0 define LDFLAGS_READLINE "" define CFLAGS_READLINE "" - set failIfNotFound 0 ; # Set to 1 for explicit --FEATURE requests when FEATURE is not found - set libsForReadline {readline edit} ; # -l names to check for readline() + set failIfNotFound 0 ; # Set to 1 for explicit --FEATURE requests + set libsForReadline {readline edit} ; # -l names to check for readline(). + # The libedit check changes this. set editLibName "readline" ; # "readline" or "editline" set editLibDef "HAVE_READLINE" ; # "HAVE_READLINE" or "HAVE_EDITLINE" - set check [opt-val with-linenoise] - if {"" ne $check} { - # Use linenoise... - set dirLn $check + set dirLn [opt-val with-linenoise] + if {"" ne $dirLn} { + # Use linenoise from a copy of its sources (not a library)... if {![file isdir $dirLn]} { proj-fatal "--with-linenoise value is not a directory" } elseif {![file exists $dirLn/linenoise.c] } { @@ -787,16 +779,13 @@ proc sqlite-check-line-editing {} { sqlite-add-shell-opt -DHAVE_LINENOISE=1 return "linenoise" } elseif {[opt-bool editline]} { - # libedit mimics of libreadline and on some systems does not - # have its own header installed (instead, that of libreadline is used). - # We treat --editline as, for purposes of this tree, readline except - # that we'll link against libedit if it's available (and fail if - # it's not). We will use either API's header file + # libedit mimics libreadline and on some systems does not have its + # own header installed (instead, that of libreadline is used). # # shell.c historically expects HAVE_EDITLINE to be set for # libedit, but it then expects to see , which - # some system's don't actually have, despite having libedit. If we - # end up finding below, we will use + # some system's don't actually have, despite having libedit. If + # we end up finding below, we will use # -DHAVE_EDITLINE=1, else we will use -DHAVE_READLINE=1. In either # case, we will link against libedit. set failIfNotFound 1 @@ -806,8 +795,8 @@ proc sqlite-check-line-editing {} { msg-result "Readline support explicitly disabled with --disable-readline" return "none" } elseif {[proj-opt-was-provided readline]} { - # If an explicit --enable-readline was used, fail if it's not found, - # else treat the feature as optional. + # If an explicit --[enable-]readline was used, fail if it's not + # found, else treat the feature as optional. set failIfNotFound 1 } @@ -836,12 +825,12 @@ proc sqlite-check-line-editing {} { if {"auto" eq $rlInc} { set rlInc "" if {$::cross_compiling} { - # ^^^ this check is derived from the legacy configure script + # ^^^ this check is derived from the legacy configure script. proj-warn "Skipping check for readline.h because we're cross-compiling." } else { set dirs "[get-define prefix] /usr /usr/local /usr/local/readline /usr/contrib /mingw" set subdirs "include/$editLibName" - if {"readline" ne $editLibName} { + if {"editline" eq $editLibName} { lappend subdirs include/readline # ^^^ editline, on some systems, does not have its own header, # and uses libreadline's header. @@ -863,7 +852,13 @@ proc sqlite-check-line-editing {} { } } - # If readline.h was found/specified, look for libreadline... + # If readline.h was found/specified, look for lib(readline|edit)... + # + # This is not quite straightforward because both libreadline and + # libedit typically require some other library which (according to + # legacy autotools-generated tests) provides tgetent(3). On some + # systems that's built into libreadline/edit, on some (most?) its in + # lib[n]curses, and on some it's in libtermcap. set rlLib "" if {"" ne $rlInc} { set rlLib [opt-val with-readline-ldflags] @@ -885,11 +880,12 @@ proc sqlite-check-line-editing {} { } } + # If we found a library, configure the build to use it... if {"" ne $rlLib} { if {"editline" eq $editLibName && "HAVE_READLINE" eq $editLibDef} { proj-indented-notice { - NOTE: this is libedit but using , - so will be compiled using -DHAVE_READLINE=1 but linked with + NOTE: the local libedit but uses so we + will compile with -DHAVE_READLINE=1 but will link with libedit. } } @@ -899,13 +895,10 @@ proc sqlite-check-line-editing {} { define CFLAGS_READLINE $rlInc proj-assert {expr {$editLibDef in {HAVE_READLINE HAVE_EDITLINE}}} proj-assert {expr {$editLibName in {readline editline}}} - define $editLibDef 1 sqlite-add-shell-opt -D${editLibDef}=1 msg-result "Using $editLibName flags: $rlInc $rlLib" - # Now check whether rl_completion_matches() has a signature we can use. - # cctest is producing unexpected test output when using: - # -includes {stdio.h readline/readline.h} - # so we have to use -source instead and write the whole test app inline + # Check whether rl_completion_matches() has a signature we can use + # and disable that sub-feature if it doesn't. if {![cctest \ -cflags "$rlInc -D${editLibDef}" -libs $rlLib -nooutput 1 -source { #include @@ -962,22 +955,6 @@ proj-if-opt-truthy math { msg-result "Disabling math SQL functions" } -define cross_compiling ${cross_compiling} - -######################################################################## -# Emscripten SDK for building the web-based wasm components. -# -set emccsh $srcdir/tool/emcc.sh -if {![get-define HAVE_WASI_SDK] && [proj-check-emsdk]} { - define EMCC_WRAPPER $emccsh - proj-make-from-dot-in $emccsh - catch {exec chmod u+x $emccsh} -} else { - define EMCC_WRAPPER "" - file delete -force $emccsh -} -unset emccsh - ######################################################################## # ICU - International Components for Unicode # @@ -988,7 +965,7 @@ unset emccsh # --enable-icu-collations # # If both icu-ldflags and icu-config are provided, they are -# cumulative. If neither are provided, icu-collations is not honored +# cumulative. If neither are provided, icu-collations is not honored # and a warning is emitted if it is provided. # # Design note: though we can automatically enable ICU if the @@ -1038,15 +1015,31 @@ proc sqlite-check-icu {} { }; # sqlite-check-icu sqlite-check-icu +######################################################################## +# Emscripten SDK for building the web-based wasm components. +# +proc sqlite-check-emsdk {} { + set emccsh $::srcdir/tool/emcc.sh + if {![get-define HAVE_WASI_SDK] && [proj-check-emsdk]} { + define EMCC_WRAPPER $emccsh + proj-make-from-dot-in $emccsh + catch {exec chmod u+x $emccsh} + } else { + define EMCC_WRAPPER "" + file delete -force $emccsh + } +} +sqlite-check-emsdk + ######################################################################## # Check for log(3) in libm and die with an error if it is not -# found. $why should be the feature name which requires that function -# (it's used only in error messages). defines LDFLAGS_MATH to the -# required linker flags (which may be empty even if the math APIs are -# found, depending on the OS). -proc affirm-have-math {why} { +# found. $featureName should be the feature name which requires that +# function (it's used only in error messages). defines LDFLAGS_MATH to +# the required linker flags (which may be empty even if the math APIs +# are found, depending on the OS). +proc affirm-have-math {featureName} { if {![msg-quiet proj-check-function-in-lib log m]} { - user-error "Missing math APIs for $why" + user-error "Missing math APIs for $featureName" } define LDFLAGS_MATH [get-define lib_log ""] undefine lib_log diff --git a/manifest b/manifest index 1c1ec9b24b..08feab3ee4 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Reformulate\sthe\sreadline\scompletion\ssignature\scompatibility\stest\sso\sthat\s-Wunused-variable\sin\sthe\sCFLAGS\sdoes\snot\scause\sit\sto\sfail.\sProblem\sreported\svia\semail. -D 2024-10-29T19:03:22.644 +C General\sauto.def\scleanups\sand\sdocs. +D 2024-10-29T20:27:36.141 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in cdf1c8db0b33fa83f400bcd63742113a727517adc55b322d2e004339c012cac2 +F Makefile.in 064898709d63e882764d2011522f0898c42a5dc2e7663ff4f4ed8fcfe6b7b067 F Makefile.linux-generic 69b54c58ab2424a0d30f340d9defd7e87c25690a55b77acb9bdc657bd9a223f1 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 1e6852f218b4d74fa79b2c85bbb19b3cf3b2c7c8e89225c8d639df2f0fd5a68f +F auto.def 50cf59530afe1a068fd1a981d5a12461e8acaaeff69778c0909aa1d29f1fea44 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 265ba15df1e64a50722118ac6d84667b0abd35fe8f4db28facf7788c50ac6cde -R e4fa5cb9421ab06b93f3a08ca998b3a0 +P 3891669a3fdd71f7095cf464f6e4e2b870d6c23e79b9f796b1125b2040f05519 +R da60f4bccf0dcae6e53b9b5b4cce8fd0 U stephan -Z af5ebb66ac586f10a87182e001c0a012 +Z ef2b5bc13a71a0b0f34c8682ca475280 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 697d2e3417..f4f4c0c131 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3891669a3fdd71f7095cf464f6e4e2b870d6c23e79b9f796b1125b2040f05519 +e2f41c2540d8ff7686bfe22336598896de9083d139fc5a291c0f19896b9c1d20 From 691e7eceb60d53d3c20ec69c9e8ad43b0c27dd8a Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 23:19:29 +0000 Subject: [PATCH 223/522] Try to detect if --with-readline-cflags is passed a non-cflags value, e.g. readline/readline.h, and fail loudly if it is. The legacy configure accepted that formulation but silently did nothing useful with it and that formulation now causes the auto-completion test to fail, as reported in [forum:f13b8e8f38402367 | forum post f13b8e8f38402367]. FossilOrigin-Name: c97f34d064c1fc1e6860761a417aaab2a79bd3871bcd1dad1d0d3b6f4b692a1e --- auto.def | 2 ++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/auto.def b/auto.def index e5da690c24..1a6bd03614 100644 --- a/auto.def +++ b/auto.def @@ -850,6 +850,8 @@ proc sqlite-check-line-editing {} { set rlInc "-I${rlInc}" } } + } elseif {"" ne $rlInc && ![string match *-I* $rlInc]} { + proj-fatal "Argument to --with-readline-cflag is intended to be CFLAGS and contain -I..." } # If readline.h was found/specified, look for lib(readline|edit)... diff --git a/manifest b/manifest index 08feab3ee4..5f72c6369e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C General\sauto.def\scleanups\sand\sdocs. -D 2024-10-29T20:27:36.141 +C Try\sto\sdetect\sif\s--with-readline-cflags\sis\spassed\sa\snon-cflags\svalue,\se.g.\sreadline/readline.h,\sand\sfail\sloudly\sif\sit\sis.\sThe\slegacy\sconfigure\saccepted\sthat\sformulation\sbut\ssilently\sdid\snothing\suseful\swith\sit\sand\sthat\sformulation\snow\scauses\sthe\sauto-completion\stest\sto\sfail,\sas\sreported\sin\s[forum:f13b8e8f38402367\s|\sforum\spost\sf13b8e8f38402367]. +D 2024-10-29T23:19:29.053 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 50cf59530afe1a068fd1a981d5a12461e8acaaeff69778c0909aa1d29f1fea44 +F auto.def b617eeed76cfc37c16462b77cc214646313df96ff904d2328042e496f2b0c9f4 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3891669a3fdd71f7095cf464f6e4e2b870d6c23e79b9f796b1125b2040f05519 -R da60f4bccf0dcae6e53b9b5b4cce8fd0 +P e2f41c2540d8ff7686bfe22336598896de9083d139fc5a291c0f19896b9c1d20 +R b6d32adaf9573d4cf76554f18adf8ffd U stephan -Z ef2b5bc13a71a0b0f34c8682ca475280 +Z 0e7364863ba936108ce5c81e5e566b82 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f4f4c0c131..c40389ade9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2f41c2540d8ff7686bfe22336598896de9083d139fc5a291c0f19896b9c1d20 +c97f34d064c1fc1e6860761a417aaab2a79bd3871bcd1dad1d0d3b6f4b692a1e From 5be33f7b3f5716091722048877e5b7cb09e85d2e Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 29 Oct 2024 23:42:24 +0000 Subject: [PATCH 224/522] Split the core-most CFLAGS, which should not be overridable (like -fPIC), into CFLAGS.core, so that went CFLAGS=... is passed on in a make invocation the -fPIC flag is not lost (as reported in [forum:39f8c54391d38c72 | forum post 39f8c543]). FossilOrigin-Name: f5899d22c6c2e65383d7e1ca43da740d3a56fb87daa204a642ce1dc963a98de2 --- Makefile.in | 14 ++++++++++++-- Makefile.linux-generic | 9 +++++++-- auto.def | 2 +- main.mk | 14 ++++++++++---- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/Makefile.in b/Makefile.in index 44a0f62932..2c7869cda9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -97,8 +97,18 @@ AR.flags = cr # TODO? Add a configure test to determine this? CC = @CC@ B.cc = @CC_FOR_BUILD@ @BUILD_CFLAGS@ T.cc = @CC@ -CFLAGS = @CPPFLAGS@ @CFLAGS@ @SH_CFLAGS@ - +# +# CFLAGS is problematic because it is frequently overridden when +# invoking make, which loses things like -fPIC. So... let's avoid +# using it directly and instead add a level of indirection. We +# combine CFLAGS and CPPFLAGS here because that's the way the legacy +# build did it. +# +CFLAGS = @CFLAGS@ @CPPFLAGS@ +# +# CFLAGS.core is documented in main.mk. +# +CFLAGS.core = @SH_CFLAGS@ LDFLAGS.shobj = @SHOBJ_LDFLAGS@ LDFLAGS.zlib = @LDFLAGS_ZLIB@ LDFLAGS.math = @LDFLAGS_MATH@ diff --git a/Makefile.linux-generic b/Makefile.linux-generic index 13a0419238..c7441fa517 100644 --- a/Makefile.linux-generic +++ b/Makefile.linux-generic @@ -24,9 +24,14 @@ TOP ?= $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) # # $(CFLAGS) will be used when compiling the library and most -# utilities. It must normally contain -fPIC on Linux systems. +# utilities. It must normally contain -fPIC on Linux systems, +# but overriding CFLAGS is an easy way for users to inadvertently +# remove -fPIC from their builds, so we generally expect to see +# -fPIC in $(CFLAGS.core), which main.mk will integrate with +# the CFLAGS where needed. # -CFLAGS = -fPIC +CFLAGS = +CFLAGS.core = -fPIC # # $(SHELL_OPT) contains CFLAGS for building the sqlite3 CLI shell. diff --git a/auto.def b/auto.def index 1a6bd03614..500456086e 100644 --- a/auto.def +++ b/auto.def @@ -851,7 +851,7 @@ proc sqlite-check-line-editing {} { } } } elseif {"" ne $rlInc && ![string match *-I* $rlInc]} { - proj-fatal "Argument to --with-readline-cflag is intended to be CFLAGS and contain -I..." + proj-fatal "Argument to --with-readline-cflags is intended to be CFLAGS and contain -I..." } # If readline.h was found/specified, look for lib(readline|edit)... diff --git a/main.mk b/main.mk index 626b297d48..467e1f3e2a 100644 --- a/main.mk +++ b/main.mk @@ -221,7 +221,7 @@ TCL_CONFIG_SH ?= # $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not # libsqlite3, and will usually differ from $(LDFLAGS.rpath). # -TCLLIB_RPATH ?= +#TCLLIB_RPATH ?= # # $(HAVE_WASI_SDK) = # @@ -247,9 +247,15 @@ all: sqlite3.h sqlite3.c # # $(CFLAGS) should ideally only contain flags which are relevant for -# all binaries built for the target platform. -# -T.cc += $(CFLAGS) +# all binaries built for the target platform. However, many people +# like to pass it to "make" without realizing that it applies to +# dozens of apps, and they override core flags when doing so. To help +# work around that, we expect core-most CFLAGS (only), e.g. -fPIC, to +# be set in $(CFLAGS.core). That enables people to pass their other +# CFLAGS without triggering, e.g., "recompile with -fPIC" errors. +# +CFLAGS.core ?= +T.cc += $(CFLAGS.core) $(CFLAGS) # # The difference between $(OPT_FEATURE_FLAGS) and $(OPTS) is that the diff --git a/manifest b/manifest index 5f72c6369e..e06adbc968 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Try\sto\sdetect\sif\s--with-readline-cflags\sis\spassed\sa\snon-cflags\svalue,\se.g.\sreadline/readline.h,\sand\sfail\sloudly\sif\sit\sis.\sThe\slegacy\sconfigure\saccepted\sthat\sformulation\sbut\ssilently\sdid\snothing\suseful\swith\sit\sand\sthat\sformulation\snow\scauses\sthe\sauto-completion\stest\sto\sfail,\sas\sreported\sin\s[forum:f13b8e8f38402367\s|\sforum\spost\sf13b8e8f38402367]. -D 2024-10-29T23:19:29.053 +C Split\sthe\score-most\sCFLAGS,\swhich\sshould\snot\sbe\soverridable\s(like\s-fPIC),\sinto\sCFLAGS.core,\sso\sthat\swent\sCFLAGS=...\sis\spassed\son\sin\sa\smake\sinvocation\sthe\s-fPIC\sflag\sis\snot\slost\s(as\sreported\sin\s[forum:39f8c54391d38c72\s|\sforum\spost\s39f8c543]). +D 2024-10-29T23:42:24.491 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 064898709d63e882764d2011522f0898c42a5dc2e7663ff4f4ed8fcfe6b7b067 -F Makefile.linux-generic 69b54c58ab2424a0d30f340d9defd7e87c25690a55b77acb9bdc657bd9a223f1 +F Makefile.in 4d261854ba83b66a790271b2d0e390f94be8fe49b3e5ae6c1596abe7917c65a3 +F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def b617eeed76cfc37c16462b77cc214646313df96ff904d2328042e496f2b0c9f4 +F auto.def 532d2b8d2d0a384476ca60144329ac12bceda654e9edd8178a88e4571dc43431 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 46f98320780c72a025bed1a5f8af3355fb2186691617f2b8d41221f9aa564494 +F main.mk 933f21c0d62076382981df123cebad08a0b4a5980629efea46d5bd81791687a7 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e2f41c2540d8ff7686bfe22336598896de9083d139fc5a291c0f19896b9c1d20 -R b6d32adaf9573d4cf76554f18adf8ffd +P c97f34d064c1fc1e6860761a417aaab2a79bd3871bcd1dad1d0d3b6f4b692a1e +R b6e862fcb5d5e7896f9f768e1edf8f0e U stephan -Z 0e7364863ba936108ce5c81e5e566b82 +Z 8441426a564a87d0438ac80a3d2d09b1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c40389ade9..d6f12026da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c97f34d064c1fc1e6860761a417aaab2a79bd3871bcd1dad1d0d3b6f4b692a1e +f5899d22c6c2e65383d7e1ca43da740d3a56fb87daa204a642ce1dc963a98de2 From 49e7cfc9a321fa405fd54e0dd5cc8dfbdc460331 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 01:47:48 +0000 Subject: [PATCH 225/522] When calculating the TCLLIBDIR in main.mk, allow the user to override it using an environment var or make var assignment, per feedback in [forum:38f6988e57b738e5|forum post 38f6988e57b]. FossilOrigin-Name: 838633182c3f9f9c4c1a23384ed025777c25427d9c4c1f1a47f1630cf4038ca5 --- main.mk | 4 +++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/main.mk b/main.mk index 467e1f3e2a..b2f4051d0f 100644 --- a/main.mk +++ b/main.mk @@ -946,10 +946,12 @@ SOURCE_TCLCONFIG = . $(TCL_CONFIG_SH) || exit $$? # to an existing dir, then append /sqlite3 to it. # T.tcllibdir = \ + if [ x != "x$(TCLLIBDIR)" ]; then tcllibdir="$(TCLLIBDIR)"; else \ for tcllibdir in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \ [ -d "$$tcllibdir" ] && break; done; \ if [ x = "x$$tcllibdir" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ - tcllibdir="$$tcllibdir/sqlite3"; echo "TCLLIBDIR=$$tcllibdir" + tcllibdir="$$tcllibdir/sqlite3"; \ + fi; echo "TCLLIBDIR=$$tcllibdir" # # $(T.compile.tcl) and $(T.link.tcl) are TCL-specific counterparts for $(T.compile) # and $(T.link) which first invoke $(SOURCE_TCLCONFIG). diff --git a/manifest b/manifest index e06adbc968..23187b4b15 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Split\sthe\score-most\sCFLAGS,\swhich\sshould\snot\sbe\soverridable\s(like\s-fPIC),\sinto\sCFLAGS.core,\sso\sthat\swent\sCFLAGS=...\sis\spassed\son\sin\sa\smake\sinvocation\sthe\s-fPIC\sflag\sis\snot\slost\s(as\sreported\sin\s[forum:39f8c54391d38c72\s|\sforum\spost\s39f8c543]). -D 2024-10-29T23:42:24.491 +C When\scalculating\sthe\sTCLLIBDIR\sin\smain.mk,\sallow\sthe\suser\sto\soverride\sit\susing\san\senvironment\svar\sor\smake\svar\sassignment,\sper\sfeedback\sin\s[forum:38f6988e57b738e5|forum\spost\s38f6988e57b]. +D 2024-10-30T01:47:48.301 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 933f21c0d62076382981df123cebad08a0b4a5980629efea46d5bd81791687a7 +F main.mk 8848d415297380eb30752cb018db540b97e2eda0bd3a6c434af040b2008ff0a7 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c97f34d064c1fc1e6860761a417aaab2a79bd3871bcd1dad1d0d3b6f4b692a1e -R b6e862fcb5d5e7896f9f768e1edf8f0e +P f5899d22c6c2e65383d7e1ca43da740d3a56fb87daa204a642ce1dc963a98de2 +R 1a0fb946c82c6ff352a73b25350541bd U stephan -Z 8441426a564a87d0438ac80a3d2d09b1 +Z 6b8bed4dd4087a47566a9613ae5d1273 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d6f12026da..dd9d7db6bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5899d22c6c2e65383d7e1ca43da740d3a56fb87daa204a642ce1dc963a98de2 +838633182c3f9f9c4c1a23384ed025777c25427d9c4c1f1a47f1630cf4038ca5 From 067f809402c5146a2b3a0f47195ed0e13e0a4b22 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 02:06:41 +0000 Subject: [PATCH 226/522] Re-enable exporting of TCLLIBDIR at configure-time so that clients can override it once there rather than having to override it on an arbitrary number of make invocations (which they can still do, but now need not). Based on feedback in [forum:38f6988e57b738e5|forum post 38f6988e57b]. FossilOrigin-Name: ee6e15f12ee55fd13cf31317d876e6ba03a7ae1fb9056f0013106948d81b31d9 --- Makefile.in | 17 ++++++++++++++--- auto.def | 17 ++++++++++------- main.mk | 5 ----- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2c7869cda9..7aac5ec02f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -213,18 +213,29 @@ TCL_CONFIG_SH = @TCL_CONFIG_SH@ # TCL config info from tclConfig.sh # # We have to inject this differently in main.mk to accommodate static -# makefiles: +# makefiles, so we don't currently bother to export it here. This +# block is retained in case we decide that we do indeed need to export +# it at configure-time instead of calculate it at make-time. # #TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ #TCL_LIB_SPEC = @TCL_LIB_SPEC@ #TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ #TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@ #TCL_VERSION = @TCL_VERSION@ +# +# $(TCLLIB_RPATH) is calculated by the configure script. Its counterpart +# in tclConfig.sh (TCL_LD_SEARCH_FLAGS) is defined in such a way as to +# make it incompatible with static makefiles. +# #TCLLIB_RPATH = @TCLLIB_RPATH@ # -# Where do we want to install the tcl plugin +# $(TCLLIBDIR) = where to install the tcl plugin. If this is empty, it +# is calculated at make-time by the targets which need it but we +# export it here so that it can be set at configure-time, so that +# clients are not required to pass it at make-time, or set it in their +# environment, to override it. # -#TCLLIBDIR = @TCLLIBDIR@ +TCLLIBDIR = @TCLLIBDIR@ # # Additional options when running tests using testrunner.tcl diff --git a/auto.def b/auto.def index 500456086e..a94c40df79 100644 --- a/auto.def +++ b/auto.def @@ -561,11 +561,15 @@ proc sqlite-check-tcl {} { } define TCLSH_CMD $with_tclsh - if {0} { + if {1} { # 2024-10-28: calculation of TCLLIBDIR is now done via the shell - # in the makefile rules which need it (search main.mk for - # T.tcllibdir). This code block is kept around as a basis for - # comparison while the new makefile-side rules get battle-tested. + # in the main.mk (search it for T.tcllibdir) so that + # static/hand-written makefiles which import main.mk do not have + # to define that before importing main.mk. Even so, we export + # TCLLIBDIR from here for the benefit of users who want to provide + # it at configure-time and have it "stick", without having to + # provide it on each make invocation or set it in their + # environment. if {$use_tcl} { # Set up the TCLLIBDIR and TCLLIB_RPATH set tcllibdir [get-env TCLLIBDIR ""] @@ -573,7 +577,7 @@ proc sqlite-check-tcl {} { if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { foreach i $result { if {[file isdir $i]} { - set tcllibdir $i + set tcllibdir $i/sqlite3 break } } @@ -583,7 +587,6 @@ proc sqlite-check-tcl {} { } set tclrpath "" if {"" ne $tcllibdir} { - set tcllibdir "${tcllibdir}/sqlite3" set rp [get-define SH_LINKRPATH] set tclrpath [string map [list "%s" $tcllibdir] $rp] # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the @@ -595,7 +598,7 @@ proc sqlite-check-tcl {} { } define TCLLIBDIR $tcllibdir define TCLLIB_RPATH $tclrpath - #proj-fatal "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" + #msg-debug "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" } else { define TCLLIBDIR "" define TCLLIB_RPATH "" diff --git a/main.mk b/main.mk index b2f4051d0f..fb60e4a752 100644 --- a/main.mk +++ b/main.mk @@ -218,11 +218,6 @@ SHELL_OPT ?= # TCL_CONFIG_SH ?= # -# $(TCLLIB_RPATH) is the -rpath flag for libtclsqlite3, not -# libsqlite3, and will usually differ from $(LDFLAGS.rpath). -# -#TCLLIB_RPATH ?= -# # $(HAVE_WASI_SDK) = # # 1 when building with the WASI SDK. This disables certain build diff --git a/manifest b/manifest index 23187b4b15..0fd78ed1e4 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C When\scalculating\sthe\sTCLLIBDIR\sin\smain.mk,\sallow\sthe\suser\sto\soverride\sit\susing\san\senvironment\svar\sor\smake\svar\sassignment,\sper\sfeedback\sin\s[forum:38f6988e57b738e5|forum\spost\s38f6988e57b]. -D 2024-10-30T01:47:48.301 +C Re-enable\sexporting\sof\sTCLLIBDIR\sat\sconfigure-time\sso\sthat\sclients\scan\soverride\sit\sonce\sthere\srather\sthan\shaving\sto\soverride\sit\son\san\sarbitrary\snumber\sof\smake\sinvocations\s(which\sthey\scan\sstill\sdo,\sbut\snow\sneed\snot).\sBased\son\sfeedback\sin\s[forum:38f6988e57b738e5|forum\spost\s38f6988e57b]. +D 2024-10-30T02:06:41.420 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 4d261854ba83b66a790271b2d0e390f94be8fe49b3e5ae6c1596abe7917c65a3 +F Makefile.in c938c6f4febb0c5d63870bf9f6f8c43e5b20f3e1cfc889460d340add94d40db3 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 532d2b8d2d0a384476ca60144329ac12bceda654e9edd8178a88e4571dc43431 +F auto.def c0c87d0df83cd73540fbc84333155b50ac58dbea64d414a05fe4123a5a2644c1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 8848d415297380eb30752cb018db540b97e2eda0bd3a6c434af040b2008ff0a7 +F main.mk 047c1192d515466bc586c1e882cf169210515b259b9b9c898171a9fc8f59c31c F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f5899d22c6c2e65383d7e1ca43da740d3a56fb87daa204a642ce1dc963a98de2 -R 1a0fb946c82c6ff352a73b25350541bd +P 838633182c3f9f9c4c1a23384ed025777c25427d9c4c1f1a47f1630cf4038ca5 +R 5f23d099a56104ea99d6a3e5077a6f43 U stephan -Z 6b8bed4dd4087a47566a9613ae5d1273 +Z 7257af8ebb5afd828f6703c7a9a784cb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dd9d7db6bc..509eebcea3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -838633182c3f9f9c4c1a23384ed025777c25427d9c4c1f1a47f1630cf4038ca5 +ee6e15f12ee55fd13cf31317d876e6ba03a7ae1fb9056f0013106948d81b31d9 From fe5f721de66c874281161f29c51ec3e595a95ed4 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 03:51:21 +0000 Subject: [PATCH 227/522] Generic makefile cleanups. FossilOrigin-Name: 6f86ff2e8c190e83c15dab532660a2a0c359621d1fcce4e6852e56ac6b7f71e3 --- main.mk | 11 ++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/main.mk b/main.mk index fb60e4a752..8f83265e30 100644 --- a/main.mk +++ b/main.mk @@ -398,7 +398,7 @@ distclean: distclean-jimsh # in other flavors of Make. # MAKE_SANITY_CHECK = .main.mk.checks -$(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) +$(MAKE_SANITY_CHECK): $(MAKEFILE_LIST) $(TOP)/auto.def @if [ x = "x$(TOP)" ]; then echo "Missing TOP var" 1>&2; exit 1; fi @if [ ! -d "$(TOP)" ]; then echo "$(TOP) is not a directory" 1>&2; exit 1; fi @if [ ! -f "$(TOP)/auto.def" ]; then echo "$(TOP) does not appear to be the top-most source dir" 1>&2; exit 1; fi @@ -442,18 +442,19 @@ LIBOBJS0 = alter.o analyze.o attach.o auth.o \ window.o LIBOBJS = $(LIBOBJS0) +# # Object files for the amalgamation. # LIBOBJS1 = sqlite3.o -# Determine the real value of LIBOBJ based on the 'configure' script +# +# Determine the real value of LIBOBJ based on whether the amalgamation +# is enabled or not. # LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION)) -#LIBSRC0 = $(SRC) -#LIBSRC1 = sqlite3.c -#LIBSRC = $(LIBSRC$(USE_AMALGAMATION)) $(LIBOBJ): $(MAKE_SANITY_CHECK) +# # All of the source code files. # SRC = \ diff --git a/manifest b/manifest index 0fd78ed1e4..119017f246 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Re-enable\sexporting\sof\sTCLLIBDIR\sat\sconfigure-time\sso\sthat\sclients\scan\soverride\sit\sonce\sthere\srather\sthan\shaving\sto\soverride\sit\son\san\sarbitrary\snumber\sof\smake\sinvocations\s(which\sthey\scan\sstill\sdo,\sbut\snow\sneed\snot).\sBased\son\sfeedback\sin\s[forum:38f6988e57b738e5|forum\spost\s38f6988e57b]. -D 2024-10-30T02:06:41.420 +C Generic\smakefile\scleanups. +D 2024-10-30T03:51:21.497 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 047c1192d515466bc586c1e882cf169210515b259b9b9c898171a9fc8f59c31c +F main.mk 824f35f64c3d4b49f04979059a147c9207acef3354cb3425a6ea0c56b5671cff F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 838633182c3f9f9c4c1a23384ed025777c25427d9c4c1f1a47f1630cf4038ca5 -R 5f23d099a56104ea99d6a3e5077a6f43 +P ee6e15f12ee55fd13cf31317d876e6ba03a7ae1fb9056f0013106948d81b31d9 +R b96df9919f9f382400249a198137582b U stephan -Z 7257af8ebb5afd828f6703c7a9a784cb +Z 7519d85a792eaa797087b3d9e5d4717f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 509eebcea3..8dd7669517 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee6e15f12ee55fd13cf31317d876e6ba03a7ae1fb9056f0013106948d81b31d9 +6f86ff2e8c190e83c15dab532660a2a0c359621d1fcce4e6852e56ac6b7f71e3 From 55865c47a7272f313123f78b8d138d8411d6ac6f Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 04:07:16 +0000 Subject: [PATCH 228/522] Remove accommodation of the legacy-named shared libraries from the installation rules, per discussion. Rename install-includes to install-headers. Quote installation target dir names "just in case". FossilOrigin-Name: 80584e165e4652e76cc3188befcee814f168298486743940bcf46696043686a0 --- main.mk | 83 ++++++++++++++------------------------------------- manifest | 12 ++++---- manifest.uuid | 2 +- 3 files changed, 30 insertions(+), 67 deletions(-) diff --git a/main.mk b/main.mk index 8f83265e30..b82b8130a5 100644 --- a/main.mk +++ b/main.mk @@ -360,7 +360,7 @@ install-dir.all = $(install-dir.bin) $(install-dir.include) \ $(install-dir.lib) $(install-dir.man1) \ $(install-dir.pkgconfig) $(install-dir.all): - $(INSTALL) -d $@ + $(INSTALL) -d "$@" # # After jimsh is compiled, we run some sanity checks to ensure that @@ -1343,59 +1343,22 @@ so: $(libsqlite3.SO)-$(ENABLE_SHARED) all: so # -# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(PACKAGE_VERSION) and -# create symlinks which point to it. Do we really need all of this -# hoop-jumping? Can we not simply install the .so as-is to -# libsqlite3.so (without the versioned bits)? +# Install the $(libsqlite3.SO) as $(libsqlite3.SO).$(PACKAGE_VERSION) +# and create symlinks which point to it: # -# Regarding the historcal installation name of libsqlite3.so.0.8.6: -# -# The historical SQLite build always used a version number of 0.8.6 -# for reasons lost to history but having something to do with libtool -# (which is not longer used in this tree). In order to retain filename -# compatibility for systems which have libraries installed using those -# conventions: -# -# 1) If libsqlite3.so.0.8.6 is found in the target installation -# directory then it is re-linked to point to the new -# names. libsqlite3.so.0 historically symlinks to -# libsqlite3.so.0.8.6, and that link is left in place. We cannot -# retain both the old and new installation because they both share -# the high-level name $(libsqlite3.SO). The down-side of this is -# that it may well upset packaging tools when we replace -# libsqlite3.so (from a legacy package) with a new symlink. -# -# 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links -# to the legacy-style names are created. The primary intent of this -# is to enable chains of operations such as the hypothetical (apt -# remove sqlite3-3.47.0 && apt install sqlite3-3.48.0). In such -# cases, condition (1) would never trigger but applications might -# still expect to see the legacy file names. -# -# In either case we also delete libsqlite3.la because it cannot work -# with the non-libtool library this installation installs. +# - libsqlite3.so.$(PACKAGE_VERSION) +# - libsqlite3.so.3 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) +# - libsqlite3.so =symlink-> libsqlite3.so.3 # install-so-1: $(install-dir.lib) $(libsqlite3.SO) - $(INSTALL) $(libsqlite3.SO) $(install-dir.lib) + $(INSTALL) $(libsqlite3.SO) "$(install-dir.lib)" @echo "Setting up SO symlinks..."; \ - cd $(install-dir.lib) || exit $$?; \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) libsqlite3.la || exit $$?; \ + cd "$(install-dir.lib)" || exit $$?; \ + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).3 || exit $$?; \ ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ - ls -la $(libsqlite3.SO) $(libsqlite3.SO).3* || exit $$?; \ - if [ -e $(libsqlite3.SO).0.8.6 ]; then \ - echo "ACHTUNG: legacy libtool-compatible install found. Re-linking it..."; \ - rm -f $(libsqlite3.SO).0.8.6 || exit $$?; \ - ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ - ls -la $(libsqlite3.SO).0*; \ - elif [ x1 = "x$(INSTALL_SO_086_LINKS)" ]; then \ - echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINKS=1"; \ - rm -f $(libsqlite3.SO).0.8.6 $(libsqlite3.SO).0 || exit $$?; \ - ln -s $(libsqlite3.SO).0.8.6 $(libsqlite3.SO).0 || exit $$?; \ - ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ - ls -la $(libsqlite3.SO).0*; \ - fi + ls -la $(libsqlite3.SO) $(libsqlite3.SO).3* install-so-0 install-so-: install-so: install-so-$(ENABLE_SHARED) install: install-so @@ -1404,7 +1367,7 @@ install: install-so # Install $(libsqlite3.LIB) # install-lib-1: $(install-dir.lib) $(libsqlite3.LIB) - $(INSTALL.noexec) $(libsqlite3.LIB) $(install-dir.lib) + $(INSTALL.noexec) $(libsqlite3.LIB) "$(install-dir.lib)" install-lib-0 install-lib-: install-lib: install-lib-$(ENABLE_STATIC) install: install-lib @@ -1412,9 +1375,9 @@ install: install-lib # # Install C header files # -install-includes: sqlite3.h $(install-dir.include) - $(INSTALL.noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" $(install-dir.include) -install: install-includes +install-headers: sqlite3.h $(install-dir.include) + $(INSTALL.noexec) sqlite3.h "$(TOP)/src/sqlite3ext.h" "$(install-dir.include)" +install: install-headers # # libtclsqlite3... @@ -1437,10 +1400,10 @@ libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL) all: libtcl install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl - @$(T.tcllibdir); set -x; dest="$(DESTDIR)$$tcllibdir"; \ - $(INSTALL) -d $$dest; \ - $(INSTALL) $(libtclsqlite3.SO) $$dest; \ - $(INSTALL.noexec) pkgIndex.tcl $$dest + @$(T.tcllibdir); set -x; \ + $(INSTALL) -d "$(DESTDIR)$$tcllibdir"; \ + $(INSTALL) $(libtclsqlite3.SO) "$(DESTDIR)$$tcllibdir"; \ + $(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$$tcllibdir" install-tcl-0 install-tcl-: install-tcl: install-tcl-$(HAVE_TCL) install: install-tcl @@ -1860,7 +1823,7 @@ sqlite3$(T.exe)-0 sqlite3$(T.exe)-: sqlite3$(T.exe) all: sqlite3$(T.exe)-$(HAVE_WASI_SDK) install-shell-0: sqlite3$(TEXT) $(install-dir.bin) - $(INSTALL) -s sqlite3$(TEXT) $(install-dir.bin) + $(INSTALL) -s sqlite3$(TEXT) "$(install-dir.bin)" install-shell-1 install-shell-: install: install-shell-$(HAVE_WASI_SDK) @@ -1868,7 +1831,7 @@ sqldiff$(T.exe): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o $(T.link) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) install-diff: sqldiff$(T.exe) $(install-dir.bin) - $(INSTALL) -s sqldiff$(TEXT) $(install-dir.bin) + $(INSTALL) -s sqldiff$(TEXT) "$(install-dir.bin)" #install: install-diff dbhash$(T.exe): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h @@ -1891,18 +1854,18 @@ sqlite3_rsync$(T.exe): $(RSYNC_SRC) xbin: sqlite3_rsync$(T.exe) install-rsync: sqlite3_rsync$(T.exe) $(install-dir.bin) - $(INSTALL) sqlite3_rsync$(TEXT) $(install-dir.bin) + $(INSTALL) sqlite3_rsync$(TEXT) "$(install-dir.bin)" #install: install-rsync install-man1: $(install-dir.man1) - $(INSTALL.noexec) $(TOP)/sqlite3.1 $(install-dir.man1) + $(INSTALL.noexec) $(TOP)/sqlite3.1 "$(install-dir.man1)" install: install-man1 # # sqlite3.pc is typically generated by the configure script but could # conceivably be generated by hand. install-pc: sqlite3.pc $(install-dir.pkgconfig) - $(INSTALL.noexec) sqlite3.pc $(install-dir.pkgconfig) + $(INSTALL.noexec) sqlite3.pc "$(install-dir.pkgconfig)" scrub$(T.exe): $(TOP)/ext/misc/scrub.c sqlite3.o $(T.link) -o $@ -I. -DSCRUB_STANDALONE \ diff --git a/manifest b/manifest index 119017f246..bcbb90c3a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Generic\smakefile\scleanups. -D 2024-10-30T03:51:21.497 +C Remove\saccommodation\sof\sthe\slegacy-named\sshared\slibraries\sfrom\sthe\sinstallation\srules,\sper\sdiscussion.\sRename\sinstall-includes\sto\sinstall-headers.\sQuote\sinstallation\starget\sdir\snames\s"just\sin\scase". +D 2024-10-30T04:07:16.329 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 824f35f64c3d4b49f04979059a147c9207acef3354cb3425a6ea0c56b5671cff +F main.mk 7795769763a5c6b12f76404b03ae568b8d3a0029d854d9b3c1355704c58c8f7a F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ee6e15f12ee55fd13cf31317d876e6ba03a7ae1fb9056f0013106948d81b31d9 -R b96df9919f9f382400249a198137582b +P 6f86ff2e8c190e83c15dab532660a2a0c359621d1fcce4e6852e56ac6b7f71e3 +R a4ac118514215cff67837ab2e030efc3 U stephan -Z 7519d85a792eaa797087b3d9e5d4717f +Z c62cc911a577bebb7f954fde1bfa7f5c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8dd7669517..4fb3a304be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f86ff2e8c190e83c15dab532660a2a0c359621d1fcce4e6852e56ac6b7f71e3 +80584e165e4652e76cc3188befcee814f168298486743940bcf46696043686a0 From 7d7e82c9b1ec7c9307734e063409000643ea42a7 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 05:07:18 +0000 Subject: [PATCH 229/522] Clean up and add docs to the TCL vetting steps. Make warning and error messages bold if stdout isatty. FossilOrigin-Name: 47157dcf9ec6b52b37578bcd5dc5ace8c36e62c8ca2625c94252c15db784b115 --- auto.def | 136 ++++++++++++++++++++++++--------------------- autosetup/proj.tcl | 9 ++- manifest | 14 ++--- manifest.uuid | 2 +- 4 files changed, 88 insertions(+), 73 deletions(-) diff --git a/auto.def b/auto.def index a94c40df79..9563405703 100644 --- a/auto.def +++ b/auto.def @@ -147,8 +147,20 @@ set flags { all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} # # + # --with-tcl=DIR may be either a dir containing tclConfig.sh or a + # dir one level up from that from which we can derive a dir + # containing tclConfig.sh. + with-tcl:DIR => {Root of path containing tclConfig.sh} + # If --with-tclsh=X given, it is used for (A) trying to find + # tclConfig.sh and (B) all TCL-based code generation. Warning: if + # its containing dir has multiple tclsh versions, it may select the + # wrong tclConfig.sh! with-tclsh:PATH => {Full pathname of tclsh to use} - with-tcl:DIR => {Directory containing tclConfig.sh} + # --disable-tcl only disables building of the SQLite TCL extension, + # not the requirement for TCL. This tree requires TCL for code + # generation but can use the in-tree copy of autosetup/jimsh0.c for + # that. The SQLite TCL extension and, by extension, the test code + # require a canonical tclsh. tcl=1 => {Disable components which require TCL-dev} # # @@ -159,7 +171,7 @@ set flags { with-readline-ldflags:=auto => {Readline LDFLAGS, e.g. -lreadline -lncurses} # --with-readline-inc is a backwards-compatible alias for - # --with-readline-cflags + # --with-readline-cflags. with-readline-inc: with-readline-cflags:=auto => {Readline CFLAGS, e.g. -I/path/to/includes} @@ -441,31 +453,36 @@ proj-if-opt-truthy with-debug { # be empty - this tree requires TCL to generated numerous # components. # -define TCLSH_CMD false ; # Significant is that it exits with non-0 -define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search proc sqlite-check-tcl {} { - # TODO: document the steps this is taking. + define TCLSH_CMD false ; # Significant is that it exits with non-0 + define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search + define TCLLIBDIR "" ; # Installation dir for TCL extension lib + define TCLLIB_RPATH "" ; # rpath for TCL extension lib + define TCL_CONFIG_SH ""; # full path to tclConfig.sh if {![opt-bool tcl]} { - msg-result "TCL disabled via --disable-tcl" - define HAVE_TCL 0 + msg-result "TCL disabled via --disable-tcl. Will not be able to run tests." return } - + # TODO: document the steps this is taking. global top_srcdir msg-result "Checking for a suitable tcl... " - set optTcl [proj-opt-truthy tcl] - set use_tcl $optTcl + proj-assert {proj-opt-truthy tcl} + set use_tcl 1 set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] msg-debug "sqlite-check-tcl: use_tcl ${use_tcl}" msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" msg-debug "sqlite-check-tcl: with_tcl=$with_tcl" if {"" eq $with_tclsh && "" eq $with_tcl} { + # If neither --with-tclsh nor --with-tcl are provided, try to find + # a workable tclsh. set with_tclsh [proj-first-bin-of tclsh9.0 tclsh8.6 tclsh] msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" } if {"" ne $with_tclsh} { + # --with-tclsh was provided. Validate it and use it to trump any + # value passed via --with-tcl=DIR. if {![file isfile $with_tclsh]} { proj-fatal "TCL shell $with_tclsh is not a file" } elseif {![file-isexec $with_tclsh]} { @@ -474,16 +491,14 @@ proc sqlite-check-tcl {} { define TCLSH_CMD $with_tclsh #msg-result "Using tclsh: $with_tclsh" } - if {$use_tcl} { - if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { - set with_tcl $result - } - if {"" ne $with_tcl && [file isdir $with_tcl]} { - msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl" - } else { - proj-warn "$with_tclsh is unable to recommand a tclConfig.sh" - set use_tcl 0 - } + if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { + set with_tcl $result + } + if {"" ne $with_tcl && [file isdir $with_tcl]} { + msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl" + } else { + proj-warn "$with_tclsh is unable to recommand a tclConfig.sh" + set use_tcl 0 } } @@ -492,6 +507,7 @@ proc sqlite-check-tcl {} { while {1} { if {$use_tcl} { if {"" ne $with_tcl} { + # Ensure that we can find tclConfig.sh under ${with_tcl}/... if {[file readable "${with_tcl}/tclConfig.sh"]} { set cfg "${with_tcl}/tclConfig.sh" } else { @@ -506,9 +522,10 @@ proc sqlite-check-tcl {} { proj-fatal "No tclConfig.sh found under ${with_tcl}" } } else { - # If we have not yet found a tclConfig.sh file, look in $libdir which is - # set automatically by autosetup or by the --prefix command-line option. - # See https://sqlite.org/forum/forumpost/e04e693439a22457 + # If we have not yet found a tclConfig.sh file, look in + # $libdir which is set automatically by autosetup or by the + # --prefix command-line option. See + # https://sqlite.org/forum/forumpost/e04e693439a22457 set libdir [get-define libdir] if {[file readable "${libdir}/tclConfig.sh"]} { set cfg "${libdir}/tclConfig.sh" @@ -531,8 +548,6 @@ proc sqlite-check-tcl {} { } } msg-result "Using tclConfig.sh: $cfg" - } elseif {!$optTcl} { - proj-warn "Unable to run tests because of --disable-tcl" } else { proj-warn "Unable to run tests because no tclConfig.sh file could be located" } @@ -540,15 +555,14 @@ proc sqlite-check-tcl {} { } define TCL_CONFIG_SH $cfg - # The historical configure.ac sources tclConfig.sh so that it can - # use the several TCL_... env vars. We obviously cannot do that from - # TCL, so we apply a level of indirection which sources that script - # then emits the pieces we're interested in as TCL code. If the + # Export a subset of tclConfig.sh to the current TCL-space. If the # config is not available, this emits empty-string entries for the # various options we're interested in. - eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "[get-define TCL_CONFIG_SH]"] + eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] if {"" eq $with_tclsh} { + proj-assert {expr {$cfg ne ""}} + proj-assert {expr {"" ne [get-define TCL_EXEC_PREFIX]}} set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] if {![file-isexec $with_tclsh]} { set with_tclsh2 [get-define TCL_EXEC_PREFIX]/bin/tclsh @@ -560,49 +574,47 @@ proc sqlite-check-tcl {} { } } define TCLSH_CMD $with_tclsh - - if {1} { + proj-assert {expr {( $cfg eq "" && 0 == $use_tcl ) \ + || ( $cfg ne "" && 1 == $use_tcl )}} + if {$use_tcl} { + # Set up the TCLLIBDIR and TCLLIB_RPATH + # # 2024-10-28: calculation of TCLLIBDIR is now done via the shell # in the main.mk (search it for T.tcllibdir) so that # static/hand-written makefiles which import main.mk do not have # to define that before importing main.mk. Even so, we export - # TCLLIBDIR from here for the benefit of users who want to provide + # TCLLIBDIR from here for the benefit of those who want to provide # it at configure-time and have it "stick", without having to # provide it on each make invocation or set it in their # environment. - if {$use_tcl} { - # Set up the TCLLIBDIR and TCLLIB_RPATH - set tcllibdir [get-env TCLLIBDIR ""] - if {"" eq $tcllibdir} { - if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { - foreach i $result { - if {[file isdir $i]} { - set tcllibdir $i/sqlite3 - break - } + set tcllibdir [get-env TCLLIBDIR ""] + if {"" eq $tcllibdir} { + # Attempt to extract TCLLIBDIR from TCL's $auto_path + if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { + foreach i $result { + if {[file isdir $i]} { + set tcllibdir $i/sqlite3 + break } - } else { - proj-warn "Cannot determine TCLLIBDIR" } + } else { + proj-warn "Cannot determine TCLLIBDIR" } - set tclrpath "" - if {"" ne $tcllibdir} { - set rp [get-define SH_LINKRPATH] - set tclrpath [string map [list "%s" $tcllibdir] $rp] - # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the - # rpath but (A) it includes an unexpand var ref to - # ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B) - # that flag is inherently compiler-dependent so it's not as - # portable as tclConfig.sh assumes. We'll instead use the rpath - # flag which autosetup determines for the current compiler. - } - define TCLLIBDIR $tcllibdir - define TCLLIB_RPATH $tclrpath - #msg-debug "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" - } else { - define TCLLIBDIR "" - define TCLLIB_RPATH "" } + set tclrpath "" + if {"" ne $tcllibdir} { + set rp [get-define SH_LINKRPATH] + set tclrpath [string map [list "%s" $tcllibdir] $rp] + # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the + # rpath but (A) it includes an unexpand var ref to + # ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B) + # that flag is inherently compiler-dependent so it's not as + # portable as tclConfig.sh assumes. We'll instead use the rpath + # flag which autosetup determines for the current compiler. + } + define TCLLIBDIR $tcllibdir + define TCLLIB_RPATH $tclrpath + #msg-debug "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" }; # find TCLLIBDIR if {[file exists $with_tclsh]} { diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 698385630e..96c63aad43 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -51,11 +51,11 @@ array set proj_ {} set proj_(isatty) [isatty? stdout] proc proj-warn {msg} { - puts stderr "WARNING: $msg" + puts stderr [proj-bold "WARNING: $msg"] } proc proj-fatal {msg} { show-notices - puts stderr "ERROR: $msg" + puts stderr [proj-bold "ERROR: $msg"] exit 1 } @@ -63,8 +63,11 @@ proc proj-fatal {msg} { # Kind of like a C assert if uplevel (eval) of $script is false, # triggers a fatal error. proc proj-assert {script} { + if {1 == [get-env proj-assert 0]} { + msg-result [proj-bold "asserting: [string trim $script]"] + } if {![uplevel 1 $script]} { - proj-fatal "Affirmation failed: $script" + proj-fatal "Assertion failed: $script" } } diff --git a/manifest b/manifest index bcbb90c3a6..6eada24a54 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\saccommodation\sof\sthe\slegacy-named\sshared\slibraries\sfrom\sthe\sinstallation\srules,\sper\sdiscussion.\sRename\sinstall-includes\sto\sinstall-headers.\sQuote\sinstallation\starget\sdir\snames\s"just\sin\scase". -D 2024-10-30T04:07:16.329 +C Clean\sup\sand\sadd\sdocs\sto\sthe\sTCL\svetting\ssteps.\sMake\swarning\sand\serror\smessages\sbold\sif\sstdout\sisatty. +D 2024-10-30T05:07:18.996 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def c0c87d0df83cd73540fbc84333155b50ac58dbea64d414a05fe4123a5a2644c1 +F auto.def 246f9d5fd2db744fd8670e2fc02ac2986501bc0fb96041bbe5891b80238e0be9 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl c37063118b4c2556bd6e9c1b1b6a96e325415ea5ff0b6c56921aed6165ccd332 +F autosetup/proj.tcl fa96b17f000042f467239f2ef3e7a33d4787bc0fb5db4e69bd5bf1e55bb380f4 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6f86ff2e8c190e83c15dab532660a2a0c359621d1fcce4e6852e56ac6b7f71e3 -R a4ac118514215cff67837ab2e030efc3 +P 80584e165e4652e76cc3188befcee814f168298486743940bcf46696043686a0 +R 9bc2e5e8de07dc365525bf3b51622805 U stephan -Z c62cc911a577bebb7f954fde1bfa7f5c +Z f36698e72a5599d183442b07666428fe # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4fb3a304be..3d887f1a00 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80584e165e4652e76cc3188befcee814f168298486743940bcf46696043686a0 +47157dcf9ec6b52b37578bcd5dc5ace8c36e62c8ca2625c94252c15db784b115 From 9bcb0a510f993b48ba3264b55b7eceb2c993a8ac Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 30 Oct 2024 14:03:56 +0000 Subject: [PATCH 230/522] Fix the CLI so that it can use either the canonical Antirez linenoise (with HAVE_LINENOISE=1) or Steve Bennett's enhanced linenoise that works on the Win32 console as well as on Unix (with HAVE_LINENOISE=2). The ./configure script detects which one to use and sets HAVE_LINENOISE accordingly. FossilOrigin-Name: c0048e4482e9cb9662637899922af9609e7c8fb002a37b71e6181074df7a0dd1 --- auto.def | 15 ++++++++++++--- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 15 ++++++++++++--- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/auto.def b/auto.def index 9563405703..2e4278e0d6 100644 --- a/auto.def +++ b/auto.def @@ -789,9 +789,18 @@ proc sqlite-check-line-editing {} { proj-fatal "Cannot find linenoise.h in $dirLn" } msg-result "Using linenoise from $dirLn" - define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise.c" - define HAVE_LINENOISE 1 - sqlite-add-shell-opt -DHAVE_LINENOISE=1 + if {[file exists $dirLn/linenoise-ship.c]} { + # HAVE_LINENOISE==2 means that the linenoise completion callback has an + # extra userdata argument. + define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise-ship.c" + define HAVE_LINENOISE 2 + sqlite-add-shell-opt -DHAVE_LINENOISE=2 + } else { + # HAVE_LINENOISE==1 is the original Antirez linenoise + define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise.c" + define HAVE_LINENOISE 1 + sqlite-add-shell-opt -DHAVE_LINENOISE=1 + } return "linenoise" } elseif {[opt-bool editline]} { # libedit mimics libreadline and on some systems does not have its diff --git a/manifest b/manifest index 6eada24a54..e58ae0e7c9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clean\sup\sand\sadd\sdocs\sto\sthe\sTCL\svetting\ssteps.\sMake\swarning\sand\serror\smessages\sbold\sif\sstdout\sisatty. -D 2024-10-30T05:07:18.996 +C Fix\sthe\sCLI\sso\sthat\sit\scan\suse\seither\sthe\scanonical\sAntirez\slinenoise\n(with\sHAVE_LINENOISE=1)\sor\sSteve\sBennett's\senhanced\slinenoise\sthat\sworks\non\sthe\sWin32\sconsole\sas\swell\sas\son\sUnix\s(with\sHAVE_LINENOISE=2).\s\sThe\n./configure\sscript\sdetects\swhich\sone\sto\suse\sand\ssets\sHAVE_LINENOISE\saccordingly. +D 2024-10-30T14:03:56.112 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 246f9d5fd2db744fd8670e2fc02ac2986501bc0fb96041bbe5891b80238e0be9 +F auto.def 2e458b180c7d6f765acd4c9f604d2087fb30114ae7343481e1ecfe7b6ddb16b5 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -777,7 +777,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in b6b7944fc076c2fd29d38edb61e3da978e838e3f79e1cf2c96a1342c423b3892 +F src/shell.c.in 4eb010971da0a4b103af5853152e9c95b991174df75528fda6f333037f0007a0 F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 80584e165e4652e76cc3188befcee814f168298486743940bcf46696043686a0 -R 9bc2e5e8de07dc365525bf3b51622805 -U stephan -Z f36698e72a5599d183442b07666428fe +P 47157dcf9ec6b52b37578bcd5dc5ace8c36e62c8ca2625c94252c15db784b115 +R 61fb904d4434d51f1a06bd710d4e38ff +U drh +Z d06b56d237b61b23e8eb2bfeab607447 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3d887f1a00..3ad30b5684 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47157dcf9ec6b52b37578bcd5dc5ace8c36e62c8ca2625c94252c15db784b115 +c0048e4482e9cb9662637899922af9609e7c8fb002a37b71e6181074df7a0dd1 diff --git a/src/shell.c.in b/src/shell.c.in index 50f1c5bfea..cdd09becf0 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -5795,15 +5795,22 @@ static char **readline_completion(const char *zText, int iStart, int iEnd){ ** Linenoise completion callback. Note that the 3rd argument is from ** the "msteveb" version of linenoise, not the "antirez" version. */ -static void linenoise_completion(const char *zLine, linenoiseCompletions *lc, - void *pUserData){ +static void linenoise_completion( + const char *zLine, + linenoiseCompletions *lc +#if HAVE_LINENOISE==2 + ,void *pUserData +#endif +){ i64 nLine = strlen(zLine); i64 i, iStart; sqlite3_stmt *pStmt = 0; char *zSql; char zBuf[1000]; +#if HAVE_LINENOISE==2 UNUSED_PARAMETER(pUserData); +#endif if( nLine>(i64)sizeof(zBuf)-30 ) return; if( zLine[0]=='.' || zLine[0]=='#') return; for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){} @@ -13196,7 +13203,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( zHistory ){ shell_read_history(zHistory); } #if (HAVE_READLINE || HAVE_EDITLINE) && !defined(SQLITE_OMIT_READLINE_COMPLETION) rl_attempted_completion_function = readline_completion; -#elif HAVE_LINENOISE +#elif HAVE_LINENOISE==1 + linenoiseSetCompletionCallback(linenoise_completion); +#elif HAVE_LINENOISE==2 linenoiseSetCompletionCallback(linenoise_completion, NULL); #endif data.in = 0; From 4f0529e33e79a2eed36f23110f3fb7b145da9b71 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 30 Oct 2024 19:13:07 +0000 Subject: [PATCH 231/522] Adjust Makefile.in to honor the CC environment variable. Add the "show-variables" target to main.mk, for debugging. FossilOrigin-Name: e5f1a01f9f574a64e464c66c1b88f76aeea83f0bbe697c53bb63d3592d93e55e --- Makefile.in | 2 +- main.mk | 8 ++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7aac5ec02f..1a093c5af6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -96,7 +96,7 @@ AR = @AR@ AR.flags = cr # TODO? Add a configure test to determine this? CC = @CC@ B.cc = @CC_FOR_BUILD@ @BUILD_CFLAGS@ -T.cc = @CC@ +T.cc = $(CC) # # CFLAGS is problematic because it is frequently overridden when # invoking make, which loses things like -fPIC. So... let's avoid diff --git a/main.mk b/main.mk index b82b8130a5..f05fae8336 100644 --- a/main.mk +++ b/main.mk @@ -2148,3 +2148,11 @@ clean: clean-. tidy # Clean up everything. No exceptions. distclean-.: distclean: distclean-. clean + + +# Show important variable settings. +show-variables: + @echo "CC = $(CC)" + @echo "B.cc = $(B.cc)" + @echo "T.cc = $(T.cc)" + @echo "T.cc.sqlite = $(T.cc.sqlite)" diff --git a/manifest b/manifest index e58ae0e7c9..5cefd09acc 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sthe\sCLI\sso\sthat\sit\scan\suse\seither\sthe\scanonical\sAntirez\slinenoise\n(with\sHAVE_LINENOISE=1)\sor\sSteve\sBennett's\senhanced\slinenoise\sthat\sworks\non\sthe\sWin32\sconsole\sas\swell\sas\son\sUnix\s(with\sHAVE_LINENOISE=2).\s\sThe\n./configure\sscript\sdetects\swhich\sone\sto\suse\sand\ssets\sHAVE_LINENOISE\saccordingly. -D 2024-10-30T14:03:56.112 +C Adjust\sMakefile.in\sto\shonor\sthe\sCC\senvironment\svariable.\s\sAdd\sthe\n"show-variables"\starget\sto\smain.mk,\sfor\sdebugging. +D 2024-10-30T19:13:07.641 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in c938c6f4febb0c5d63870bf9f6f8c43e5b20f3e1cfc889460d340add94d40db3 +F Makefile.in 77b49b5a1acb2d5f026dea3f974306fa1be7d99fe0a1917cab313844716461f0 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 7795769763a5c6b12f76404b03ae568b8d3a0029d854d9b3c1355704c58c8f7a +F main.mk f53fa37c14bbf1f561f1c1e0cc4108987ad986e6b609bb9040b4a47e8312887c F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 47157dcf9ec6b52b37578bcd5dc5ace8c36e62c8ca2625c94252c15db784b115 -R 61fb904d4434d51f1a06bd710d4e38ff +P c0048e4482e9cb9662637899922af9609e7c8fb002a37b71e6181074df7a0dd1 +R 7a0cc20d4b50730c4df041dd5290b33e U drh -Z d06b56d237b61b23e8eb2bfeab607447 +Z 640e6e3c39ea4199b20729a50edbbfbb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3ad30b5684..a6b02a414e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0048e4482e9cb9662637899922af9609e7c8fb002a37b71e6181074df7a0dd1 +e5f1a01f9f574a64e464c66c1b88f76aeea83f0bbe697c53bb63d3592d93e55e From 26eccee74101f00c74df4ecea605098d7988a39e Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 22:09:49 +0000 Subject: [PATCH 232/522] proj.tcl/main.mk doc updates. No functional changes. FossilOrigin-Name: e06574c6b4b666ef26f0fa06e6d60e5d896caaf1b1ca27f5369f5b7650d12b9b --- autosetup/proj.tcl | 10 +++++----- main.mk | 6 +++--- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 96c63aad43..e1191dd44b 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -936,12 +936,12 @@ proc proj-dump-defs-json {file args} { # form which autosetup will expect for passing to [opt-val NAME] and # friends. # -# Commend lines are permitted in the input. +# Comment lines are permitted in the input. # -# If [opt-val $hidden] has a value but [opt-val -# $canonical] does not, it copies the former over the latter. If -# $hidden has no value set, this is a no-op. If both have explicit -# values a fatal usage error is triggered. +# For each pair ALIAS and CANONICAL, if --ALIAS is provided but +# --CANONICAL is not, the value of the former is copied to the +# latter. If --ALIAS is not provided, this is a no-op. If both have +# explicitly been provided a fatal usage error is triggered. # # Motivation: autosetup enables "hidden aliases" in [options] lists, # and elides the aliases from --help output but does no further diff --git a/main.mk b/main.mk index f05fae8336..7da3d327d5 100644 --- a/main.mk +++ b/main.mk @@ -1431,14 +1431,14 @@ tclextension-install: tclsqlite3.c $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(T.cc)" $(CFLAGS.tclextension) # -# Install the SQLite TCL extension that is used by $TCLSH_CMD +# Uninstall the SQLite TCL extension that is used by $TCLSH_CMD. # tclextension-uninstall: $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --uninstall # -# List all installed the SQLite TCL extension that is are accessible -# by $TCLSH_CMD, included prior versions. +# List all installed the SQLite TCL extensions that is are accessible +# by $TCLSH_CMD, including prior versions. # tclextension-list: $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info diff --git a/manifest b/manifest index 5cefd09acc..34f4ce8faf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sMakefile.in\sto\shonor\sthe\sCC\senvironment\svariable.\s\sAdd\sthe\n"show-variables"\starget\sto\smain.mk,\sfor\sdebugging. -D 2024-10-30T19:13:07.641 +C proj.tcl/main.mk\sdoc\supdates.\sNo\sfunctional\schanges. +D 2024-10-30T22:09:49.845 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl fa96b17f000042f467239f2ef3e7a33d4787bc0fb5db4e69bd5bf1e55bb380f4 +F autosetup/proj.tcl bbcad82f274f23b4467ba346a750b340ba97ff6218e231e8b471f8b960ed1273 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk f53fa37c14bbf1f561f1c1e0cc4108987ad986e6b609bb9040b4a47e8312887c +F main.mk 3eb1213b7a8f1a6a86bc59ca910b608d60670fb915c5a76cbfb90f84c61ab4dd F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c0048e4482e9cb9662637899922af9609e7c8fb002a37b71e6181074df7a0dd1 -R 7a0cc20d4b50730c4df041dd5290b33e -U drh -Z 640e6e3c39ea4199b20729a50edbbfbb +P e5f1a01f9f574a64e464c66c1b88f76aeea83f0bbe697c53bb63d3592d93e55e +R eda87ae0aaa5ae05af6dcdd7368f1637 +U stephan +Z 69321f0b758a6072a7c355e769ce2507 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a6b02a414e..7f63cc2e61 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5f1a01f9f574a64e464c66c1b88f76aeea83f0bbe697c53bb63d3592d93e55e +e06574c6b4b666ef26f0fa06e6d60e5d896caaf1b1ca27f5369f5b7650d12b9b From 2d73547cdb0b12fbadf9cabd65d84086b57af521 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 22:41:12 +0000 Subject: [PATCH 233/522] Expand [c0048e4482e9] to determine the linenoise API flavor via a compile test rather than guessing based on the filename. FossilOrigin-Name: dbf0079190d98ec1760cc3b55aa0116c9f85f215586bd864c5d6cede5a034fa5 --- auto.def | 82 ++++++++++++++++++++++++++++++++++++++++----------- manifest | 12 ++++---- manifest.uuid | 2 +- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/auto.def b/auto.def index 2e4278e0d6..09a070b1b1 100644 --- a/auto.def +++ b/auto.def @@ -731,12 +731,45 @@ if {1} { unset ts tsn } +######################################################################## +# Attempts to determine whether the given linenoise header file is of +# the "antirez" or "msteveb" flavor. It returns 1 for antirez, 2 for +# msteveb, and 0 if it's neither. +proc sqlite-which-linenoise {dotH} { + set sourceOrig { + #include + #include + #include + /* size_t has to be be in there _somewhere_ */ + } + append sourceOrig [proj-file-content $dotH] + set sourceTail { + int main(void) { + linenoiseSetCompletionCallback(0 $arg); + return 0; + } + } + set arg "" + set source $sourceOrig + append source [subst $sourceTail] + if {[cctest -nooutput 1 -source $source]} { + return 1 + } + set arg ", 0" + set source $sourceOrig + append source [subst $sourceTail] + if {[cctest -nooutput 1 -source $source]} { + return 2 + } + return 0 +} + ######################################################################## # sqlite-check-line-editing jumps through proverbial hoops to try to # find a working line-editing library, setting: # # - HAVE_READLINE to 0 or 1 -# - HAVE_LINENOISE to 0 or 1 +# - HAVE_LINENOISE to 0, 1, or 2 # - HAVE_EDITLINE to 0 or 1 # # Only one of ^^^ those will be set to 1. @@ -783,25 +816,40 @@ proc sqlite-check-line-editing {} { # Use linenoise from a copy of its sources (not a library)... if {![file isdir $dirLn]} { proj-fatal "--with-linenoise value is not a directory" - } elseif {![file exists $dirLn/linenoise.c] } { - proj-fatal "Cannot find linenoise.c in $dirLn" - } elseif {![file exists $dirLn/linenoise.h] } { + } + set lnH $dirLn/linenoise.h + if {![file exists $lnH] } { proj-fatal "Cannot find linenoise.h in $dirLn" } - msg-result "Using linenoise from $dirLn" - if {[file exists $dirLn/linenoise-ship.c]} { - # HAVE_LINENOISE==2 means that the linenoise completion callback has an - # extra userdata argument. - define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise-ship.c" - define HAVE_LINENOISE 2 - sqlite-add-shell-opt -DHAVE_LINENOISE=2 - } else { - # HAVE_LINENOISE==1 is the original Antirez linenoise - define CFLAGS_READLINE "-I$dirLn $dirLn/linenoise.c" - define HAVE_LINENOISE 1 - sqlite-add-shell-opt -DHAVE_LINENOISE=1 + set flavor "" + switch -- [sqlite-which-linenoise $lnH] { + 1 { + set flavor "antirez" + define HAVE_LINENOISE 1 + } + 2 { + set flavor "msteveb" + define HAVE_LINENOISE 2 + } + default { + user-error "Cannot determine the flavor of linenoise from $lnH" + } + } + set lnC "" + set lnCOpts {linenoise-ship.c linenoise.c} + foreach f $lnCOpts { + if {[file exists $dirLn/$f]} { + set lnC $dirLn/$f + break; + } + } + if {"" eq $lnC} { + proj-fatal "Cannot find any of $lnCOpts in $dirLn" } - return "linenoise" + msg-result "Using $flavor linenoise from $dirLn" + define CFLAGS_READLINE "-I$dirLn $lnC" + sqlite-add-shell-opt -DHAVE_LINENOISE=[get-define HAVE_LINENOISE] + return "linenoise ($flavor)" } elseif {[opt-bool editline]} { # libedit mimics libreadline and on some systems does not have its # own header installed (instead, that of libreadline is used). diff --git a/manifest b/manifest index 34f4ce8faf..728c800620 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C proj.tcl/main.mk\sdoc\supdates.\sNo\sfunctional\schanges. -D 2024-10-30T22:09:49.845 +C Expand\s[c0048e4482e9]\sto\sdetermine\sthe\slinenoise\sAPI\sflavor\svia\sa\scompile\stest\srather\sthan\sguessing\sbased\son\sthe\sfilename. +D 2024-10-30T22:41:12.401 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 2e458b180c7d6f765acd4c9f604d2087fb30114ae7343481e1ecfe7b6ddb16b5 +F auto.def 9a03b31df3ceaf4fbf62e3467502caac5dda856ba73d4a47b63b4c379805313c F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e5f1a01f9f574a64e464c66c1b88f76aeea83f0bbe697c53bb63d3592d93e55e -R eda87ae0aaa5ae05af6dcdd7368f1637 +P e06574c6b4b666ef26f0fa06e6d60e5d896caaf1b1ca27f5369f5b7650d12b9b +R d52ea075c2a44b2ded7d1c0f8762d401 U stephan -Z 69321f0b758a6072a7c355e769ce2507 +Z 35f287fa088fe3c09becc3325399abda # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7f63cc2e61..9da7dd97d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e06574c6b4b666ef26f0fa06e6d60e5d896caaf1b1ca27f5369f5b7650d12b9b +dbf0079190d98ec1760cc3b55aa0116c9f85f215586bd864c5d6cede5a034fa5 From 1e563f4817705ae2dd8fd03b70383976186f98e3 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 22:49:40 +0000 Subject: [PATCH 234/522] Move the linenoise flavor check from auto.def to proj.tcl for re-use in downstream projects. FossilOrigin-Name: 84e503dc1e3672fe7787fb747ed70ca14ad181a743925bd1658c40baaa8a27cd --- auto.def | 60 +++++++++------------------------------------- autosetup/proj.tcl | 33 +++++++++++++++++++++++++ manifest | 14 +++++------ manifest.uuid | 2 +- 4 files changed, 52 insertions(+), 57 deletions(-) diff --git a/auto.def b/auto.def index 09a070b1b1..6093f2a21a 100644 --- a/auto.def +++ b/auto.def @@ -731,39 +731,6 @@ if {1} { unset ts tsn } -######################################################################## -# Attempts to determine whether the given linenoise header file is of -# the "antirez" or "msteveb" flavor. It returns 1 for antirez, 2 for -# msteveb, and 0 if it's neither. -proc sqlite-which-linenoise {dotH} { - set sourceOrig { - #include - #include - #include - /* size_t has to be be in there _somewhere_ */ - } - append sourceOrig [proj-file-content $dotH] - set sourceTail { - int main(void) { - linenoiseSetCompletionCallback(0 $arg); - return 0; - } - } - set arg "" - set source $sourceOrig - append source [subst $sourceTail] - if {[cctest -nooutput 1 -source $source]} { - return 1 - } - set arg ", 0" - set source $sourceOrig - append source [subst $sourceTail] - if {[cctest -nooutput 1 -source $source]} { - return 2 - } - return 0 -} - ######################################################################## # sqlite-check-line-editing jumps through proverbial hoops to try to # find a working line-editing library, setting: @@ -821,20 +788,6 @@ proc sqlite-check-line-editing {} { if {![file exists $lnH] } { proj-fatal "Cannot find linenoise.h in $dirLn" } - set flavor "" - switch -- [sqlite-which-linenoise $lnH] { - 1 { - set flavor "antirez" - define HAVE_LINENOISE 1 - } - 2 { - set flavor "msteveb" - define HAVE_LINENOISE 2 - } - default { - user-error "Cannot determine the flavor of linenoise from $lnH" - } - } set lnC "" set lnCOpts {linenoise-ship.c linenoise.c} foreach f $lnCOpts { @@ -846,9 +799,18 @@ proc sqlite-check-line-editing {} { if {"" eq $lnC} { proj-fatal "Cannot find any of $lnCOpts in $dirLn" } - msg-result "Using $flavor linenoise from $dirLn" + set flavor "" + set lnVal [proj-which-linenoise $lnH] + switch -- $lnVal { + 1 { set flavor "antirez" } + 2 { set flavor "msteveb" } + default { + proj-fatal "Cannot determine the flavor of linenoise from $lnH" + } + } define CFLAGS_READLINE "-I$dirLn $lnC" - sqlite-add-shell-opt -DHAVE_LINENOISE=[get-define HAVE_LINENOISE] + define HAVE_LINENOISE $lnVal + sqlite-add-shell-opt -DHAVE_LINENOISE=$lnVal return "linenoise ($flavor)" } elseif {[opt-bool editline]} { # libedit mimics libreadline and on some systems does not have its diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index e1191dd44b..b691162aa6 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -989,3 +989,36 @@ proc proj-redefine-cc-for-build {} { define CC_FOR_BUILD [get-define CC] } } + +######################################################################## +# Attempts to determine whether the given linenoise header file is of +# the "antirez" or "msteveb" flavor. It returns 1 for antirez, 2 for +# msteveb, and 0 if it's neither. +proc proj-which-linenoise {dotH} { + set sourceOrig { + #include + #include + #include + /* size_t has to be be in there _somewhere_ */ + } + append sourceOrig [proj-file-content $dotH] + set sourceTail { + int main(void) { + linenoiseSetCompletionCallback(0 $arg); + return 0; + } + } + set arg "" + set source $sourceOrig + append source [subst $sourceTail] + if {[cctest -nooutput 1 -source $source]} { + return 1 + } + set arg ", 0" + set source $sourceOrig + append source [subst $sourceTail] + if {[cctest -nooutput 1 -source $source]} { + return 2 + } + return 0 +} diff --git a/manifest b/manifest index 728c800620..eecf278ccd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\s[c0048e4482e9]\sto\sdetermine\sthe\slinenoise\sAPI\sflavor\svia\sa\scompile\stest\srather\sthan\sguessing\sbased\son\sthe\sfilename. -D 2024-10-30T22:41:12.401 +C Move\sthe\slinenoise\sflavor\scheck\sfrom\sauto.def\sto\sproj.tcl\sfor\sre-use\sin\sdownstream\sprojects. +D 2024-10-30T22:49:40.804 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 9a03b31df3ceaf4fbf62e3467502caac5dda856ba73d4a47b63b4c379805313c +F auto.def 690effe8c5d7bb046120bd30400896b1a7fdd649912c01114df1c0df400bb62b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl bbcad82f274f23b4467ba346a750b340ba97ff6218e231e8b471f8b960ed1273 +F autosetup/proj.tcl 035cc7ab786b11eb771f19bca7d908cd64f783af85a21e6594a3634acd67b726 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e06574c6b4b666ef26f0fa06e6d60e5d896caaf1b1ca27f5369f5b7650d12b9b -R d52ea075c2a44b2ded7d1c0f8762d401 +P dbf0079190d98ec1760cc3b55aa0116c9f85f215586bd864c5d6cede5a034fa5 +R c2cdfa3dffe3b9b6690b173654ff9db0 U stephan -Z 35f287fa088fe3c09becc3325399abda +Z 0dcc5db1b022ddc0e6c0ca033d369137 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9da7dd97d6..704e8f252f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dbf0079190d98ec1760cc3b55aa0116c9f85f215586bd864c5d6cede5a034fa5 +84e503dc1e3672fe7787fb747ed70ca14ad181a743925bd1658c40baaa8a27cd From 07a1e3eb91e710a973cfb44690ad9dba010deff4 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 30 Oct 2024 23:10:38 +0000 Subject: [PATCH 235/522] Minor cleanups to the linenoise flavor detection test. FossilOrigin-Name: 3be32de1626f940e256076df76388e7633de57f340aac937f6a48d3585b96ca4 --- autosetup/proj.tcl | 25 ++++++++++++------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index b691162aa6..a5be20929d 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -12,6 +12,9 @@ # Routines for Steve Bennett's autosetup which are common to trees # managed in and around the umbrella of the SQLite project. # +# The intent is that these routines be relatively generic, independent +# of a given project. +# # This file was initially derived from one used in the libfossil # project, authored by the same person who ported it here, and this is # noted here only as an indication that there are no licensing issues @@ -995,28 +998,24 @@ proc proj-redefine-cc-for-build {} { # the "antirez" or "msteveb" flavor. It returns 1 for antirez, 2 for # msteveb, and 0 if it's neither. proc proj-which-linenoise {dotH} { - set sourceOrig { - #include - #include - #include - /* size_t has to be be in there _somewhere_ */ - } - append sourceOrig [proj-file-content $dotH] - set sourceTail { + set srcHeader [proj-file-content $dotH] + set srcMain { int main(void) { - linenoiseSetCompletionCallback(0 $arg); + linenoiseSetCompletionCallback(0$arg) + /* antirez has only 1 arg, msteveb has 2 */; return 0; } } set arg "" - set source $sourceOrig - append source [subst $sourceTail] + append source $srcHeader [subst $srcMain] if {[cctest -nooutput 1 -source $source]} { return 1 } + set source { + #include /* size_t */ + } set arg ", 0" - set source $sourceOrig - append source [subst $sourceTail] + append source $srcHeader [subst $srcMain] if {[cctest -nooutput 1 -source $source]} { return 2 } diff --git a/manifest b/manifest index eecf278ccd..795ff46c21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sthe\slinenoise\sflavor\scheck\sfrom\sauto.def\sto\sproj.tcl\sfor\sre-use\sin\sdownstream\sprojects. -D 2024-10-30T22:49:40.804 +C Minor\scleanups\sto\sthe\slinenoise\sflavor\sdetection\stest. +D 2024-10-30T23:10:38.423 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 035cc7ab786b11eb771f19bca7d908cd64f783af85a21e6594a3634acd67b726 +F autosetup/proj.tcl 1e9262757c39afe996a4866fb81c4619d4822b2de09952132d362271f4e069c5 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P dbf0079190d98ec1760cc3b55aa0116c9f85f215586bd864c5d6cede5a034fa5 -R c2cdfa3dffe3b9b6690b173654ff9db0 +P 84e503dc1e3672fe7787fb747ed70ca14ad181a743925bd1658c40baaa8a27cd +R 235f5f08d1190fddb79e56ae3a84f4e6 U stephan -Z 0dcc5db1b022ddc0e6c0ca033d369137 +Z e505c01bc9a5f78170d2f000898996a1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 704e8f252f..81a5e858c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84e503dc1e3672fe7787fb747ed70ca14ad181a743925bd1658c40baaa8a27cd +3be32de1626f940e256076df76388e7633de57f340aac937f6a48d3585b96ca4 From 7a55fe3a95e4238dc819554114f875ad69f4412d Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 00:56:05 +0000 Subject: [PATCH 236/522] Reimplement how the TCL-related environment vars are made available to make recipes which need them, reducing the console noise and consolidating it with the has_tclconfig flag file. It now uses a generated shell snippet which it sources, rather than inlining all of that shell code. FossilOrigin-Name: 0cdfd142e11824d41ebb6c6e508933e04ac6f6dc0dc375cc5b0032f56eb7f423 --- main.mk | 112 +++++++++++++++++++++++--------------------------- manifest | 12 +++--- manifest.uuid | 2 +- 3 files changed, 58 insertions(+), 68 deletions(-) diff --git a/main.mk b/main.mk index 7da3d327d5..bb4f3b7e58 100644 --- a/main.mk +++ b/main.mk @@ -906,60 +906,51 @@ has_tclsh85: touch has_tclsh85 # -# .tclconfig.make has the config info from tclConfig.sh, but in -# makefile form. If TCL_CONFIG_SH is empty then it will emit -# empty config state (which is harmless). +# $(T.tcl.env.sh) is a shell script intended for source'ing to set +# various TCL config info in the current shell context: # -# Alas, it turns out that POSIX make cannot both generate a makefile -# and import it in the same make invocation (GNU make can), so this -# approach, while simple to implement and non-intrusive on the targets -# which require the config state, is not portable. +# - All info exported by tclConfig.sh # -# An alternative is $(SOURCE_TCLCONFIG), defined below, but this impl -# is retained as a reminder of why we cannot portably use this -# otherwise trivial approach. +# - TCLLIBDIR = the first entry from TCL's $auto_path which refers to +# an existing dir, then append /sqlite3 to it. If TCLLIBDIR is +# provided via the environment, that value is used instead. # -#.tclconfig.make: -# sh $(TOP)/tool/tclConfigShToMake.sh $(TCL_CONFIG_SH) > .tclconfig.make -#distclean-tclconfig: -# rm -f .tclconfig.make -#distclean: distclean-tclconfig -#-include .tclconfig.make - +# Maintenance reminder: the ./ at the start of the name is required or /bin/sh +# refuses to source it: # -# SOURCE_TCLCONFIG is shell code to be run as part of any compilation -# or link step which requires vars from $(TCL_CONFIG_SH). All targets -# which use this should also have a dependency on has_tclconfig. +# . .tclenv.sh ==> .tclenv.sh: not found +# . ./.tclenv.sh ==> fine # -SOURCE_TCLCONFIG = . $(TCL_CONFIG_SH) || exit $$? +# It took half an hour to figure that out. # -# T.tcllibdir = shell code to extract the TCLLIBDIR to the tcllibdir -# shell var and exit with !0 if it cannot be determined. It must be -# part of a chained series of commands so that the var survives for -# the following rules in the same recipe. +T.tcl.env.sh = ./.tclenv.sh +$(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) + @if [ x = "x$(TCL_CONFIG_SH)" ]; then \ + echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ + fi + @if [ x != "x$(TCLLIBDIR)" ]; then echo TCLLIBDIR="$(TCLLIBDIR)"; else \ + for TCLLIBDIR in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \ + [ -d "$$TCLLIBDIR" ] && break; done; \ + if [ x = "x$$TCLLIBDIR" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ + echo TCLLIBDIR="$$TCLLIBDIR/sqlite3"; \ + fi > $@; \ + echo ". $(TCL_CONFIG_SH) || exit \$$?" >> $@ + # -# Algo: tcllibdir = the first entry from TCL's $auto_path which refers -# to an existing dir, then append /sqlite3 to it. +# $(T.tcl.env.source) is shell code to be run as part of any +# compilation or link step which requires vars from +# $(TCL_CONFIG_SH). All targets which use this should also have a +# dependency on $(T.tcl.env.sh). # -T.tcllibdir = \ - if [ x != "x$(TCLLIBDIR)" ]; then tcllibdir="$(TCLLIBDIR)"; else \ - for tcllibdir in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \ - [ -d "$$tcllibdir" ] && break; done; \ - if [ x = "x$$tcllibdir" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ - tcllibdir="$$tcllibdir/sqlite3"; \ - fi; echo "TCLLIBDIR=$$tcllibdir" +T.tcl.env.source = . $(T.tcl.env.sh) || exit $$? + # # $(T.compile.tcl) and $(T.link.tcl) are TCL-specific counterparts for $(T.compile) -# and $(T.link) which first invoke $(SOURCE_TCLCONFIG). +# and $(T.link) which first invoke $(T.tcl.env.source). Any targets which used them +# must have a dependency on $(T.tcl.env.sh) # -T.compile.tcl = $(SOURCE_TCLCONFIG); $(T.compile) -T.link.tcl = $(SOURCE_TCLCONFIG); $(T.link) - -has_tclconfig: - @if [ x = "x$(TCL_CONFIG_SH)" ]; then \ - echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ - fi - touch has_tclconfig +T.compile.tcl = $(T.tcl.env.source); $(T.compile) +T.link.tcl = $(T.tcl.env.source); $(T.link) # # This target creates a directory named "tsrc" and fills it with @@ -1274,17 +1265,17 @@ whereexpr.o: $(TOP)/src/whereexpr.c $(DEPS_OBJ_COMMON) window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON) $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/window.c -tclsqlite.o: has_tclconfig $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) +tclsqlite.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) $(T.compile.tcl) -DUSE_TCL_STUBS=1 $$TCL_INCLUDE_SPEC $(CFLAGS.intree_includes) \ -c $(TOP)/src/tclsqlite.c -tclsqlite-shell.o: has_tclconfig $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) +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-stubs.o: has_tclconfig $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) +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 -tclsqlite3$(T.exe): has_tclconfig tclsqlite-shell.o $(libsqlite3.SO) +tclsqlite3$(T.exe): $(T.tcl.env.sh) tclsqlite-shell.o $(libsqlite3.SO) $(T.link.tcl) -o $@ tclsqlite-shell.o \ $(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) @@ -1385,12 +1376,11 @@ install: install-headers pkgIndex.tcl: echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(T.dll) -$(libtclsqlite3.SO): has_tclconfig tclsqlite.o $(libsqlite3.SO) - @$(T.tcllibdir); \ - $(SOURCE_TCLCONFIG); set -x; \ +$(libtclsqlite3.SO): $(T.tcl.env.sh) tclsqlite.o $(libsqlite3.SO) + $(T.tcl.env.source); \ $(T.link.shared) -o $@ tclsqlite.o \ $$TCL_INCLUDE_SPEC $$TCL_STUB_LIB_SPEC $(LDFLAGS.libsqlite3) \ - $(libsqlite3.SO) -Wl,-rpath,$$tcllibdir + $(libsqlite3.SO) -Wl,-rpath,$$TCLLIBDIR # ^^^ that rpath bit is defined as TCL_LD_SEARCH_FLAGS in # tclConfig.sh, but it's defined in such a way as to be useless for a # _static_ makefile. @@ -1400,10 +1390,10 @@ libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL) all: libtcl install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl - @$(T.tcllibdir); set -x; \ - $(INSTALL) -d "$(DESTDIR)$$tcllibdir"; \ - $(INSTALL) $(libtclsqlite3.SO) "$(DESTDIR)$$tcllibdir"; \ - $(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$$tcllibdir" + $(T.tcl.env.source); \ + $(INSTALL) -d "$(DESTDIR)$$TCLLIBDIR"; \ + $(INSTALL) $(libtclsqlite3.SO) "$(DESTDIR)$$TCLLIBDIR"; \ + $(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$$TCLLIBDIR" install-tcl-0 install-tcl-: install-tcl: install-tcl-$(HAVE_TCL) install: install-tcl @@ -1507,7 +1497,7 @@ TESTFIXTURE_SRC1 = sqlite3.c TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) -testfixture$(T.exe): has_tclconfig has_tclsh85 $(TESTFIXTURE_SRC) +testfixture$(T.exe): $(T.tcl.env.sh) has_tclsh85 $(TESTFIXTURE_SRC) $(T.link.tcl) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -o $@ $(TESTFIXTURE_SRC) \ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC \ @@ -1627,7 +1617,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c -sqlite3_analyzer$(T.exe): has_tclconfig sqlite3_analyzer.c +sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c $(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC $(LDFLAGS.libsqlite3) sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ @@ -1635,7 +1625,7 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(TOP)/tool/sqltclsh.c.in has_tclsh85 $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c -sqltclsh$(T.exe): has_tclconfig sqltclsh.c +sqltclsh$(T.exe): $(T.tcl.env.sh) sqltclsh.c $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. @@ -1660,7 +1650,7 @@ CHECKER_DEPS =\ sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ -sqlite3_checker$(T.exe): has_tclconfig sqlite3_checker.c +sqlite3_checker$(T.exe): $(T.tcl.env.sh) sqlite3_checker.c $(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) xbin: sqlite3_checker$(T.exe) @@ -2134,8 +2124,8 @@ tidy: tidy-. rm -f sessionfuzz$(T.exe) changesetfuzz$(T.exe) rm -f dbdump$(T.exe) dbtotxt$(T.exe) atrc$(T.exe) rm -f threadtest5$(T.exe) - rm -f src-verify$(B.exe) has_tclsh* has_tclconfig - rm -f tclsqlite3.c + rm -f src-verify$(B.exe) + rm -f tclsqlite3.c has_tclsh* $(T.tcl.env.sh) rm -f sqlite3rc.h sqlite3.def # diff --git a/manifest b/manifest index 795ff46c21..79e704016d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scleanups\sto\sthe\slinenoise\sflavor\sdetection\stest. -D 2024-10-30T23:10:38.423 +C Reimplement\show\sthe\sTCL-related\senvironment\svars\sare\smade\savailable\sto\smake\srecipes\swhich\sneed\sthem,\sreducing\sthe\sconsole\snoise\sand\sconsolidating\sit\swith\sthe\shas_tclconfig\sflag\sfile.\sIt\snow\suses\sa\sgenerated\sshell\ssnippet\swhich\sit\ssources,\srather\sthan\sinlining\sall\sof\sthat\sshell\scode. +D 2024-10-31T00:56:05.498 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 3eb1213b7a8f1a6a86bc59ca910b608d60670fb915c5a76cbfb90f84c61ab4dd +F main.mk 79a3a4bae01816303a6f027a2bed45afceb6bf0929bd4f5b7141cfb0a8b9c950 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 84e503dc1e3672fe7787fb747ed70ca14ad181a743925bd1658c40baaa8a27cd -R 235f5f08d1190fddb79e56ae3a84f4e6 +P 3be32de1626f940e256076df76388e7633de57f340aac937f6a48d3585b96ca4 +R 9216ca2734a13c3e7fb0657b81bdb07d U stephan -Z e505c01bc9a5f78170d2f000898996a1 +Z 59155e9ae3f05d19e5817b0f4a32cdcf # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 81a5e858c5..9c807f575a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3be32de1626f940e256076df76388e7633de57f340aac937f6a48d3585b96ca4 +0cdfd142e11824d41ebb6c6e508933e04ac6f6dc0dc375cc5b0032f56eb7f423 From fe9baec6456029612bc530a4e506f29e64bfb8d1 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 01:51:00 +0000 Subject: [PATCH 237/522] Fix a corner case in automatic TCLLIBDIR detection: if the $auto_path list is not empty but none of them refer to an existing dir, the last dir in that list would have been accepted as the TCLLIBDIR. It will now error out instead. FossilOrigin-Name: 1d2ecae1304d9f677bd50eaae6bd9cb25cb75c611d88a30839f5287a7a97d7d5 --- main.mk | 12 +++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/main.mk b/main.mk index bb4f3b7e58..59aadfd370 100644 --- a/main.mk +++ b/main.mk @@ -929,12 +929,14 @@ $(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ fi @if [ x != "x$(TCLLIBDIR)" ]; then echo TCLLIBDIR="$(TCLLIBDIR)"; else \ - for TCLLIBDIR in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \ - [ -d "$$TCLLIBDIR" ] && break; done; \ - if [ x = "x$$TCLLIBDIR" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ - echo TCLLIBDIR="$$TCLLIBDIR/sqlite3"; \ + ld= ; \ + for d in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \ + if [ -d "$$d" ]; then ld=$$d; break; fi; \ + done; \ + if [ x = "x$$ld" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ + echo "TCLLIBDIR=$$ld/sqlite3"; \ fi > $@; \ - echo ". $(TCL_CONFIG_SH) || exit \$$?" >> $@ + echo ". \"$(TCL_CONFIG_SH)\" || exit \$$?" >> $@ # # $(T.tcl.env.source) is shell code to be run as part of any diff --git a/manifest b/manifest index 79e704016d..81b41c931a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reimplement\show\sthe\sTCL-related\senvironment\svars\sare\smade\savailable\sto\smake\srecipes\swhich\sneed\sthem,\sreducing\sthe\sconsole\snoise\sand\sconsolidating\sit\swith\sthe\shas_tclconfig\sflag\sfile.\sIt\snow\suses\sa\sgenerated\sshell\ssnippet\swhich\sit\ssources,\srather\sthan\sinlining\sall\sof\sthat\sshell\scode. -D 2024-10-31T00:56:05.498 +C Fix\sa\scorner\scase\sin\sautomatic\sTCLLIBDIR\sdetection:\sif\sthe\s$auto_path\slist\sis\snot\sempty\sbut\snone\sof\sthem\srefer\sto\san\sexisting\sdir,\sthe\slast\sdir\sin\sthat\slist\swould\shave\sbeen\saccepted\sas\sthe\sTCLLIBDIR.\sIt\swill\snow\serror\sout\sinstead. +D 2024-10-31T01:51:00.715 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 79a3a4bae01816303a6f027a2bed45afceb6bf0929bd4f5b7141cfb0a8b9c950 +F main.mk 89d5f9a552f4933d8d4d8fafc0d5899c5622863173fbadfb3dd404440aeb38e7 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3be32de1626f940e256076df76388e7633de57f340aac937f6a48d3585b96ca4 -R 9216ca2734a13c3e7fb0657b81bdb07d +P 0cdfd142e11824d41ebb6c6e508933e04ac6f6dc0dc375cc5b0032f56eb7f423 +R fc35c15ebb3d82bb0506da0227aa9928 U stephan -Z 59155e9ae3f05d19e5817b0f4a32cdcf +Z 341fe632ebb3723ef897619681058c98 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9c807f575a..ca6b4686ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0cdfd142e11824d41ebb6c6e508933e04ac6f6dc0dc375cc5b0032f56eb7f423 +1d2ecae1304d9f677bd50eaae6bd9cb25cb75c611d88a30839f5287a7a97d7d5 From c6cfc8e3ea09174c8ce4b5c2eb887cc6ce4713c4 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 05:47:56 +0000 Subject: [PATCH 238/522] Change default CFLAGS to {-g -O2} to match the legacy build. FossilOrigin-Name: 511774942903277b3d38f28336599667df20f94a8de79746b6c236b827b7ffc6 --- auto.def | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/auto.def b/auto.def index 6093f2a21a..3242b3cbd3 100644 --- a/auto.def +++ b/auto.def @@ -308,6 +308,7 @@ if {"" eq [proj-bin-define install]} { # compiling binaries for the target system (CC a.k.a. $(T.cc)). # Normally they're the same, but they will differ when # cross-compiling. +define CFLAGS [get-env CFLAGS {-g -O2}] define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] ######################################################################## diff --git a/manifest b/manifest index 81b41c931a..10640680b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scorner\scase\sin\sautomatic\sTCLLIBDIR\sdetection:\sif\sthe\s$auto_path\slist\sis\snot\sempty\sbut\snone\sof\sthem\srefer\sto\san\sexisting\sdir,\sthe\slast\sdir\sin\sthat\slist\swould\shave\sbeen\saccepted\sas\sthe\sTCLLIBDIR.\sIt\swill\snow\serror\sout\sinstead. -D 2024-10-31T01:51:00.715 +C Change\sdefault\sCFLAGS\sto\s{-g\s-O2}\sto\smatch\sthe\slegacy\sbuild. +D 2024-10-31T05:47:56.652 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 690effe8c5d7bb046120bd30400896b1a7fdd649912c01114df1c0df400bb62b +F auto.def b4d03e1a29472666304c17e4cad8957bf9608fdb69ba604fae42280cfe6d76b1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0cdfd142e11824d41ebb6c6e508933e04ac6f6dc0dc375cc5b0032f56eb7f423 -R fc35c15ebb3d82bb0506da0227aa9928 +P 1d2ecae1304d9f677bd50eaae6bd9cb25cb75c611d88a30839f5287a7a97d7d5 +R 7bbd44495a31d853a8cdadac4c7a9a6c U stephan -Z 341fe632ebb3723ef897619681058c98 +Z d036e10613b3c2839c9ebbb2201382e3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ca6b4686ad..b760684c13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d2ecae1304d9f677bd50eaae6bd9cb25cb75c611d88a30839f5287a7a97d7d5 +511774942903277b3d38f28336599667df20f94a8de79746b6c236b827b7ffc6 From 0e07bc36d9018444d405a639fc652813a35db98d Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 06:38:30 +0000 Subject: [PATCH 239/522] When --with-wasi-sdk is active, temporarily swap CC and CC_FOR_BUILD for purposes of looking for APIs required by B.cc. FossilOrigin-Name: 435f2ee818d7181551c6860b6bc4db97f82d76b58fd82765a6cf49e2d02ff18c --- auto.def | 121 ++++++++++++++++++++++++++++---------------------- manifest | 12 ++--- manifest.uuid | 2 +- 3 files changed, 75 insertions(+), 60 deletions(-) diff --git a/auto.def b/auto.def index 3242b3cbd3..47ea017a48 100644 --- a/auto.def +++ b/auto.def @@ -225,7 +225,6 @@ define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION $PACKAGE_VERSION define PACKAGE_STRING "[get-define PACKAGE_NAME] $PACKAGE_VERSION" define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum - msg-result "srcdir = $srcdir" msg-result "top_srcdir = $top_srcdir" msg-result [proj-bold "Configuring SQLite version $PACKAGE_VERSION"] @@ -242,7 +241,7 @@ foreach arg $::autosetup(argv) { } # Are we cross-compiling? -set cross_compiling [proj-is-cross-compiling] +set isCrossCompiling [proj-is-cross-compiling] if {![file exists sqlite3.pc.in]} { msg-result "This appears to be an out-of-tree build." } @@ -314,41 +313,51 @@ define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] ######################################################################## # Handle --with-wasi-sdk=DIR # -# This must be early because it may change the toolchain and disable -# several config options. +# This MUST be run early on because it may change the toolchain and +# disable a number of config options. proc sqlite-check-wasi-sdk {} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] define HAVE_WASI_SDK 0 - #puts "x wasiSdkDir=$wasiSdkDir foo=[lindex [opt-val with-wasi-sdk] end]" if {$wasiSdkDir eq ""} { return 0 - } elseif {$::cross_compiling} { + } elseif {$::isCrossCompiling} { proj-fatal "Cannot combine --with-wasi-sdk with cross-compilation" } msg-result "Checking WASI SDK directory \[$wasiSdkDir]... " #puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" proj-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] - msg-result "Using wasi-sdk clang, disabling: tcl, CLI shell, DLL, loadable extensions, threading" define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir - proj-opt-set load-extension 0 ;# ==> --disable-load-extension - proj-opt-set threadsafe 0 ;# ==> --threadsafe=0 - proj-opt-set tcl 0 ;# ==> --disable-tcl - proj-opt-set shared 0 ;# ==> --disable-shared - set cross_compiling 1 + # Disable numerous options which we know either can't work or are + # not useful in this build... + msg-result [proj-bold "Using wasi-sdk clang. Disabling CLI shell and forcing:"] + foreach opt { + editline + gcov + load-extension + readline + shared + tcl + threadsafe + } { + msg-result " --disable-$opt" + proj-opt-set $opt 0 + } + # Remember that we now have a discrepancy beteween + # $::isCrossCompiling and [proj-is-cross-compiling]. + set ::isCrossCompiling 1 - # Changing --host and --target have no effect here except to possibly - # cause confusion. autoconf has finished processing them by this - # point. + # + # Changing --host and --target have no effect here except to + # possibly cause confusion. Autosetup has finished processing them + # by this point. # # host_alias=wasm32-wasi # target=wasm32-wasi # # Merely changing CC and LD to the wasi-sdk's is enough to get # sqlite3.o building in WASM format. - # XXX CC="${wasiSdkDir}/bin/clang" - # XXX LD="${wasiSdkDir}/bin/wasm-ld" - # XXX RANLIB="${wasiSdkDir}/bin/llvm-ranlib" + # define CC "${wasiSdkDir}/bin/clang" define LD "${wasiSdkDir}/bin/wasm-ld" #define STRIP "${wasiSdkDir}/bin/strip" @@ -387,7 +396,7 @@ cc-check-includes \ inttypes.h if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { - # TODO: port over the more sophisticated zlib search from the fossil auto.def + # TODO? port over the more sophisticated zlib search from the fossil auto.def define HAVE_ZLIB 1 define LDFLAGS_ZLIB -lz sqlite-add-shell-opt -DSQLITE_HAVE_ZLIB=1 @@ -648,45 +657,51 @@ proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " define CFLAGS_JIMSH {} set cgtcl [opt-val with-tclsh jimsh] - if {"jimsh" ne $cgtcl} { - # When --with-tclsh=X is used, use that for all TCL purposes, - # including in-tree code generation, per developer request. - define BTCLSH "\$(TCLSH_CMD)" - } else { - # These headers are technically optional for JimTCL but necessary if - # we want to use it for code generation: - set sysh [cc-check-includes dirent.h sys/time.h] - if {$sysh && [cc-check-functions realpath]} { - define-append CFLAGS_JIMSH -DHAVE_REALPATH - define BTCLSH "\$(JIMSH)" - } elseif {$sysh && [cc-check-functions _fullpath]} { - # _fullpath() is a Windows API - define-append CFLAGS_JIMSH -DHAVE__FULLPATH - define BTCLSH "\$(JIMSH)" - } elseif {[file exists [get-define TCLSH_CMD]]} { - set cgtcl [get-define TCLSH_CMD] + define-push {CC} { + # We have to swap CC to CC_FOR_BUILD for purposes of the various + # [cc-...] tests below. Recall that --with-wasi-sdk may have + # swapped out CC with one which is not appropriate for this block. + define CC [get-define CC_FOR_BUILD] + if {"jimsh" ne $cgtcl} { + # When --with-tclsh=X is used, use that for all TCL purposes, + # including in-tree code generation, per developer request. define BTCLSH "\$(TCLSH_CMD)" } else { - # One last-ditch effort to find TCLSH_CMD: use info from - # tclConfig.sh to try to find a tclsh - if {"" eq [get-define TCLSH_CMD]} { - set tpre [get-define TCL_EXEC_PREFIX] - if {"" ne $tpre} { - set tv [get-define TCL_VERSION] - if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { - define TCLSH_CMD "${tpre}/bin/tclsh${tv}" - } elseif {[file-isexec "${tpre}/bin/tclsh"]} { - define TCLSH_CMD "${tpre}/bin/tclsh" + # These headers are technically optional for JimTCL but necessary if + # we want to use it for code generation: + set sysh [cc-check-includes dirent.h sys/time.h] + if {$sysh && [cc-check-functions realpath]} { + define-append CFLAGS_JIMSH -DHAVE_REALPATH + define BTCLSH "\$(JIMSH)" + } elseif {$sysh && [cc-check-functions _fullpath]} { + # _fullpath() is a Windows API + define-append CFLAGS_JIMSH -DHAVE__FULLPATH + define BTCLSH "\$(JIMSH)" + } elseif {[file exists [get-define TCLSH_CMD]]} { + set cgtcl [get-define TCLSH_CMD] + define BTCLSH "\$(TCLSH_CMD)" + } else { + # One last-ditch effort to find TCLSH_CMD: use info from + # tclConfig.sh to try to find a tclsh + if {"" eq [get-define TCLSH_CMD]} { + set tpre [get-define TCL_EXEC_PREFIX] + if {"" ne $tpre} { + set tv [get-define TCL_VERSION] + if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { + define TCLSH_CMD "${tpre}/bin/tclsh${tv}" + } elseif {[file-isexec "${tpre}/bin/tclsh"]} { + define TCLSH_CMD "${tpre}/bin/tclsh" + } } } + set cgtcl [get-define TCLSH_CMD] + if {![file exists $cgtcl]} { + proj-fatal "Cannot find a tclsh to use for code generation." + } + define BTCLSH "\$(TCLSH_CMD)" } - set cgtcl [get-define TCLSH_CMD] - if {![file exists $cgtcl]} { - proj-fatal "Cannot find a tclsh to use for code generation." - } - define BTCLSH "\$(TCLSH_CMD)" } - } + }; # CC swap-out return $cgtcl }; # sqlite-determine-codegen-tcl msg-result "TCL for code generation: [sqlite-determine-codegen-tcl]" @@ -859,7 +874,7 @@ proc sqlite-check-line-editing {} { set rlInc [opt-val with-readline-cflags auto] if {"auto" eq $rlInc} { set rlInc "" - if {$::cross_compiling} { + if {$::isCrossCompiling} { # ^^^ this check is derived from the legacy configure script. proj-warn "Skipping check for readline.h because we're cross-compiling." } else { diff --git a/manifest b/manifest index 10640680b7..3ba8a1be70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sdefault\sCFLAGS\sto\s{-g\s-O2}\sto\smatch\sthe\slegacy\sbuild. -D 2024-10-31T05:47:56.652 +C When\s--with-wasi-sdk\sis\sactive,\stemporarily\sswap\sCC\sand\sCC_FOR_BUILD\sfor\spurposes\sof\slooking\sfor\sAPIs\srequired\sby\sB.cc. +D 2024-10-31T06:38:30.018 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def b4d03e1a29472666304c17e4cad8957bf9608fdb69ba604fae42280cfe6d76b1 +F auto.def d1e7ea57121be95dce59cd908a72e871c3217664d9a9cd6bcfbefbb602d94f67 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1d2ecae1304d9f677bd50eaae6bd9cb25cb75c611d88a30839f5287a7a97d7d5 -R 7bbd44495a31d853a8cdadac4c7a9a6c +P 511774942903277b3d38f28336599667df20f94a8de79746b6c236b827b7ffc6 +R 826bef03c13c186e5e25d69159376b65 U stephan -Z d036e10613b3c2839c9ebbb2201382e3 +Z 31d99618f66414cd664007258185ba71 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b760684c13..a76ab71634 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -511774942903277b3d38f28336599667df20f94a8de79746b6c236b827b7ffc6 +435f2ee818d7181551c6860b6bc4db97f82d76b58fd82765a6cf49e2d02ff18c From 343fe033c073588b235c91546da6eae105222391 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 06:52:09 +0000 Subject: [PATCH 240/522] If a file named .default-CFLAGS exists in the build dir, use its contents as the default value of the CFLAGS unless it's overridden by being passed in or in the environment. FossilOrigin-Name: 731d333c224e70190dadd214de1970ea541a3d716d1d7ff2c0ef6c63b8be9b13 --- auto.def | 9 +++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index 47ea017a48..c29ef86337 100644 --- a/auto.def +++ b/auto.def @@ -194,7 +194,7 @@ set flags { # test-status => {Enable status of tests} gcov=0 => {Enable coverage testing using gcov} - linemacros => {Enable #line macros in the amalgamation.} + linemacros => {Enable #line macros in the amalgamation} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} # @@ -307,7 +307,12 @@ if {"" eq [proj-bin-define install]} { # compiling binaries for the target system (CC a.k.a. $(T.cc)). # Normally they're the same, but they will differ when # cross-compiling. -define CFLAGS [get-env CFLAGS {-g -O2}] +set defaultCFlags {-g -O2} +if {[file exists .default-CFLAGS]} { + set defaultCFlags [proj-file-content .default-CFLAGS] +} +define CFLAGS [get-env CFLAGS $defaultCFlags] +unset defaultCFlags define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] ######################################################################## diff --git a/manifest b/manifest index 3ba8a1be70..4561e24b66 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\s--with-wasi-sdk\sis\sactive,\stemporarily\sswap\sCC\sand\sCC_FOR_BUILD\sfor\spurposes\sof\slooking\sfor\sAPIs\srequired\sby\sB.cc. -D 2024-10-31T06:38:30.018 +C If\sa\sfile\snamed\s.default-CFLAGS\sexists\sin\sthe\sbuild\sdir,\suse\sits\scontents\sas\sthe\sdefault\svalue\sof\sthe\sCFLAGS\sunless\sit's\soverridden\sby\sbeing\spassed\sin\sor\sin\sthe\senvironment. +D 2024-10-31T06:52:09.938 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d1e7ea57121be95dce59cd908a72e871c3217664d9a9cd6bcfbefbb602d94f67 +F auto.def 343bcb3fff35742e9916bda3e0d5e786ef26610adb00e4039a1763a81330b6a6 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 511774942903277b3d38f28336599667df20f94a8de79746b6c236b827b7ffc6 -R 826bef03c13c186e5e25d69159376b65 +P 435f2ee818d7181551c6860b6bc4db97f82d76b58fd82765a6cf49e2d02ff18c +R 2b5ed1184d3543a78b203dd5ec51e348 U stephan -Z 31d99618f66414cd664007258185ba71 +Z 9c24c680b13f0a8ab7e6d4fbe6464cec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a76ab71634..be045af54b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -435f2ee818d7181551c6860b6bc4db97f82d76b58fd82765a6cf49e2d02ff18c +731d333c224e70190dadd214de1970ea541a3d716d1d7ff2c0ef6c63b8be9b13 From cf758d23cdb08eda624e8556e6628b6f7b790df9 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 07:01:31 +0000 Subject: [PATCH 241/522] Add more deps to T.tcl.env.sh so that it gets rebuilt if configure is run with a different --with-tcl value. Remove all references to the superfluous XYZdir makefile vars conventionally set by the autotools (they're just noise in this build). FossilOrigin-Name: 831665101e9c62cf49c173cb11705033eb9135a6a6965718285d81113ee5ba4c --- Makefile.in | 6 ------ main.mk | 22 ++++++++++++---------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/Makefile.in b/Makefile.in index 1a093c5af6..7de1ff39d4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -75,13 +75,7 @@ clean: TOP = @abs_top_srcdir@ # # Some standard variables and programs -# prefix ?= @prefix@ -exec_prefix ?= @exec_prefix@ -libdir ?= @libdir@ -pkgconfigdir ?= $(libdir)/pkgconfig -bindir ?= @bindir@ -includedir ?= @includedir@ # # Just testing some default dir expansions... # srcdir = @srcdir@ diff --git a/main.mk b/main.mk index 59aadfd370..359ded7c39 100644 --- a/main.mk +++ b/main.mk @@ -9,7 +9,10 @@ # # - This file must remain devoid of GNU Make-isms. i.e. it must be # POSIX Make compatible. "bmake" (BSD make) is available on most -# Linux systems, so compatibility is relatively easy to test. +# Linux systems, so compatibility is relatively easy to test. As a +# harmless exception, this file sometimes uses $(MAKEFILE_LIST) as a +# dependency. That var, in GNU Make, lists all of the makefile +# currently loaded. # # The variables listed below must be defined before this script is # invoked. This file will use defaults, very possibly invalid, for any @@ -117,12 +120,11 @@ B.tclsh ?= $(JIMSH) # Various system-level directories, mostly needed for installation and # for finding system-level dependencies. # +# Aside from ${prefix}, we do not need to (and intentionally do not) +# export any of the dozen-ish shorthand ${XYZdir} vars the autotools +# conventionally defines. +# prefix ?= /usr/local -exec_prefix ?= $(prefix) -libdir ?= $(prefix)/lib -pkgconfigdir ?= $(libdir)/pkgconfig -bindir ?= $(prefix)/bin -includedir ?= $(prefix)/include # # $(LDFLAGS.{feature}) and $(CFLAGS.{feature}) = # @@ -351,10 +353,10 @@ LDFLAGS.libsqlite3 = \ # moral of this story is that spaces in installation paths will break # the install process. # -install-dir.bin = $(DESTDIR)$(bindir) -install-dir.lib = $(DESTDIR)$(libdir) +install-dir.bin = $(DESTDIR)$(prefix)/bin +install-dir.lib = $(DESTDIR)$(prefix)/lib install-dir.include = $(DESTDIR)$(prefix)/include -install-dir.pkgconfig = $(DESTDIR)$(pkgconfigdir) +install-dir.pkgconfig = $(DESTDIR)$(prefix)/lib/pkgconfig install-dir.man1 = $(DESTDIR)$(prefix)/share/man/man1 install-dir.all = $(install-dir.bin) $(install-dir.include) \ $(install-dir.lib) $(install-dir.man1) \ @@ -924,7 +926,7 @@ has_tclsh85: # It took half an hour to figure that out. # T.tcl.env.sh = ./.tclenv.sh -$(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) +$(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST) @if [ x = "x$(TCL_CONFIG_SH)" ]; then \ echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ fi diff --git a/manifest b/manifest index 4561e24b66..1d4baa98c7 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C If\sa\sfile\snamed\s.default-CFLAGS\sexists\sin\sthe\sbuild\sdir,\suse\sits\scontents\sas\sthe\sdefault\svalue\sof\sthe\sCFLAGS\sunless\sit's\soverridden\sby\sbeing\spassed\sin\sor\sin\sthe\senvironment. -D 2024-10-31T06:52:09.938 +C Add\smore\sdeps\sto\sT.tcl.env.sh\sso\sthat\sit\sgets\srebuilt\sif\sconfigure\sis\srun\swith\sa\sdifferent\s--with-tcl\svalue.\sRemove\sall\sreferences\sto\sthe\ssuperfluous\sXYZdir\smakefile\svars\sconventionally\sset\sby\sthe\sautotools\s(they're\sjust\snoise\sin\sthis\sbuild). +D 2024-10-31T07:01:31.541 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 77b49b5a1acb2d5f026dea3f974306fa1be7d99fe0a1917cab313844716461f0 +F Makefile.in ec65af679ae42b4ddf521a1b0221240b4546d6c479115785001af5774dc0b709 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 89d5f9a552f4933d8d4d8fafc0d5899c5622863173fbadfb3dd404440aeb38e7 +F main.mk 3877df8c031fbb957cab9a07656d49757a6f2dba58c00519fd63ba34510de541 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 435f2ee818d7181551c6860b6bc4db97f82d76b58fd82765a6cf49e2d02ff18c -R 2b5ed1184d3543a78b203dd5ec51e348 +P 731d333c224e70190dadd214de1970ea541a3d716d1d7ff2c0ef6c63b8be9b13 +R e25e71c570d0b383f2dd1972c79d58ed U stephan -Z 9c24c680b13f0a8ab7e6d4fbe6464cec +Z a1888b91dcad0995a429adcb5d8c79e4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index be045af54b..21ab449f76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -731d333c224e70190dadd214de1970ea541a3d716d1d7ff2c0ef6c63b8be9b13 +831665101e9c62cf49c173cb11705033eb9135a6a6965718285d81113ee5ba4c From 07cdceed8e1c8979e83065d8fdb7e48f4b2d0416 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 07:20:22 +0000 Subject: [PATCH 242/522] Add the .POSIX special target to the main makefiles to hint to the make impl that it should behave POSIXly-correct. Fix the default file extension for static libs in main.mk. FossilOrigin-Name: 2c615d3a3206536f12c0723b8997bda9ab61f95a468f77697856213b46c0135e --- Makefile.in | 26 ++++---------------------- main.mk | 4 +++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 15 insertions(+), 31 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7de1ff39d4..052f4fc833 100644 --- a/Makefile.in +++ b/Makefile.in @@ -11,10 +11,9 @@ # The docs for many of its variables are in the primary static # makefile, main.mk (which this one includes at runtime). # +.POSIX: #maintenance reminder: X:=Y is not POSIX-portable all: -clean: ######################################################################## -#XX# Lines starting with #XX# are TODOs for the port to autosetup. # # Known TODOs/FIXMEs/TOIMPROVEs for the autosetup port, in no # particular order... @@ -27,31 +26,14 @@ clean: # # - Replace the autotools-specific distribution deliverable(s). # -# - Provide Makefile.msc, Makefile.linux-gcc, and any required similar -# makefile stubs for environments where the configure script will not -# run. The core makefile rules in main.mk "should" apply as-is for -# most platforms. We can potentially generate those makefiles, along -# with main.mk, like we do in the Fossil project. -# # - Confirm whether cross-compilation works and patch it # appropriately. # -# - There are some lingering dependencies issues which cause a -# re-configure to trigger more often than it should. This is -# especially a problem in parallel builds, which may launch multiple -# re-configures in parallel. GNU Make offers ways of controlling -# that, but we're limited to POSIX Make compatibility here. The -# automatic reconfigures are not too onerous, though, because they're -# much, much faster than Autotools configure runs. -# -# - Add target(s) to dump out specific vars, e.g. SQLITE_OPT, as -# requested at https://sqlite.org/forum/forumpost/75cb3179216f8d86. -# This would also be useful for the ext/wasm build, which fishes -# SHELL_OPT out of the makefile. -# -# # Maintenance reminders: # +# - This makefile should remain as POSIX-make-compatible as possible: +# https://pubs.opengroup.org/onlinepubs/9799919799/utilities/make.html +# # - When using the X?=Y variable assignment formulation, please test # the build with both GNU make and a POSIX make (e.g. BSD make, # a.k.a. bmake). On at least one occassion, that formulation has led diff --git a/main.mk b/main.mk index 359ded7c39..454528ba41 100644 --- a/main.mk +++ b/main.mk @@ -18,6 +18,8 @@ # invoked. This file will use defaults, very possibly invalid, for any # which are not defined. ######################################################################## +.POSIX: #maintenance reminder: X:=Y is not POSIX-portable +all: # # $(TOP) = # @@ -71,7 +73,7 @@ B.exe ?= # The DLL resp. static library counterparts of $(B.exe). # B.dll ?= .so -B.lib ?= .lib +B.lib ?= .a # # $(T.exe) = # diff --git a/manifest b/manifest index 1d4baa98c7..0992e9b86b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\smore\sdeps\sto\sT.tcl.env.sh\sso\sthat\sit\sgets\srebuilt\sif\sconfigure\sis\srun\swith\sa\sdifferent\s--with-tcl\svalue.\sRemove\sall\sreferences\sto\sthe\ssuperfluous\sXYZdir\smakefile\svars\sconventionally\sset\sby\sthe\sautotools\s(they're\sjust\snoise\sin\sthis\sbuild). -D 2024-10-31T07:01:31.541 +C Add\sthe\s.POSIX\sspecial\starget\sto\sthe\smain\smakefiles\sto\shint\sto\sthe\smake\simpl\sthat\sit\sshould\sbehave\sPOSIXly-correct.\sFix\sthe\sdefault\sfile\sextension\sfor\sstatic\slibs\sin\smain.mk. +D 2024-10-31T07:20:22.577 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in ec65af679ae42b4ddf521a1b0221240b4546d6c479115785001af5774dc0b709 +F Makefile.in caeee287b060f652a9b69ccaad783729e2d6b28c7dfa82881837dc3fad1ed78f F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 3877df8c031fbb957cab9a07656d49757a6f2dba58c00519fd63ba34510de541 +F main.mk fea07cfa9091e5029b30980530353ba85a644acebe0ff9061c1bde7115863a8a F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 731d333c224e70190dadd214de1970ea541a3d716d1d7ff2c0ef6c63b8be9b13 -R e25e71c570d0b383f2dd1972c79d58ed +P 831665101e9c62cf49c173cb11705033eb9135a6a6965718285d81113ee5ba4c +R 4a69f33cb347363bc3407201453ac489 U stephan -Z a1888b91dcad0995a429adcb5d8c79e4 +Z 4eb25a548225e7e13c3bd2c622a6f4b0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 21ab449f76..2624fc31ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -831665101e9c62cf49c173cb11705033eb9135a6a6965718285d81113ee5ba4c +2c615d3a3206536f12c0723b8997bda9ab61f95a468f77697856213b46c0135e From 7be78606ffe8eb42e398fe493b0e5ab9e09d9451 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 07:30:53 +0000 Subject: [PATCH 243/522] When reading in .default-CFLAGS, trim it. FossilOrigin-Name: a62a5171ace53b79feda93701f90d6d6f88eb5542bd35ac76f962745c58588b0 --- auto.def | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index c29ef86337..34e70dfcfc 100644 --- a/auto.def +++ b/auto.def @@ -309,7 +309,7 @@ if {"" eq [proj-bin-define install]} { # cross-compiling. set defaultCFlags {-g -O2} if {[file exists .default-CFLAGS]} { - set defaultCFlags [proj-file-content .default-CFLAGS] + set defaultCFlags [string trim [proj-file-content .default-CFLAGS]] } define CFLAGS [get-env CFLAGS $defaultCFlags] unset defaultCFlags diff --git a/manifest b/manifest index 0992e9b86b..f108e50998 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s.POSIX\sspecial\starget\sto\sthe\smain\smakefiles\sto\shint\sto\sthe\smake\simpl\sthat\sit\sshould\sbehave\sPOSIXly-correct.\sFix\sthe\sdefault\sfile\sextension\sfor\sstatic\slibs\sin\smain.mk. -D 2024-10-31T07:20:22.577 +C When\sreading\sin\s.default-CFLAGS,\strim\sit. +D 2024-10-31T07:30:53.399 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 343bcb3fff35742e9916bda3e0d5e786ef26610adb00e4039a1763a81330b6a6 +F auto.def 9b43af60e0ac708da9a84d489820eca5899a894d53420b339d12cfcc411620c1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 831665101e9c62cf49c173cb11705033eb9135a6a6965718285d81113ee5ba4c -R 4a69f33cb347363bc3407201453ac489 +P 2c615d3a3206536f12c0723b8997bda9ab61f95a468f77697856213b46c0135e +R 21c04bd2c5dfb28bd50b344cb95ee239 U stephan -Z 4eb25a548225e7e13c3bd2c622a6f4b0 +Z 48bef13d8f51175654cd176b9ca6952d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2624fc31ab..5340bb49d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c615d3a3206536f12c0723b8997bda9ab61f95a468f77697856213b46c0135e +a62a5171ace53b79feda93701f90d6d6f88eb5542bd35ac76f962745c58588b0 From ec04c41be6e08dbb74c98820803cd4d08c600f3c Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 08:03:35 +0000 Subject: [PATCH 244/522] Remove some proj-assert checks which are not valid on OpenBSD. Ensure that queued up notices about TCL warnings are displayed before leaving sqlite-check-tcl. FossilOrigin-Name: 3447308f3f66046ffedd502161757211bef0384d7a735ff675c06c04fbc22655 --- auto.def | 7 ++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/auto.def b/auto.def index 34e70dfcfc..0696cb53a8 100644 --- a/auto.def +++ b/auto.def @@ -568,15 +568,13 @@ proc sqlite-check-tcl {} { } break } - define TCL_CONFIG_SH $cfg # Export a subset of tclConfig.sh to the current TCL-space. If the # config is not available, this emits empty-string entries for the # various options we're interested in. eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] - if {"" eq $with_tclsh} { - proj-assert {expr {$cfg ne ""}} + if {"" eq $with_tclsh && $cfg ne ""} { proj-assert {expr {"" ne [get-define TCL_EXEC_PREFIX]}} set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] if {![file-isexec $with_tclsh]} { @@ -589,8 +587,6 @@ proc sqlite-check-tcl {} { } } define TCLSH_CMD $with_tclsh - proj-assert {expr {( $cfg eq "" && 0 == $use_tcl ) \ - || ( $cfg ne "" && 1 == $use_tcl )}} if {$use_tcl} { # Set up the TCLLIBDIR and TCLLIB_RPATH # @@ -638,6 +634,7 @@ proc sqlite-check-tcl {} { } else { proj-warn "Cannot find a usable tclsh, so cannot run tests." } + show-notices }; # sqlite-check-tcl sqlite-check-tcl diff --git a/manifest b/manifest index f108e50998..2d9380d767 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sreading\sin\s.default-CFLAGS,\strim\sit. -D 2024-10-31T07:30:53.399 +C Remove\ssome\sproj-assert\schecks\swhich\sare\snot\svalid\son\sOpenBSD.\sEnsure\sthat\squeued\sup\snotices\sabout\sTCL\swarnings\sare\sdisplayed\sbefore\sleaving\ssqlite-check-tcl. +D 2024-10-31T08:03:35.227 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 9b43af60e0ac708da9a84d489820eca5899a894d53420b339d12cfcc411620c1 +F auto.def 4df2b29cfabce9e64992b557e58e6b69405c58d2dcac071b70e0ddbad24a3c11 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2c615d3a3206536f12c0723b8997bda9ab61f95a468f77697856213b46c0135e -R 21c04bd2c5dfb28bd50b344cb95ee239 +P a62a5171ace53b79feda93701f90d6d6f88eb5542bd35ac76f962745c58588b0 +R 541059fa6d4b4792ae313ac1b77e951c U stephan -Z 48bef13d8f51175654cd176b9ca6952d +Z 68b7c1ee23dc2d6c759433af0943e546 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5340bb49d0..b2a4dafcd6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a62a5171ace53b79feda93701f90d6d6f88eb5542bd35ac76f962745c58588b0 +3447308f3f66046ffedd502161757211bef0384d7a735ff675c06c04fbc22655 From 98eb4ad6eecafa8ed81151366f93bae2300fe228 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 08:12:48 +0000 Subject: [PATCH 245/522] Add -trim flag to proj-file-content. FossilOrigin-Name: babf66f5c7074c24ca8ae898cd850964e99cef41fd1395a0d6c582cab75ae3bf --- auto.def | 2 +- autosetup/proj.tcl | 13 +++++++++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/auto.def b/auto.def index 0696cb53a8..8b5306b6e0 100644 --- a/auto.def +++ b/auto.def @@ -309,7 +309,7 @@ if {"" eq [proj-bin-define install]} { # cross-compiling. set defaultCFlags {-g -O2} if {[file exists .default-CFLAGS]} { - set defaultCFlags [string trim [proj-file-content .default-CFLAGS]] + set defaultCFlags [proj-file-content -trim .default-CFLAGS] } define CFLAGS [get-env CFLAGS $defaultCFlags] unset defaultCFlags diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index a5be20929d..291b1d909b 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -466,11 +466,20 @@ proc proj-no-check-module-loader {} { } ######################################################################## -# Opens the given file, reads all of its content, and returns it. -proc proj-file-content {fname} { +# Opens the given file, reads all of its content, and returns it. If +# the first arg is -trim, the contents of the file named by the second +# argument are trimmed before returning them. +proc proj-file-content {args} { + set trim 0 + set fname $args + if {"-trim" eq [lindex $args 0]} { + set trim 1 + lassign $args - fname + } set fp [open $fname r] set rc [read $fp] close $fp + if {$trim} { return [string trim $rc] } return $rc } diff --git a/manifest b/manifest index 2d9380d767..f561a5f8a9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sproj-assert\schecks\swhich\sare\snot\svalid\son\sOpenBSD.\sEnsure\sthat\squeued\sup\snotices\sabout\sTCL\swarnings\sare\sdisplayed\sbefore\sleaving\ssqlite-check-tcl. -D 2024-10-31T08:03:35.227 +C Add\s-trim\sflag\sto\sproj-file-content. +D 2024-10-31T08:12:48.543 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 4df2b29cfabce9e64992b557e58e6b69405c58d2dcac071b70e0ddbad24a3c11 +F auto.def cf1acfbbe13d6d041f5a50c8f0db43eb598754081f8f93a7724abfa4a065bf7d F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 1e9262757c39afe996a4866fb81c4619d4822b2de09952132d362271f4e069c5 +F autosetup/proj.tcl 44bc14f956bd2ca0d906ce1ff520504d93400800ab52dd413428f0679a458c59 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a62a5171ace53b79feda93701f90d6d6f88eb5542bd35ac76f962745c58588b0 -R 541059fa6d4b4792ae313ac1b77e951c +P 3447308f3f66046ffedd502161757211bef0384d7a735ff675c06c04fbc22655 +R d554c551215eb4af094319247cb3122a U stephan -Z 68b7c1ee23dc2d6c759433af0943e546 +Z b13c2c59ce3f6c90d0aa0b5e69353220 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b2a4dafcd6..bd93b8af9b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3447308f3f66046ffedd502161757211bef0384d7a735ff675c06c04fbc22655 +babf66f5c7074c24ca8ae898cd850964e99cef41fd1395a0d6c582cab75ae3bf From 6d3f22cdc1733df041a30a2bae7b5bf719033360 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 31 Oct 2024 09:25:58 +0000 Subject: [PATCH 246/522] Add a missing 'close' call to proj-file-content-list. FossilOrigin-Name: 005702f334e7c51d83fc1b142ab90fa6867c4c2e75c8a3d2a17e07669b47fb23 --- autosetup/proj.tcl | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 291b1d909b..19278aaf4b 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -492,6 +492,7 @@ proc proj-file-content-list {fname} { while { [gets $fp line] >= 0 } { lappend rc $line } + close $fp return $rc } diff --git a/manifest b/manifest index f561a5f8a9..497cf46a19 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s-trim\sflag\sto\sproj-file-content. -D 2024-10-31T08:12:48.543 +C Add\sa\smissing\s'close'\scall\sto\sproj-file-content-list. +D 2024-10-31T09:25:58.617 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 44bc14f956bd2ca0d906ce1ff520504d93400800ab52dd413428f0679a458c59 +F autosetup/proj.tcl fb1bd72961082ed50c0a03c2254664d4d765d8d593929f171b6f371090a31a03 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3447308f3f66046ffedd502161757211bef0384d7a735ff675c06c04fbc22655 -R d554c551215eb4af094319247cb3122a +P babf66f5c7074c24ca8ae898cd850964e99cef41fd1395a0d6c582cab75ae3bf +R 1566d9e697ff519ff3abad2856793988 U stephan -Z b13c2c59ce3f6c90d0aa0b5e69353220 +Z 5342ae504826c884cc1ebd55b932924b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bd93b8af9b..3a3317e586 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -babf66f5c7074c24ca8ae898cd850964e99cef41fd1395a0d6c582cab75ae3bf +005702f334e7c51d83fc1b142ab90fa6867c4c2e75c8a3d2a17e07669b47fb23 From 3764f632b894847d2acbe61122d20c60f1ce80a9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Oct 2024 11:19:22 +0000 Subject: [PATCH 247/522] Improved differentiation between antirez and msteveb linenoise. FossilOrigin-Name: cfb4bfcf1498b3740d210c24a71be343e8e0f262f3d9bddd45a673011307068c --- autosetup/proj.tcl | 22 +++------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 27 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 19278aaf4b..a607a0d149 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1009,25 +1009,9 @@ proc proj-redefine-cc-for-build {} { # msteveb, and 0 if it's neither. proc proj-which-linenoise {dotH} { set srcHeader [proj-file-content $dotH] - set srcMain { - int main(void) { - linenoiseSetCompletionCallback(0$arg) - /* antirez has only 1 arg, msteveb has 2 */; - return 0; - } - } - set arg "" - append source $srcHeader [subst $srcMain] - if {[cctest -nooutput 1 -source $source]} { - return 1 - } - set source { - #include /* size_t */ - } - set arg ", 0" - append source $srcHeader [subst $srcMain] - if {[cctest -nooutput 1 -source $source]} { + if {[string match *userdata* $srcHeader]} { return 2 + } else { + return 1 } - return 0 } diff --git a/manifest b/manifest index 497cf46a19..3226f2b2c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smissing\s'close'\scall\sto\sproj-file-content-list. -D 2024-10-31T09:25:58.617 +C Improved\sdifferentiation\sbetween\santirez\sand\smsteveb\slinenoise. +D 2024-10-31T11:19:22.925 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl fb1bd72961082ed50c0a03c2254664d4d765d8d593929f171b6f371090a31a03 +F autosetup/proj.tcl b1a10140de41c4538959feec4032bc40b83d7b8f235e7b331040da87988b36e4 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P babf66f5c7074c24ca8ae898cd850964e99cef41fd1395a0d6c582cab75ae3bf -R 1566d9e697ff519ff3abad2856793988 -U stephan -Z 5342ae504826c884cc1ebd55b932924b +P 005702f334e7c51d83fc1b142ab90fa6867c4c2e75c8a3d2a17e07669b47fb23 +R 18dc2f778b8898bf0fa14c0afd13b18b +U drh +Z 75daa62785acb8fad58113e17b1479b5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3a3317e586..4e731d9515 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -005702f334e7c51d83fc1b142ab90fa6867c4c2e75c8a3d2a17e07669b47fb23 +cfb4bfcf1498b3740d210c24a71be343e8e0f262f3d9bddd45a673011307068c From 583770af285b6e813c973aed972679766c32761b Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Oct 2024 11:21:35 +0000 Subject: [PATCH 248/522] Omit unnecessary bold text in ./configure output. FossilOrigin-Name: d1368dc12b05e9828cb86a608771b666914c0e027ac4c42dea0042b0345d8b22 --- auto.def | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index 8b5306b6e0..e8c7773b4d 100644 --- a/auto.def +++ b/auto.def @@ -227,7 +227,7 @@ define PACKAGE_STRING "[get-define PACKAGE_NAME] $PACKAGE_VERSION" define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum msg-result "srcdir = $srcdir" msg-result "top_srcdir = $top_srcdir" -msg-result [proj-bold "Configuring SQLite version $PACKAGE_VERSION"] +msg-result "Configuring SQLite version $PACKAGE_VERSION" # # SQLITE_AUTORECONFIG contains make target rules for re-running the @@ -335,7 +335,7 @@ proc sqlite-check-wasi-sdk {} { define WASI_SDK_DIR $wasiSdkDir # Disable numerous options which we know either can't work or are # not useful in this build... - msg-result [proj-bold "Using wasi-sdk clang. Disabling CLI shell and forcing:"] + msg-result "Using wasi-sdk clang. Disabling CLI shell and forcing:" foreach opt { editline gcov diff --git a/manifest b/manifest index 3226f2b2c2..a8a9ea8f08 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdifferentiation\sbetween\santirez\sand\smsteveb\slinenoise. -D 2024-10-31T11:19:22.925 +C Omit\sunnecessary\sbold\stext\sin\s./configure\soutput. +D 2024-10-31T11:21:35.065 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def cf1acfbbe13d6d041f5a50c8f0db43eb598754081f8f93a7724abfa4a065bf7d +F auto.def 5e5bac1b983628125722a64ab8fce9ea1755c5483a078704ac27de7f99f32f2b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 005702f334e7c51d83fc1b142ab90fa6867c4c2e75c8a3d2a17e07669b47fb23 -R 18dc2f778b8898bf0fa14c0afd13b18b +P cfb4bfcf1498b3740d210c24a71be343e8e0f262f3d9bddd45a673011307068c +R deeda53f6d9982318710f230fa82388b U drh -Z 75daa62785acb8fad58113e17b1479b5 +Z 8e7ce6a7f971554c634e2af4fa35d784 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4e731d9515..9650e63d1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cfb4bfcf1498b3740d210c24a71be343e8e0f262f3d9bddd45a673011307068c +d1368dc12b05e9828cb86a608771b666914c0e027ac4c42dea0042b0345d8b22 From f5187de2fba7723a1788117f49093edccbf2fe25 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Oct 2024 11:53:18 +0000 Subject: [PATCH 249/522] When building a shared library on Mac, one must specify the original *.o files that go into that library. It does not work to specify a prior shared library containing a subset of the files to be included. FossilOrigin-Name: 5adc7d5dabbd9e2b18b3e13ab4e6463bfa8b5c1d604c94c8e67e6b812873ed30 --- main.mk | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index 454528ba41..06d44ec184 100644 --- a/main.mk +++ b/main.mk @@ -1382,11 +1382,11 @@ install: install-headers pkgIndex.tcl: echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ libtclsqlite3.SO = libtclsqlite3$(T.dll) -$(libtclsqlite3.SO): $(T.tcl.env.sh) tclsqlite.o $(libsqlite3.SO) +$(libtclsqlite3.SO): $(T.tcl.env.sh) tclsqlite.o $(LIBOBJ) $(T.tcl.env.source); \ $(T.link.shared) -o $@ tclsqlite.o \ $$TCL_INCLUDE_SPEC $$TCL_STUB_LIB_SPEC $(LDFLAGS.libsqlite3) \ - $(libsqlite3.SO) -Wl,-rpath,$$TCLLIBDIR + $(LIBOBJ) -Wl,-rpath,$$TCLLIBDIR # ^^^ that rpath bit is defined as TCL_LD_SEARCH_FLAGS in # tclConfig.sh, but it's defined in such a way as to be useless for a # _static_ makefile. diff --git a/manifest b/manifest index a8a9ea8f08..6aa280c675 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sunnecessary\sbold\stext\sin\s./configure\soutput. -D 2024-10-31T11:21:35.065 +C When\sbuilding\sa\sshared\slibrary\son\sMac,\sone\smust\sspecify\sthe\soriginal\s*.o\nfiles\sthat\sgo\sinto\sthat\slibrary.\s\sIt\sdoes\snot\swork\sto\sspecify\sa\sprior\sshared\nlibrary\scontaining\sa\ssubset\sof\sthe\sfiles\sto\sbe\sincluded. +D 2024-10-31T11:53:18.461 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk fea07cfa9091e5029b30980530353ba85a644acebe0ff9061c1bde7115863a8a +F main.mk 4941b5880b4ea528258e2186e814463e438a812677478e318920f312408121c7 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cfb4bfcf1498b3740d210c24a71be343e8e0f262f3d9bddd45a673011307068c -R deeda53f6d9982318710f230fa82388b +P d1368dc12b05e9828cb86a608771b666914c0e027ac4c42dea0042b0345d8b22 +R 7a5385e858f58e3f1a354ee71815c1fa U drh -Z 8e7ce6a7f971554c634e2af4fa35d784 +Z bb2214a3239826088ee34db0ce5245b8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9650e63d1b..e1354bc5a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d1368dc12b05e9828cb86a608771b666914c0e027ac4c42dea0042b0345d8b22 +5adc7d5dabbd9e2b18b3e13ab4e6463bfa8b5c1d604c94c8e67e6b812873ed30 From d27f6d788187565588155167e0096ef27601561a Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Oct 2024 17:23:40 +0000 Subject: [PATCH 250/522] Extra defenses against UAF when failing to allocate a transient cursor. No known path to a UAF currently exists. This change just helps with the static analysis to prove it. FossilOrigin-Name: bae05811116dae0d05bcc001655416d0316ca1c16cbde2bd49f691c832261b89 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6aa280c675..814b3ce149 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sbuilding\sa\sshared\slibrary\son\sMac,\sone\smust\sspecify\sthe\soriginal\s*.o\nfiles\sthat\sgo\sinto\sthat\slibrary.\s\sIt\sdoes\snot\swork\sto\sspecify\sa\sprior\sshared\nlibrary\scontaining\sa\ssubset\sof\sthe\sfiles\sto\sbe\sincluded. -D 2024-10-31T11:53:18.461 +C Extra\sdefenses\sagainst\sUAF\swhen\sfailing\sto\sallocate\sa\stransient\scursor.\s\sNo\nknown\spath\sto\sa\sUAF\scurrently\sexists.\s\sThis\schange\sjust\shelps\swith\sthe\sstatic\nanalysis\sto\sprove\sit. +D 2024-10-31T17:23:40.795 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -845,7 +845,7 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba F src/util.c ceebf912f673247e305f16f97f0bb7285fca1d37413b79680714a553a9021d33 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 -F src/vdbe.c 1f56a0ae24115c2e37213e77cf79aa3b8c8d0366755707385564f6b8dd83d0fb +F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a F src/vdbeInt.h af7d7e8291edd0b19f2cd698e60e4d4031078f9a2f2328ac8f0b7efb134f8a1d F src/vdbeapi.c 53c7e26a2c0821a892b20eee2cde4656e31998212f3d515576c780dfaa45fd17 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d1368dc12b05e9828cb86a608771b666914c0e027ac4c42dea0042b0345d8b22 -R 7a5385e858f58e3f1a354ee71815c1fa +P 5adc7d5dabbd9e2b18b3e13ab4e6463bfa8b5c1d604c94c8e67e6b812873ed30 +R 3055b723c94c4b7dc7038e85a5c66af4 U drh -Z bb2214a3239826088ee34db0ce5245b8 +Z 44ba66da1a0b584652919774e84edda3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e1354bc5a0..6f67ac85d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5adc7d5dabbd9e2b18b3e13ab4e6463bfa8b5c1d604c94c8e67e6b812873ed30 +bae05811116dae0d05bcc001655416d0316ca1c16cbde2bd49f691c832261b89 diff --git a/src/vdbe.c b/src/vdbe.c index eb61b4d299..558970ed95 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4538,9 +4538,11 @@ case OP_OpenEphemeral: { /* ncycle */ } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + assert( p->apCsr[pOp->p1]==pCx ); if( rc ){ assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); sqlite3BtreeClose(pCx->ub.pBtx); + p->apCsr[pOp->p1] = 0; /* Not required; helps with static analysis */ }else{ assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); } From 03cfce20c9c204dfa0bed37bfca8d476179bacd9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Oct 2024 17:38:30 +0000 Subject: [PATCH 251/522] Fix the clean-autosetup target in Makefile.in so that it does not fail even in cases where gmake is unavailable. FossilOrigin-Name: 207ca21bd7060a163da60b432f61ffaad8bedb6c0d59f090f9c5addb5b56d82d --- Makefile.in | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 052f4fc833..db7c8d5001 100644 --- a/Makefile.in +++ b/Makefile.in @@ -313,7 +313,7 @@ misspell: ./custom.rws has_tclsh84 # build. # clean-autosetup: - -gmake -C ext/wasm distclean 2>/dev/null; true + -gmake -C ext/wasm distclean 2>/dev/null || true clean: clean-autosetup distclean-autosetup: clean diff --git a/manifest b/manifest index 814b3ce149..5b63841aed 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Extra\sdefenses\sagainst\sUAF\swhen\sfailing\sto\sallocate\sa\stransient\scursor.\s\sNo\nknown\spath\sto\sa\sUAF\scurrently\sexists.\s\sThis\schange\sjust\shelps\swith\sthe\sstatic\nanalysis\sto\sprove\sit. -D 2024-10-31T17:23:40.795 +C Fix\sthe\sclean-autosetup\starget\sin\sMakefile.in\sso\sthat\sit\sdoes\snot\sfail\seven\nin\scases\swhere\sgmake\sis\sunavailable. +D 2024-10-31T17:38:30.682 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in caeee287b060f652a9b69ccaad783729e2d6b28c7dfa82881837dc3fad1ed78f +F Makefile.in 3a98abc984222a31c8597a0cd516c8dd9b72554d784a87c915d2e586db4ddb18 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5adc7d5dabbd9e2b18b3e13ab4e6463bfa8b5c1d604c94c8e67e6b812873ed30 -R 3055b723c94c4b7dc7038e85a5c66af4 +P bae05811116dae0d05bcc001655416d0316ca1c16cbde2bd49f691c832261b89 +R 957ccd48fa7bc0c62d7e67c32bc0fbd2 U drh -Z 44ba66da1a0b584652919774e84edda3 +Z cb32b7812ceb5a71ca7b422751807af3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6f67ac85d1..0abf8b60e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bae05811116dae0d05bcc001655416d0316ca1c16cbde2bd49f691c832261b89 +207ca21bd7060a163da60b432f61ffaad8bedb6c0d59f090f9c5addb5b56d82d From bce0d04c98f09bf39ac6693d492cb363dbad139e Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Oct 2024 18:29:55 +0000 Subject: [PATCH 252/522] In testrunner.tcl, only show the ETC on the status line if it will fit within the 80-character line limit. FossilOrigin-Name: 45a3213d23f4691732ba2eb54d440355ce5757aad4cec8eb92f53b4bd7e7f5cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/testrunner.tcl | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5b63841aed..fb07f0a2c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sclean-autosetup\starget\sin\sMakefile.in\sso\sthat\sit\sdoes\snot\sfail\seven\nin\scases\swhere\sgmake\sis\sunavailable. -D 2024-10-31T17:38:30.682 +C In\stestrunner.tcl,\sonly\sshow\sthe\sETC\son\sthe\sstatus\sline\sif\sit\swill\sfit\swithin\nthe\s80-character\sline\slimit. +D 2024-10-31T18:29:55.322 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -1719,7 +1719,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 -F test/testrunner.tcl 4e764b0da245add9670d1010a69a3ac5474a5dfe15e1d3183294c23cca43ef13 x +F test/testrunner.tcl 3c6acf0eecd2b5459082639183f2b4f667aa0b74ddab24e4d37295112c7a5325 x F test/testrunner_data.tcl ba4aeea28aa03cfa6fe7e57782ddecb7a7b91c3a0b3251583cb4f0ee002de6a6 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bae05811116dae0d05bcc001655416d0316ca1c16cbde2bd49f691c832261b89 -R 957ccd48fa7bc0c62d7e67c32bc0fbd2 +P 207ca21bd7060a163da60b432f61ffaad8bedb6c0d59f090f9c5addb5b56d82d +R 65cc2e74cca41252a2309f0b7a90695b U drh -Z cb32b7812ceb5a71ca7b422751807af3 +Z 2c689aa6cac5108020ff6901e85b9ecd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0abf8b60e7..0e3e9259a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -207ca21bd7060a163da60b432f61ffaad8bedb6c0d59f090f9c5addb5b56d82d +45a3213d23f4691732ba2eb54d440355ce5757aad4cec8eb92f53b4bd7e7f5cd diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 09c9f8ac24..66fa1058bb 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -547,7 +547,7 @@ proc show_status {db cls} { set srcdir [file dirname [file dirname $TRG(info_script)]] set line "Running: $S(running) (max: $nJob)" - if {$S(running)>0 && $fin>10} { + if {$S(running)>0 && $fin>10 && [string length $line]<69} { set tmleft [expr {($tm/$fin)*($totalw-$fin)}] if {$tmleft<0.02*$tm} { set tmleft [expr {$tm*0.02}] From afb879858067f0fda250ffa0a5762e62c4d16a64 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 1 Nov 2024 01:56:27 +0000 Subject: [PATCH 253/522] When configuring with --with-wasi-sdk, ensure that we use that SDK's 'ar' tool instead of whatever is in the PATH. When pushing/popping the define var scope for the jimsh compatility check, include more defines per consultation with autosetup's creator. FossilOrigin-Name: 2dcc465a7090811ddbc210673f37b4c3a4439c501874abefd403efe1e98f5b17 --- auto.def | 10 ++++++++-- autosetup/proj.tcl | 5 +++-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/auto.def b/auto.def index e8c7773b4d..46a0721731 100644 --- a/auto.def +++ b/auto.def @@ -360,11 +360,12 @@ proc sqlite-check-wasi-sdk {} { # host_alias=wasm32-wasi # target=wasm32-wasi # - # Merely changing CC and LD to the wasi-sdk's is enough to get + # Merely changing CC, LD, and AR to the wasi-sdk's is enough to get # sqlite3.o building in WASM format. # define CC "${wasiSdkDir}/bin/clang" define LD "${wasiSdkDir}/bin/wasm-ld" + define AR "${wasiSdkDir}/bin/ar" #define STRIP "${wasiSdkDir}/bin/strip" return 1 }; # sqlite-check-wasi-sdk @@ -659,10 +660,15 @@ proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " define CFLAGS_JIMSH {} set cgtcl [opt-val with-tclsh jimsh] - define-push {CC} { + set flagsToRestore {CC CFLAGS CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} + define-push $flagsToRestore { # We have to swap CC to CC_FOR_BUILD for purposes of the various # [cc-...] tests below. Recall that --with-wasi-sdk may have # swapped out CC with one which is not appropriate for this block. + # Per consulation with autosetup's creator, doing this properly + # requires us to [define-push] the whole $flagsToRestore list + # (plus a few others which are not relevant in this tree). + foreach flag $flagsToRestore {define $flag ""} define CC [get-define CC_FOR_BUILD] if {"jimsh" ne $cgtcl} { # When --with-tclsh=X is used, use that for all TCL purposes, diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index a607a0d149..537b281dde 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1005,8 +1005,9 @@ proc proj-redefine-cc-for-build {} { ######################################################################## # Attempts to determine whether the given linenoise header file is of -# the "antirez" or "msteveb" flavor. It returns 1 for antirez, 2 for -# msteveb, and 0 if it's neither. +# the "antirez" or "msteveb" flavor. It returns 2 for msteveb, else 1 +# (it does not validate that the header otherwise contains the +# linenoise API). proc proj-which-linenoise {dotH} { set srcHeader [proj-file-content $dotH] if {[string match *userdata* $srcHeader]} { diff --git a/manifest b/manifest index fb07f0a2c5..23504255f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\stestrunner.tcl,\sonly\sshow\sthe\sETC\son\sthe\sstatus\sline\sif\sit\swill\sfit\swithin\nthe\s80-character\sline\slimit. -D 2024-10-31T18:29:55.322 +C When\sconfiguring\swith\s--with-wasi-sdk,\sensure\sthat\swe\suse\sthat\sSDK's\s'ar'\stool\sinstead\sof\swhatever\sis\sin\sthe\sPATH.\sWhen\spushing/popping\sthe\sdefine\svar\sscope\sfor\sthe\sjimsh\scompatility\scheck,\sinclude\smore\sdefines\sper\sconsultation\swith\sautosetup's\screator. +D 2024-11-01T01:56:27.462 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 5e5bac1b983628125722a64ab8fce9ea1755c5483a078704ac27de7f99f32f2b +F auto.def 9cf971c8877aa7b999c3b3b41fe802feea49a50ea98afc0f9964cfc5cc69057b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl b1a10140de41c4538959feec4032bc40b83d7b8f235e7b331040da87988b36e4 +F autosetup/proj.tcl 68362ca12e1a32fe73ece32b59a8e8e02a3983295f2dd82c9c4700507bade02c F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 207ca21bd7060a163da60b432f61ffaad8bedb6c0d59f090f9c5addb5b56d82d -R 65cc2e74cca41252a2309f0b7a90695b -U drh -Z 2c689aa6cac5108020ff6901e85b9ecd +P 45a3213d23f4691732ba2eb54d440355ce5757aad4cec8eb92f53b4bd7e7f5cd +R b36a62b0c9c5b7166714591dccfa9711 +U stephan +Z ff7715650889932fe27891a2e68d9d47 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0e3e9259a8..536ff23a71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45a3213d23f4691732ba2eb54d440355ce5757aad4cec8eb92f53b4bd7e7f5cd +2dcc465a7090811ddbc210673f37b4c3a4439c501874abefd403efe1e98f5b17 From dea749acc39a2666ce3426a46e67d059227cae84 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 2 Nov 2024 03:34:04 +0000 Subject: [PATCH 254/522] Add autotools-compatible overridable dir name vars for the various installation targets, calculated at make-time instead of exported at configure-time for reasons explained at length in the accompanying comments. FossilOrigin-Name: 24aba7ee58f3048d70ff0c2b2cda26bc04bfb46b3055d25d62ab5ff97b106be2 --- Makefile.in | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--- main.mk | 43 +++++++++++++++++++++++++++------------ manifest | 14 ++++++------- manifest.uuid | 2 +- 4 files changed, 91 insertions(+), 24 deletions(-) diff --git a/Makefile.in b/Makefile.in index db7c8d5001..ca48f7512c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -56,9 +56,6 @@ all: # TOP = @abs_top_srcdir@ # -# Some standard variables and programs -prefix ?= @prefix@ -# # Just testing some default dir expansions... # srcdir = @srcdir@ # builddir = @builddir@ @@ -67,6 +64,59 @@ prefix ?= @prefix@ # abs_top_builddir = @abs_top_builddir@ # +# +# Autotools-conventional vars which are used by package installation +# rules in main.mk. +# +# Autosetup allows the various XYZdir vars to be overridden at +# configure-time with, e.g. --libdir=X and --mandir=Y. However, +# defining them at configure-time, instead of at make-time, leads to +# later awkwardness: +# +# $ ./configure --prefix=/usr +# $ make prefix=/bar +# +# In that invocation, libdir will be /usr/foo, not /bar/foo as it +# normally should, unless the user _also_ passes libdir=... to make. +# +# In 99%+ of use cases, setting prefix=X has the desired effect of +# calculating conventional defaults for various other dirs, like +# $prefix/lib, $prefix/include, etc. If, however, we export those at +# configure-time, the passing prefix=... to make will update only +# $prefix and none of its derived dirs. +# +# Because it is more important (for our use cases) that these vars be +# overridable via a make invocation than a configure invocation, and +# they conventionally derive from $(prefix) in all but the most exotic +# of use cases, we do not export the configure-defined overrides of +# those vars to this makefile. Instead, we export only $prefix and +# its derived vars are set to their conventional default values in +# main.mk, which users can then override at make-time as needed. +# Overriding $prefix via make will also calculate any derived vars, as +# one would expect, unless each is specifically overridden. +# +# For completeness's sake, the aforementioned conventional vars which +# are relevant to our installation rules are: +# +# datadir = $(prefix)/share +# mandir = $(datadir)/man +# includedir = $(prefix)/include +# exec_prefix = $(prefix) +# bindir = $(exec_prefix)/bin +# libdir = $(exec_prefix)/lib +# +# Our builds do not require any of their relatives: +# +# sbindir = $(exec_prefix)/sbin +# sysconfdir = /etc +# sharedstatedir = $(prefix)/com +# localstatedir = /var +# runstatedir = /run +# infodir = $(datadir)/info +# libexec = $(exec_prefix)/libexec +# +prefix = @prefix@ + INSTALL = @BIN_INSTALL@ AR = @AR@ AR.flags = cr # TODO? Add a configure test to determine this? diff --git a/main.mk b/main.mk index 06d44ec184..2146ba49ef 100644 --- a/main.mk +++ b/main.mk @@ -119,14 +119,31 @@ JIMSH ?= ./jimsh$(T.exe) B.tclsh ?= $(JIMSH) # -# Various system-level directories, mostly needed for installation and -# for finding system-level dependencies. -# -# Aside from ${prefix}, we do not need to (and intentionally do not) -# export any of the dozen-ish shorthand ${XYZdir} vars the autotools -# conventionally defines. -# -prefix ?= /usr/local +# Autotools-conventional vars which are (in this tree) used only by +# package installation rules. +# +# The following ${XYZdir} vars are provided for the sake of clients +# who expect to be able to override these using autotools-conventional +# dir name vars. In this build they apply only to installation-related +# rules. +# +prefix ?= /usr/local +datadir ?= $(prefix)/share +mandir ?= $(datadir)/man +includedir ?= $(prefix)/include +exec_prefix ?= $(prefix) +bindir ?= $(exec_prefix)/bin +libdir ?= $(exec_prefix)/lib +# This makefile does not use any of: +# sbindir ?= $(exec_prefix)/sbin +# sysconfdir ?= /etc +# sharedstatedir ?= $(prefix)/com +# localstatedir ?= /var +# runstatedir ?= /run +# infodir ?= $(datadir)/info +# libexec ?= $(exec_prefix)/libexec + + # # $(LDFLAGS.{feature}) and $(CFLAGS.{feature}) = # @@ -355,11 +372,11 @@ LDFLAGS.libsqlite3 = \ # moral of this story is that spaces in installation paths will break # the install process. # -install-dir.bin = $(DESTDIR)$(prefix)/bin -install-dir.lib = $(DESTDIR)$(prefix)/lib -install-dir.include = $(DESTDIR)$(prefix)/include -install-dir.pkgconfig = $(DESTDIR)$(prefix)/lib/pkgconfig -install-dir.man1 = $(DESTDIR)$(prefix)/share/man/man1 +install-dir.bin = $(DESTDIR)$(bindir) +install-dir.lib = $(DESTDIR)$(libdir) +install-dir.include = $(DESTDIR)$(includedir) +install-dir.pkgconfig = $(DESTDIR)$(libdir)/pkgconfig +install-dir.man1 = $(DESTDIR)$(mandir)/man1 install-dir.all = $(install-dir.bin) $(install-dir.include) \ $(install-dir.lib) $(install-dir.man1) \ $(install-dir.pkgconfig) diff --git a/manifest b/manifest index 23504255f1..b0e73839dd 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C When\sconfiguring\swith\s--with-wasi-sdk,\sensure\sthat\swe\suse\sthat\sSDK's\s'ar'\stool\sinstead\sof\swhatever\sis\sin\sthe\sPATH.\sWhen\spushing/popping\sthe\sdefine\svar\sscope\sfor\sthe\sjimsh\scompatility\scheck,\sinclude\smore\sdefines\sper\sconsultation\swith\sautosetup's\screator. -D 2024-11-01T01:56:27.462 +C Add\sautotools-compatible\soverridable\sdir\sname\svars\sfor\sthe\svarious\sinstallation\stargets,\scalculated\sat\smake-time\sinstead\sof\sexported\sat\sconfigure-time\sfor\sreasons\sexplained\sat\slength\sin\sthe\saccompanying\scomments. +D 2024-11-02T03:34:04.784 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 3a98abc984222a31c8597a0cd516c8dd9b72554d784a87c915d2e586db4ddb18 +F Makefile.in 55cd298aa41436c426351d7a4f387d5502431f07c96b52f2b4154f0193379150 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 4941b5880b4ea528258e2186e814463e438a812677478e318920f312408121c7 +F main.mk 01f83a096392922826bca5dda938235f2c2f94988c1f467fe90a8e31aaeed912 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 45a3213d23f4691732ba2eb54d440355ce5757aad4cec8eb92f53b4bd7e7f5cd -R b36a62b0c9c5b7166714591dccfa9711 +P 2dcc465a7090811ddbc210673f37b4c3a4439c501874abefd403efe1e98f5b17 +R 565488b6d72da8ea787b0c37e1464eb8 U stephan -Z ff7715650889932fe27891a2e68d9d47 +Z 2d29757f9585ee6ad461db23d83778f6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 536ff23a71..ade193ca47 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2dcc465a7090811ddbc210673f37b4c3a4439c501874abefd403efe1e98f5b17 +24aba7ee58f3048d70ff0c2b2cda26bc04bfb46b3055d25d62ab5ff97b106be2 From f0e7f4c1f2d4b9a52064c4fc2417b78f38f4f365 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 2 Nov 2024 05:50:22 +0000 Subject: [PATCH 255/522] An experiment in hybridizing overriding of autotools-conventional XYZdir vars, the goal being to be able to provide both overrriding of them at configure-time and make-time with sensible semantics. Based on notes from [forum:00d12a41f7|forum post 00d12a41f7]. FossilOrigin-Name: cc259bf5f176bf89b6effedfc716d19d2437fc761c20870d1c69205d4bcee12b --- Makefile.in | 6 ++++ auto.def | 5 ++++ autosetup/proj.tcl | 70 ++++++++++++++++++++++++++++++++++++++++++++++ manifest | 20 +++++++------ manifest.uuid | 2 +- 5 files changed, 94 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index ca48f7512c..cb25a002a8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -116,6 +116,12 @@ TOP = @abs_top_srcdir@ # libexec = $(exec_prefix)/libexec # prefix = @prefix@ +datadir = @datadir@ +mandir = @mandir@ +includedir = @includedir@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ INSTALL = @BIN_INSTALL@ AR = @AR@ diff --git a/auto.def b/auto.def index 46a0721731..59827879d0 100644 --- a/auto.def +++ b/auto.def @@ -216,6 +216,11 @@ proj-xfer-options-aliases { with-readline-inc => with-readline-cflags with-readline-lib => with-readline-ldflags } +# +# "Re-export" the autoconf-conventional --XYZdir flags into something +# which is more easily overridable from a make invocation. +# +proj-redirect-autoconf-dir-vars set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 537b281dde..06c51ee14b 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1016,3 +1016,73 @@ proc proj-which-linenoise {dotH} { return 1 } } + +######################################################################## +# +# "Re-export" the autoconf-conventional --XYZdir flags into something +# which is more easily overridable from a make invocation. +# +# Based off of notes in . +# +# Consider: +# +# $ ./configure --prefix=/foo +# $ make install prefix=/blah +# +# In that make invocation, $(libdir) would, at make-time, normally be +# hard-coded to /foo/lib, rather than /blah/lib. That happens because +# the autosetup exports conventional $prefix-based values for the +# numerious autoconfig-compatible XYZdir vars at configure-time. What +# we would normally want, however, is that --libdir derives from the +# make-time $(prefix). The distinction between configure-time and +# make-time is the significant factor there. +# +# This function attempts to reconcile those vars in such a way that +# they will derive, at make-time, from $(prefix) in a conventional +# manner unless they are explicitly overridden at configure-time, in +# which case those overrides takes precedence. +# +# Each --XYZdir flag which is explicitly passed to configure is +# exported as-is, as are those which default to some top-level system +# directory, e.g. /etc or /var. All which derive from either $prefix +# or $exec_prefix are exported in the form of a Makefile var +# reference, e.g. libdir=${exec_prefix}/lib. Ergo, if +# --exec-prefix=FOO is passed to configure, libdir will still derive, +# at make-time, from whatever exec_prefix is passed to make, and will +# use FOO if exec_prefix is not overridden. Without this +# post-processing, libdir would be cemented in as FOO/lib at +# configure-time, so would be tedious to override properly via a make +# invocation. +# +proc proj-redirect-autoconf-dir-vars {} { + set prefix [get-define prefix] + set exec_prefix [get-define exec_prefix $prefix] + # Note that the ${...} here refers to make-side var derefs, not + # TCL-side vars. + foreach {flag makeVar makeDeref} { + exec-prefix exec_prefix ${prefix} + libdir libdir ${exec_prefix}/lib + datadir datadir ${prefix}/share + mandir mandir ${datadir}/man + includedir includedir ${prefix}/include + bindir bindir ${exec_prefix}/bin + libdir libdir ${exec_prefix}/lib + sbindir sbindir ${exec_prefix}/sbin + sysconfdir sysconfdir /etc + sharedstatedir sharedstatedir ${prefix}/com + localstatedir localstatedir /var + runstatedir runstatedir /run + infodir infodir ${datadir}/info + libexec libexec ${exec_prefix}/libexec + } { + # puts "flag=$flag var=$makeVar makeDeref=$makeDeref" + if {[proj-opt-was-provided $flag]} { + #set x "+" + define $makeVar [opt-val $flag] + } else { + #set x "~" + define $makeVar $makeDeref + } + #puts "$x $makeVar = [get-define $makeVar]" + } +} diff --git a/manifest b/manifest index b0e73839dd..ad27f8950b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\sautotools-compatible\soverridable\sdir\sname\svars\sfor\sthe\svarious\sinstallation\stargets,\scalculated\sat\smake-time\sinstead\sof\sexported\sat\sconfigure-time\sfor\sreasons\sexplained\sat\slength\sin\sthe\saccompanying\scomments. -D 2024-11-02T03:34:04.784 +C An\sexperiment\sin\shybridizing\soverriding\sof\sautotools-conventional\sXYZdir\svars,\sthe\sgoal\sbeing\sto\sbe\sable\sto\sprovide\sboth\soverrriding\sof\sthem\sat\sconfigure-time\sand\smake-time\swith\ssensible\ssemantics.\sBased\son\snotes\sfrom\s[forum:00d12a41f7|forum\spost\s00d12a41f7]. +D 2024-11-02T05:50:22.194 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 55cd298aa41436c426351d7a4f387d5502431f07c96b52f2b4154f0193379150 +F Makefile.in 6c595d1a09516770375dd466a91ba2f88ff8d6c1b12c2e0eb2b0ef645b6ed94f F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 9cf971c8877aa7b999c3b3b41fe802feea49a50ea98afc0f9964cfc5cc69057b +F auto.def 9a0c7a3165be8abf0e6c67cf02af7d7c5669def7416e40fd3d54fd8cae9b6d14 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 68362ca12e1a32fe73ece32b59a8e8e02a3983295f2dd82c9c4700507bade02c +F autosetup/proj.tcl 952eb7d6a9d0f1f50c85c823089665eadd718e0f85372198a4e743b67e41481d F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,12 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2dcc465a7090811ddbc210673f37b4c3a4439c501874abefd403efe1e98f5b17 -R 565488b6d72da8ea787b0c37e1464eb8 +P 24aba7ee58f3048d70ff0c2b2cda26bc04bfb46b3055d25d62ab5ff97b106be2 +R 6f6eddd40305846c7e8dc49e81bcb71c +T *branch * autosetup-dir-overrides +T *sym-autosetup-dir-overrides * +T +closed * +T -sym-trunk * Cancelled\sby\sbranch. U stephan -Z 2d29757f9585ee6ad461db23d83778f6 +Z 7916dea993020a5fa99a26daa68b6c79 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ade193ca47..0e82160c45 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24aba7ee58f3048d70ff0c2b2cda26bc04bfb46b3055d25d62ab5ff97b106be2 +cc259bf5f176bf89b6effedfc716d19d2437fc761c20870d1c69205d4bcee12b From 090b8649be3603920327a0ae45c2cf9384d8615b Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 2 Nov 2024 19:10:50 +0000 Subject: [PATCH 256/522] Allow an fts5 table or query to be configured to collect xInstToken data for any prefix terms as part of the first parse of the main index, if any. FossilOrigin-Name: 46929ae92b26f02bc70de9931b21a8a7cf9a2453d5fb07f68b712f62e28e9152 --- ext/fts5/fts5Int.h | 3 +- ext/fts5/fts5_config.c | 13 + ext/fts5/fts5_index.c | 501 +++++++++++++++-------------- ext/fts5/fts5_main.c | 28 +- ext/fts5/test/fts5origintext.test | 121 ++++--- ext/fts5/test/fts5origintext3.test | 47 ++- manifest | 24 +- manifest.uuid | 2 +- 8 files changed, 430 insertions(+), 309 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index bb72f45c7b..832f9ad477 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -247,7 +247,8 @@ struct Fts5Config { char *zRank; /* Name of rank function */ char *zRankArgs; /* Arguments to rank function */ int bSecureDelete; /* 'secure-delete' */ - int nDeleteMerge; /* 'deletemerge' */ + int nDeleteMerge; /* 'deletemerge' */ + int bPrefixInsttoken; /* 'prefix-insttoken' */ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ char **pzErrmsg; diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index a674b44d0b..eea82b046d 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -1026,6 +1026,19 @@ int sqlite3Fts5ConfigSetValue( }else{ pConfig->bSecureDelete = (bVal ? 1 : 0); } + } + + else if( 0==sqlite3_stricmp(zKey, "insttoken") ){ + int bVal = -1; + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + bVal = sqlite3_value_int(pVal); + } + if( bVal<0 ){ + *pbBadkey = 1; + }else{ + pConfig->bPrefixInsttoken = (bVal ? 1 : 0); + } + }else{ *pbBadkey = 1; } diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 04f0a6740c..e7028e411c 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6260,6 +6260,7 @@ static int fts5VisitEntries( const u8 *pNew = 0; p1->xSetOutputs(p1, pSeg); + if( p->rc ) break; if( bNewTerm ){ nNew = pSeg->term.n; @@ -6275,6 +6276,247 @@ static int fts5VisitEntries( return p->rc; } + +/* +** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an +** array of these for each row it visits (so all iRowid fields are the same). +** Or, for an iterator used by an "ORDER BY rank" query, it accumulates an +** array of these for the entire query (in which case iRowid fields may take +** a variety of values). +** +** Each instance in the array indicates the iterator (and therefore term) +** associated with position iPos of rowid iRowid. This is used by the +** xInstToken() API. +** +** iRowid: +** Rowid for the current entry. +** +** iPos: +** Position of current entry within row. In the usual ((iCol<<32)+iOff) +** format (e.g. see macros FTS5_POS2COLUMN() and FTS5_POS2OFFSET()). +** +** iIter: +** If the Fts5TokenDataIter iterator that the entry is part of is +** actually an iterator (i.e. with nIter>0, not just a container for +** Fts5TokenDataMap structures), then this variable is an index into +** the apIter[] array. The corresponding term is that which the iterator +** at apIter[iIter] currently points to. +** +** Or, if the Fts5TokenDataIter iterator is just a container object +** (nIter==0), then iIter is an index into the term.p[] buffer where +** the term is stored. +** +** nByte: +** In the case where iIter is an index into term.p[], this variable +** is the size of the term in bytes. If iIter is an index into apIter[], +** this variable is unused. +*/ +struct Fts5TokenDataMap { + i64 iRowid; /* Row this token is located in */ + i64 iPos; /* Position of token */ + int iIter; /* Iterator token was read from */ + int nByte; /* Length of token in bytes (or 0) */ +}; + +/* +** An object used to supplement Fts5Iter for tokendata=1 iterators. +** +** This object serves two purposes. The first is as a container for an array +** of Fts5TokenDataMap structures, which are used to find the token required +** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and +** aMap[] variables. +*/ +struct Fts5TokenDataIter { + int nMapAlloc; /* Allocated size of aMap[] in entries */ + int nMap; /* Number of valid entries in aMap[] */ + Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */ + + /* The following are used for prefix-queries only. */ + Fts5Buffer terms; + + /* The following are used for other full-token tokendata queries only. */ + int nIter; + int nIterAlloc; + Fts5PoslistReader *aPoslistReader; + int *aPoslistToIter; + Fts5Iter *apIter[1]; +}; + +/* +** The two input arrays - a1[] and a2[] - are in sorted order. This function +** merges the two arrays together and writes the result to output array +** aOut[]. aOut[] is guaranteed to be large enough to hold the result. +** +** Duplicate entries are copied into the output. So the size of the output +** array is always (n1+n2) entries. +*/ +static void fts5TokendataMerge( + Fts5TokenDataMap *a1, int n1, /* Input array 1 */ + Fts5TokenDataMap *a2, int n2, /* Input array 2 */ + Fts5TokenDataMap *aOut /* Output array */ +){ + int i1 = 0; + int i2 = 0; + + assert( n1>=0 && n2>=0 ); + while( i1=n2 || (i1rc==SQLITE_OK ){ + if( pT->nMap==pT->nMapAlloc ){ + int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; + int nByte = nNew * sizeof(Fts5TokenDataMap); + Fts5TokenDataMap *aNew; + + aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte); + if( aNew==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pT->aMap[pT->nMap].iRowid = iRowid; + pT->aMap[pT->nMap].iPos = iPos; + pT->aMap[pT->nMap].iIter = iIter; + pT->aMap[pT->nMap].nByte = nByte; + pT->nMap++; + } +} + +/* +** Sort the contents of the pT->aMap[] array. +** +** The sorting algorithm requries a malloc(). If this fails, an error code +** is left in Fts5Index.rc before returning. +*/ +static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ + Fts5TokenDataMap *aTmp = 0; + int nByte = pT->nMap * sizeof(Fts5TokenDataMap); + + aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( aTmp ){ + Fts5TokenDataMap *a1 = pT->aMap; + Fts5TokenDataMap *a2 = aTmp; + i64 nHalf; + + for(nHalf=1; nHalfnMap; nHalf=nHalf*2){ + int i1; + for(i1=0; i1nMap; i1+=(nHalf*2)){ + int n1 = MIN(nHalf, pT->nMap-i1); + int n2 = MIN(nHalf, pT->nMap-i1-n1); + fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]); + } + SWAPVAL(Fts5TokenDataMap*, a1, a2); + } + + if( a1!=pT->aMap ){ + memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap)); + } + sqlite3_free(aTmp); + +#ifdef SQLITE_DEBUG + { + int ii; + for(ii=1; iinMap; ii++){ + Fts5TokenDataMap *p1 = &pT->aMap[ii-1]; + Fts5TokenDataMap *p2 = &pT->aMap[ii]; + assert( p1->iRowidiRowid + || (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos) + ); + } + } +#endif + } +} + +/* +** Delete an Fts5TokenDataIter structure and its contents. +*/ +static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ + if( pSet ){ + int ii; + for(ii=0; iinIter; ii++){ + fts5MultiIterFree(pSet->apIter[ii]); + } + fts5BufferFree(&pSet->terms); + sqlite3_free(pSet->aPoslistReader); + sqlite3_free(pSet->aMap); + sqlite3_free(pSet); + } +} + + +/* +** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata() +** to pass data to prefixIterSetupTokendataCb(). +*/ +typedef struct TokendataSetupCtx TokendataSetupCtx; +struct TokendataSetupCtx { + Fts5TokenDataIter *pT; /* Object being populated with mappings */ + int iTermOff; /* Offset of current term in terms.p[] */ + int nTermByte; /* Size of current term in bytes */ +}; + +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This +** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each +** position in the current position-list. It doesn't matter that some of +** these may be out of order - they will be sorted later. +*/ +static void prefixIterSetupTokendataCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx; + int iPosOff = 0; + i64 iPos = 0; + + if( pNew ){ + pSetup->nTermByte = nNew-1; + pSetup->iTermOff = pSetup->pT->terms.n; + fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1); + } + + while( 0==sqlite3Fts5PoslistNext64( + p1->base.pData, p1->base.nData, &iPosOff, &iPos + ) ){ + fts5TokendataIterAppendMap(p, + pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos + ); + } +} + + /* ** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries(). */ @@ -6287,6 +6529,7 @@ struct PrefixSetupCtx { Fts5Buffer *aBuf; int nBuf; Fts5Buffer doclist; + TokendataSetupCtx *pTokendata; }; /* @@ -6331,6 +6574,10 @@ static void prefixIterSetupCb( ); pSetup->iLastRowid = p1->base.iRowid; } + + if( pSetup->pTokendata ){ + prefixIterSetupTokendataCb(p, (void*)pSetup->pTokendata, p1, pNew, nNew); + } } static void fts5SetupPrefixIter( @@ -6344,11 +6591,21 @@ static void fts5SetupPrefixIter( ){ Fts5Structure *pStruct; PrefixSetupCtx s; + TokendataSetupCtx s2; memset(&s, 0, sizeof(s)); + memset(&s2, 0, sizeof(s2)); + s.nMerge = 1; s.iLastRowid = 0; s.nBuf = 32; + if( iIdx==0 + && p->pConfig->eDetail==FTS5_DETAIL_FULL + && p->pConfig->bPrefixInsttoken + ){ + s.pTokendata = &s2; + s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT)); + } if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ s.xMerge = fts5MergeRowidLists; @@ -6400,8 +6657,15 @@ static void fts5SetupPrefixIter( if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n); fts5MultiIterNew2(p, pData, bDesc, ppIter); } + + if( p->rc==SQLITE_OK && s.pTokendata ){ + fts5TokendataIterSortMap(p, s2.pT); + (*ppIter)->pTokenDataIter = s2.pT; + s2.pT = 0; + } } + fts5TokendataIterDelete(s2.pT); fts5BufferFree(&s.doclist); fts5StructureRelease(pStruct); sqlite3_free(s.aBuf); @@ -6658,71 +6922,6 @@ static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ pSeg->pLeaf = 0; } -/* -** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an -** array of these for each row it visits (so all iRowid fields are the same). -** Or, for an iterator used by an "ORDER BY rank" query, it accumulates an -** array of these for the entire query (in which case iRowid fields may take -** a variety of values). -** -** Each instance in the array indicates the iterator (and therefore term) -** associated with position iPos of rowid iRowid. This is used by the -** xInstToken() API. -** -** iRowid: -** Rowid for the current entry. -** -** iPos: -** Position of current entry within row. In the usual ((iCol<<32)+iOff) -** format (e.g. see macros FTS5_POS2COLUMN() and FTS5_POS2OFFSET()). -** -** iIter: -** If the Fts5TokenDataIter iterator that the entry is part of is -** actually an iterator (i.e. with nIter>0, not just a container for -** Fts5TokenDataMap structures), then this variable is an index into -** the apIter[] array. The corresponding term is that which the iterator -** at apIter[iIter] currently points to. -** -** Or, if the Fts5TokenDataIter iterator is just a container object -** (nIter==0), then iIter is an index into the term.p[] buffer where -** the term is stored. -** -** nByte: -** In the case where iIter is an index into term.p[], this variable -** is the size of the term in bytes. If iIter is an index into apIter[], -** this variable is unused. -*/ -struct Fts5TokenDataMap { - i64 iRowid; /* Row this token is located in */ - i64 iPos; /* Position of token */ - int iIter; /* Iterator token was read from */ - int nByte; /* Length of token in bytes (or 0) */ -}; - -/* -** An object used to supplement Fts5Iter for tokendata=1 iterators. -** -** This object serves two purposes. The first is as a container for an array -** of Fts5TokenDataMap structures, which are used to find the token required -** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and -** aMap[] variables. -*/ -struct Fts5TokenDataIter { - int nMapAlloc; /* Allocated size of aMap[] in entries */ - int nMap; /* Number of valid entries in aMap[] */ - Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */ - - /* The following are used for prefix-queries only. */ - Fts5Buffer terms; - - /* The following are used for other full-token tokendata queries only. */ - int nIter; - int nIterAlloc; - Fts5PoslistReader *aPoslistReader; - int *aPoslistToIter; - Fts5Iter *apIter[1]; -}; - /* ** This function appends iterator pAppend to Fts5TokenDataIter pIn and ** returns the result. @@ -6759,57 +6958,6 @@ static Fts5TokenDataIter *fts5AppendTokendataIter( return pRet; } -/* -** Delete an Fts5TokenDataIter structure and its contents. -*/ -static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ - if( pSet ){ - int ii; - for(ii=0; iinIter; ii++){ - fts5MultiIterFree(pSet->apIter[ii]); - } - fts5BufferFree(&pSet->terms); - sqlite3_free(pSet->aPoslistReader); - sqlite3_free(pSet->aMap); - sqlite3_free(pSet); - } -} - -/* -** Append a mapping to the token-map belonging to object pT. -*/ -static void fts5TokendataIterAppendMap( - Fts5Index *p, - Fts5TokenDataIter *pT, - int iIter, - int nByte, - i64 iRowid, - i64 iPos -){ - if( p->rc==SQLITE_OK ){ - if( pT->nMap==pT->nMapAlloc ){ - int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; - int nByte = nNew * sizeof(Fts5TokenDataMap); - Fts5TokenDataMap *aNew; - - aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte); - if( aNew==0 ){ - p->rc = SQLITE_NOMEM; - return; - } - - pT->aMap = aNew; - pT->nMapAlloc = nNew; - } - - pT->aMap[pT->nMap].iRowid = iRowid; - pT->aMap[pT->nMap].iPos = iPos; - pT->aMap[pT->nMap].iIter = iIter; - pT->aMap[pT->nMap].nByte = nByte; - pT->nMap++; - } -} - /* ** The iterator passed as the only argument must be a tokendata=1 iterator ** (pIter->pTokenDataIter!=0). This function sets the iterator output @@ -7285,127 +7433,6 @@ const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return (z ? &z[1] : 0); } -/* -** The two input arrays - a1[] and a2[] - are in sorted order. This function -** merges the two arrays together and writes the result to output array -** aOut[]. aOut[] is guaranteed to be large enough to hold the result. -** -** Duplicate entries are copied into the output. So the size of the output -** array is always (n1+n2) entries. -*/ -static void fts5TokendataMerge( - Fts5TokenDataMap *a1, int n1, /* Input array 1 */ - Fts5TokenDataMap *a2, int n2, /* Input array 2 */ - Fts5TokenDataMap *aOut /* Output array */ -){ - int i1 = 0; - int i2 = 0; - - assert( n1>=0 && n2>=0 ); - while( i1=n2 || (i1aMap[] array. -** -** The sorting algorithm requries a malloc(). If this fails, an error code -** is left in Fts5Index.rc before returning. -*/ -static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ - Fts5TokenDataMap *aTmp = 0; - int nByte = pT->nMap * sizeof(Fts5TokenDataMap); - - aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); - if( aTmp ){ - Fts5TokenDataMap *a1 = pT->aMap; - Fts5TokenDataMap *a2 = aTmp; - i64 nHalf; - - for(nHalf=1; nHalfnMap; nHalf=nHalf*2){ - int i1; - for(i1=0; i1nMap; i1+=(nHalf*2)){ - int n1 = MIN(nHalf, pT->nMap-i1); - int n2 = MIN(nHalf, pT->nMap-i1-n1); - fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]); - } - SWAPVAL(Fts5TokenDataMap*, a1, a2); - } - - if( a1!=pT->aMap ){ - memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap)); - } - sqlite3_free(aTmp); - -#ifdef SQLITE_DEBUG - { - int ii; - for(ii=1; iinMap; ii++){ - Fts5TokenDataMap *p1 = &pT->aMap[ii-1]; - Fts5TokenDataMap *p2 = &pT->aMap[ii]; - assert( p1->iRowidiRowid - || (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos) - ); - } - } -#endif - } -} - -/* -** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata() -** to pass data to prefixIterSetupTokendataCb(). -*/ -typedef struct TokendataSetupCtx TokendataSetupCtx; -struct TokendataSetupCtx { - Fts5TokenDataIter *pT; /* Object being populated with mappings */ - int iTermOff; /* Offset of current term in terms.p[] */ - int nTermByte; /* Size of current term in bytes */ -}; - -/* -** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This -** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each -** position in the current position-list. It doesn't matter that some of -** these may be out of order - they will be sorted later. -*/ -static void prefixIterSetupTokendataCb( - Fts5Index *p, - void *pCtx, - Fts5Iter *p1, - const u8 *pNew, - int nNew -){ - TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx; - int iPosOff = 0; - i64 iPos = 0; - - if( pNew ){ - pSetup->nTermByte = nNew-1; - pSetup->iTermOff = pSetup->pT->terms.n; - fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1); - } - - while( 0==sqlite3Fts5PoslistNext64( - p1->base.pData, p1->base.nData, &iPosOff, &iPos - ) ){ - fts5TokendataIterAppendMap(p, - pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos - ); - } -} - /* ** pIter is a prefix query. This function populates pIter->pTokenDataIter ** with an Fts5TokenDataIter object containing mappings for all rows diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 5713fccdd1..a65750f8e1 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -93,6 +93,7 @@ struct Fts5Global { #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr )) #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr)) +#define FTS5_INSTTOKEN_SUBTYPE 73 /* ** Each auxiliary function registered with the FTS5 module is represented @@ -1417,6 +1418,7 @@ static int fts5FilterMethod( sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; + int bPrefixInsttoken = pConfig->bPrefixInsttoken; int i; int iIdxStr = 0; Fts5Expr *pExpr = 0; @@ -1452,6 +1454,9 @@ static int fts5FilterMethod( rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset); if( rc!=SQLITE_OK ) goto filter_out; if( zText==0 ) zText = ""; + if( sqlite3_value_subtype(apVal[i])==FTS5_INSTTOKEN_SUBTYPE ){ + pConfig->bPrefixInsttoken = 1; + } iCol = 0; do{ @@ -1592,6 +1597,7 @@ static int fts5FilterMethod( filter_out: sqlite3Fts5ExprFree(pExpr); pConfig->pzErrmsg = pzErrmsg; + pConfig->bPrefixInsttoken = bPrefixInsttoken; return rc; } @@ -3651,6 +3657,19 @@ static void fts5LocaleFunc( } } +/* +** Implementation of fts5_insttoken() function. +*/ +static void fts5InsttokenFunc( + sqlite3_context *pCtx, /* Function call context */ + int nArg, /* Number of args */ + sqlite3_value **apArg /* Function arguments */ +){ + assert( nArg==1 ); + sqlite3_result_value(pCtx, apArg[0]); + sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE); +} + /* ** Return true if zName is the extension on one of the shadow tables used ** by this module. @@ -3780,10 +3799,17 @@ static int fts5Init(sqlite3 *db){ if( rc==SQLITE_OK ){ rc = sqlite3_create_function( db, "fts5_locale", 2, - SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE|SQLITE_SUBTYPE, p, fts5LocaleFunc, 0, 0 ); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function( + db, "fts5_insttoken", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + p, fts5InsttokenFunc, 0, 0 + ); + } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file diff --git a/ext/fts5/test/fts5origintext.test b/ext/fts5/test/fts5origintext.test index 9741f786e8..be77cbfca5 100644 --- a/ext/fts5/test/fts5origintext.test +++ b/ext/fts5/test/fts5origintext.test @@ -22,34 +22,40 @@ ifcapable !fts5 { } foreach_detail_mode $testprefix { +foreach {tn insttoken} { + 1 0 + 2 1 +} { +reset_db sqlite3_fts5_register_origintext db -do_execsql_test 1.0 { +do_execsql_test $tn.1.0 { CREATE VIRTUAL TABLE ft USING fts5( x, tokenize="origintext unicode61", detail=%DETAIL% ); + INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken); CREATE VIRTUAL TABLE vocab USING fts5vocab(ft, instance); } -do_execsql_test 1.1 { +do_execsql_test $tn.1.1 { INSERT INTO ft VALUES('Hello world'); } -do_execsql_test 1.2 { +do_execsql_test $tn.1.2 { INSERT INTO ft(ft) VALUES('integrity-check'); } proc b {x} { string map [list "\0" "."] $x } db func b b -do_execsql_test 1.3 { +do_execsql_test $tn.1.3 { select b(term) from vocab; } { hello.Hello world } -do_execsql_test 1.4 { +do_execsql_test $tn.1.4 { SELECT rowid FROM ft('Hello'); } {1} @@ -88,33 +94,34 @@ proc document {} { db func document document sqlite3_fts5_register_origintext db -do_execsql_test 2.0 { +do_execsql_test $tn.2.0 { CREATE VIRTUAL TABLE ft USING fts5( x, tokenize="origintext unicode61", detail=%DETAIL% ); + INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken); INSERT INTO ft(ft, rank) VALUES('pgsz', 128); CREATE VIRTUAL TABLE vocab USING fts5vocab(ft, instance); } -do_test 2.1 { +do_test $tn.2.1 { for {set ii 0} {$ii < 500} {incr ii} { execsql { INSERT INTO ft VALUES( document() ) } } } {} -do_execsql_test 2.2 { +do_execsql_test $tn.2.2 { INSERT INTO ft(ft) VALUES('integrity-check'); } -do_execsql_test 2.3 { +do_execsql_test $tn.2.3 { INSERT INTO ft(ft, rank) VALUES('merge', 16); } -do_execsql_test 2.4 { +do_execsql_test $tn.2.4 { INSERT INTO ft(ft) VALUES('integrity-check'); } -do_execsql_test 2.5 { +do_execsql_test $tn.2.5 { INSERT INTO ft(ft) VALUES('optimize'); } @@ -122,10 +129,11 @@ do_execsql_test 2.5 { reset_db sqlite3_fts5_register_origintext db -do_execsql_test 3.0 { +do_execsql_test $tn.3.0 { CREATE VIRTUAL TABLE ft USING fts5( x, tokenize="origintext unicode61", detail=%DETAIL% ); + INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken); CREATE VIRTUAL TABLE vocab USING fts5vocab(ft, instance); INSERT INTO ft(rowid, x) VALUES(1, 'hello'); @@ -137,16 +145,17 @@ do_execsql_test 3.0 { #db func b b #execsql_pp { SELECT b(term) FROM vocab } -do_execsql_test 3.1.1 { SELECT rowid FROM ft('hello') } 1 -do_execsql_test 3.1.2 { SELECT rowid FROM ft('Hello') } 2 -do_execsql_test 3.1.3 { SELECT rowid FROM ft('HELLO') } 3 +do_execsql_test $tn.3.1.1 { SELECT rowid FROM ft('hello') } 1 +do_execsql_test $tn.3.1.2 { SELECT rowid FROM ft('Hello') } 2 +do_execsql_test $tn.3.1.3 { SELECT rowid FROM ft('HELLO') } 3 -do_execsql_test 3.2 { +do_execsql_test $tn.3.2 { CREATE VIRTUAL TABLE ft2 USING fts5(x, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL% ); + INSERT INTO ft2(ft2, rank) VALUES('insttoken', $insttoken); CREATE VIRTUAL TABLE vocab2 USING fts5vocab(ft2, instance); INSERT INTO ft2(rowid, x) VALUES(1, 'hello'); @@ -160,16 +169,16 @@ do_execsql_test 3.2 { #db func b b #execsql_pp { SELECT b(term) FROM vocab } -do_execsql_test 3.3.1 { SELECT rowid FROM ft2('hello') } {1 2 3} -do_execsql_test 3.3.2 { SELECT rowid FROM ft2('Hello') } {1 2 3} -do_execsql_test 3.3.3 { SELECT rowid FROM ft2('HELLO') } {1 2 3} +do_execsql_test $tn.3.3.1 { SELECT rowid FROM ft2('hello') } {1 2 3} +do_execsql_test $tn.3.3.2 { SELECT rowid FROM ft2('Hello') } {1 2 3} +do_execsql_test $tn.3.3.3 { SELECT rowid FROM ft2('HELLO') } {1 2 3} -do_execsql_test 3.3.4 { SELECT rowid FROM ft2('hello*') } {1 2 3 10} +do_execsql_test $tn.3.3.4 { SELECT rowid FROM ft2('hello*') } {1 2 3 10} -do_execsql_test 3.3.5.1 { SELECT rowid FROM ft2('HELLO') ORDER BY rowid DESC} { +do_execsql_test $tn.3.3.5.1 { SELECT rowid FROM ft2('HELLO') ORDER BY rowid DESC} { 3 2 1 } -do_execsql_test 3.3.5.2 { SELECT rowid FROM ft2('HELLO') ORDER BY +rowid DESC} { +do_execsql_test $tn.3.3.5.2 { SELECT rowid FROM ft2('HELLO') ORDER BY +rowid DESC} { 3 2 1 } @@ -183,36 +192,37 @@ proc querytoken {cmd iPhrase iToken} { } sqlite3_fts5_create_function db querytoken querytoken -do_execsql_test 4.0 { +do_execsql_test $tn.4.0 { CREATE VIRTUAL TABLE ft USING fts5( x, tokenize='origintext unicode61', tokendata=1, detail=%DETAIL% ); + INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken); INSERT INTO ft VALUES('one two three four'); } -do_execsql_test 4.1 { +do_execsql_test $tn.4.1 { SELECT rowid, querytoken(ft, 0, 0) FROM ft('TwO') } {1 two.TwO} -do_execsql_test 4.2 { +do_execsql_test $tn.4.2 { SELECT rowid, querytoken(ft, 0, 0) FROM ft('one TWO ThreE') } {1 one} -do_execsql_test 4.3 { +do_execsql_test $tn.4.3 { SELECT rowid, querytoken(ft, 1, 0) FROM ft('one TWO ThreE') } {1 two.TWO} if {"%DETAIL%"=="full"} { # Phrase queries are only supported for detail=full. # - do_execsql_test 4.4 { + do_execsql_test $tn.4.4 { SELECT rowid, querytoken(ft, 0, 2) FROM ft('"one TWO ThreE"') } {1 three.ThreE} - do_catchsql_test 4.5 { + do_catchsql_test $tn.4.5 { SELECT rowid, querytoken(ft, 0, 3) FROM ft('"one TWO ThreE"') } {1 SQLITE_RANGE} - do_catchsql_test 4.6 { + do_catchsql_test $tn.4.6 { SELECT rowid, querytoken(ft, 1, 0) FROM ft('"one TWO ThreE"') } {1 SQLITE_RANGE} - do_catchsql_test 4.7 { + do_catchsql_test $tn.4.7 { SELECT rowid, querytoken(ft, -1, 0) FROM ft('"one TWO ThreE"') } {1 SQLITE_RANGE} } @@ -228,14 +238,15 @@ proc insttoken {cmd iIdx iToken} { sqlite3_fts5_create_function db insttoken insttoken fts5_aux_test_functions db -do_execsql_test 5.0 { +do_execsql_test $tn.5.0 { CREATE VIRTUAL TABLE ft USING fts5( x, tokenize='origintext unicode61', tokendata=1, detail=%DETAIL% ); + INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken); INSERT INTO ft VALUES('one ONE One oNe oNE one'); } -do_execsql_test 5.1 { +do_execsql_test $tn.5.1 { SELECT insttoken(ft, 0, 0), insttoken(ft, 1, 0), insttoken(ft, 2, 0), @@ -247,13 +258,37 @@ do_execsql_test 5.1 { one one.ONE one.One one.oNe one.oNE one } -do_execsql_test 5.2 { +do_execsql_test $tn.5.2 { + SELECT insttoken(ft, 0, 0), + insttoken(ft, 1, 0), + insttoken(ft, 2, 0), + insttoken(ft, 3, 0), + insttoken(ft, 4, 0), + insttoken(ft, 5, 0) + FROM ft('on*'); +} { + one one.ONE one.One one.oNe one.oNE one +} + +do_execsql_test $tn.5.3 { + SELECT insttoken(ft, 0, 0), + insttoken(ft, 1, 0), + insttoken(ft, 2, 0), + insttoken(ft, 3, 0), + insttoken(ft, 4, 0), + insttoken(ft, 5, 0) + FROM ft(fts5_insttoken('on*')); +} { + one one.ONE one.One one.oNe one.oNE one +} + +do_execsql_test $tn.5.4 { SELECT insttoken(ft, 1, 0) FROM ft('one'); } { one.ONE } -do_execsql_test 5.3 { +do_execsql_test $tn.5.5 { SELECT fts5_test_poslist(ft) FROM ft('one'); } { {0.0.0 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5} @@ -267,10 +302,11 @@ do_execsql_test 5.3 { # reset_db sqlite3_fts5_register_origintext db -do_execsql_test 6.0 { +do_execsql_test $tn.6.0 { CREATE VIRTUAL TABLE ft USING fts5( x, y, tokenize='origintext unicode61', detail=%DETAIL%, tokendata=0 ); + INSERT INTO ft(ft, rank) VALUES('insttoken', $insttoken); INSERT INTO ft VALUES('One Two', 'Three two'); INSERT INTO ft VALUES('three Three', 'one One'); @@ -286,34 +322,35 @@ proc tokens {cmd} { } sqlite3_fts5_create_function db tokens tokens -do_execsql_test 6.1 { +do_execsql_test $tn.6.1 { SELECT rowid, tokens(ft) FROM ft('One'); } {1 one.One 2 one.One} -do_execsql_test 6.2 { +do_execsql_test $tn.6.2 { SELECT rowid, tokens(ft) FROM ft('on*'); } {1 one.One 2 {one one.One}} -do_execsql_test 6.3 { +do_execsql_test $tn.6.3 { SELECT rowid, tokens(ft) FROM ft('Three*'); } {1 three.Three 2 three.Three} fts5_aux_test_functions db -do_catchsql_test 6.4 { +do_catchsql_test $tn.6.4 { SELECT fts5_test_insttoken(ft, -1, 0) FROM ft('one'); } {1 SQLITE_RANGE} -do_catchsql_test 6.5 { +do_catchsql_test $tn.6.5 { SELECT fts5_test_insttoken(ft, 1, 0) FROM ft('one'); } {1 SQLITE_RANGE} -do_catchsql_test 6.6 { +do_catchsql_test $tn.6.6 { CREATE VIRTUAL TABLE ft2 USING fts5(x, tokendata=2); } {1 {malformed tokendata=... directive}} -do_catchsql_test 6.7 { +do_catchsql_test $tn.6.7 { CREATE VIRTUAL TABLE ft2 USING fts5(x, content='', tokendata=11); } {1 {malformed tokendata=... directive}} +} } finish_test diff --git a/ext/fts5/test/fts5origintext3.test b/ext/fts5/test/fts5origintext3.test index a4bca0de9b..351ab1f617 100644 --- a/ext/fts5/test/fts5origintext3.test +++ b/ext/fts5/test/fts5origintext3.test @@ -22,6 +22,11 @@ ifcapable !fts5 { } foreach_detail_mode $testprefix { + foreach {tn insttoken} { + 1 0 + 2 1 + } { + reset_db sqlite3_fts5_register_origintext db @@ -32,21 +37,25 @@ foreach_detail_mode $testprefix { } sqlite3_fts5_create_function db insttoken insttoken - do_execsql_test 1.0 { + do_execsql_test $tn.1.0 { CREATE VIRTUAL TABLE ft USING fts5( x, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL% ); } + + do_execsql_test $tn.1.0.1 { + INSERT INTO ft(ft, rank) VALUES('insttoken', 1); + } - do_execsql_test 1.1 { + do_execsql_test $tn.1.1 { INSERT INTO ft VALUES('Hello world HELLO WORLD hello'); } - do_execsql_test 1.2 { + do_execsql_test $tn.1.2 { SELECT fts5_test_poslist(ft) FROM ft('hello'); } {{0.0.0 0.0.2 0.0.4}} - do_execsql_test 1.3 { + do_execsql_test $tn.1.3 { SELECT insttoken(ft, 0, 0), insttoken(ft, 1, 0), @@ -54,7 +63,15 @@ foreach_detail_mode $testprefix { FROM ft('hello'); } {hello.Hello hello.HELLO hello} - do_execsql_test 1.4 { + do_execsql_test $tn.1.3.1 { + SELECT + insttoken(ft, 0, 0), + insttoken(ft, 1, 0), + insttoken(ft, 2, 0) + FROM ft('hel*'); + } {hello.Hello hello.HELLO hello} + + do_execsql_test $tn.1.4 { SELECT insttoken(ft, 0, 0), insttoken(ft, 1, 0), @@ -62,7 +79,7 @@ foreach_detail_mode $testprefix { FROM ft('hello') ORDER BY rank; } {hello.Hello hello.HELLO hello} - do_execsql_test 1.5 { + do_execsql_test $tn.1.5 { CREATE VIRTUAL TABLE ft2 USING fts5( x, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL% ); @@ -71,11 +88,11 @@ foreach_detail_mode $testprefix { INSERT INTO ft2(rowid, x) VALUES(3, 'THREE one two three THREE'); } - do_execsql_test 1.6 { + do_execsql_test $tn.1.6 { SELECT insttoken(ft2, 0, 0), rowid FROM ft2('three') ORDER BY rank; } {three.THREE 3 three 1 three 2} - do_execsql_test 1.7 { + do_execsql_test $tn.1.7 { INSERT INTO ft2(rowid, x) VALUES(10, 'aaa bbb BBB'); INSERT INTO ft2(rowid, x) VALUES(12, 'bbb bbb bbb'); INSERT INTO ft2(rowid, x) VALUES(13, 'bbb bbb bbb'); @@ -92,16 +109,16 @@ foreach_detail_mode $testprefix { INSERT INTO ft2(rowid, x) VALUES(24, 'aaa bbb BBB'); } - do_execsql_test 1.8 { SELECT rowid FROM ft2('aaa AND bbb'); } {10 24} - do_execsql_test 1.9 { SELECT rowid FROM ft2('bbb AND aaa'); } {10 24} + do_execsql_test $tn.1.8 { SELECT rowid FROM ft2('aaa AND bbb'); } {10 24} + do_execsql_test $tn.1.9 { SELECT rowid FROM ft2('bbb AND aaa'); } {10 24} - do_execsql_test 2.0 { + do_execsql_test $tn.2.0 { CREATE VIRTUAL TABLE ft3 USING fts5( x, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%, prefix=2 ); } - do_execsql_test 2.1 { + do_execsql_test $tn.2.1 { INSERT INTO ft3(rowid, x) VALUES(1, 'one'); INSERT INTO ft3(rowid, x) VALUES(2, 'ONE'); INSERT INTO ft3(rowid, x) VALUES(3, 'ONT'); @@ -109,15 +126,15 @@ foreach_detail_mode $testprefix { INSERT INTO ft3(rowid, x) VALUES(5, 'On'); } - do_execsql_test 2.2 { + do_execsql_test $tn.2.2 { SELECT rowid FROM ft3('on*'); } {1 2 3 4 5} - do_execsql_test 2.3 { + do_execsql_test $tn.2.3 { SELECT rowid, insttoken(ft3, 0, 0) FROM ft3('on*'); } {1 one 2 one.ONE 3 ont.ONT 4 on 5 on.On} - + } } finish_test diff --git a/manifest b/manifest index 2bd0c9cf8d..603ced6491 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\sinto\sthis\sbranch. -D 2024-11-01T19:41:22.452 +C Allow\san\sfts5\stable\sor\squery\sto\sbe\sconfigured\sto\scollect\sxInstToken\sdata\sfor\sany\sprefix\sterms\sas\spart\sof\sthe\sfirst\sparse\sof\sthe\smain\sindex,\sif\sany. +D 2024-11-02T19:10:50.264 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 68362ca12e1a32fe73ece32b59a8e8e02a3983295f2dd82c9c4700507bade02c w autosetup/hwaci-common.tcl +F autosetup/proj.tcl 68362ca12e1a32fe73ece32b59a8e8e02a3983295f2dd82c9c4700507bade02c F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -106,14 +106,14 @@ F ext/fts3/unicode/mkunicode.tcl 63db9624ccf70d4887836c320eda93ab552f21008f3be7e F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15 F ext/fts5/fts5.h 6b4b92df890965567360db5f1ead24fd13a72cb23b95e4ed2ff58d1d89f7aa42 -F ext/fts5/fts5Int.h a282f33a260ddce09dc2b0334d41d83aab0893b2b1656eb83c595a3d0eec2975 +F ext/fts5/fts5Int.h 6abff7dd770dc5969c994c281e6e77fc277ce414d56cc4a62c145cc7036b0b67 F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 -F ext/fts5/fts5_config.c a6633d88596758941c625b526075b85d3d9fd1089d8d9eab5db6e8a71fd347ad +F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c ee650a838fc0591776f7582de578f414959a76cc0118851e4c1f7d13e7365379 -F ext/fts5/fts5_main.c 50eb059e51d730e8e0c77df4e568b018079e112a755c094488b0d5b1aa06afbb +F ext/fts5/fts5_index.c 2cef40d6fdd761229dd4127e0b1ddcb61dfd6a4ac7e73653b7fddbe0075e50be +F ext/fts5/fts5_main.c b2ec6bf97fc378906c0e78c61f10ca8e64f15e03237f2521f7d81736983be378 F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c F ext/fts5/fts5_tcl.c 5b16a249962809b2aaaab964bf58838ea72f30b8b12373cafe612f8cc71e2a40 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -214,9 +214,9 @@ F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618 F ext/fts5/test/fts5optimize.test 264b9101721c17d06d1d174feb743fda3ddc89fad41dee980fef821428258e47 F ext/fts5/test/fts5optimize2.test 795d4ae5f66a7239cf8d5aef4c2ea96aeb8bcd907bd9be0cfe22064fc71a44ed F ext/fts5/test/fts5optimize3.test 1653029284e10e0715246819893ba30565c4ead0d0fc470adae92c353ea857d3 -F ext/fts5/test/fts5origintext.test 63d5b0dc00f0104add8960da0705a70bffd4d86b6feb6ddbb38bff21141d42f0 +F ext/fts5/test/fts5origintext.test 3b73aa036ce5244bb7c5782c5441b979585bdca026accf75d16026a2a8119c09 F ext/fts5/test/fts5origintext2.test f4505ff79bf7369f2b8b10b9cef7476049d844e20b37f29cad3a8b8d5ac6f9ba -F ext/fts5/test/fts5origintext3.test 1f5174a9f4cf42f58f833dbfb314940793ca4723854ec2651e7530ddb35a66a6 +F ext/fts5/test/fts5origintext3.test 4988b6375acc3bbb0515667765f57e389caf449814af9c1095c053f7de2b4223 F ext/fts5/test/fts5origintext4.test 0d3ef0a8038f471dbc83001c34fe5f7ae39b571bfc209670771eb28bc0fc50e8 F ext/fts5/test/fts5origintext5.test ee12b440ec335e5b422d1668aca0051b52ff28b6ee67073e8bbc29f509fd562b F ext/fts5/test/fts5phrase.test bb2554bb61d15f859678c96dc89a7de415cd5fc3b7b54c29b82a0d0ad138091c @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bce9a524de6dda87daa90395cd55713d2d3ccfc090e53a947548e434db5eef5e 2dcc465a7090811ddbc210673f37b4c3a4439c501874abefd403efe1e98f5b17 -R 86617b1841d68e4c10c087c197cdd65c +P 790c56d493c66a2136e24d349d169639809d70bfab6996975a403be568a267a5 +R 71ba4975c4c76073cda6dd2f314d94d1 U dan -Z c01ad82d76d71ffe9e5032c32219c470 +Z 95da39a03d7bb4b9bc58c6dbf7b809e5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 05f1de1961..94e1307210 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -790c56d493c66a2136e24d349d169639809d70bfab6996975a403be568a267a5 +46929ae92b26f02bc70de9931b21a8a7cf9a2453d5fb07f68b712f62e28e9152 From 13f03afd17b9cc367c3b4fb68e04425f5dcd8ab0 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 3 Nov 2024 01:31:34 +0000 Subject: [PATCH 257/522] Fix T.exe typos in main.mk which break installation on platforms where that value is not empty. Also some unrelated doc tweaks. FossilOrigin-Name: ab97ff44e66fd3639adbae4e0cc387fbcd09fbd5cd90ec3df7294c3e7b3a446e --- autosetup/proj.tcl | 10 +++++----- main.mk | 9 +++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 537b281dde..074806ffa8 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -951,7 +951,7 @@ proc proj-dump-defs-json {file args} { # # Comment lines are permitted in the input. # -# For each pair ALIAS and CANONICAL, if --ALIAS is provided but +# For each pair of ALIAS and CANONICAL, if --ALIAS is provided but # --CANONICAL is not, the value of the former is copied to the # latter. If --ALIAS is not provided, this is a no-op. If both have # explicitly been provided a fatal usage error is triggered. @@ -962,10 +962,10 @@ proc proj-dump-defs-json {file args} { # --canonical and a user passes --alias=X, [opt-val canonical] returns # no value. i.e. the script must check both [opt-val alias] and # [opt-val canonical]. The intent here is that this function be -# passed such mappings immediately after [options] is called, -# to carry over any values from hidden aliases into their canonical -# names, so that in the above example [opt-value canonical] will -# return X if --alias=X is passed in. +# passed such mappings immediately after [options] is called, to carry +# over any values from hidden aliases into their canonical names, such +# that [opt-value canonical] will return X if --alias=X is passed to +# configure. proc proj-xfer-options-aliases {mapping} { foreach {hidden - canonical} [proj-strip-hash-comments_ $mapping] { if {[proj-opt-was-provided $hidden]} { diff --git a/main.mk b/main.mk index 2146ba49ef..562dfaa77b 100644 --- a/main.mk +++ b/main.mk @@ -142,6 +142,7 @@ libdir ?= $(exec_prefix)/lib # runstatedir ?= /run # infodir ?= $(datadir)/info # libexec ?= $(exec_prefix)/libexec +### end of autotools-compatible install dir vars # @@ -1835,8 +1836,8 @@ sqlite3$(T.exe)-1: sqlite3$(T.exe)-0 sqlite3$(T.exe)-: sqlite3$(T.exe) all: sqlite3$(T.exe)-$(HAVE_WASI_SDK) -install-shell-0: sqlite3$(TEXT) $(install-dir.bin) - $(INSTALL) -s sqlite3$(TEXT) "$(install-dir.bin)" +install-shell-0: sqlite3$(T.exe) $(install-dir.bin) + $(INSTALL) -s sqlite3$(T.exe) "$(install-dir.bin)" install-shell-1 install-shell-: install: install-shell-$(HAVE_WASI_SDK) @@ -1844,7 +1845,7 @@ sqldiff$(T.exe): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o $(T.link) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) install-diff: sqldiff$(T.exe) $(install-dir.bin) - $(INSTALL) -s sqldiff$(TEXT) "$(install-dir.bin)" + $(INSTALL) -s sqldiff$(T.exe) "$(install-dir.bin)" #install: install-diff dbhash$(T.exe): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h @@ -1867,7 +1868,7 @@ sqlite3_rsync$(T.exe): $(RSYNC_SRC) xbin: sqlite3_rsync$(T.exe) install-rsync: sqlite3_rsync$(T.exe) $(install-dir.bin) - $(INSTALL) sqlite3_rsync$(TEXT) "$(install-dir.bin)" + $(INSTALL) sqlite3_rsync$(T.exe) "$(install-dir.bin)" #install: install-rsync install-man1: $(install-dir.man1) diff --git a/manifest b/manifest index b0e73839dd..beafc464e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sautotools-compatible\soverridable\sdir\sname\svars\sfor\sthe\svarious\sinstallation\stargets,\scalculated\sat\smake-time\sinstead\sof\sexported\sat\sconfigure-time\sfor\sreasons\sexplained\sat\slength\sin\sthe\saccompanying\scomments. -D 2024-11-02T03:34:04.784 +C Fix\sT.exe\stypos\sin\smain.mk\swhich\sbreak\sinstallation\son\splatforms\swhere\sthat\svalue\sis\snot\sempty.\sAlso\ssome\sunrelated\sdoc\stweaks. +D 2024-11-03T01:31:34.901 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 68362ca12e1a32fe73ece32b59a8e8e02a3983295f2dd82c9c4700507bade02c +F autosetup/proj.tcl d17e06959b233466dc4b02f811ec8b8d3689017287e1cc2f10fe6c2c87f79f86 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 01f83a096392922826bca5dda938235f2c2f94988c1f467fe90a8e31aaeed912 +F main.mk eaa1afc4e306e409b95edf9c357a56f066c40605fc1d6bcaa293a2ed5b928384 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2dcc465a7090811ddbc210673f37b4c3a4439c501874abefd403efe1e98f5b17 -R 565488b6d72da8ea787b0c37e1464eb8 +P 24aba7ee58f3048d70ff0c2b2cda26bc04bfb46b3055d25d62ab5ff97b106be2 +R 13337065c17d9699dc617729b132177a U stephan -Z 2d29757f9585ee6ad461db23d83778f6 +Z b1339e6cde9ae41997d61a7143086b2c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ade193ca47..7b7f2561f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24aba7ee58f3048d70ff0c2b2cda26bc04bfb46b3055d25d62ab5ff97b106be2 +ab97ff44e66fd3639adbae4e0cc387fbcd09fbd5cd90ec3df7294c3e7b3a446e From e595a8385608f3bcc2826a3ae460a08dcaddf187 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 3 Nov 2024 05:33:45 +0000 Subject: [PATCH 258/522] Fix another T.exe typo and remove an outdated TODO. FossilOrigin-Name: 02208e6bfa7b791b958d45ad25eaac3a16d3e9f6ab203b9fc760c67785525395 --- main.mk | 21 +++++---------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/main.mk b/main.mk index 562dfaa77b..74617e3a8f 100644 --- a/main.mk +++ b/main.mk @@ -1724,9 +1724,9 @@ rollback-test$(T.exe): $(TOP)/tool/rollback-test.c sqlite3.o $(T.link) -o $@ $(TOP)/tool/rollback-test.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: rollback-test$(T.exe) -atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.o +atrc$(T.exe): $(TOP)/test/atrc.c sqlite3.o $(T.link) -o $@ $(TOP)/test/atrc.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: atrc$(TEXX) +xbin: atrc$(T.exe) LogEst$(T.exe): $(TOP)/tool/logest.c sqlite3.h $(T.link) -I. -o $@ $(TOP)/tool/logest.c @@ -1787,20 +1787,9 @@ tool-zip: testfixture$(T.exe) sqlite3$(T.exe) sqldiff$(T.exe) \ clean-tool-zip: rm -f sqlite-tools-*.zip clean: clean-tool-zip -#XX# TODO: adapt the autoconf amalgamation for autosetup -#XX# -#XX## Build the amalgamation-autoconf package. The amalamgation-tarball target builds -#XX## a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. -#XX## The snapshot-tarball target builds a tarball named by the SHA1 hash -#XX## -#XX#amalgamation-tarball: sqlite3.c sqlite3rc.h -#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal -#XX# -#XX#snapshot-tarball: sqlite3.c sqlite3rc.h -#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot -#XX# - -# The next two rules are used to support the "threadtest" target. Building + +# +# The next few rules are used to support the "threadtest" target. Building # threadtest runs a few thread-safety tests that are implemented in C. This # target is invoked by the releasetest.tcl script. # diff --git a/manifest b/manifest index beafc464e0..2b0000af9d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sT.exe\stypos\sin\smain.mk\swhich\sbreak\sinstallation\son\splatforms\swhere\sthat\svalue\sis\snot\sempty.\sAlso\ssome\sunrelated\sdoc\stweaks. -D 2024-11-03T01:31:34.901 +C Fix\sanother\sT.exe\stypo\sand\sremove\san\soutdated\sTODO. +D 2024-11-03T05:33:45.188 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk eaa1afc4e306e409b95edf9c357a56f066c40605fc1d6bcaa293a2ed5b928384 +F main.mk f8b82b2422ad161e2f8b463a57db1fd0f4419b82834d722a1ae956945aaa2eb5 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 24aba7ee58f3048d70ff0c2b2cda26bc04bfb46b3055d25d62ab5ff97b106be2 -R 13337065c17d9699dc617729b132177a +P ab97ff44e66fd3639adbae4e0cc387fbcd09fbd5cd90ec3df7294c3e7b3a446e +R 854321bdbff572ab4026aca779bc79d2 U stephan -Z b1339e6cde9ae41997d61a7143086b2c +Z 2c36c6fdbb9bb6f11a927793a835ae9d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7b7f2561f2..953a99eafd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab97ff44e66fd3639adbae4e0cc387fbcd09fbd5cd90ec3df7294c3e7b3a446e +02208e6bfa7b791b958d45ad25eaac3a16d3e9f6ab203b9fc760c67785525395 From 18d21497b28820c5e71ef330dc128e8dc79e3e9d Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 3 Nov 2024 07:45:56 +0000 Subject: [PATCH 259/522] Minor doc updates. Remove two outdated todos. FossilOrigin-Name: ad19237845b7791dd90fa4b3586f39f6ab700462e826baf53d4cde7f7fa06449 --- autosetup/proj.tcl | 20 ++++++++------------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 074806ffa8..3a831a269b 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -630,9 +630,6 @@ proc proj-looks-like-windows {{key host}} { # 'build' (==the being-built-on platform) define value and returns if # if that value seems to indicate that it represents a Mac platform, # else returns 0. -# -# TODO: have someone verify whether this is correct for the -# non-Linux/BSD platforms. proc proj-looks-like-mac {{key host}} { switch -glob -- [get-define $key] { *apple* { @@ -669,9 +666,6 @@ proc proj-exe-extension {} { # # Trivia: for .dylib files, the linker needs the -dynamiclib flag # instead of -shared. -# -# TODO: have someone verify whether this is correct for the -# non-Linux/BSD platforms. proc proj-dll-extension {} { proc inner {key} { switch -glob -- [get-define $key] { @@ -842,7 +836,9 @@ proc proj-defs-type_ {name spec} { ######################################################################## # Internal helper for proj-defs-format_: returns a JSON-ish quoted -# form of the given (JSON) string-type values. +# form of the given string-type values. It only performs the most +# basic of escaping. The input must not contain any control +# characters. proc proj-quote-str_ {value} { return \"[string map [list \\ \\\\ \" \\\"] $value]\" } @@ -939,8 +935,8 @@ proc proj-dump-defs-json {file args} { } ######################################################################## -# Expects a list of pairs of configure flags with the given names to -# have been registered with autosetup, in this form: +# Expects a list of pairs of configure flags which have been +# registered with autosetup, in this form: # # { alias1 => canonical1 # aliasN => canonicalN ... } @@ -993,11 +989,11 @@ proc proj-xfer-options-aliases {mapping} { # # Sidebar: if we do this before the cc package is installed, it gets # reverted by that package. Ergo, the cc package init will tell the -# user "Build C compiler...cc" shortly before we tell them: +# user "Build C compiler...cc" shortly before we tell them otherwise. proc proj-redefine-cc-for-build {} { if {![proj-is-cross-compiling] - && "nope" eq [get-env CC_FOR_BUILD "nope"] - && [get-define CC] ne [get-define CC_FOR_BUILD]} { + && [get-define CC] ne [get-define CC_FOR_BUILD] + && "nope" eq [get-env CC_FOR_BUILD "nope"]} { user-notice "Re-defining CC_FOR_BUILD to CC=[get-define CC]. To avoid this, explicitly pass CC_FOR_BUILD=..." define CC_FOR_BUILD [get-define CC] } diff --git a/manifest b/manifest index 2b0000af9d..6ae9389c14 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sT.exe\stypo\sand\sremove\san\soutdated\sTODO. -D 2024-11-03T05:33:45.188 +C Minor\sdoc\supdates.\sRemove\stwo\soutdated\stodos. +D 2024-11-03T07:45:56.350 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl d17e06959b233466dc4b02f811ec8b8d3689017287e1cc2f10fe6c2c87f79f86 +F autosetup/proj.tcl cb7983c8eb47c9518c3039556e655e5237952d9c068fe36c624e9f6a73cd1098 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ab97ff44e66fd3639adbae4e0cc387fbcd09fbd5cd90ec3df7294c3e7b3a446e -R 854321bdbff572ab4026aca779bc79d2 +P 02208e6bfa7b791b958d45ad25eaac3a16d3e9f6ab203b9fc760c67785525395 +R 129876c7397cde2ce7d1cd13dddc82e3 U stephan -Z 2c36c6fdbb9bb6f11a927793a835ae9d +Z 719bb9a6901f4e1cd5a5816d1e6f64dc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 953a99eafd..1c517a5a63 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02208e6bfa7b791b958d45ad25eaac3a16d3e9f6ab203b9fc760c67785525395 +ad19237845b7791dd90fa4b3586f39f6ab700462e826baf53d4cde7f7fa06449 From c6cdee83036864627e222f2bee2d0f00187efd76 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 3 Nov 2024 18:30:45 +0000 Subject: [PATCH 260/522] Workaround for a compiler-specific jimsh compilation error reported in [forum:18e420d0b1404d63|forum post 18e420d0]. Reported upstream as [https://github.com/msteveb/jimtcl/issues/322|ticket #322]. FossilOrigin-Name: 29b94495956802d0eedcd669e45308c56278e43aab62bd7c3bb7153b47c9d4c0 --- autosetup/jimsh0.c | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index fb4e8b806d..c6d5eb0d4e 100644 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -19286,7 +19286,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a JIM_DEF_SUBCMD("trim", "string ?trimchars?", 1, 2), JIM_DEF_SUBCMD("trimleft", "string ?trimchars?", 1, 2), JIM_DEF_SUBCMD("trimright", "string ?trimchars?", 1, 2), - { } + JIM_DEF_SUBCMD(0,0,0,0) }; const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, cmds, argc, argv); if (!ct) { @@ -20179,7 +20179,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("for", "vars dictionary script", 3, 3), JIM_DEF_SUBCMD("replace", "dictionary ?key value ...?", 1, -1), JIM_DEF_SUBCMD("update", "varName ?arg ...? script", 2, -1), - { } + JIM_DEF_SUBCMD(0,0,0,0) }; const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, cmds, argc, argv); if (!ct) { @@ -20388,7 +20388,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("statics", "procname", 1, 1), JIM_DEF_SUBCMD("vars", "?pattern?", 0, 1), JIM_DEF_SUBCMD("version", NULL, 0, 0), - { } + JIM_DEF_SUBCMD(0,0,0,0) }; const jim_subcmd_type *ct; #ifdef jim_ext_namespace diff --git a/manifest b/manifest index 6ae9389c14..e92afdde31 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sdoc\supdates.\sRemove\stwo\soutdated\stodos. -D 2024-11-03T07:45:56.350 +C Workaround\sfor\sa\scompiler-specific\sjimsh\scompilation\serror\sreported\sin\s[forum:18e420d0b1404d63|forum\spost\s18e420d0].\sReported\supstream\sas\s[https://github.com/msteveb/jimtcl/issues/322|ticket\s#322]. +D 2024-11-03T18:30:45.368 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 +F autosetup/jimsh0.c 9860c2bd7825cb9d21616237e59a2dfa29acbd98c00da5f842e5abe222e69288 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/proj.tcl cb7983c8eb47c9518c3039556e655e5237952d9c068fe36c624e9f6a73cd1098 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 02208e6bfa7b791b958d45ad25eaac3a16d3e9f6ab203b9fc760c67785525395 -R 129876c7397cde2ce7d1cd13dddc82e3 +P ad19237845b7791dd90fa4b3586f39f6ab700462e826baf53d4cde7f7fa06449 +R fbc9af98c69bf3f4eab9e4f1eaa6856c U stephan -Z 719bb9a6901f4e1cd5a5816d1e6f64dc +Z cd366cd0592f2836fdc5215675eb9eb6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1c517a5a63..c52d720347 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad19237845b7791dd90fa4b3586f39f6ab700462e826baf53d4cde7f7fa06449 +29b94495956802d0eedcd669e45308c56278e43aab62bd7c3bb7153b47c9d4c0 From a9b00b0fb7d075e788ccf4e0a90c63e13b32bd2f Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 3 Nov 2024 20:15:38 +0000 Subject: [PATCH 261/522] Fix a CFLAGS.jimsh typo in Makefile.in. Change default jimsh flags to include -O1, which slows down its build but speeds up its runtime considerably. FossilOrigin-Name: a912c169152623f261fb5469a49f00aca1d8a273d8f7187744de12a26aede7cf --- Makefile.in | 4 ++-- auto.def | 5 ++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Makefile.in b/Makefile.in index cb25a002a8..6995ff945e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -183,11 +183,11 @@ T.cc.sqlite += -I$(prefix)/include #XX#T.cc += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ # -# $(JIMSH) and $(CFLAGS.JIMSH) are documented in main.mk. $(JIMSH) +# $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH) # must start with a path component so that it can be invoked as a # shell command. # -CFLAGS.JIMSH = @CFLAGS_JIMSH@ +CFLAGS.jimsh = @CFLAGS_JIMSH@ JIMSH = ./jimsh$(TEXE) # diff --git a/auto.def b/auto.def index 09024a207a..5dab1f8555 100644 --- a/auto.def +++ b/auto.def @@ -664,7 +664,10 @@ sqlite-check-tcl # jimsh. proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " - define CFLAGS_JIMSH {} + define CFLAGS_JIMSH {-O1} ; # Re. -O# flag: jimsh runs much faster when built + # with with -O2 but it takes ages to compile. -O1 + # provides a fair compromise between build and run + # speeds. set cgtcl [opt-val with-tclsh jimsh] set flagsToRestore {CC CFLAGS CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} define-push $flagsToRestore { diff --git a/manifest b/manifest index 36f3ef8c3b..2c2ee4fbb4 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C If\sany\sautotools-conventional\sdir\snames\sare\sexplicitly\soverridden\svia\s./configure\s--dirname=X\sthen\sexport\sthose\snames\sas-is\sto\sthe\smakefile,\sotherwise\sderive\sthem\sfrom\s$prefix.\sThis\sis,\sat\sleast\sin\spart,\sa\scompromise\sto\sprovide\spackage\smaintainers\sa\sway\sto\sspecify\sa\slibdir\swhich\swill\sbe\sincorporated\sinto\sthe\s-rpath\slink\sflag\s(which\swe\scan\sonly\sdetermine\sat\sconfigure-time). -D 2024-11-03T19:42:41.677 +C Fix\sa\sCFLAGS.jimsh\stypo\sin\sMakefile.in.\sChange\sdefault\sjimsh\sflags\sto\sinclude\s-O1,\swhich\sslows\sdown\sits\sbuild\sbut\sspeeds\sup\sits\sruntime\sconsiderably. +D 2024-11-03T20:15:38.645 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 6c595d1a09516770375dd466a91ba2f88ff8d6c1b12c2e0eb2b0ef645b6ed94f +F Makefile.in b490c1230b030da8d597688c09ec395340eb834cc858437d5c3a3ce45e8aaf3e F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d47bb3030f1b77a3131a4192fe17fb50da13bb6d9405306368ae9c06bca9455c +F auto.def b69dd467437cf572cb084cd9e515b30e35cfc866f80d5dd778cbed409aaf71e5 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 29b94495956802d0eedcd669e45308c56278e43aab62bd7c3bb7153b47c9d4c0 cc259bf5f176bf89b6effedfc716d19d2437fc761c20870d1c69205d4bcee12b -R 79d48715ac1148c0c1fcdae652e09505 +P 832abe8a8a347718e47f73a1f9be1fb084a1c28cac6b1c70f6c9a9cabeb0fb53 +R 5e0f5bfa6d8e8c09888bb4531f17a3c6 U stephan -Z 9bbd3b23f124df01ef5b1e7cf0c3306e +Z 192b376f24b23f1b797dc7a2c01813b1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 052272ac5c..26c6506ad0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -832abe8a8a347718e47f73a1f9be1fb084a1c28cac6b1c70f6c9a9cabeb0fb53 +a912c169152623f261fb5469a49f00aca1d8a273d8f7187744de12a26aede7cf From 88349483efb8538785c6138a3e1dbbe4b9ffcf49 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 3 Nov 2024 21:32:24 +0000 Subject: [PATCH 262/522] Move the .default-CFLAGS handling into a utility function, rename the corresponding file to .env-VAR, and apply that lookup to a couple more places. FossilOrigin-Name: f01b61f21d105706e78eb1e3e7971e9ccb7a68250f8cda96ce285f0fd6b2f7f2 --- auto.def | 21 +++++++-------------- autosetup/proj.tcl | 26 ++++++++++++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/auto.def b/auto.def index 5dab1f8555..a11560fb56 100644 --- a/auto.def +++ b/auto.def @@ -313,13 +313,8 @@ if {"" eq [proj-bin-define install]} { # compiling binaries for the target system (CC a.k.a. $(T.cc)). # Normally they're the same, but they will differ when # cross-compiling. -set defaultCFlags {-g -O2} -if {[file exists .default-CFLAGS]} { - set defaultCFlags [proj-file-content -trim .default-CFLAGS] -} -define CFLAGS [get-env CFLAGS $defaultCFlags] -unset defaultCFlags -define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] +define CFLAGS [proj-get-env CFLAGS {-g -O2}] +define BUILD_CFLAGS [proj-get-env BUILD_CFLAGS {-g}] ######################################################################## # Handle --with-wasi-sdk=DIR @@ -652,8 +647,8 @@ sqlite-check-tcl # in-tree (it's part of autosetup) unless --with-tclsh=X is used, in # which case prefix X. # -# Returns the name of the TCL it selects. Fails fatally if it cannot -# detect a TCL appropriate for code generation. +# Returns the human-readable name of the TCL it selects. Fails fatally +# if it cannot detect a TCL appropriate for code generation. # # Defines: # @@ -661,13 +656,11 @@ sqlite-check-tcl # to an unexpanded makefile var name. # # - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible -# jimsh. +# jimsh. The defaults may be pass on to configure as +# CFLAGS_JIMSH=... proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " - define CFLAGS_JIMSH {-O1} ; # Re. -O# flag: jimsh runs much faster when built - # with with -O2 but it takes ages to compile. -O1 - # provides a fair compromise between build and run - # speeds. + define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}] set cgtcl [opt-val with-tclsh jimsh] set flagsToRestore {CC CFLAGS CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} define-push $flagsToRestore { diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index d386d4d499..a1e77a482a 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1090,3 +1090,29 @@ proc proj-redirect-autoconf-dir-vars {} { #puts "$x $makeVar = [get-define $makeVar]" } } + +######################################################################## +# If a file named .env-$flag exists, this function returns a +# trimmed copy of its contents, else it returns $dflt. The intended +# usage is that things like developer-specific CFLAGS preferences can +# be stored in .env-CFLAGS. +proc proj-default-flags {flag {dflt ""}} { + set fn ".env-${flag}" + if {[file readable $fn]} { + return [proj-file-content -trim $fn] + } + return $dflt +} + +######################################################################## +# Extracts the value of "environment" variable $var from the first of +# the following places where it's defined: +# +# - Passed to configure as $var=... +# - A file named .env-$var (see [proj-default-flags]) +# - Exists as an environment variable +# +# If none of those are set, $dflt is returned. +proc proj-get-env {var {dflt ""}} { + return [get-env $var [proj-default-flags $var $dflt]] +} diff --git a/manifest b/manifest index 2c2ee4fbb4..7d5859740b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sCFLAGS.jimsh\stypo\sin\sMakefile.in.\sChange\sdefault\sjimsh\sflags\sto\sinclude\s-O1,\swhich\sslows\sdown\sits\sbuild\sbut\sspeeds\sup\sits\sruntime\sconsiderably. -D 2024-11-03T20:15:38.645 +C Move\sthe\s.default-CFLAGS\shandling\sinto\sa\sutility\sfunction,\srename\sthe\scorresponding\sfile\sto\s.env-VAR,\sand\sapply\sthat\slookup\sto\sa\scouple\smore\splaces. +D 2024-11-03T21:32:24.526 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def b69dd467437cf572cb084cd9e515b30e35cfc866f80d5dd778cbed409aaf71e5 +F auto.def 19b5df445fab703133f430b1169968d702cf421d752199ee77d11626062f7755 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 9860c2bd7825cb9d21616237e59a2dfa29acbd98c00da5f842e5abe222e69288 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl d0008015b481ed5a4e952b72e703a905ba232f979a3740614d2ea716a19f6718 +F autosetup/proj.tcl 8f81f61b427b91b30983f0b2a9c169b453099ed4a209f526d0843df5ad1610e9 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 832abe8a8a347718e47f73a1f9be1fb084a1c28cac6b1c70f6c9a9cabeb0fb53 -R 5e0f5bfa6d8e8c09888bb4531f17a3c6 +P a912c169152623f261fb5469a49f00aca1d8a273d8f7187744de12a26aede7cf +R a550a6f064acac325701eee77b42038f U stephan -Z 192b376f24b23f1b797dc7a2c01813b1 +Z 180f9d1639b03db412606e42d092a67a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 26c6506ad0..637b15dc31 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a912c169152623f261fb5469a49f00aca1d8a273d8f7187744de12a26aede7cf +f01b61f21d105706e78eb1e3e7971e9ccb7a68250f8cda96ce285f0fd6b2f7f2 From eb837474411b24494449eac43b696beab5beab5e Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 4 Nov 2024 03:43:07 +0000 Subject: [PATCH 263/522] Minor doc correction and proj.tcl-internal API renaming. FossilOrigin-Name: c8b24c590ef318e687ab76cd1a5d6c8fed84389e3ebbe544aa8b15759324958a --- autosetup/proj.tcl | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index a1e77a482a..f82dcc3581 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1096,7 +1096,7 @@ proc proj-redirect-autoconf-dir-vars {} { # trimmed copy of its contents, else it returns $dflt. The intended # usage is that things like developer-specific CFLAGS preferences can # be stored in .env-CFLAGS. -proc proj-default-flags {flag {dflt ""}} { +proc proj-env-file {flag {dflt ""}} { set fn ".env-${flag}" if {[file readable $fn]} { return [proj-file-content -trim $fn] @@ -1109,10 +1109,10 @@ proc proj-default-flags {flag {dflt ""}} { # the following places where it's defined: # # - Passed to configure as $var=... -# - A file named .env-$var (see [proj-default-flags]) # - Exists as an environment variable +# - A file named .env-$var (see [proj-env-file]) # # If none of those are set, $dflt is returned. proc proj-get-env {var {dflt ""}} { - return [get-env $var [proj-default-flags $var $dflt]] + return [get-env $var [proj-env-file $var $dflt]] } diff --git a/manifest b/manifest index 7d5859740b..ef4042732b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sthe\s.default-CFLAGS\shandling\sinto\sa\sutility\sfunction,\srename\sthe\scorresponding\sfile\sto\s.env-VAR,\sand\sapply\sthat\slookup\sto\sa\scouple\smore\splaces. -D 2024-11-03T21:32:24.526 +C Minor\sdoc\scorrection\sand\sproj.tcl-internal\sAPI\srenaming. +D 2024-11-04T03:43:07.489 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bd F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c 9860c2bd7825cb9d21616237e59a2dfa29acbd98c00da5f842e5abe222e69288 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 8f81f61b427b91b30983f0b2a9c169b453099ed4a209f526d0843df5ad1610e9 +F autosetup/proj.tcl ece0c56651493b63770f3553c04897e793eea0a63c6204563281796ed1204fb5 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a912c169152623f261fb5469a49f00aca1d8a273d8f7187744de12a26aede7cf -R a550a6f064acac325701eee77b42038f +P f01b61f21d105706e78eb1e3e7971e9ccb7a68250f8cda96ce285f0fd6b2f7f2 +R 74b038e8c09c34a894181c49cfb9529f U stephan -Z 180f9d1639b03db412606e42d092a67a +Z 17f517ee0d6e61152da25eb3ad04eb37 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 637b15dc31..728287e9cb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f01b61f21d105706e78eb1e3e7971e9ccb7a68250f8cda96ce285f0fd6b2f7f2 +c8b24c590ef318e687ab76cd1a5d6c8fed84389e3ebbe544aa8b15759324958a From 05e279fa463c9a182fdbfb44f15740eed97ae732 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 4 Nov 2024 04:12:02 +0000 Subject: [PATCH 264/522] Latest upstream jimsh0.c, which accounts for the problem patched locally by [29b944959568]. FossilOrigin-Name: c7a5b7d2dbfd5c44980f7e9d7efc1e8c7882f192b14f534537745d0a0125909f --- autosetup/jimsh0.c | 16 +++++++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index c6d5eb0d4e..84db85a207 100644 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -1293,8 +1293,14 @@ int Jim_initjimshInit(Jim_Interp *interp) " if {[string match \"*/*\" $jim::argv0]} {\n" " set jim::exe [file join [pwd] $jim::argv0]\n" " } else {\n" -" foreach path [split [env PATH \"\"] $tcl_platform(pathSeparator)] {\n" -" set exec [file join [pwd] [string map {\\\\ /} $path] $jim::argv0]\n" +" set jim::argv0 [file tail $jim::argv0]\n" +" set path [split [env PATH \"\"] $tcl_platform(pathSeparator)]\n" +" if {$tcl_platform(platform) eq \"windows\"} {\n" +"\n" +" set path [lmap p [list \"\" {*}$path] { string map {\\\\ /} $p }]\n" +" }\n" +" foreach p $path {\n" +" set exec [file join [pwd] $p $jim::argv0]\n" " if {[file executable $exec]} {\n" " set jim::exe $exec\n" " break\n" @@ -19286,7 +19292,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a JIM_DEF_SUBCMD("trim", "string ?trimchars?", 1, 2), JIM_DEF_SUBCMD("trimleft", "string ?trimchars?", 1, 2), JIM_DEF_SUBCMD("trimright", "string ?trimchars?", 1, 2), - JIM_DEF_SUBCMD(0,0,0,0) + { NULL } }; const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, cmds, argc, argv); if (!ct) { @@ -20179,7 +20185,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("for", "vars dictionary script", 3, 3), JIM_DEF_SUBCMD("replace", "dictionary ?key value ...?", 1, -1), JIM_DEF_SUBCMD("update", "varName ?arg ...? script", 2, -1), - JIM_DEF_SUBCMD(0,0,0,0) + { NULL } }; const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, cmds, argc, argv); if (!ct) { @@ -20388,7 +20394,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("statics", "procname", 1, 1), JIM_DEF_SUBCMD("vars", "?pattern?", 0, 1), JIM_DEF_SUBCMD("version", NULL, 0, 0), - JIM_DEF_SUBCMD(0,0,0,0) + { NULL } }; const jim_subcmd_type *ct; #ifdef jim_ext_namespace diff --git a/manifest b/manifest index ef4042732b..f45a9e75a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sdoc\scorrection\sand\sproj.tcl-internal\sAPI\srenaming. -D 2024-11-04T03:43:07.489 +C Latest\supstream\sjimsh0.c,\swhich\saccounts\sfor\sthe\sproblem\spatched\slocally\sby\s[29b944959568]. +D 2024-11-04T04:12:02.279 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -47,7 +47,7 @@ F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795f F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/jimsh0.c 9860c2bd7825cb9d21616237e59a2dfa29acbd98c00da5f842e5abe222e69288 +F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/proj.tcl ece0c56651493b63770f3553c04897e793eea0a63c6204563281796ed1204fb5 F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f01b61f21d105706e78eb1e3e7971e9ccb7a68250f8cda96ce285f0fd6b2f7f2 -R 74b038e8c09c34a894181c49cfb9529f +P c8b24c590ef318e687ab76cd1a5d6c8fed84389e3ebbe544aa8b15759324958a +R fca10953222d79165bdf7ba3f1399e32 U stephan -Z 17f517ee0d6e61152da25eb3ad04eb37 +Z 8016e4a01b178558212e609b0d7b0b87 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 728287e9cb..e97925e9a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8b24c590ef318e687ab76cd1a5d6c8fed84389e3ebbe544aa8b15759324958a +c7a5b7d2dbfd5c44980f7e9d7efc1e8c7882f192b14f534537745d0a0125909f From 266685c7e78435c3d2137745f233c46cae4e73e2 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 4 Nov 2024 05:27:21 +0000 Subject: [PATCH 265/522] Latest upstream autosetup to get handling of (==ignoring) autotools' x-includes and x-libraries flags and stop leakage of some autosetup-init-level vars into auto.def's global scope. FossilOrigin-Name: 307349bf91df2935efeaeb5617f43c2223aa7523e55034fb532cc4386a29d74c --- autosetup/autosetup-find-tclsh | 6 +- autosetup/cc.tcl | 124 ++++++++++++------------ autosetup/system.tcl | 170 +++++++++++++++++---------------- manifest | 16 ++-- manifest.uuid | 2 +- 5 files changed, 164 insertions(+), 154 deletions(-) diff --git a/autosetup/autosetup-find-tclsh b/autosetup/autosetup-find-tclsh index 3b661d26ae..2b2006241c 100755 --- a/autosetup/autosetup-find-tclsh +++ b/autosetup/autosetup-find-tclsh @@ -5,12 +5,12 @@ # If an argument is given, use that as the test instead of autosetup-test-tclsh d="`dirname "$0"`" for tclsh in ./jimsh0 $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; do - { $tclsh "$d/${1-autosetup-test-tclsh}"; } 2>/dev/null && exit 0 + { $tclsh "$d/${1-autosetup-test-tclsh}"; } 2>/dev/null && exit 0 done echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" for cc in ${CC_FOR_BUILD:-cc} gcc; do - { $cc -o jimsh0 "$d/jimsh0.c"; } >/dev/null 2>&1 || continue - ./jimsh0 "$d/${1-autosetup-test-tclsh}" && exit 0 + { $cc -o jimsh0 "$d/jimsh0.c"; } >/dev/null 2>&1 || continue + ./jimsh0 "$d/${1-autosetup-test-tclsh}" && exit 0 done echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." echo false diff --git a/autosetup/cc.tcl b/autosetup/cc.tcl index 5e724d9b78..05c1b1cf40 100644 --- a/autosetup/cc.tcl +++ b/autosetup/cc.tcl @@ -677,80 +677,82 @@ proc calc-define-output-type {name spec} { return "" } -# Initialise some values from the environment or commandline or default settings -foreach i {LDFLAGS LIBS CPPFLAGS LINKFLAGS CFLAGS} { - lassign $i var default - define $var [get-env $var $default] -} +proc cc-init {} { + global autosetup -if {[env-is-set CC]} { - # Set by the user, so don't try anything else - set try [list [get-env CC ""]] -} else { - # Try some reasonable options - set try [list [get-define cross]cc [get-define cross]gcc] -} -define CC [find-an-executable {*}$try] -if {[get-define CC] eq ""} { - user-error "Could not find a C compiler. Tried: [join $try ", "]" -} + # Initialise some values from the environment or commandline or default settings + foreach i {LDFLAGS LIBS CPPFLAGS LINKFLAGS CFLAGS} { + lassign $i var default + define $var [get-env $var $default] + } -define CPP [get-env CPP "[get-define CC] -E"] + if {[env-is-set CC]} { + # Set by the user, so don't try anything else + set try [list [get-env CC ""]] + } else { + # Try some reasonable options + set try [list [get-define cross]cc [get-define cross]gcc] + } + define CC [find-an-executable {*}$try] + if {[get-define CC] eq ""} { + user-error "Could not find a C compiler. Tried: [join $try ", "]" + } -# XXX: Could avoid looking for a C++ compiler until requested -# If CXX isn't found, it is set to the empty string. -if {[env-is-set CXX]} { - define CXX [find-an-executable -required [get-env CXX ""]] -} else { - define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++] -} + define CPP [get-env CPP "[get-define CC] -E"] -# CXXFLAGS default to CFLAGS if not specified -define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]] + # XXX: Could avoid looking for a C++ compiler until requested + # If CXX isn't found, it is set to the empty string. + if {[env-is-set CXX]} { + define CXX [find-an-executable -required [get-env CXX ""]] + } else { + define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++] + } -# May need a CC_FOR_BUILD, so look for one -define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false] + # CXXFLAGS default to CFLAGS if not specified + define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]] -if {[get-define CC] eq ""} { - user-error "Could not find a C compiler. Tried: [join $try ", "]" -} + # May need a CC_FOR_BUILD, so look for one + define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false] -# These start empty and never come from the user or environment -define AS_CFLAGS "" -define AS_CPPFLAGS "" -define AS_CXXFLAGS "" + # These start empty and never come from the user or environment + define AS_CFLAGS "" + define AS_CPPFLAGS "" + define AS_CXXFLAGS "" -define CCACHE [find-an-executable [get-env CCACHE ccache]] + define CCACHE [find-an-executable [get-env CCACHE ccache]] -# If any of these are set in the environment, propagate them to the AUTOREMAKE commandline -foreach i {CC CXX CCACHE CPP CFLAGS CXXFLAGS CXXFLAGS LDFLAGS LIBS CROSS CPPFLAGS LINKFLAGS CC_FOR_BUILD LD} { - if {[env-is-set $i]} { - # Note: If the variable is set on the command line, get-env will return that value - # so the command line will continue to override the environment - define-append-argv AUTOREMAKE $i=[get-env $i ""] + # If any of these are set in the environment, propagate them to the AUTOREMAKE commandline + foreach i {CC CXX CCACHE CPP CFLAGS CXXFLAGS CXXFLAGS LDFLAGS LIBS CROSS CPPFLAGS LINKFLAGS CC_FOR_BUILD LD} { + if {[env-is-set $i]} { + # Note: If the variable is set on the command line, get-env will return that value + # so the command line will continue to override the environment + define-append-argv AUTOREMAKE $i=[get-env $i ""] + } } -} -# Initial cctest settings -cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {} -nooutput 0} -set autosetup(cc-include-deps) {} + # Initial cctest settings + cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {} -nooutput 0} + set autosetup(cc-include-deps) {} -msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS] [get-define CPPFLAGS]" -if {[get-define CXX] ne "false"} { - msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS] [get-define CPPFLAGS]" -} -msg-result "Build C compiler...[get-define CC_FOR_BUILD]" - -# On Darwin, we prefer to use -g0 to avoid creating .dSYM directories -# but some compilers may not support it, so test here. -switch -glob -- [get-define host] { - *-*-darwin* { - if {[cctest -cflags {-g0}]} { - define cc-default-debug -g0 + msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS] [get-define CPPFLAGS]" + if {[get-define CXX] ne "false"} { + msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS] [get-define CPPFLAGS]" + } + msg-result "Build C compiler...[get-define CC_FOR_BUILD]" + + # On Darwin, we prefer to use -g0 to avoid creating .dSYM directories + # but some compilers may not support it, so test here. + switch -glob -- [get-define host] { + *-*-darwin* { + if {[cctest -cflags {-g0}]} { + define cc-default-debug -g0 + } } } -} -if {![cc-check-includes stdlib.h]} { - user-error "Compiler does not work. See config.log" + if {![cc-check-includes stdlib.h]} { + user-error "Compiler does not work. See config.log" + } } + +cc-init diff --git a/autosetup/system.tcl b/autosetup/system.tcl index f23781b5da..05d378afdd 100644 --- a/autosetup/system.tcl +++ b/autosetup/system.tcl @@ -55,6 +55,8 @@ options { program-prefix: program-suffix: program-transform-name: + x-includes: + x-libraries: } # @check-feature name { script } @@ -318,95 +320,101 @@ proc make-template {template {out {}}} { } } -# build/host tuples and cross-compilation prefix -opt-str build build "" -define build_alias $build -if {$build eq ""} { - define build [config_guess] -} else { - define build [config_sub $build] -} +proc system-init {} { + global autosetup -opt-str host host "" -define host_alias $host -if {$host eq ""} { - define host [get-define build] - set cross "" -} else { - define host [config_sub $host] - set cross $host- -} -define cross [get-env CROSS $cross] + # build/host tuples and cross-compilation prefix + opt-str build build "" + define build_alias $build + if {$build eq ""} { + define build [config_guess] + } else { + define build [config_sub $build] + } -# build/host _cpu, _vendor and _os -foreach type {build host} { - set v [get-define $type] - if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} { - user-error "Invalid canonical $type: $v" + opt-str host host "" + define host_alias $host + if {$host eq ""} { + define host [get-define build] + set cross "" + } else { + define host [config_sub $host] + set cross $host- } - define ${type}_cpu $cpu - define ${type}_vendor $vendor - define ${type}_os $os -} + define cross [get-env CROSS $cross] -opt-str prefix prefix /usr/local - -# These are for compatibility with autoconf -define target [get-define host] -define prefix $prefix -define builddir $autosetup(builddir) -define srcdir $autosetup(srcdir) -define top_srcdir $autosetup(srcdir) -define abs_top_srcdir [file-normalize $autosetup(srcdir)] -define abs_top_builddir [file-normalize $autosetup(builddir)] - -# autoconf supports all of these -define exec_prefix [opt-str exec-prefix exec_prefix $prefix] -foreach {name defpath} { - bindir /bin - sbindir /sbin - libexecdir /libexec - libdir /lib -} { - define $name [opt-str $name o $exec_prefix$defpath] -} -foreach {name defpath} { - datadir /share - sharedstatedir /com - infodir /share/info - mandir /share/man - includedir /include -} { - define $name [opt-str $name o $prefix$defpath] -} -if {$prefix ne {/usr}} { - opt-str sysconfdir sysconfdir $prefix/etc -} else { - opt-str sysconfdir sysconfdir /etc -} -define sysconfdir $sysconfdir + # build/host _cpu, _vendor and _os + foreach type {build host} { + set v [get-define $type] + if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} { + user-error "Invalid canonical $type: $v" + } + define ${type}_cpu $cpu + define ${type}_vendor $vendor + define ${type}_os $os + } + + opt-str prefix prefix /usr/local + + # These are for compatibility with autoconf + define target [get-define host] + define prefix $prefix + define builddir $autosetup(builddir) + define srcdir $autosetup(srcdir) + define top_srcdir $autosetup(srcdir) + define abs_top_srcdir [file-normalize $autosetup(srcdir)] + define abs_top_builddir [file-normalize $autosetup(builddir)] + + # autoconf supports all of these + define exec_prefix [opt-str exec-prefix exec_prefix $prefix] + foreach {name defpath} { + bindir /bin + sbindir /sbin + libexecdir /libexec + libdir /lib + } { + define $name [opt-str $name o $exec_prefix$defpath] + } + foreach {name defpath} { + datadir /share + sharedstatedir /com + infodir /share/info + mandir /share/man + includedir /include + } { + define $name [opt-str $name o $prefix$defpath] + } + if {$prefix ne {/usr}} { + opt-str sysconfdir sysconfdir $prefix/etc + } else { + opt-str sysconfdir sysconfdir /etc + } + define sysconfdir $sysconfdir -define localstatedir [opt-str localstatedir o /var] -define runstatedir [opt-str runstatedir o /run] + define localstatedir [opt-str localstatedir o /var] + define runstatedir [opt-str runstatedir o /run] -define SHELL [get-env SHELL [find-an-executable sh bash ksh]] + define SHELL [get-env SHELL [find-an-executable sh bash ksh]] -# These could be used to generate Makefiles following some automake conventions -define AM_SILENT_RULES [opt-bool silent-rules] -define AM_MAINTAINER_MODE [opt-bool maintainer-mode] -define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking] + # These could be used to generate Makefiles following some automake conventions + define AM_SILENT_RULES [opt-bool silent-rules] + define AM_MAINTAINER_MODE [opt-bool maintainer-mode] + define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking] -# Windows vs. non-Windows -switch -glob -- [get-define host] { - *-*-ming* - *-*-cygwin - *-*-msys { - define-feature windows - define EXEEXT .exe - } - default { - define EXEEXT "" + # Windows vs. non-Windows + switch -glob -- [get-define host] { + *-*-ming* - *-*-cygwin - *-*-msys { + define-feature windows + define EXEEXT .exe + } + default { + define EXEEXT "" + } } + + # Display + msg-result "Host System...[get-define host]" + msg-result "Build System...[get-define build]" } -# Display -msg-result "Host System...[get-define host]" -msg-result "Build System...[get-define build]" +system-init diff --git a/manifest b/manifest index f45a9e75a3..ebf31f0dd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Latest\supstream\sjimsh0.c,\swhich\saccounts\sfor\sthe\sproblem\spatched\slocally\sby\s[29b944959568]. -D 2024-11-04T04:12:02.279 +C Latest\supstream\sautosetup\sto\sget\shandling\sof\s(==ignoring)\sautotools'\sx-includes\sand\sx-libraries\sflags\sand\sstop\sleakage\sof\ssome\sautosetup-init-level\svars\sinto\sauto.def's\sglobal\sscope. +D 2024-11-04T05:27:21.599 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -40,17 +40,17 @@ F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a7 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x -F autosetup/autosetup-find-tclsh 38dc4ac03c061d5ee53ecd1ec2fc3d5f0bbf4e84a7123d3160e01d26b5858f36 x +F autosetup/autosetup-find-tclsh 25905f6c302959db80c2951aa267b4411c5645b598ce761cfc24a166141e2c4c x F autosetup/autosetup-test-tclsh 749d20defee533a3842139df47d700fc7a334a5da7bdbd444ae5331744b06c5f F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034b10a7b F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360 F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 -F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 +F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/proj.tcl ece0c56651493b63770f3553c04897e793eea0a63c6204563281796ed1204fb5 -F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb +F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c8b24c590ef318e687ab76cd1a5d6c8fed84389e3ebbe544aa8b15759324958a -R fca10953222d79165bdf7ba3f1399e32 +P c7a5b7d2dbfd5c44980f7e9d7efc1e8c7882f192b14f534537745d0a0125909f +R 9d969aef88eeaf83ab6ce0653cd59928 U stephan -Z 8016e4a01b178558212e609b0d7b0b87 +Z 3f6aa18fba7361a3a88e0bc2c85add71 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e97925e9a7..e79415f9be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7a5b7d2dbfd5c44980f7e9d7efc1e8c7882f192b14f534537745d0a0125909f +307349bf91df2935efeaeb5617f43c2223aa7523e55034fb532cc4386a29d74c From 78600522098bc8053bab21c8d9fec530ad4079d2 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 4 Nov 2024 06:38:44 +0000 Subject: [PATCH 266/522] Minor internal doc additions. FossilOrigin-Name: 9edc8582c97f40f546699e6d1fb075773d5476df81b6c3f8900d1f2716549295 --- autosetup/proj.tcl | 4 +++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index f82dcc3581..8f621e23da 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1062,7 +1062,9 @@ proc proj-redirect-autoconf-dir-vars {} { set prefix [get-define prefix] set exec_prefix [get-define exec_prefix $prefix] # Note that the ${...} here refers to make-side var derefs, not - # TCL-side vars. + # TCL-side vars. They must be formulated such that they are legal + # for use in (A) makefiles, (B) pkgconfig files, and (C) TCL's + # [subst] command. i.e. they must use the form ${X}. foreach {flag makeVar makeDeref} { exec-prefix exec_prefix ${prefix} libdir libdir ${exec_prefix}/lib diff --git a/manifest b/manifest index ebf31f0dd4..079355a6d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Latest\supstream\sautosetup\sto\sget\shandling\sof\s(==ignoring)\sautotools'\sx-includes\sand\sx-libraries\sflags\sand\sstop\sleakage\sof\ssome\sautosetup-init-level\svars\sinto\sauto.def's\sglobal\sscope. -D 2024-11-04T05:27:21.599 +C Minor\sinternal\sdoc\sadditions. +D 2024-11-04T06:38:44.954 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl ece0c56651493b63770f3553c04897e793eea0a63c6204563281796ed1204fb5 +F autosetup/proj.tcl 9e053edf844bb21eecf11ae895fdcc8a8faa53b62bd3590e987fac47e81f112f F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c7a5b7d2dbfd5c44980f7e9d7efc1e8c7882f192b14f534537745d0a0125909f -R 9d969aef88eeaf83ab6ce0653cd59928 +P 307349bf91df2935efeaeb5617f43c2223aa7523e55034fb532cc4386a29d74c +R e7a94327d3f12fe81bcdebfd3b5f54d7 U stephan -Z 3f6aa18fba7361a3a88e0bc2c85add71 +Z 8ef48fb18c43937b2bb7608e93f04fd4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e79415f9be..9b032d7655 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -307349bf91df2935efeaeb5617f43c2223aa7523e55034fb532cc4386a29d74c +9edc8582c97f40f546699e6d1fb075773d5476df81b6c3f8900d1f2716549295 From f3d279595ed866ca6d787e39e11d1b5fdde26374 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 4 Nov 2024 08:29:02 +0000 Subject: [PATCH 267/522] When installing the shared lib, re-activate the accommodation of legacy-style .so links (removed in [80584e165e4]) based on two reports that not having those will cause all clients linked against the legacy naming convention to fail to dynamically link (which would preclude an update of a system-level libsqlite3 package). Set up the infrastructure needed for adding an SONAME to the library but do not yet activate it. See discussion in/around [forum:046133a7da|forum post 046133a7da]. FossilOrigin-Name: 1586eaceb1716fbeafc4af691d0f80206cd5390388b099d4939e6be5d3eb975b --- Makefile.in | 2 +- auto.def | 8 +++++++- autosetup/proj.tcl | 17 ++++++++++++++++ main.mk | 49 ++++++++++++++++++++++++++++++++++++++++++++-- manifest | 18 ++++++++--------- manifest.uuid | 2 +- 6 files changed, 82 insertions(+), 14 deletions(-) diff --git a/Makefile.in b/Makefile.in index 6995ff945e..0e7887f377 100644 --- a/Makefile.in +++ b/Makefile.in @@ -150,7 +150,7 @@ LDFLAGS.dlopen = @LDFLAGS_DLOPEN@ LDFLAGS.readline = @LDFLAGS_READLINE@ CFLAGS.readline = @CFLAGS_READLINE@ LDFLAGS.icu = @LDFLAGS_ICU@ - +LDFLAGS.soname.libsqlite3 = @LDFLAGS_SONAME_LIBSQLITE3@ ENABLE_SHARED = @ENABLE_SHARED@ ENABLE_STATIC = @ENABLE_STATIC@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ diff --git a/auto.def b/auto.def index a11560fb56..77db2d41a7 100644 --- a/auto.def +++ b/auto.def @@ -412,7 +412,13 @@ if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { define LDFLAGS_ZLIB "" } -proj-check-rpath; # Determine proper rpath-handling flags. +proj-check-rpath ; # Determine proper rpath-handling flag +if {0 && [proj-check-soname]} { + # It's not yet clear whether we gain anything from setting -soname + define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]libsqlite3.so.3 +} else { + define LDFLAGS_SONAME_LIBSQLITE3 "" +} proj-define-if-opt-truthy shared ENABLE_SHARED "Build shared library?" diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 8f621e23da..c5f057c2d4 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -825,6 +825,23 @@ proc proj-check-rpath {} { return $rc } +######################################################################## +# Checks whether CC supports the -Wl,soname,lib... flag. If so, it +# returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, +# which the client would need to append "libwhatever.N" to. If not, it +# returns 0 and defines LDFLAGS_SONAME_PREFIX to an empty string. +proc proj-check-soname {} { + cc-with {} { + if {[cc-check-flags "-Wl,-soname,libfoo.so.0"]} { + define LDFLAGS_SONAME_PREFIX "-Wl,-soname," + return 1 + } else { + define LDFLAGS_SONAME_PREFIX "" + return 0 + } + } +} + ######################################################################## # Internal helper for proj-dump-defs-json. Expects to be passed a # [define] name and the variadic $args which are passed to diff --git a/main.mk b/main.mk index 74617e3a8f..99366ea26b 100644 --- a/main.mk +++ b/main.mk @@ -162,6 +162,7 @@ LDFLAGS.pthread ?= -lpthread LDFLAGS.dlopen ?= -ldl LDFLAGS.shobj ?= -shared LDFLAGS.icu ?= # -licui18n -licuuc -licudata +LDFLAGS.soname.libsqlite3 ?= # libreadline (or a workalike): # To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE=1 LDFLAGS.readline ?= -lreadline # these vary wildly across platforms @@ -1351,7 +1352,7 @@ all: lib # Dynamic libsqlite3 # $(libsqlite3.SO): $(LIBOBJ) - $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.libsqlite3) + $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.soname.libsqlite3) $(LDFLAGS.libsqlite3) $(libsqlite3.SO)-1: $(libsqlite3.SO) $(libsqlite3.SO)-0 $(libsqlite3.SO)-: so: $(libsqlite3.SO)-$(ENABLE_SHARED) @@ -1365,6 +1366,37 @@ all: so # - libsqlite3.so.3 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) # - libsqlite3.so =symlink-> libsqlite3.so.3 # +# Regarding the historcal installation name of libsqlite3.so.0.8.6: +# +# Historically libtool installed the library like so: +# +# libsqlite3.so -> libsqlite3.so.0.8.6 +# libsqlite3.so.0 -> libsqlite3.so.0.8.6 +# libsqlite3.so.0.8.6 +# +# The historical SQLite build always used a version number of 0.8.6 +# for reasons lost to history but having something to do with libtool +# (which is no longer used in this tree). In order to retain filename +# compatibility for systems which have libraries installed using those +# conventions: +# +# 1) If libsqlite3.so.0 is found in the target installation directory +# then it is re-linked to point to the newer-style names. We cannot +# retain both the old and new installation because they both share +# the high-level name $(libsqlite3.SO). The down-side of this is +# that it may well upset packaging tools when we replace +# libsqlite3.so (from a legacy package) with a new symlink. +# +# 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links +# to the legacy-style names are created. The primary intent of this +# is to enable chains of operations such as the hypothetical (apt +# remove sqlite3-3.47.0 && apt install sqlite3-3.48.0). In such +# cases, condition (1) would never trigger but applications might +# still expect to see the legacy file names. +# +# In either case, libsqlite3.la, if found, is deleted because it would +# contain stale state, refering to non-libtool-generated libraries. +# install-so-1: $(install-dir.lib) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) "$(install-dir.lib)" @echo "Setting up SO symlinks..."; \ @@ -1373,7 +1405,20 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).3 || exit $$?; \ ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ - ls -la $(libsqlite3.SO) $(libsqlite3.SO).3* + ls -la $(libsqlite3.SO) $(libsqlite3.SO).3*; \ + if [ -e $(libsqlite3.SO).0 ]; then \ + echo "ACHTUNG: legacy libtool-compatible install found. Re-linking it..."; \ + rm -f libsqlite3.la $(libsqlite3.SO).0* || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ + ls -la $(libsqlite3.SO).0*; \ + elif [ x1 = "x$(INSTALL_SO_086_LINKS)" ]; then \ + echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINKS=1"; \ + rm -f libsqlite3.la $(libsqlite3.SO).0* || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ + ls -la $(libsqlite3.SO).0*; \ + fi install-so-0 install-so-: install-so: install-so-$(ENABLE_SHARED) install: install-so diff --git a/manifest b/manifest index 079355a6d6..3c38464b73 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Minor\sinternal\sdoc\sadditions. -D 2024-11-04T06:38:44.954 +C When\sinstalling\sthe\sshared\slib,\sre-activate\sthe\saccommodation\sof\slegacy-style\s.so\slinks\s(removed\sin\s[80584e165e4])\sbased\son\stwo\sreports\sthat\snot\shaving\sthose\swill\scause\sall\sclients\slinked\sagainst\sthe\slegacy\snaming\sconvention\sto\sfail\sto\sdynamically\slink\s(which\swould\spreclude\san\supdate\sof\sa\ssystem-level\slibsqlite3\spackage).\sSet\sup\sthe\sinfrastructure\sneeded\sfor\sadding\san\sSONAME\sto\sthe\slibrary\sbut\sdo\snot\syet\sactivate\sit.\sSee\sdiscussion\sin/around\s[forum:046133a7da|forum\spost\s046133a7da]. +D 2024-11-04T08:29:02.129 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in b490c1230b030da8d597688c09ec395340eb834cc858437d5c3a3ce45e8aaf3e +F Makefile.in 5f7d14ad4b7a2e150efaffdef6b0351fb2f7a58e2f5dfc24a06064bf779a4ed7 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 19b5df445fab703133f430b1169968d702cf421d752199ee77d11626062f7755 +F auto.def df0c81945586931dad81173d1c997deeecfa1a422db4bcd5ff4c9b425ed8aa44 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 9e053edf844bb21eecf11ae895fdcc8a8faa53b62bd3590e987fac47e81f112f +F autosetup/proj.tcl 40e3a4ffd4677ddd98426ef1b398a45eba51038c295f6ea95eff207b79401669 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk f8b82b2422ad161e2f8b463a57db1fd0f4419b82834d722a1ae956945aaa2eb5 +F main.mk 548b0263d0bfa7f9219c340a48f1b8be3d51244942d7afbf55633c6a5e9574a6 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 307349bf91df2935efeaeb5617f43c2223aa7523e55034fb532cc4386a29d74c -R e7a94327d3f12fe81bcdebfd3b5f54d7 +P 9edc8582c97f40f546699e6d1fb075773d5476df81b6c3f8900d1f2716549295 +R 8cf84e7f7765f04ea61c293658e080de U stephan -Z 8ef48fb18c43937b2bb7608e93f04fd4 +Z 73922ef92d5fe4d287303f5a200f92b0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9b032d7655..fe22ef1b69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9edc8582c97f40f546699e6d1fb075773d5476df81b6c3f8900d1f2716549295 +1586eaceb1716fbeafc4af691d0f80206cd5390388b099d4939e6be5d3eb975b From 21d90a1607ae616c1d6827c51b4f6958da6ac0d6 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 4 Nov 2024 10:16:15 +0000 Subject: [PATCH 268/522] Ensure that the ext/wasm fiddle build undefines certain shell feature flags which it cannot use but might be inherited from the top-level makefile. FossilOrigin-Name: 99bb5d9b68edc3c5439f0776bce74532dd0131894c31dc8227d084e926c4638c --- ext/wasm/fiddle.make | 2 ++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index df5c7ab7b7..2a43959e2b 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -46,6 +46,8 @@ fiddle.emcc-flags = \ $(SQLITE_OPT.full-featured) \ $(SQLITE_OPT.common) \ $(SHELL_OPT) \ + -UHAVE_READLINE -UHAVE_EDITLINE -UHAVE_LINENOISE \ + -USQLITE_HAVE_ZLIB \ -USQLITE_WASM_BARE_BONES \ -DSQLITE_SHELL_FIDDLE diff --git a/manifest b/manifest index 3c38464b73..253cdecf2a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sinstalling\sthe\sshared\slib,\sre-activate\sthe\saccommodation\sof\slegacy-style\s.so\slinks\s(removed\sin\s[80584e165e4])\sbased\son\stwo\sreports\sthat\snot\shaving\sthose\swill\scause\sall\sclients\slinked\sagainst\sthe\slegacy\snaming\sconvention\sto\sfail\sto\sdynamically\slink\s(which\swould\spreclude\san\supdate\sof\sa\ssystem-level\slibsqlite3\spackage).\sSet\sup\sthe\sinfrastructure\sneeded\sfor\sadding\san\sSONAME\sto\sthe\slibrary\sbut\sdo\snot\syet\sactivate\sit.\sSee\sdiscussion\sin/around\s[forum:046133a7da|forum\spost\s046133a7da]. -D 2024-11-04T08:29:02.129 +C Ensure\sthat\sthe\sext/wasm\sfiddle\sbuild\sundefines\scertain\sshell\sfeature\sflags\swhich\sit\scannot\suse\sbut\smight\sbe\sinherited\sfrom\sthe\stop-level\smakefile. +D 2024-11-04T10:16:15.685 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -667,7 +667,7 @@ F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2 F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef F ext/wasm/dist.make 653e212c1e84aa3be168d62a10616ccea45ee9585b0192745d2706707a5248ce F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make ec2353f0eddade864f67b993376a0949e27b72465c24b1970940e48b70bc2df1 +F ext/wasm/fiddle.make d4969f0322a582c57a22ce3541f10a5b09a609d14eab32891f613f43b3c14d8b F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1 F ext/wasm/fiddle/index.html c79b1741cbeba78f88af0a84cf5ec7de87a909a6a8d10a369b1f4824c66c2088 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9edc8582c97f40f546699e6d1fb075773d5476df81b6c3f8900d1f2716549295 -R 8cf84e7f7765f04ea61c293658e080de +P 1586eaceb1716fbeafc4af691d0f80206cd5390388b099d4939e6be5d3eb975b +R 73cc0db79188b923e5ebd7ada97d907d U stephan -Z 73922ef92d5fe4d287303f5a200f92b0 +Z 1e2b27c01bd1350b57bba6fb5cb67540 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fe22ef1b69..f8ced9d60e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1586eaceb1716fbeafc4af691d0f80206cd5390388b099d4939e6be5d3eb975b +99bb5d9b68edc3c5439f0776bce74532dd0131894c31dc8227d084e926c4638c From 2fd38836dcb57abc6b6925b180c5b6fb737f7b2a Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 4 Nov 2024 12:11:20 +0000 Subject: [PATCH 269/522] Fix typo of --libexec ==> --libexecdir, discovered via audit of a downstream build script. Unrelated doc touchups. FossilOrigin-Name: a60e5d76d06ae0568fbc6e068a7012c77778607cd60da92a1b84ff8f33049a93 --- Makefile.in | 2 +- auto.def | 2 +- autosetup/proj.tcl | 16 +++++++++++----- main.mk | 13 +++++++------ manifest | 18 +++++++++--------- manifest.uuid | 2 +- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Makefile.in b/Makefile.in index 0e7887f377..3a1c491997 100644 --- a/Makefile.in +++ b/Makefile.in @@ -113,7 +113,7 @@ TOP = @abs_top_srcdir@ # localstatedir = /var # runstatedir = /run # infodir = $(datadir)/info -# libexec = $(exec_prefix)/libexec +# libexecdir = $(exec_prefix)/libexec # prefix = @prefix@ datadir = @datadir@ diff --git a/auto.def b/auto.def index 77db2d41a7..cf50eecf0f 100644 --- a/auto.def +++ b/auto.def @@ -413,7 +413,7 @@ if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { } proj-check-rpath ; # Determine proper rpath-handling flag -if {0 && [proj-check-soname]} { +if {0 && [proj-check-soname libsqlite3.so.3]} { # It's not yet clear whether we gain anything from setting -soname define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]libsqlite3.so.3 } else { diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index c5f057c2d4..eee526dea6 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -827,12 +827,18 @@ proc proj-check-rpath {} { ######################################################################## # Checks whether CC supports the -Wl,soname,lib... flag. If so, it -# returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, -# which the client would need to append "libwhatever.N" to. If not, it +# returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, to +# which the client would need to append "libwhatever.N". If not, it # returns 0 and defines LDFLAGS_SONAME_PREFIX to an empty string. -proc proj-check-soname {} { +# +# The libname argument is only for purposes of running the flag +# compatibility test, and is not included in the resulting +# LDFLAGS_SONAME_PREFIX. It is provided so that clients may +# potentially avoid some end-user confusion by using their own lib's +# name here (which shows up in the "checking..." output). +proc proj-check-soname {{libname "libfoo.so.0"}} { cc-with {} { - if {[cc-check-flags "-Wl,-soname,libfoo.so.0"]} { + if {[cc-check-flags "-Wl,-soname,${libname}"]} { define LDFLAGS_SONAME_PREFIX "-Wl,-soname," return 1 } else { @@ -1096,7 +1102,7 @@ proc proj-redirect-autoconf-dir-vars {} { localstatedir localstatedir /var runstatedir runstatedir /run infodir infodir ${datadir}/info - libexec libexec ${exec_prefix}/libexec + libexecdir libexecdir ${exec_prefix}/libexec } { # puts "flag=$flag var=$makeVar makeDeref=$makeDeref" if {[proj-opt-was-provided $flag]} { diff --git a/main.mk b/main.mk index 99366ea26b..a89aa5e9dc 100644 --- a/main.mk +++ b/main.mk @@ -141,7 +141,7 @@ libdir ?= $(exec_prefix)/lib # localstatedir ?= /var # runstatedir ?= /run # infodir ?= $(datadir)/info -# libexec ?= $(exec_prefix)/libexec +# libexecdir ?= $(exec_prefix)/libexec ### end of autotools-compatible install dir vars @@ -1381,11 +1381,12 @@ all: so # conventions: # # 1) If libsqlite3.so.0 is found in the target installation directory -# then it is re-linked to point to the newer-style names. We cannot -# retain both the old and new installation because they both share -# the high-level name $(libsqlite3.SO). The down-side of this is -# that it may well upset packaging tools when we replace -# libsqlite3.so (from a legacy package) with a new symlink. +# then it and libsqlite3.so.0.8.6 are re-linked to point to the +# newer-style names. We cannot retain both the old and new +# installation because they both share the high-level name +# $(libsqlite3.SO). The down-side of this is that it may well upset +# packaging tools when we replace libsqlite3.so (from a legacy +# package) with a new symlink. # # 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links # to the legacy-style names are created. The primary intent of this diff --git a/manifest b/manifest index 253cdecf2a..af91b13380 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Ensure\sthat\sthe\sext/wasm\sfiddle\sbuild\sundefines\scertain\sshell\sfeature\sflags\swhich\sit\scannot\suse\sbut\smight\sbe\sinherited\sfrom\sthe\stop-level\smakefile. -D 2024-11-04T10:16:15.685 +C Fix\stypo\sof\s--libexec\s==>\s--libexecdir,\sdiscovered\svia\saudit\sof\sa\sdownstream\sbuild\sscript.\sUnrelated\sdoc\stouchups. +D 2024-11-04T12:11:20.215 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 5f7d14ad4b7a2e150efaffdef6b0351fb2f7a58e2f5dfc24a06064bf779a4ed7 +F Makefile.in 3cb3754680dc2f06f6858ef8068ad1c947709dfae705466d383f25d7f222f4ab F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def df0c81945586931dad81173d1c997deeecfa1a422db4bcd5ff4c9b425ed8aa44 +F auto.def dc62d3c918d2750248e6811b24c2cbbd51d1457d7f6ffd11e0bf61dd5770cb3e F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 40e3a4ffd4677ddd98426ef1b398a45eba51038c295f6ea95eff207b79401669 +F autosetup/proj.tcl 0bcced417a59fc56da5e6cc6a83e10cca4e10710c0f2f1ae9bc82b366d17699d F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -697,7 +697,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 548b0263d0bfa7f9219c340a48f1b8be3d51244942d7afbf55633c6a5e9574a6 +F main.mk a066ab09a00cfc641359db6fde6d466201c2bf51d95bf48086e5bc3ea401640d F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1586eaceb1716fbeafc4af691d0f80206cd5390388b099d4939e6be5d3eb975b -R 73cc0db79188b923e5ebd7ada97d907d +P 99bb5d9b68edc3c5439f0776bce74532dd0131894c31dc8227d084e926c4638c +R 4f2c4e757a85bb00a8c970e35c0cdef2 U stephan -Z 1e2b27c01bd1350b57bba6fb5cb67540 +Z 236eab552ea1842cd9bb8ad82e3ed96f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f8ced9d60e..baa0a3c1e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99bb5d9b68edc3c5439f0776bce74532dd0131894c31dc8227d084e926c4638c +a60e5d76d06ae0568fbc6e068a7012c77778607cd60da92a1b84ff8f33049a93 From 88ef6be57d8e306fcf927d97a7147688ae7df4f6 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 4 Nov 2024 13:57:20 +0000 Subject: [PATCH 270/522] Fix two mismatched uses of malloc() and sqlite3_free() in sqlite3_stdio.c, as reported in [forum:7dd7c70038 | forum post 7dd7c70038]. FossilOrigin-Name: af0a345b3b287f82b54249cfa574ef3ce52305a6452058aac98cd473c361919e --- ext/misc/sqlite3_stdio.c | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/misc/sqlite3_stdio.c b/ext/misc/sqlite3_stdio.c index 5bb26084c2..ba37e4be30 100644 --- a/ext/misc/sqlite3_stdio.c +++ b/ext/misc/sqlite3_stdio.c @@ -146,7 +146,7 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){ ** that into UTF-8. Otherwise, non-ASCII characters all get translated ** into '?'. */ - wchar_t *b1 = malloc( sz*sizeof(wchar_t) ); + wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) ); if( b1==0 ) return 0; _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); if( fgetws(b1, sz/4, in)==0 ){ @@ -212,7 +212,7 @@ int sqlite3_fputs(const char *z, FILE *out){ ** use O_U8TEXT for everything in text mode. */ int sz = (int)strlen(z); - wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) ); + wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) ); if( b1==0 ) return 0; sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); b1[sz] = 0; diff --git a/manifest b/manifest index af91b13380..e80bdc1732 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sof\s--libexec\s==>\s--libexecdir,\sdiscovered\svia\saudit\sof\sa\sdownstream\sbuild\sscript.\sUnrelated\sdoc\stouchups. -D 2024-11-04T12:11:20.215 +C Fix\stwo\smismatched\suses\sof\smalloc()\sand\ssqlite3_free()\sin\ssqlite3_stdio.c,\sas\sreported\sin\s[forum:7dd7c70038\s|\sforum\spost\s7dd7c70038]. +D 2024-11-04T13:57:20.510 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -440,7 +440,7 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 -F ext/misc/sqlite3_stdio.c 73192f75e1e89722fbdf209056a562ca2a35df3c9e998f9270331e03cb621e7a +F ext/misc/sqlite3_stdio.c d3359cb499ddf2fcf50c630166821b329d35c1f8ddcf78b333c894845d9e3d6c F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 99bb5d9b68edc3c5439f0776bce74532dd0131894c31dc8227d084e926c4638c -R 4f2c4e757a85bb00a8c970e35c0cdef2 +P a60e5d76d06ae0568fbc6e068a7012c77778607cd60da92a1b84ff8f33049a93 +R 1e21ba8321e5a6b22692a09525e9bc1b U stephan -Z 236eab552ea1842cd9bb8ad82e3ed96f +Z 743a8b18a247cccbb6a7ea690e8b0e07 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index baa0a3c1e5..6b47a0a442 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a60e5d76d06ae0568fbc6e068a7012c77778607cd60da92a1b84ff8f33049a93 +af0a345b3b287f82b54249cfa574ef3ce52305a6452058aac98cd473c361919e From 4bf24c8830d21509df5819b0a2c7fdcd0e45f42e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 4 Nov 2024 16:59:02 +0000 Subject: [PATCH 271/522] Avoid loading the entire record into memory for an sqlite3_preupdate_old() call that retrieves an IPK value. FossilOrigin-Name: 7f4de43733200beeb3ff0a70d51bbc68f5331895698ea95a82741cfd7bb66834 --- ext/session/sessionblob.test | 55 +++++++++++++++++++ manifest | 19 +++---- manifest.uuid | 2 +- src/vdbeInt.h | 1 + src/vdbeapi.c | 102 ++++++++++++++++++----------------- src/vdbeaux.c | 1 + 6 files changed, 121 insertions(+), 59 deletions(-) create mode 100644 ext/session/sessionblob.test diff --git a/ext/session/sessionblob.test b/ext/session/sessionblob.test new file mode 100644 index 0000000000..ed7ec67b48 --- /dev/null +++ b/ext/session/sessionblob.test @@ -0,0 +1,55 @@ +# 2024 November 04 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +if {$::tcl_platform(pointerSize)<8} { + finish_test + return +} + +set testprefix sessionblob + +forcedelete test.db2 +sqlite3 db2 test.db2 + +set NBLOB 2000000 + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(123, zeroblob($NBLOB)); +} + +do_test 1.1 { + sqlite3session S db main + S attach t1 +} {} + +set b2 [string repeat x 1000] +do_test 1.2 { + set ::blob [db incrblob t1 b 123] + for {set ii 0} {$ii < $NBLOB} {incr ii [string length $b2]} { + seek $::blob $ii + puts -nonewline $::blob $b2 + } + close $::blob +} {} + +S delete + +finish_test + diff --git a/manifest b/manifest index e80bdc1732..76c6219937 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stwo\smismatched\suses\sof\smalloc()\sand\ssqlite3_free()\sin\ssqlite3_stdio.c,\sas\sreported\sin\s[forum:7dd7c70038\s|\sforum\spost\s7dd7c70038]. -D 2024-11-04T13:57:20.510 +C Avoid\sloading\sthe\sentire\srecord\sinto\smemory\sfor\san\ssqlite3_preupdate_old()\scall\sthat\sretrieves\san\sIPK\svalue. +D 2024-11-04T16:59:02.337 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -595,6 +595,7 @@ F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8 F ext/session/sessionalter.test e852acb3d2357aac7d0b920a2109da758c4331bfdf85b41d39aa3a8c18914f65 F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b85419035bc04b45ee F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf +F ext/session/sessionblob.test 87faf667870b72f08e91969abd9f52a383ab7b514506ee194d64a39d8faff00a F ext/session/sessionchange.test 77c4702050f24270b58070e2cf01c95c3d232a3ef164b70f31974b386ce69903 F ext/session/sessionconflict.test 8b8cbd98548e2e636ddc17d0986276f60e833fb865617dd4f88ea5bbe3a16b96 F ext/session/sessiondiff.test e89f7aedcdd89e5ebac3a455224eb553a171e9586fc3e1e6a7b3388d2648ba8d @@ -847,9 +848,9 @@ F src/util.c ceebf912f673247e305f16f97f0bb7285fca1d37413b79680714a553a9021d33 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a -F src/vdbeInt.h af7d7e8291edd0b19f2cd698e60e4d4031078f9a2f2328ac8f0b7efb134f8a1d -F src/vdbeapi.c 53c7e26a2c0821a892b20eee2cde4656e31998212f3d515576c780dfaa45fd17 -F src/vdbeaux.c f06f011e4fac948941ea821ac365a9f1c163ef473e63756d6e499a37c6bda9ef +F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e +F src/vdbeapi.c 6353de05e8e78e497ccb33381ba5662ccc11c0339e5b1455faff01b6dacc3075 +F src/vdbeaux.c f0706ad786b8a6c5bc7ea622f3916c2ba2b883abc872d0b4911c4f021945c0e5 F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797 F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2 F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f @@ -2198,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a60e5d76d06ae0568fbc6e068a7012c77778607cd60da92a1b84ff8f33049a93 -R 1e21ba8321e5a6b22692a09525e9bc1b -U stephan -Z 743a8b18a247cccbb6a7ea690e8b0e07 +P af0a345b3b287f82b54249cfa574ef3ce52305a6452058aac98cd473c361919e +R 84f5bc88e95886a46e23b56039713592 +U dan +Z ba372c464e587d954c923d1075bdeb25 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6b47a0a442..8ed87eec77 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af0a345b3b287f82b54249cfa574ef3ce52305a6452058aac98cd473c361919e +7f4de43733200beeb3ff0a70d51bbc68f5331895698ea95a82741cfd7bb66834 diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b26860f3a6..467f488905 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -540,6 +540,7 @@ struct PreUpdate { int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ + Mem oldipk; /* Memory cell holding "old" IPK value */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b6ad5f3d95..014ad95393 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -2197,60 +2197,64 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ goto preupdate_old_out; } - /* If the old.* record has not yet been loaded into memory, do so now. */ - if( p->pUnpacked==0 ){ - u32 nRec; - u8 *aRec; - - assert( p->pCsr->eCurType==CURTYPE_BTREE ); - nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); - aRec = sqlite3DbMallocRaw(db, nRec); - if( !aRec ) goto preupdate_old_out; - rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); - if( rc==SQLITE_OK ){ - p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); - if( !p->pUnpacked ) rc = SQLITE_NOMEM; - } - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, aRec); - goto preupdate_old_out; - } - p->aRecord = aRec; - } - - pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; if( iIdx==p->pTab->iPKey ){ + *ppValue = pMem = &p->oldipk; sqlite3VdbeMemSetInt64(pMem, p->iKey1); - }else if( iIdx>=p->pUnpacked->nField ){ - /* This occurs when the table has been extended using ALTER TABLE - ** ADD COLUMN. The value to return is the default value of the column. */ - Column *pCol = &p->pTab->aCol[iIdx]; - if( pCol->iDflt>0 ){ - if( p->apDflt==0 ){ - int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; - p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); - if( p->apDflt==0 ) goto preupdate_old_out; + }else{ + + /* If the old.* record has not yet been loaded into memory, do so now. */ + if( p->pUnpacked==0 ){ + u32 nRec; + u8 *aRec; + + assert( p->pCsr->eCurType==CURTYPE_BTREE ); + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); + aRec = sqlite3DbMallocRaw(db, nRec); + if( !aRec ) goto preupdate_old_out; + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); + if( rc==SQLITE_OK ){ + p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); + if( !p->pUnpacked ) rc = SQLITE_NOMEM; } - if( p->apDflt[iIdx]==0 ){ - sqlite3_value *pVal = 0; - Expr *pDflt; - assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); - pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; - rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); - if( rc==SQLITE_OK && pVal==0 ){ - rc = SQLITE_CORRUPT_BKPT; - } - p->apDflt[iIdx] = pVal; + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, aRec); + goto preupdate_old_out; } - *ppValue = p->apDflt[iIdx]; - }else{ - *ppValue = (sqlite3_value *)columnNullValue(); + p->aRecord = aRec; } - }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ - if( pMem->flags & (MEM_Int|MEM_IntReal) ){ - testcase( pMem->flags & MEM_Int ); - testcase( pMem->flags & MEM_IntReal ); - sqlite3VdbeMemRealify(pMem); + + pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; + if( iIdx>=p->pUnpacked->nField ){ + /* This occurs when the table has been extended using ALTER TABLE + ** ADD COLUMN. The value to return is the default value of the column. */ + Column *pCol = &p->pTab->aCol[iIdx]; + if( pCol->iDflt>0 ){ + if( p->apDflt==0 ){ + int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); + if( p->apDflt==0 ) goto preupdate_old_out; + } + if( p->apDflt[iIdx]==0 ){ + sqlite3_value *pVal = 0; + Expr *pDflt; + assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); + pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; + rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); + if( rc==SQLITE_OK && pVal==0 ){ + rc = SQLITE_CORRUPT_BKPT; + } + p->apDflt[iIdx] = pVal; + } + *ppValue = p->apDflt[iIdx]; + }else{ + *ppValue = (sqlite3_value *)columnNullValue(); + } + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pMem); + } } } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8120536b98..4414f7a2ec 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -5529,6 +5529,7 @@ void sqlite3VdbePreUpdateHook( sqlite3DbFree(db, preupdate.aRecord); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); + sqlite3VdbeMemRelease(&preupdate.oldipk); if( preupdate.aNew ){ int i; for(i=0; inField; i++){ From bc60d7bee9797ecc6f33128b36527b70371d1748 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Nov 2024 19:08:53 +0000 Subject: [PATCH 272/522] Ensure that the database encoding is detected before the code generator gets too far down into byte-code generation and execution, but not so early that it interferes with initialization. [forum:/forumpost/bc75a4d20b756044|Forum thread bc75a4d20b756044]. FossilOrigin-Name: af7173a10ec6a4ab465207c1ee20393e8b5f06604c0f3b2fdc19e52c2fc013d5 --- ext/rtree/rtreecheck.test | 2 +- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/parse.y | 6 +++++- src/prepare.c | 9 +-------- test/enc.test | 29 +++++++++++++++++++++++++++++ test/misc5.test | 1 + 7 files changed, 49 insertions(+), 22 deletions(-) diff --git a/ext/rtree/rtreecheck.test b/ext/rtree/rtreecheck.test index 7a98f9bf4e..d2c521cb8f 100644 --- a/ext/rtree/rtreecheck.test +++ b/ext/rtree/rtreecheck.test @@ -198,7 +198,7 @@ if {[permutation]=="inmemory_journal"} { } else { do_catchsql_test 6.1 { SELECT ( 'elvis' IN(SELECT rtreecheck('t1')) ) FROM (SELECT 1) GROUP BY 1; - } {1 {database table is locked}} + } {0 0} } finish_test diff --git a/manifest b/manifest index 76c6219937..95362feaf7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sloading\sthe\sentire\srecord\sinto\smemory\sfor\san\ssqlite3_preupdate_old()\scall\sthat\sretrieves\san\sIPK\svalue. -D 2024-11-04T16:59:02.337 +C Ensure\sthat\sthe\sdatabase\sencoding\sis\sdetected\sbefore\sthe\scode\sgenerator\sgets\ntoo\sfar\sdown\sinto\sbyte-code\sgeneration\sand\sexecution,\sbut\snot\sso\searly\sthat\nit\sinterferes\swith\sinitialization.\n[forum:/forumpost/bc75a4d20b756044|Forum\sthread\sbc75a4d20b756044]. +D 2024-11-04T19:08:53.154 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -558,7 +558,7 @@ F ext/rtree/rtreeI.test 608e77f7fde9be5a12eae316baef640fffaafcfa90a3d67443e78123 F ext/rtree/rtreeJ.test 93227ccd4d6c328f5ac46a902b8880041509dd2d68f6ce71560f0d8ab5bb507a F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 202ca70df1f0645ef9d5a2170e62d378a28098d9407f0569e85c9c1cf1bd020a -F ext/rtree/rtreecheck.test 934546ad9b563e090ee0c5cbdc69ad014189ad76e5df7320526797a9a345661f +F ext/rtree/rtreecheck.test 84eedb43b25b3edf591125266d0bb1cebdfcdcc9c4a56b27d85bcb63c7dd7558 F ext/rtree/rtreecirc.test aec664eb21ae943aeb344191407afff5d392d3ae9d12b9a112ced0d9c5de298e F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d F ext/rtree/rtreedoc.test d633982d61542f3bc0a0a2df0382a02cc699ac56cbda01130cde6da44a228490 @@ -766,13 +766,13 @@ F src/os_win.c 69fa1aaff68270423c85cff4327ba17ef99a1eb017e1a2bfb97416d9b8398b05 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a -F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61 +F src/parse.y 8ec56598aa0df92428627502267d0d1c9778cc27308f8ffd31dfb2d017a8755f F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 F src/pragma.c a2ec3657a953fa7dea7c1e680e4358b6ce6ae570b6c5234e0f5ef219d308d223 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 -F src/prepare.c 3ba0ad907b7773ed642f66cea8a2c9c8edc18841aa1050b6218dbb3479e86225 +F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126 F src/printf.c 6a87534ebfb9e5346011191b1f3a7ebc457f5938c7e4feeea478ecf53f6a41b2 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 @@ -1120,7 +1120,7 @@ F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66 F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62 -F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a +F test/enc.test b5503a87b31cea8a5084c6e447383f9ca08933bd2f29d97b6b6201081b2343eb F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 @@ -1457,7 +1457,7 @@ F test/misc1.test e3e36262aff1bd9b8b9bf1eeb3af04adb3fc1e23f0a92dbff708bba9e939ac F test/misc2.test a1a3573cc02662becd967766021d6f16c54684d56df5f227481c7ef0d9df0bd0 F test/misc3.test 651b88bca19b8ff6a7b6af73dae00c3fd5b3ea5bee0c0d1d91abd4c4b4748718 F test/misc4.test 10cd6addb2fa9093df4751a1b92b50440175dd5468a6ec84d0386e78f087db0e -F test/misc5.test 027cf0ac10314ea534173f335a33bb4059907ddabbac2c16786766d6f26c8923 +F test/misc5.test 02fcaf4d42405be02ec975e946270a50b0282dac98c78303ade0d1392839d2b8 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test d912f3d45c2989191b797504a220ca225d6be80b21acad22ba0d35f4a9ee4579 F test/misc8.test 08d2380bc435486b12161521f225043ac2be26f02471c2c1ea4cac0b1548edbd @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P af0a345b3b287f82b54249cfa574ef3ce52305a6452058aac98cd473c361919e -R 84f5bc88e95886a46e23b56039713592 -U dan -Z ba372c464e587d954c923d1075bdeb25 +P 7f4de43733200beeb3ff0a70d51bbc68f5331895698ea95a82741cfd7bb66834 +R 37843e70c3ec2e1305165bf8dbe6f9d9 +U drh +Z 34b3ce0ce5f61e360e39d80506afd73c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8ed87eec77..8ab21c8735 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f4de43733200beeb3ff0a70d51bbc68f5331895698ea95a82741cfd7bb66834 +af7173a10ec6a4ab465207c1ee20393e8b5f06604c0f3b2fdc19e52c2fc013d5 diff --git a/src/parse.y b/src/parse.y index a6a5e046db..8fdea9bfa3 100644 --- a/src/parse.y +++ b/src/parse.y @@ -499,7 +499,11 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). { // cmd ::= select(X). { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, X, &dest); + if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0 + || sqlite3ReadSchema(pParse)==SQLITE_OK + ){ + sqlite3Select(pParse, X, &dest); + } sqlite3SelectDelete(pParse->db, X); } diff --git a/src/prepare.c b/src/prepare.c index 7aa1e1a022..de364f925b 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -306,14 +306,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ #else encoding = SQLITE_UTF8; #endif - if( db->nVdbeActive>0 && encoding!=ENC(db) - && (db->mDbFlags & DBFLAG_Vacuum)==0 - ){ - rc = SQLITE_LOCKED; - goto initone_error_out; - }else{ - sqlite3SetTextEncoding(db, encoding); - } + sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ diff --git a/test/enc.test b/test/enc.test index ffe24164bd..0aec224e2d 100644 --- a/test/enc.test +++ b/test/enc.test @@ -249,4 +249,33 @@ do_execsql_test enc-12.10 { SELECT * FROM t1; } {d e f xxx yyy zzz} + +# 2024-11-04 +# https://sqlite.org/forum/forumpost/bc75a4d20b756044 +# +# Ensure the database encoding is detected in a timely manner, +# and before we get too far along in generating and running +# bytecode. +# +# See also check-in https://sqlite.org/src/info/a02da71f3a. +# +db close +forcedelete utf16.db +sqlite3 db utf16.db +db eval {PRAGMA encoding=UTF16; CREATE TABLE t2(y); INSERT INTO t2 VALUES('utf16');} +db close +sqlite3 db utf16.db +do_test enc-13.1 { + db eval {PRAGMA function_list} {db eval {SELECT * FROM sqlite_schema}} +} {} +ifcapable rtree { + db eval {CREATE VIRTUAL TABLE t3 USING rtree(id,x1,x2)} + db close + sqlite3 db utf16.db + do_execsql_test enc-13.2 { + WITH t1(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM t1 WHERE x<3) + SELECT rtreecheck('t3') FROM t1; + } {ok ok ok} +} + finish_test diff --git a/test/misc5.test b/test/misc5.test index 84aa9586d3..43ee2781a1 100644 --- a/test/misc5.test +++ b/test/misc5.test @@ -523,6 +523,7 @@ if {[permutation] == ""} { CREATE TABLE t1(a,b,c); } } {1 {file is not a database}} + reset_db } # Ticket #1371. Allow floating point numbers of the form .N or N. From c6a6f1507c72de649a4c0179a5ce0beff517ec50 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Nov 2024 19:18:19 +0000 Subject: [PATCH 273/522] Fix harmless compiler warnings. FossilOrigin-Name: bc93e17924f732468282c5e7a483811d27af573a47aec8ba806f4fe3c5919893 --- ext/fts5/fts5_tcl.c | 3 +-- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test1.c | 1 - 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index dd2ed82c9e..247b4f0e90 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -1642,7 +1642,7 @@ void f5tStrFunc(sqlite3_context *pCtx, int nArg, sqlite3_value **apArg){ const char *zText = 0; assert( nArg==1 ); - zText = sqlite3_value_text(apArg[0]); + zText = (const char*)sqlite3_value_text(apArg[0]); if( zText ){ sqlite3_int64 nText = strlen(zText); char *zCopy = (char*)ckalloc(nText+8); @@ -1670,7 +1670,6 @@ static int SQLITE_TCLAPI f5tRegisterStr( Tcl_Obj *CONST objv[] ){ sqlite3 *db = 0; - int rc; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB"); diff --git a/manifest b/manifest index 95362feaf7..2ecc560429 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sdatabase\sencoding\sis\sdetected\sbefore\sthe\scode\sgenerator\sgets\ntoo\sfar\sdown\sinto\sbyte-code\sgeneration\sand\sexecution,\sbut\snot\sso\searly\sthat\nit\sinterferes\swith\sinitialization.\n[forum:/forumpost/bc75a4d20b756044|Forum\sthread\sbc75a4d20b756044]. -D 2024-11-04T19:08:53.154 +C Fix\sharmless\scompiler\swarnings. +D 2024-11-04T19:18:19.862 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -115,7 +115,7 @@ F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6 F ext/fts5/fts5_main.c 50eb059e51d730e8e0c77df4e568b018079e112a755c094488b0d5b1aa06afbb F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c -F ext/fts5/fts5_tcl.c 5b16a249962809b2aaaab964bf58838ea72f30b8b12373cafe612f8cc71e2a40 +F ext/fts5/fts5_tcl.c aee6ae6d0c6968564c392bf0d09aaabb4d8bea9ca69fd224dc9b44243324acbf F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9 @@ -788,7 +788,7 @@ F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 -F src/test1.c 9df74d1d8c0513b0f906942d004b7d7aff5c6f47320a921a0b890748bac0e34d +F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7f4de43733200beeb3ff0a70d51bbc68f5331895698ea95a82741cfd7bb66834 -R 37843e70c3ec2e1305165bf8dbe6f9d9 +P af7173a10ec6a4ab465207c1ee20393e8b5f06604c0f3b2fdc19e52c2fc013d5 +R eb678ffcb571020f94837f100e38114b U drh -Z 34b3ce0ce5f61e360e39d80506afd73c +Z 8b654757f27b76942598a454f31000c3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8ab21c8735..1692b05e7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af7173a10ec6a4ab465207c1ee20393e8b5f06604c0f3b2fdc19e52c2fc013d5 +bc93e17924f732468282c5e7a483811d27af573a47aec8ba806f4fe3c5919893 diff --git a/src/test1.c b/src/test1.c index b124faa0c4..cf5d484e9e 100644 --- a/src/test1.c +++ b/src/test1.c @@ -8796,7 +8796,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite3_max_blobsize; extern int SQLITE_TCLAPI sqlite3BtreeSharedCacheReport(void*, Tcl_Interp*,int,Tcl_Obj*CONST*); - static int iZero = 0; static struct { char *zName; Tcl_CmdProc *xProc; From bf19927688a29a88de58eaf2b0618cc1c374708c Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Nov 2024 20:16:30 +0000 Subject: [PATCH 274/522] Fix the percentile extension so that works as an independent extension. [forum:/forumpost/ab25469a350e0488|Forum post ab25469a350e0488] FossilOrigin-Name: 27b829c34463d141125d31b59dd65275b88200e3edb1f8238979e02d0fc3614e --- ext/misc/percentile.c | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/misc/percentile.c b/ext/misc/percentile.c index 1c6191d42e..06865185df 100644 --- a/ext/misc/percentile.c +++ b/ext/misc/percentile.c @@ -484,10 +484,10 @@ int sqlite3_percentile_init( ){ int rc = SQLITE_OK; unsigned int i; -#if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE) - (void)pApi; /* Unused parameter */ -#else +#ifdef SQLITE3EXT_H SQLITE_EXTENSION_INIT2(pApi); +#else + (void)pApi; /* Unused parameter */ #endif (void)pzErrMsg; /* Unused parameter */ for(i=0; i Date: Tue, 5 Nov 2024 02:14:23 +0000 Subject: [PATCH 275/522] sqlite3_stdio.c now uses sqlite3_malloc()/sqlite3_free() instead of malloc()/free(). Reported in [forum:6b6cb3ddc8a89b55|forum post 6b6cb3dd]. FossilOrigin-Name: 1982471da14648594d616233be947e343611e7e3d6be7ae6b20d739e544675ea --- ext/misc/sqlite3_stdio.c | 16 ++++++++-------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/misc/sqlite3_stdio.c b/ext/misc/sqlite3_stdio.c index ba37e4be30..729504629b 100644 --- a/ext/misc/sqlite3_stdio.c +++ b/ext/misc/sqlite3_stdio.c @@ -96,8 +96,8 @@ FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ sz1 = (int)strlen(zFilename); sz2 = (int)strlen(zMode); - b1 = malloc( (sz1+1)*sizeof(b1[0]) ); - b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) ); if( b1 && b2 ){ sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); b1[sz1] = 0; @@ -105,8 +105,8 @@ FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ b2[sz2] = 0; fp = _wfopen(b1, b2); } - free(b1); - free(b2); + sqlite3_free(b1); + sqlite3_free(b2); simBinaryOther = 0; return fp; } @@ -122,8 +122,8 @@ FILE *sqlite3_popen(const char *zCommand, const char *zMode){ sz1 = (int)strlen(zCommand); sz2 = (int)strlen(zMode); - b1 = malloc( (sz1+1)*sizeof(b1[0]) ); - b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) ); if( b1 && b2 ){ sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1); b1[sz1] = 0; @@ -131,8 +131,8 @@ FILE *sqlite3_popen(const char *zCommand, const char *zMode){ b2[sz2] = 0; fp = _wpopen(b1, b2); } - free(b1); - free(b2); + sqlite3_free(b1); + sqlite3_free(b2); return fp; } diff --git a/manifest b/manifest index 0af779f43a..2274251cc9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\spercentile\sextension\sso\sthat\sworks\sas\san\sindependent\sextension.\n[forum:/forumpost/ab25469a350e0488|Forum\spost\sab25469a350e0488] -D 2024-11-04T20:16:30.101 +C sqlite3_stdio.c\snow\suses\ssqlite3_malloc()/sqlite3_free()\sinstead\sof\smalloc()/free().\sReported\sin\s[forum:6b6cb3ddc8a89b55|forum\spost\s6b6cb3dd]. +D 2024-11-05T02:14:23.003 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -440,7 +440,7 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 -F ext/misc/sqlite3_stdio.c d3359cb499ddf2fcf50c630166821b329d35c1f8ddcf78b333c894845d9e3d6c +F ext/misc/sqlite3_stdio.c c34b4aba8aec6c1ca7058a7a6319a37ab629135091600aee202390a8cd20e842 F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bc93e17924f732468282c5e7a483811d27af573a47aec8ba806f4fe3c5919893 -R a9dbcc35f79b1cb838cea81e173f644f -U drh -Z 2637c45b38cbe31368fbadc90c8592da +P 27b829c34463d141125d31b59dd65275b88200e3edb1f8238979e02d0fc3614e +R 130c58b511ddf8bb4bdfb89f08a40529 +U stephan +Z 632b31ac5524b42c189c4a8bf8a02ef6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e32f2d33bb..c072c27d7e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27b829c34463d141125d31b59dd65275b88200e3edb1f8238979e02d0fc3614e +1982471da14648594d616233be947e343611e7e3d6be7ae6b20d739e544675ea From 710d00aa6f4035561bf9be54adc4f1dec1211793 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 5 Nov 2024 02:38:32 +0000 Subject: [PATCH 276/522] Change a (#define HAVE_FCHMOD) to (#define HAVE_FCHMOD 1) per user request in [forum:24cf6020c6|forum post 24cf6020c6]. There's no semantic change for this tree, but this is consistent with how auto-config tools would define it and the empty #define interferes with some downstream code. FossilOrigin-Name: 9c46d84f3bf2f5876211b498104067d32a4000979fad1345deb1000c23716d75 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2274251cc9..dabad7b261 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C sqlite3_stdio.c\snow\suses\ssqlite3_malloc()/sqlite3_free()\sinstead\sof\smalloc()/free().\sReported\sin\s[forum:6b6cb3ddc8a89b55|forum\spost\s6b6cb3dd]. -D 2024-11-05T02:14:23.003 +C Change\sa\s(#define\sHAVE_FCHMOD)\sto\s(#define\sHAVE_FCHMOD\s1)\sper\suser\srequest\sin\s[forum:24cf6020c6|forum\spost\s24cf6020c6].\sThere's\sno\ssemantic\schange\sfor\sthis\stree,\sbut\sthis\sis\sconsistent\swith\show\sauto-config\stools\swould\sdefine\sit\sand\sthe\sempty\s#define\sinterferes\swith\ssome\sdownstream\scode. +D 2024-11-05T02:38:32.936 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -761,7 +761,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 0ad4e0885294b3a0e135a18533590ec9ad91ffe82f6a08e55b40babd51772928 +F src/os_unix.c c84a3add1e480499261a41d77d3f87d18f27aaebec6376655c177a3886a5b67c F src/os_win.c 69fa1aaff68270423c85cff4327ba17ef99a1eb017e1a2bfb97416d9b8398b05 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 27b829c34463d141125d31b59dd65275b88200e3edb1f8238979e02d0fc3614e -R 130c58b511ddf8bb4bdfb89f08a40529 +P 1982471da14648594d616233be947e343611e7e3d6be7ae6b20d739e544675ea +R 0c8d1f7a9b5a779ada3248a71bc6c2aa U stephan -Z 632b31ac5524b42c189c4a8bf8a02ef6 +Z 8d82b36b75e38596c6f943e0301a7565 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c072c27d7e..0200670fb5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1982471da14648594d616233be947e343611e7e3d6be7ae6b20d739e544675ea +9c46d84f3bf2f5876211b498104067d32a4000979fad1345deb1000c23716d75 diff --git a/src/os_unix.c b/src/os_unix.c index c13c5cece0..8cc1886745 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -213,7 +213,7 @@ # endif #else /* !SQLITE_WASI */ # ifndef HAVE_FCHMOD -# define HAVE_FCHMOD +# define HAVE_FCHMOD 1 # endif #endif /* SQLITE_WASI */ From 2c8d2519568cfe88cf9ebf82ab45bd50dd8ddc18 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 5 Nov 2024 07:29:25 +0000 Subject: [PATCH 277/522] Remove some dead makefile code. FossilOrigin-Name: b69ce89d22c4f3a2ba176f2b4b39fd430da4e253a484a1e61ec7beff3c7522a1 --- Makefile.in | 11 ----------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3a1c491997..de59f4aaa8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -171,17 +171,6 @@ T.cc.sqlite += -I$(prefix)/include # # main.mk will fill out T.cc.sqlite with some flags common to all builds. -#XX#CFLAGS.readline += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ -#XX#CFLAGS.readline += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ -#XX# -#XX## The library that programs using readline() must link against. -#XX## -#XX#LIBREADLINE = @TARGET_READLINE_LIBS@ -#XX# -#XX## Should the database engine be compiled threadsafe -#XX## -#XX#T.cc += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ - # # $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH) # must start with a path component so that it can be invoked as a diff --git a/manifest b/manifest index dabad7b261..bb1102e2d7 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Change\sa\s(#define\sHAVE_FCHMOD)\sto\s(#define\sHAVE_FCHMOD\s1)\sper\suser\srequest\sin\s[forum:24cf6020c6|forum\spost\s24cf6020c6].\sThere's\sno\ssemantic\schange\sfor\sthis\stree,\sbut\sthis\sis\sconsistent\swith\show\sauto-config\stools\swould\sdefine\sit\sand\sthe\sempty\s#define\sinterferes\swith\ssome\sdownstream\scode. -D 2024-11-05T02:38:32.936 +C Remove\ssome\sdead\smakefile\scode. +D 2024-11-05T07:29:25.010 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 3cb3754680dc2f06f6858ef8068ad1c947709dfae705466d383f25d7f222f4ab +F Makefile.in 66cd5f5b89e6f21f7475fd6cd34008c8cd1ec773f22c4aa7f7eafd3ca3634fe9 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1982471da14648594d616233be947e343611e7e3d6be7ae6b20d739e544675ea -R 0c8d1f7a9b5a779ada3248a71bc6c2aa +P 9c46d84f3bf2f5876211b498104067d32a4000979fad1345deb1000c23716d75 +R 94be190eadef1e7adb6950cdb6c35260 U stephan -Z 8d82b36b75e38596c6f943e0301a7565 +Z 0835ffe7367ea13f057f80bd1a7d7fa5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0200670fb5..9172ab38bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c46d84f3bf2f5876211b498104067d32a4000979fad1345deb1000c23716d75 +b69ce89d22c4f3a2ba176f2b4b39fd430da4e253a484a1e61ec7beff3c7522a1 From 63346a4bcaf1db736602a9921afe648a23a8dc94 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 5 Nov 2024 07:55:33 +0000 Subject: [PATCH 278/522] Add the --enable-rbu configure flag and building of the commented-out rbu binary. FossilOrigin-Name: 6c6fa3adfee6ec2c57dc76461e7c97416b4fad45772ce367d223cc67e66049f6 --- auto.def | 6 ++++-- main.mk | 6 +++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/auto.def b/auto.def index cf50eecf0f..7d67ad7675 100644 --- a/auto.def +++ b/auto.def @@ -144,6 +144,7 @@ set flags { geopoly => {Enable the GEOPOLY extension} rtree => {Enable the RTREE extension} session => {Enable the SESSION extension} + rbu => {Enable the RBU extension} all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} # # @@ -169,7 +170,7 @@ set flags { # --with-readline-ldflags with-readline-lib: with-readline-ldflags:=auto - => {Readline LDFLAGS, e.g. -lreadline -lncurses} + => {Readline LDFLAGS, e.g. -lreadline -lncurses} # --with-readline-inc is a backwards-compatible alias for # --with-readline-cflags. with-readline-inc: @@ -178,7 +179,7 @@ set flags { with-readline-header:PATH => {Full path to readline.h, from which --with-readline-cflags will be derived} with-linenoise:DIR => {Source directory for linenoise.c and linenoise.h} - editline=0 => {BSD editline support} + editline=0 => {Enable BSD editline support} # # with-icu-ldflags:LDFLAGS @@ -1128,6 +1129,7 @@ foreach {boolFlag featureFlag ifSetEvalThis} { fts5 -DSQLITE_ENABLE_FTS5 {affirm-have-math fts5} geopoly -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree} rtree -DSQLITE_ENABLE_RTREE {} + rbu -DSQLITE_ENABLE_RBU {} session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {} update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {} memsys5 -DSQLITE_ENABLE_MEMSYS5 {} diff --git a/main.mk b/main.mk index a89aa5e9dc..a0fc7de672 100644 --- a/main.mk +++ b/main.mk @@ -1796,9 +1796,9 @@ kvtest$(T.exe): $(TOP)/test/kvtest.c sqlite3.c $(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3) xbin: kvtest$(T.exe) -#rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o -# $(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) -#xbin: rbu$(T.exe) +rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o + $(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) +xbin: rbu$(T.exe) loadfts$(T.exe): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) $(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3) diff --git a/manifest b/manifest index bb1102e2d7..398e462911 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sdead\smakefile\scode. -D 2024-11-05T07:29:25.010 +C Add\sthe\s--enable-rbu\sconfigure\sflag\sand\sbuilding\sof\sthe\scommented-out\srbu\sbinary. +D 2024-11-05T07:55:33.088 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def dc62d3c918d2750248e6811b24c2cbbd51d1457d7f6ffd11e0bf61dd5770cb3e +F auto.def dd8555a00b22645f0ec06bde38f36fb4a9625fb2ce0950d79dc13c3051f242d1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -698,7 +698,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk a066ab09a00cfc641359db6fde6d466201c2bf51d95bf48086e5bc3ea401640d +F main.mk 342578d173fd10ab1128d29b0fb61722b8ac08d73e1dd2cf66ea1f27c3bea0f2 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9c46d84f3bf2f5876211b498104067d32a4000979fad1345deb1000c23716d75 -R 94be190eadef1e7adb6950cdb6c35260 +P b69ce89d22c4f3a2ba176f2b4b39fd430da4e253a484a1e61ec7beff3c7522a1 +R 7ed0947f08dede3e232e5b0d2dca4087 U stephan -Z 0835ffe7367ea13f057f80bd1a7d7fa5 +Z ca576f54e59ca5482db96e0d783912c6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9172ab38bf..cbaca5f695 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b69ce89d22c4f3a2ba176f2b4b39fd430da4e253a484a1e61ec7beff3c7522a1 +6c6fa3adfee6ec2c57dc76461e7c97416b4fad45772ce367d223cc67e66049f6 From 3205eab2f2026606f556be71d7a045d77078571e Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 5 Nov 2024 08:14:27 +0000 Subject: [PATCH 279/522] Roll back [47e50fa84dacf83c] for consistency with the legacy build. sqlite3.pc is now generated equivalently to prior versions. FossilOrigin-Name: af79d11e389b4772a401f6c2cbde42de95287addf7077ad4db55d39cc504f9fe --- manifest | 12 ++++++------ manifest.uuid | 2 +- sqlite3.pc.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 398e462911..7e9a7e6d58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--enable-rbu\sconfigure\sflag\sand\sbuilding\sof\sthe\scommented-out\srbu\sbinary. -D 2024-11-05T07:55:33.088 +C Roll\sback\s[47e50fa84dacf83c]\sfor\sconsistency\swith\sthe\slegacy\sbuild.\ssqlite3.pc\sis\snow\sgenerated\sequivalently\sto\sprior\sversions. +D 2024-11-05T08:14:27.481 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -707,7 +707,7 @@ F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0 F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc -F sqlite3.pc.in 2d5c88643679fc199dafc9afb6ea8868ea3192d941c2e57dbe06395149d892ba +F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b69ce89d22c4f3a2ba176f2b4b39fd430da4e253a484a1e61ec7beff3c7522a1 -R 7ed0947f08dede3e232e5b0d2dca4087 +P 6c6fa3adfee6ec2c57dc76461e7c97416b4fad45772ce367d223cc67e66049f6 +R 91f8f712e56b95f1d0840a661628f372 U stephan -Z ca576f54e59ca5482db96e0d783912c6 +Z 5ec50233ebe03347ef3d5c1ede9ca068 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cbaca5f695..00a2ccce48 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c6fa3adfee6ec2c57dc76461e7c97416b4fad45772ce367d223cc67e66049f6 +af79d11e389b4772a401f6c2cbde42de95287addf7077ad4db55d39cc504f9fe diff --git a/sqlite3.pc.in b/sqlite3.pc.in index 97f3c1a60d..a9f941b1e4 100644 --- a/sqlite3.pc.in +++ b/sqlite3.pc.in @@ -9,5 +9,5 @@ Name: SQLite Description: SQL database engine Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lsqlite3 -Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ICU@ +Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ZLIB@ @LDFLAGS_ICU@ Cflags: -I${includedir} From e69d98df22bf49c4016b0b99cec8b0d73c99f2e3 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 5 Nov 2024 08:21:47 +0000 Subject: [PATCH 280/522] Enhance the rpath configure check to honor --exec-prefix=... Remove some debugging code and move other debugging code around. FossilOrigin-Name: a8c1a82b56412a4277a3c9bf2b256d3bd22bd8aca9096b8d08fcc0bf7d9364cb --- auto.def | 65 +++++++++++++++++++++++++--------------------- autosetup/proj.tcl | 15 +++++------ manifest | 14 +++++----- manifest.uuid | 2 +- 4 files changed, 49 insertions(+), 47 deletions(-) diff --git a/auto.def b/auto.def index 7d67ad7675..aa3e23e85f 100644 --- a/auto.def +++ b/auto.def @@ -217,12 +217,6 @@ proj-xfer-options-aliases { with-readline-inc => with-readline-cflags with-readline-lib => with-readline-ldflags } -# -# "Re-export" the autoconf-conventional --XYZdir flags into something -# which is more easily overridable from a make invocation. See the docs -# for [proj-redirect-autoconf-dir-vars] for the explanation of why. -# -proj-redirect-autoconf-dir-vars set srcdir $::autosetup(srcdir) set top_srcdir [get-define abs_top_srcdir] @@ -1204,6 +1198,18 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available }; # JimTCL + +######################################################################## +# "Re-export" the autoconf-conventional --XYZdir flags into something +# which is more easily overridable from a make invocation. See the docs +# for [proj-redirect-autoconf-dir-vars] for the explanation of why. +# +# We do this late in the config process, immediately before we export +# the Makefile and other generated files, so that configure tests +# which may make use of the autotools-conventional flags +# (e.g. [proj-check-rpath]) may do so before we "mangle" them here. +proj-redirect-autoconf-dir-vars + ######################################################################## # Generate the output files. # @@ -1224,30 +1230,6 @@ if {0} { -none * proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@ } -#TODO proj-make-from-dot-in ext/wasm/GNUmakefile - -if {"" ne $DUMP_DEFINES_JSON} { - ######################################################################## - # Dump config-defines.json... - # Demonstrate (mis?)handling of spaces in JSON-export array values: - # define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} - define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] - define OPT_SHELL.list [get-define OPT_SHELL] - set dumpDefsOpt { - -bare {SIZEOF_* HAVE_DECL_*} - -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG TARGET_* USE_GCOV TCL_*} - -array {*.list} - -auto {OPT_* PACKAGE_* HAVE_*} - } - if {[opt-bool defines-json-include-lowercase]} { - lappend dumpDefsOpt -none {lib_*} ; # remnants from proj-check-function-in-lib and friends - lappend dumpDefsOpt -auto {[a-z]*} - } - lappend dumpDefsOpt -none * - proj-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt - undefine OPT_FEATURE_FLAGS.list - undefine OPT_SHELL.list -} ######################################################################## # Some build-dev/debug-only output @@ -1264,4 +1246,27 @@ proj-if-opt-truthy dump-defines { puts "\t$x" } } + if {"" ne $DUMP_DEFINES_JSON} { + msg-result "--dump-defines is creating $::DUMP_DEFINES_JSON" + ######################################################################## + # Dump config-defines.json... + # Demonstrate (mis?)handling of spaces in JSON-export array values: + # define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} + define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] + define OPT_SHELL.list [get-define OPT_SHELL] + set dumpDefsOpt { + -bare {SIZEOF_* HAVE_DECL_*} + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG TARGET_* USE_GCOV TCL_*} + -array {*.list} + -auto {OPT_* PACKAGE_* HAVE_*} + } + if {[opt-bool defines-json-include-lowercase]} { + lappend dumpDefsOpt -none {lib_*} ; # remnants from proj-check-function-in-lib and friends + lappend dumpDefsOpt -auto {[a-z]*} + } + lappend dumpDefsOpt -none * + proj-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt + undefine OPT_FEATURE_FLAGS.list + undefine OPT_SHELL.list + } } diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index eee526dea6..05695ca26a 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -790,16 +790,18 @@ proc proj-check-emsdk {} { # flag. Defines LDFLAGS_RPATH to that/those flag(s) or an empty # string. Returns 1 if it finds an option, else 0. # -# By default, the rpath is set to $prefix/lib. However, if -# --libdir=... is explicitly passed to configure then that value is -# used. +# By default, the rpath is set to $prefix/lib. However, if either of +# --exec-prefix=... or --libdir=... are explicitly passed to +# configure then [get-define libdir] is used (noting that it derives +# from exec-prefix by default). # # Achtung: we have seen platforms which report that a given option # checked here will work but then fails at build-time, and the current # order of checks reflects that. proc proj-check-rpath {} { set rc 1 - if {[proj-opt-was-provided libdir]} { + if {[proj-opt-was-provided libdir] + || [proj-opt-was-provided exec-prefix]} { set lp "[get-define libdir]" } else { set lp "[get-define prefix]/lib" @@ -1090,7 +1092,6 @@ proc proj-redirect-autoconf-dir-vars {} { # [subst] command. i.e. they must use the form ${X}. foreach {flag makeVar makeDeref} { exec-prefix exec_prefix ${prefix} - libdir libdir ${exec_prefix}/lib datadir datadir ${prefix}/share mandir mandir ${datadir}/man includedir includedir ${prefix}/include @@ -1104,15 +1105,11 @@ proc proj-redirect-autoconf-dir-vars {} { infodir infodir ${datadir}/info libexecdir libexecdir ${exec_prefix}/libexec } { - # puts "flag=$flag var=$makeVar makeDeref=$makeDeref" if {[proj-opt-was-provided $flag]} { - #set x "+" define $makeVar [opt-val $flag] } else { - #set x "~" define $makeVar $makeDeref } - #puts "$x $makeVar = [get-define $makeVar]" } } diff --git a/manifest b/manifest index 7e9a7e6d58..3c5981fff8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Roll\sback\s[47e50fa84dacf83c]\sfor\sconsistency\swith\sthe\slegacy\sbuild.\ssqlite3.pc\sis\snow\sgenerated\sequivalently\sto\sprior\sversions. -D 2024-11-05T08:14:27.481 +C Enhance\sthe\srpath\sconfigure\scheck\sto\shonor\s--exec-prefix=...\sRemove\ssome\sdebugging\scode\sand\smove\sother\sdebugging\scode\saround. +D 2024-11-05T08:21:47.035 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def dd8555a00b22645f0ec06bde38f36fb4a9625fb2ce0950d79dc13c3051f242d1 +F auto.def 3f6aec871699bc3e54f7dc6f4496daf4b435d4b8326bfed51ccabd12b633988c F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 0bcced417a59fc56da5e6cc6a83e10cca4e10710c0f2f1ae9bc82b366d17699d +F autosetup/proj.tcl 16138ac9c8bc071613b260a18f46ada9a31ed3b496a7ae6f403fd9d49d588aea F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6c6fa3adfee6ec2c57dc76461e7c97416b4fad45772ce367d223cc67e66049f6 -R 91f8f712e56b95f1d0840a661628f372 +P af79d11e389b4772a401f6c2cbde42de95287addf7077ad4db55d39cc504f9fe +R 8f4205f94f3bfdb54022edc4daed40c7 U stephan -Z 5ec50233ebe03347ef3d5c1ede9ca068 +Z 23df65f4992f1d4489c83b5031514bec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 00a2ccce48..a0e57dacbc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af79d11e389b4772a401f6c2cbde42de95287addf7077ad4db55d39cc504f9fe +a8c1a82b56412a4277a3c9bf2b256d3bd22bd8aca9096b8d08fcc0bf7d9364cb From 6d443b0d74a5096da679f545989b8a8d78fbd9d5 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 5 Nov 2024 09:49:53 +0000 Subject: [PATCH 281/522] auto.def: remove an extraneous global var, some dead tcl/makefile code/comments, and some extraneous output. Rename an internal-use proc. Disable the ext/wasm cleanup in the top-level (dist)clean because the noise from gmake is irritating. FossilOrigin-Name: ee9eb8b157c93b33a8ac201c31169cdd1d2cf2f21da92f7a6a418a41e5a50b7b --- Makefile.in | 27 +++++++++------------------ auto.def | 31 ++++++++++--------------------- autosetup/proj.tcl | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 29 insertions(+), 49 deletions(-) diff --git a/Makefile.in b/Makefile.in index de59f4aaa8..79154f3fed 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4,9 +4,7 @@ # Makefile for SQLITE # # This makefile is intended to be configured automatically using the -# configure script. Hand editing may not work as expected because -# certain blocks are added or removed depending on configure-time -# information. +# configure script. # # The docs for many of its variables are in the primary static # makefile, main.mk (which this one includes at runtime). @@ -18,10 +16,6 @@ all: # Known TODOs/FIXMEs/TOIMPROVEs for the autosetup port, in no # particular order... # -# - libreadline detection and handling of its -I, -L, and -l flags. -# These can vary considerably across systems. e.g. some need -lncurses, -# and some don't know what an -lncurses is. -# # - TEA pieces. # # - Replace the autotools-specific distribution deliverable(s). @@ -34,13 +28,6 @@ all: # - This makefile should remain as POSIX-make-compatible as possible: # https://pubs.opengroup.org/onlinepubs/9799919799/utilities/make.html # -# - When using the X?=Y variable assignment formulation, please test -# the build with both GNU make and a POSIX make (e.g. BSD make, -# a.k.a. bmake). On at least one occassion, that formulation has led -# to inconsistent behavior between the two major make flavors when -# used with variable names which might sensibly be in the -# developer's environment (namely CC). -# # - The naming convention of some vars, using periods instead of # underscores, though unconventional, was selected for a couple of # reasons: 1) Personal taste (for which there is no accounting). 2) @@ -357,16 +344,20 @@ misspell: ./custom.rws has_tclsh84 # perform cleanup known to be relevant to (only) the autosetup-driven # build. # -clean-autosetup: - -gmake -C ext/wasm distclean 2>/dev/null || true -clean: clean-autosetup +#clean-autosetup: +# -if [ -f ext/wasm/GNUmakefile ]; then \ +# gmake --no-print-directory --ignore-errors -C ext/wasm clean; \ +# fi >/dev/null 2>&1; true +#clean: clean-autosetup distclean-autosetup: clean rm -f sqlite_cfg.h config.log config.status config.defines.* Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh rm -f libsqlite3*$(T.dll) rm -f jimsh0* - -gmake -C ext/wasm distclean 2>/dev/null; true +# -if [ -f ext/wasm/GNUmakefile ]; then \ +# gmake --no-print-directory --ignore-errors -C ext/wasm distclean; \ +# fi >/dev/null 2>&1; true distclean: distclean-autosetup # diff --git a/auto.def b/auto.def index aa3e23e85f..5f751c77f8 100644 --- a/auto.def +++ b/auto.def @@ -219,15 +219,14 @@ proj-xfer-options-aliases { } set srcdir $::autosetup(srcdir) -set top_srcdir [get-define abs_top_srcdir] -set PACKAGE_VERSION [readfile $srcdir/VERSION] +set PACKAGE_VERSION [proj-file-content -trim $srcdir/VERSION] define PACKAGE_NAME "sqlite" define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION $PACKAGE_VERSION define PACKAGE_STRING "[get-define PACKAGE_NAME] $PACKAGE_VERSION" define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum -msg-result "srcdir = $srcdir" -msg-result "top_srcdir = $top_srcdir" +msg-result "Source dir = $srcdir" +msg-result "Build dir = $::autosetup(builddir)" msg-result "Configuring SQLite version $PACKAGE_VERSION" # @@ -235,7 +234,7 @@ msg-result "Configuring SQLite version $PACKAGE_VERSION" # configure script with the same arguments it was initially invoked # with. This can be used to automatically reconfigure # -define-append SQLITE_AUTORECONFIG cd '$::autosetup(builddir)' && '$top_srcdir/configure' +define-append SQLITE_AUTORECONFIG cd '$::autosetup(builddir)' && '$srcdir/configure' #{*}$::autosetup(argv) breaks with --flag='val with spaces', so... foreach arg $::autosetup(argv) { define-append SQLITE_AUTORECONFIG '$arg' @@ -243,11 +242,6 @@ foreach arg $::autosetup(argv) { # Are we cross-compiling? set isCrossCompiling [proj-is-cross-compiling] -if {![file exists sqlite3.pc.in]} { - msg-result "This appears to be an out-of-tree build." -} - -cc-check-tools ld ar define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags. define OPT_SHELL {} ; # CFLAGS for the sqlite3 CLI app @@ -297,6 +291,7 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { ######### # Programs needed +cc-check-tools ld ar ; # must come before sqlite-check-wasi-sdk if {"" eq [proj-bin-define install]} { proj-warn "Cannot find install binary, so 'make install' will not work." } @@ -482,7 +477,7 @@ proc sqlite-check-tcl {} { return } # TODO: document the steps this is taking. - global top_srcdir + global srcdir msg-result "Checking for a suitable tcl... " proj-assert {proj-opt-truthy tcl} set use_tcl 1 @@ -509,7 +504,7 @@ proc sqlite-check-tcl {} { define TCLSH_CMD $with_tclsh #msg-result "Using tclsh: $with_tclsh" } - if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { + if {[catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} { set with_tcl $result } if {"" ne $with_tcl && [file isdir $with_tcl]} { @@ -575,7 +570,7 @@ proc sqlite-check-tcl {} { # Export a subset of tclConfig.sh to the current TCL-space. If the # config is not available, this emits empty-string entries for the # various options we're interested in. - eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] + eval [exec "${srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] if {"" eq $with_tclsh && $cfg ne ""} { proj-assert {expr {"" ne [get-define TCL_EXEC_PREFIX]}} @@ -1202,13 +1197,13 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { ######################################################################## # "Re-export" the autoconf-conventional --XYZdir flags into something # which is more easily overridable from a make invocation. See the docs -# for [proj-redirect-autoconf-dir-vars] for the explanation of why. +# for [proj-remap-autoconf-dir-vars] for the explanation of why. # # We do this late in the config process, immediately before we export # the Makefile and other generated files, so that configure tests # which may make use of the autotools-conventional flags # (e.g. [proj-check-rpath]) may do so before we "mangle" them here. -proj-redirect-autoconf-dir-vars +proj-remap-autoconf-dir-vars ######################################################################## # Generate the output files. @@ -1234,18 +1229,12 @@ if {0} { ######################################################################## # Some build-dev/debug-only output proj-if-opt-truthy dump-defines { - msg-result "--dump-defines is creating $::DUMP_DEFINES_TXT" make-config-header $::DUMP_DEFINES_TXT \ -bare {SQLITE_OS* SQLITE_DEBUG USE_*} \ -str {BIN_* CC LD AR LDFLAG* OPT_*} \ -auto {*} # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will # get _undefined_ here unless it's part of the -bare set. - if {0} { - foreach x [all-defines] { - puts "\t$x" - } - } if {"" ne $DUMP_DEFINES_JSON} { msg-result "--dump-defines is creating $::DUMP_DEFINES_JSON" ######################################################################## diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 05695ca26a..5f6f083ead 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1083,7 +1083,7 @@ proc proj-which-linenoise {dotH} { # configure-time, so would be tedious to override properly via a make # invocation. # -proc proj-redirect-autoconf-dir-vars {} { +proc proj-remap-autoconf-dir-vars {} { set prefix [get-define prefix] set exec_prefix [get-define exec_prefix $prefix] # Note that the ${...} here refers to make-side var derefs, not diff --git a/manifest b/manifest index 3c5981fff8..531fd86fad 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Enhance\sthe\srpath\sconfigure\scheck\sto\shonor\s--exec-prefix=...\sRemove\ssome\sdebugging\scode\sand\smove\sother\sdebugging\scode\saround. -D 2024-11-05T08:21:47.035 +C auto.def:\sremove\san\sextraneous\sglobal\svar,\ssome\sdead\stcl/makefile\scode/comments,\sand\ssome\sextraneous\soutput.\sRename\san\sinternal-use\sproc.\sDisable\sthe\sext/wasm\scleanup\sin\sthe\stop-level\s(dist)clean\sbecause\sthe\snoise\sfrom\sgmake\sis\sirritating. +D 2024-11-05T09:49:53.043 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 66cd5f5b89e6f21f7475fd6cd34008c8cd1ec773f22c4aa7f7eafd3ca3634fe9 +F Makefile.in 3a54957d16c3f4666922f170a19b4b51dc13be039c29394dd38caa95ade5d731 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 3f6aec871699bc3e54f7dc6f4496daf4b435d4b8326bfed51ccabd12b633988c +F auto.def ac7dfc51216c6aa7d34e82d73c945cb71758a3fb79612ef2c5ed38f468d980e8 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 16138ac9c8bc071613b260a18f46ada9a31ed3b496a7ae6f403fd9d49d588aea +F autosetup/proj.tcl f4762bc4826f3b378bef71236643413c501d537be7320cbc3a163752b1f90964 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P af79d11e389b4772a401f6c2cbde42de95287addf7077ad4db55d39cc504f9fe -R 8f4205f94f3bfdb54022edc4daed40c7 +P a8c1a82b56412a4277a3c9bf2b256d3bd22bd8aca9096b8d08fcc0bf7d9364cb +R 486858acf83a0ad9398b7511ee6bf899 U stephan -Z 23df65f4992f1d4489c83b5031514bec +Z 17b7f42f98ea7458ea07b6ef75ca0d94 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a0e57dacbc..2aaf46d2a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8c1a82b56412a4277a3c9bf2b256d3bd22bd8aca9096b8d08fcc0bf7d9364cb +ee9eb8b157c93b33a8ac201c31169cdd1d2cf2f21da92f7a6a418a41e5a50b7b From 2139c35da0349277dfcf4a830a8df4e316383188 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 5 Nov 2024 11:59:45 +0000 Subject: [PATCH 282/522] Ensure that the one-line running status output from testrunner.tcl does not exceed the 80-char line width of a standard terminal. FossilOrigin-Name: 1eae0f9ed3c4530d117a8efc4adaf0b2cc422083f0407830a1a6d2a5b970fa1a --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/testrunner.tcl | 32 +++++++++++++------------------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 531fd86fad..8d6a1004aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C auto.def:\sremove\san\sextraneous\sglobal\svar,\ssome\sdead\stcl/makefile\scode/comments,\sand\ssome\sextraneous\soutput.\sRename\san\sinternal-use\sproc.\sDisable\sthe\sext/wasm\scleanup\sin\sthe\stop-level\s(dist)clean\sbecause\sthe\snoise\sfrom\sgmake\sis\sirritating. -D 2024-11-05T09:49:53.043 +C Ensure\sthat\sthe\sone-line\srunning\sstatus\soutput\sfrom\stestrunner.tcl\sdoes\snot\nexceed\sthe\s80-char\sline\swidth\sof\sa\sstandard\sterminal. +D 2024-11-05T11:59:45.661 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -1720,7 +1720,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 -F test/testrunner.tcl 3c6acf0eecd2b5459082639183f2b4f667aa0b74ddab24e4d37295112c7a5325 x +F test/testrunner.tcl c40d5700578f8c9d00e0e15f105f645c471bc2c48eb8b013bd2953400f2c6bf0 x F test/testrunner_data.tcl ba4aeea28aa03cfa6fe7e57782ddecb7a7b91c3a0b3251583cb4f0ee002de6a6 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a8c1a82b56412a4277a3c9bf2b256d3bd22bd8aca9096b8d08fcc0bf7d9364cb -R 486858acf83a0ad9398b7511ee6bf899 -U stephan -Z 17b7f42f98ea7458ea07b6ef75ca0d94 +P ee9eb8b157c93b33a8ac201c31169cdd1d2cf2f21da92f7a6a418a41e5a50b7b +R 42fdf6d683cf4cf4bef385bd5a8dd761 +U drh +Z 5ea36a74eb3b5e1b4fcf77e0c8195535 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2aaf46d2a2..83fd9d0272 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee9eb8b157c93b33a8ac201c31169cdd1d2cf2f21da92f7a6a418a41e5a50b7b +1eae0f9ed3c4530d117a8efc4adaf0b2cc422083f0407830a1a6d2a5b970fa1a diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 66fa1058bb..889bfeaffd 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -547,12 +547,15 @@ proc show_status {db cls} { set srcdir [file dirname [file dirname $TRG(info_script)]] set line "Running: $S(running) (max: $nJob)" - if {$S(running)>0 && $fin>10 && [string length $line]<69} { + if {$S(running)>0 && $fin>10} { set tmleft [expr {($tm/$fin)*($totalw-$fin)}] if {$tmleft<0.02*$tm} { set tmleft [expr {$tm*0.02}] } - append line " ETC [elapsetime $tmleft]" + set etc " ETC [elapsetime $tmleft]" + if {[string length $line]+[string length $etc]<80} { + append line $etc + } } puts [format %-79.79s $line] if {$S(running)>0} { @@ -1369,10 +1372,7 @@ proc script_input_ready {fd iJob jobid} { set state "done" set rc [catch { close $fd } msg] if {$rc} { - if {[info exists TRG(reportlength)]} { - puts -nonewline "[string repeat " " $TRG(reportlength)]\r" - } - puts "FAILED: $job(displayname) ($iJob)" + puts [format %-79.79s "FAILED: $job(displayname) ($iJob)"] set state "failed" if {$TRG(stopOnError)} { puts "OUTPUT: $O($iJob)" @@ -1523,22 +1523,16 @@ proc progress_report {} { lappend text "r$v(running,$j)" } } + set report "[elapsetime $tmms] [join $text { }]" if {$wdone>0} { set tmleft [expr {($tmms/$wdone)*($wtotal-$wdone)}] - append text " ETC [elapsetime $tmleft]" - } - - if {[info exists TRG(reportlength)]} { - puts -nonewline "[string repeat " " $TRG(reportlength)]\r" - } - set report "[elapsetime $tmms] [join $text { }]" - set TRG(reportlength) [string length $report] - if {[string length $report]<100} { - puts -nonewline "$report\r" - flush stdout - } else { - puts $report + set etc " ETC [elapsetime $tmleft]" + if {[string length $report]+[string length $etc]<80} { + append report $etc + } } + puts -nonewline [format %-79.79s $report]\r + flush stdout } after $TRG(reporttime) progress_report } From d2ac1c5b7c0d3d41624b9c3aa71db6246ec26f46 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 5 Nov 2024 13:03:58 +0000 Subject: [PATCH 283/522] Remove the --enable-rbu flag from the configure script, per /chat discussion, because it's a highly niche feature not in active use. FossilOrigin-Name: 77db0cd736746873d4ed3dbf0e9a43a3e15ab49961fccee20417e01f88de8664 --- auto.def | 2 -- main.mk | 5 ++++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/auto.def b/auto.def index 5f751c77f8..7f1c9d6a86 100644 --- a/auto.def +++ b/auto.def @@ -144,7 +144,6 @@ set flags { geopoly => {Enable the GEOPOLY extension} rtree => {Enable the RTREE extension} session => {Enable the SESSION extension} - rbu => {Enable the RBU extension} all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} # # @@ -1118,7 +1117,6 @@ foreach {boolFlag featureFlag ifSetEvalThis} { fts5 -DSQLITE_ENABLE_FTS5 {affirm-have-math fts5} geopoly -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree} rtree -DSQLITE_ENABLE_RTREE {} - rbu -DSQLITE_ENABLE_RBU {} session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {} update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {} memsys5 -DSQLITE_ENABLE_MEMSYS5 {} diff --git a/main.mk b/main.mk index a0fc7de672..bcb642398e 100644 --- a/main.mk +++ b/main.mk @@ -1796,9 +1796,12 @@ kvtest$(T.exe): $(TOP)/test/kvtest.c sqlite3.c $(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3) xbin: kvtest$(T.exe) +# +# rbu$(T.exe) requires building with -DSQLITE_ENABLE_RBU, which +# specifically does not have an --enable-rbu flag in the configure +# script. rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o $(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: rbu$(T.exe) loadfts$(T.exe): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) $(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3) diff --git a/manifest b/manifest index 8d6a1004aa..fb9f6e0d34 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sone-line\srunning\sstatus\soutput\sfrom\stestrunner.tcl\sdoes\snot\nexceed\sthe\s80-char\sline\swidth\sof\sa\sstandard\sterminal. -D 2024-11-05T11:59:45.661 +C Remove\sthe\s--enable-rbu\sflag\sfrom\sthe\sconfigure\sscript,\sper\s/chat\sdiscussion,\sbecause\sit's\sa\shighly\sniche\sfeature\snot\sin\sactive\suse. +D 2024-11-05T13:03:58.554 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def ac7dfc51216c6aa7d34e82d73c945cb71758a3fb79612ef2c5ed38f468d980e8 +F auto.def 348be257a61090f739287d54046f63801c99705f42fae0dffa2ba415dd9afcfb F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -698,7 +698,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 342578d173fd10ab1128d29b0fb61722b8ac08d73e1dd2cf66ea1f27c3bea0f2 +F main.mk ef087df40894cf2c024ec5f4d763853616c9616b073fb86b71146f11fa003af3 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ee9eb8b157c93b33a8ac201c31169cdd1d2cf2f21da92f7a6a418a41e5a50b7b -R 42fdf6d683cf4cf4bef385bd5a8dd761 -U drh -Z 5ea36a74eb3b5e1b4fcf77e0c8195535 +P 1eae0f9ed3c4530d117a8efc4adaf0b2cc422083f0407830a1a6d2a5b970fa1a +R 5832e2fda8be65dd3be8138925e4ff6f +U stephan +Z 66fc4d6192e82f3b20a33931887419b0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 83fd9d0272..36c6766e69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1eae0f9ed3c4530d117a8efc4adaf0b2cc422083f0407830a1a6d2a5b970fa1a +77db0cd736746873d4ed3dbf0e9a43a3e15ab49961fccee20417e01f88de8664 From 2ad29f3611e47d83d69bb6fbbad47a852a839907 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 5 Nov 2024 13:34:30 +0000 Subject: [PATCH 284/522] Work around a TCL {list-quoting} quirk when escaped/deferred var derefs are passed in as values to the autotools-conventional --XYZdir flags (as seen in a downstream package build script). FossilOrigin-Name: 6adfca7e85648584740c8a127b95bd46aaad45fa2d162bd44622bb47debbcbcb --- autosetup/proj.tcl | 8 ++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 5f6f083ead..82835ed601 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1106,10 +1106,14 @@ proc proj-remap-autoconf-dir-vars {} { libexecdir libexecdir ${exec_prefix}/libexec } { if {[proj-opt-was-provided $flag]} { - define $makeVar [opt-val $flag] + define $makeVar [join [opt-val $flag]] } else { - define $makeVar $makeDeref + define $makeVar [join $makeDeref] } + # Maintenance reminder: the [join] call is to avoid {braces} + # around the output when someone passes in, + # e.g. --libdir=\${prefix}/foo/bar. The Debian package build + # script does that. } } diff --git a/manifest b/manifest index fb9f6e0d34..09fe31c060 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\s--enable-rbu\sflag\sfrom\sthe\sconfigure\sscript,\sper\s/chat\sdiscussion,\sbecause\sit's\sa\shighly\sniche\sfeature\snot\sin\sactive\suse. -D 2024-11-05T13:03:58.554 +C Work\saround\sa\sTCL\s{list-quoting}\squirk\swhen\sescaped/deferred\svar\sderefs\sare\spassed\sin\sas\svalues\sto\sthe\sautotools-conventional\s--XYZdir\sflags\s(as\sseen\sin\sa\sdownstream\spackage\sbuild\sscript). +D 2024-11-05T13:34:30.811 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -49,7 +49,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl f4762bc4826f3b378bef71236643413c501d537be7320cbc3a163752b1f90964 +F autosetup/proj.tcl a3f180a97db6cf398f12d8e688651d10b8707c4869eb0096bfbf0b2952b31131 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1eae0f9ed3c4530d117a8efc4adaf0b2cc422083f0407830a1a6d2a5b970fa1a -R 5832e2fda8be65dd3be8138925e4ff6f +P 77db0cd736746873d4ed3dbf0e9a43a3e15ab49961fccee20417e01f88de8664 +R dc412e7f7529f14cc6f79cc175ee95e6 U stephan -Z 66fc4d6192e82f3b20a33931887419b0 +Z 5cbeb98d76b54f40a03e87cc7f52d846 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 36c6766e69..e42222f4fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77db0cd736746873d4ed3dbf0e9a43a3e15ab49961fccee20417e01f88de8664 +6adfca7e85648584740c8a127b95bd46aaad45fa2d162bd44622bb47debbcbcb From 19c4fa92dda7ed7e2fee4d91fb3be456b59e83c7 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 5 Nov 2024 18:25:32 +0000 Subject: [PATCH 285/522] Have the xBestIndex method of the generate_series virtual table ignore contraints on the "value" column with usable=0. FossilOrigin-Name: f5113a2ef84831ad2da723fa7e29e0d575e74e10585741ff51db8c2e37332cd2 --- ext/misc/series.c | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/tabfunc01.test | 23 +++++++++++++++++++++++ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index 64f3be2c05..aff9796922 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -659,7 +659,7 @@ static int seriesBestIndex( continue; } if( pConstraint->iColumniColumn==SERIES_COLUMN_VALUE ){ + if( pConstraint->iColumn==SERIES_COLUMN_VALUE && pConstraint->usable ){ switch( op ){ case SQLITE_INDEX_CONSTRAINT_EQ: case SQLITE_INDEX_CONSTRAINT_IS: { diff --git a/manifest b/manifest index 09fe31c060..267fa43e10 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Work\saround\sa\sTCL\s{list-quoting}\squirk\swhen\sescaped/deferred\svar\sderefs\sare\spassed\sin\sas\svalues\sto\sthe\sautotools-conventional\s--XYZdir\sflags\s(as\sseen\sin\sa\sdownstream\spackage\sbuild\sscript). -D 2024-11-05T13:34:30.811 +C Have\sthe\sxBestIndex\smethod\sof\sthe\sgenerate_series\svirtual\stable\signore\scontraints\son\sthe\s"value"\scolumn\swith\susable=0. +D 2024-11-05T18:25:32.313 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -434,7 +434,7 @@ F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab840709636240 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c ea604a16f9c5f7e09ccff3f18d94f2c3a6fa24ca08856156823d981873b8143c +F ext/misc/series.c cbdda2e2eb8159a1331974d246984c6e2693c6ea93930e6165046c8dbb8db0e9 F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9 F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 @@ -1707,7 +1707,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a067468b43b8cb2305e9f9fe414e5f40c875bb5d2cba5f00b8154396e95fcf37 F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 6002a5f37b76355f173c75c2b3b03173b19d6a8b078c5baaa4c78bbcd0fa6323 +F test/tabfunc01.test 7be82bd50c7ede7f01b2dd17cd1b84f352c516078222d0b067d858f081e3f9a7 F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 77db0cd736746873d4ed3dbf0e9a43a3e15ab49961fccee20417e01f88de8664 -R dc412e7f7529f14cc6f79cc175ee95e6 -U stephan -Z 5cbeb98d76b54f40a03e87cc7f52d846 +P 6adfca7e85648584740c8a127b95bd46aaad45fa2d162bd44622bb47debbcbcb +R fb38b73bd5bdc524c9d9ddb12da6fa10 +U dan +Z af4d59a9b5ba76359d3ebd50499f4172 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e42222f4fc..e2fd805ec2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6adfca7e85648584740c8a127b95bd46aaad45fa2d162bd44622bb47debbcbcb +f5113a2ef84831ad2da723fa7e29e0d575e74e10585741ff51db8c2e37332cd2 diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 8c24198e1d..b6797171e0 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -348,6 +348,29 @@ do_execsql_test tabfunc01-920 { ) LIMIT -1 OFFSET 0; } {1 2 3 4 5 6 7 8 9 10 101 102 103 104} +#------------------------------------------------------------------------- +# Forum post https://sqlite.org/forum/forumpost/e7c3ae1215 +# +foreach {tn where res} { + 1000 "where value = 2" 2 + 1010 "where value in (2)" 2 + 1020 "where value in (select 2)" 2 + 1030 "where value = 2 OR value = 4" {2 4} + 1040 "where value in (2, 4)" {2 4} +} { + do_execsql_test $tn " + SELECT value FROM generate_series(1, 5) $where + " $res +} + +do_execsql_test 1100 { + select 1 as c_0 + from + generate_series(1, 1) as ref_3 + where (ref_3.value) in (select 1); +} {1} + + # Free up memory allocations intarray_addr From edf7efc61cc65f9e5695017cb7e1eaba8c6a74d5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 5 Nov 2024 23:26:31 +0000 Subject: [PATCH 286/522] Improve the ".mode json" output of the CLI so that it encodes U+007f using an escape sequence. FossilOrigin-Name: 8b58cf9bbd3090c60f1ee7468cdeeb0b0fa4560d1e51a5fd0bef43692d10fe04 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 267fa43e10..a6816b068b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\sxBestIndex\smethod\sof\sthe\sgenerate_series\svirtual\stable\signore\scontraints\son\sthe\s"value"\scolumn\swith\susable=0. -D 2024-11-05T18:25:32.313 +C Improve\sthe\s".mode\sjson"\soutput\sof\sthe\sCLI\sso\sthat\sit\sencodes\sU+007f\susing\nan\sescape\ssequence. +D 2024-11-05T23:26:31.239 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -778,7 +778,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 4eb010971da0a4b103af5853152e9c95b991174df75528fda6f333037f0007a0 +F src/shell.c.in bb8ca98e903ea1dc60cee7e0a82017879662a2e4ce1f43889da87e8d4d774a5d F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6adfca7e85648584740c8a127b95bd46aaad45fa2d162bd44622bb47debbcbcb -R fb38b73bd5bdc524c9d9ddb12da6fa10 -U dan -Z af4d59a9b5ba76359d3ebd50499f4172 +P f5113a2ef84831ad2da723fa7e29e0d575e74e10585741ff51db8c2e37332cd2 +R bbfc36e2090df7d25792a8d2c806a189 +U drh +Z cf46ecae3bdcb7001fed6ddb7dbd656a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e2fd805ec2..56803aeda4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5113a2ef84831ad2da723fa7e29e0d575e74e10585741ff51db8c2e37332cd2 +8b58cf9bbd3090c60f1ee7468cdeeb0b0fa4560d1e51a5fd0bef43692d10fe04 diff --git a/src/shell.c.in b/src/shell.c.in index cdd09becf0..180768b7fb 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2037,8 +2037,8 @@ const char *zSkipValidUtf8(const char *z, int nAccept, long ccm){ const char *pcLimit = (nAccept>=0)? z+nAccept : 0; assert(z!=0); while( (pcLimit)? (z Date: Wed, 6 Nov 2024 02:59:59 +0000 Subject: [PATCH 287/522] Enhance the --with-emsdk flag to use a default value of 'auto', meaning to search the environment for it, and to fail fatally if --with-emsdk is explicitly provided but the SDK is not found. FossilOrigin-Name: 9724b747caa926bca09653ea6ac3c0f7869824c9a476eb81f03e1a6763552da1 --- auto.def | 5 ++--- autosetup/proj.tcl | 38 +++++++++++++++++++++++++++----------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- tool/emcc.sh.in | 30 ++++++++++++++++-------------- 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/auto.def b/auto.def index 7f1c9d6a86..0314bc3cde 100644 --- a/auto.def +++ b/auto.def @@ -189,7 +189,7 @@ set flags { # with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build} - with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} + with-emsdk:=auto => {Top-most dir of the Emscripten SDK installation. Default = EMSDK env var.} # # test-status => {Enable status of tests} @@ -197,7 +197,6 @@ set flags { linemacros => {Enable #line macros in the amalgamation} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} # - } if {"" ne $DUMP_DEFINES_JSON} { lappend flags \ @@ -205,7 +204,7 @@ if {"" ne $DUMP_DEFINES_JSON} { => {Include lower-case defines (primarily system paths) in $DUMP_DEFINES_JSON} } -options [subst $flags] +options [subst -nobackslashes -nocommands $flags] unset flags # diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 82835ed601..c6b8b35d07 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -738,29 +738,41 @@ proc proj-affirm-files-exist {args} { # Emscripten is used for doing in-tree builds of web-based WASM stuff, # as opposed to WASI-based WASM or WASM binaries we import from other # places. This is only set up for Unix-style OSes and is untested -# anywhere but Linux. +# anywhere but Linux. Requires that the --with-emsdk flag be +# registered with autosetup. +# +# It looks for the SDK in the location specified by --with-emsdk. +# Values of "" or "auto" mean to check for the environment var EMSDK +# (which gets set by the emsdk_env.sh script from the SDK) or that +# same var passed to configure. +# +# If the given directory is found, it expects to find emsdk_env.sh in +# that directory, as well as the emcc compiler somewhere under there. +# +# If the --with-emsdk flag is explicitly provided and the SDK is not +# found then a fatal error is generated, otherwise failure to find the +# SDK is not fatal. # # Defines the following: # -# - EMSDK_HOME = top dir of the emsdk or "". It looks for -# --with-emsdk=DIR or the $EMSDK environment variable. -# - EMSDK_ENV = path to EMSDK_HOME/emsdk_env.sh or "" +# - EMSDK_HOME = top dir of the emsdk or "". +# - EMSDK_ENV_SH = path to EMSDK_HOME/emsdk_env.sh or "" # - BIN_EMCC = $EMSDK_HOME/upstream/emscripten/emcc or "" # - HAVE_EMSDK = 0 or 1 (this function's return value) # -# Returns 1 if EMSDK_ENV is found, else 0. If EMSDK_HOME is not empty +# Returns 1 if EMSDK_ENV_SH is found, else 0. If EMSDK_HOME is not empty # but BIN_EMCC is then emcc was not found in the EMSDK_HOME, in which -# case we have to rely on the fact that sourcing $EMSDK_ENV from a +# case we have to rely on the fact that sourcing $EMSDK_ENV_SH from a # shell will add emcc to the $PATH. proc proj-check-emsdk {} { set emsdkHome [opt-val with-emsdk] define EMSDK_HOME "" - define EMSDK_ENV "" + define EMSDK_ENV_SH "" define BIN_EMCC "" + set hadValue [llength $emsdkHome] msg-checking "Emscripten SDK? " - if {$emsdkHome eq ""} { - # Fall back to checking the environment. $EMSDK gets set by - # sourcing emsdk_env.sh. + if {$emsdkHome in {"" "auto"}} { + # Check the environment. $EMSDK gets set by sourcing emsdk_env.sh. set emsdkHome [get-env EMSDK ""] } set rc 0 @@ -769,7 +781,7 @@ proc proj-check-emsdk {} { set emsdkEnv "$emsdkHome/emsdk_env.sh" if {[file exists $emsdkEnv]} { msg-result "$emsdkHome" - define EMSDK_ENV $emsdkEnv + define EMSDK_ENV_SH $emsdkEnv set rc 1 set emcc "$emsdkHome/upstream/emscripten/emcc" if {[file exists $emcc]} { @@ -781,6 +793,10 @@ proc proj-check-emsdk {} { } else { msg-result "not found" } + if {$hadValue && 0 == $rc} { + # Fail if it was explicitly requested but not found + proj-fatal "Cannot find the Emscripten SDK" + } define HAVE_EMSDK $rc return $rc } diff --git a/manifest b/manifest index a6816b068b..e4c205c753 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\s".mode\sjson"\soutput\sof\sthe\sCLI\sso\sthat\sit\sencodes\sU+007f\susing\nan\sescape\ssequence. -D 2024-11-05T23:26:31.239 +C Enhance\sthe\s--with-emsdk\sflag\sto\suse\sa\sdefault\svalue\sof\s'auto',\smeaning\sto\ssearch\sthe\senvironment\sfor\sit,\sand\sto\sfail\sfatally\sif\s--with-emsdk\sis\sexplicitly\sprovided\sbut\sthe\sSDK\sis\snot\sfound. +D 2024-11-06T02:59:59.807 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 348be257a61090f739287d54046f63801c99705f42fae0dffa2ba415dd9afcfb +F auto.def 4a5115da298b51f0332fda72933976bded86700c94e30d75066e665795d638d7 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl a3f180a97db6cf398f12d8e688651d10b8707c4869eb0096bfbf0b2952b31131 +F autosetup/proj.tcl 57b9c794d01124c91af840b3ba0ef1e991e815c9a872fa451baff0dc03e9f84a F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2115,7 +2115,7 @@ F tool/custom.txt 24ed55e71c5edae0067ba159bbf09240d58b160331f7716e95816cd3aa0ba5 F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c -F tool/emcc.sh.in 5a3534af8d437747cf4141abaab3db558756f4a1ac8f3ebf28a16ffa26209921 +F tool/emcc.sh.in 1f3226166bad1765c0bf42fac3d29037704c2078eb22562f9ddfbe73bff023b0 F tool/enlargedb.c 3e8b2612b985cfa7e3e8800031ee191b43ae80de96abb5abbd5eada62651ee21 F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f5113a2ef84831ad2da723fa7e29e0d575e74e10585741ff51db8c2e37332cd2 -R bbfc36e2090df7d25792a8d2c806a189 -U drh -Z cf46ecae3bdcb7001fed6ddb7dbd656a +P 8b58cf9bbd3090c60f1ee7468cdeeb0b0fa4560d1e51a5fd0bef43692d10fe04 +R caf12b590890f202527bfa9f99549a98 +U stephan +Z 9566a0d488cad676e06a60ec48a87114 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 56803aeda4..95cc89888f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b58cf9bbd3090c60f1ee7468cdeeb0b0fa4560d1e51a5fd0bef43692d10fe04 +9724b747caa926bca09653ea6ac3c0f7869824c9a476eb81f03e1a6763552da1 diff --git a/tool/emcc.sh.in b/tool/emcc.sh.in index fb849545f8..1263e1b0ea 100644 --- a/tool/emcc.sh.in +++ b/tool/emcc.sh.in @@ -10,10 +10,10 @@ # script, if needed. ######################################################################## # EMSDK_HOME comes from the configure --with-emsdk=/dir flag. -# EMSDK_ENV is ${thatDir}/emsdk_env.sh and is also set by the +# EMSDK_ENV_SH is ${thatDir}/emsdk_env.sh and is also set by the # configure process. EMSDK_HOME="@EMSDK_HOME@" -EMSDK_ENV="@EMSDK_ENV@" +EMSDK_ENV_SH="@EMSDK_ENV_SH@" emcc="@BIN_EMCC@" if [ x = "x${emcc}" ]; then @@ -22,41 +22,43 @@ fi if [ x = "x${emcc}" ]; then # If emcc is not found in the path, try to find it via an emsdk - # installation. The SDK variant is the official installation - # style supported by the Emscripten folks, but emcc is also - # available via package managers on some OSes. + # installation. The SDK variant is the official installation style + # supported by the Emscripten project, but emcc is also available + # via package managers on some OSes. if [ x = "x${EMSDK_HOME}" ]; then echo "EMSDK_HOME is not set. Pass --with-emsdk=/path/to/emsdk" \ "to the configure script." 1>&2 exit 1 fi - if [ x = "x${EMSDK_ENV}" ]; then + if [ x = "x${EMSDK_ENV_SH}" ]; then if [ -f "${EMSDK_HOME}/emsdk_env.sh" ]; then - EMSDK_ENV="${EMSDK_HOME}/emsdk_env.sh" + EMSDK_ENV_SH="${EMSDK_HOME}/emsdk_env.sh" else - echo "EMSDK_ENV is not set. Expecting configure script to set it." 1>&2 + echo "EMSDK_ENV_SH is not set. Expecting configure script to set it." 1>&2 exit 2 fi fi - if [ ! -f "${EMSDK_ENV}" ]; then - echo "emsdk_env script not found: $EMSDK_ENV" 1>&2 + if [ ! -f "${EMSDK_ENV_SH}" ]; then + echo "emsdk_env script not found: $EMSDK_ENV_SH" 1>&2 exit 3 fi # $EMSDK is part of the state set by emsdk_env.sh. if [ x = "x${EMSDK}" ]; then - source "${EMSDK_ENV}" >/dev/null 2>&1 || { - # ^^^ unfortunately outputs lots of noise to stderr + EMSDK_QUIET=1 + export EMSDK_QUIET + # ^^^ Squelches informational output from ${EMSDK_ENV_SH}. + source "${EMSDK_ENV_SH}" || { rc=$? - echo "Error sourcing ${EMSDK_ENV}" + echo "Error sourcing ${EMSDK_ENV_SH}" exit $rc } fi emcc=`which emcc 2>/dev/null` if [ x = "x${emcc}" ]; then - echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV}." 1>&2 + echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV_SH}." 1>&2 exit 4 fi fi From 4c2f7e57a2e2c1a0a351543d1b410d2023f19cd7 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 6 Nov 2024 04:38:05 +0000 Subject: [PATCH 288/522] Add autosetup/README.md - maintenance-related docs for SQLite developers (e.g. how to update autosetup). Start marking up the proj.tcl APIs with autosetup's doc markup so that they appear in the ./configure --reference output. FossilOrigin-Name: aa6213767f0d7e63c753e33aadb95cbeb8e522c22f2fe1bbfa4df66bea6e3380 --- auto.def | 3 + autosetup/README.md | 164 ++++++++++++++++++++++++++++++++++++++++++++ autosetup/proj.tcl | 94 ++++++++++++++++++++++--- manifest | 15 ++-- manifest.uuid | 2 +- 5 files changed, 260 insertions(+), 18 deletions(-) create mode 100644 autosetup/README.md diff --git a/auto.def b/auto.def index 0314bc3cde..0f33f5b225 100644 --- a/auto.def +++ b/auto.def @@ -939,6 +939,9 @@ proc sqlite-check-line-editing {} { # If we found a library, configure the build to use it... if {"" ne $rlLib} { if {"editline" eq $editLibName && "HAVE_READLINE" eq $editLibDef} { + # Alert the user that, despite outward appearances, we won't be + # linking to the GPL'd libreadline. Presumably that distinction is + # significant for those using --editline. proj-indented-notice { NOTE: the local libedit but uses so we will compile with -DHAVE_READLINE=1 but will link with diff --git a/autosetup/README.md b/autosetup/README.md new file mode 100644 index 0000000000..8bb2a8c3ae --- /dev/null +++ b/autosetup/README.md @@ -0,0 +1,164 @@ +Maintaining Autosetup in the SQLite Tree +======================================================================== + +This document provides some tips and reminders for the SQLite +developers regarding using and maintaining the [Autosetup][]-based +build infrastructure. It is not an [Autosetup][] reference. + +**Table of Contents**: + +- [Autosetup API Reference](#apiref) +- [API Tips](#apitips) +- [Ensuring TCL Compatibility](#tclcompat) +- [Updating Autosetup](#updating) + +------------------------------------------------------------------------ + + +Autosetup API Reference +======================================================================== + +The Autosetup API is quite extensive and can be read either in +the [files in the `autosetup` dir](/dir/autosetup) or using: + +> +``` +$ ./configure --reference | less +``` + +That will include any docs from any TCL files in the `./autosetup` dir +which contain certain (simple) markup defined by autosetup. + +This project's own autosetup-related APIs are in [proj.tcl][] or +[auto.def][]. The former contains helper APIs which are, more or +less, portable across projects (that file is re-used as-is in other +projects) and all have a `proj-` name prefix. The latter is the main +configure script driver and contains related functions which are +specific to this tree. + + +Autosetup API Tips +======================================================================== + +This section briefly covers only APIs which are frequently useful in +day-to-day maintenance and might not be immediately recognized as such +obvious from a casual perusal of `auto.def`. Their complete docs can be +found in [proj.tcl][]. + +In (mostly) alphabetical order: + +- **`get-env VAR ?default?`**\ + Will fetch an "environment variable" + from the first of either: (A) a KEY=VALUE passed to the configure + script or (B) the system's environment variables. Not to be confused + with `getenv`, which only does the latter and is rarely, if ever, + useful in this tree. + - **`proj-get-env VAR ?default?`**\ + Works like `get-env` but will, if that function finds no match, + look for a file named `./.env-$VAR` and, if found, return its + trimmed contents. This can be used, e.g., to set a developer's + local preferences for the default `CFLAGS`. + +- **`proj-define-if-opt-truthy flag defineName checkingMsg ?yesVal=1? ?noVal=0?`**\ + Defines `defineName` to either `yesVal` or `noVal`, depending on + whether `--flag` is truthy or not. + +- **`proj-if-opt-truthy flag thenScript ?elseScript?`**\ + Evals `thenScript` if the given `--flag` is truthy, else it + evals the optional `elseScript`. + +- **`proj-indented-notice ?-error? msg`**\ + Breaks its `msg` argument into lines, trims them, and emits them + with consistent indentation. If the `-error` flag is used, it them + exits with non-0. This will stick out starkly from normal output + and is intended to be used only for important notices. + +- **`proj-opt-truthy flag`**\ + Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on, + enabled, yes). + +- **`proj-opt-was-provided FLAG`**\ + Returns 1 if `--FLAG` was explicitly provided to configure, + else 0. This distinction can be used to determine, e.g., whether + `--with-readline` was provided or whether we're searching for + readline by default. In the former case, failure to find it should + be treated as fatal. + +- **`proj-val-truthy value`**\ + Returns 1 if `$value` is "truthy," i.e. one of (1, on, enabled, + yes). + + + +Ensuring TCL Compatibility +======================================================================== + +It is important that any TCL files used by the configure process +remain compatible with both [JimTCL][] and the canonical TCL. Though +JimTCL has outstanding compatibility with canonical TCL, it does have +a few corners with incompatibilities, e.g. regular expressions. If a +script runs in JimTCL without using any JimTCL-specific features, then +it's a certainty that it will run in canonical TCL as well. The +opposite, however, is not _always_ the case. + +By default, the configure script will search for an available `tclsh` +(under several common names, e.g. `tclsh8.6`) before falling back to +compiling the copy of `jimsh0.c` included in the source tree. + +There are two simple ways to ensure that the configure process uses +JimTCL instead of the canonical `tclsh`, and either approach ensures +configure script compatibility: + +1. Build on a system with no `tclsh` installed. In that case, the + configure process will fall back to building the in-tree copy of + JimTCL. + +2. Manually build `./jimsh0` in the top of the checkout with:\ + `cc -o jimsh0 autosetup/jimsh0.c`\ + With that in place, the configure script will prefer to use that + before looking for a system-level `tclsh`. Note that `make distclean` + will remove that file. + +**Note that `jimsh0` is distinctly different** from the `jimsh` which +gets built for code-generation purposes. The latter requires +non-default build flags to enable features which are +platform-dependent, most notably to make its `[file normalize]` +work. This means, for example, that the configure script and its +utility APIs must not use `[file normalize]`, but autosetup provides a +TCL implementation of `[file-normalize]` (note the dash) for portable +use in the configure script. + + +Updating Autosetup +======================================================================== + +Updating autosetup is, more often than not, painless. It requires having +a checked-out copy of [the autosetup git repository][autosetup-git]: + +> +``` +$ git clone https://github.com/msteveb/autosetup +$ cd autosetup +# Or, if it's already checked out: +$ git pull +``` + +Then, from the top-most directory of an SQLite checkout: + +> +``` +$ /path/to/autosetup-checkout/autosetup --install . +$ fossil status # show the modified files +``` + +Unless the upgrade made any incompatible changes (which is exceedingly +rare), that's all there is to it. Check over the diff, test the +configure process, and check it in. + + + +[Autosetup]: https://msteveb.github.io/autosetup/ +[auto.def]: ../auto.def?mimetype=text/plain +[autosetup-git]: https://github.com/msteveb/autosetup +[proj.tcl]: ./proj.tcl?mimetype=text/plain +[JimTCL]: https://jim.tcl.tk diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index c6b8b35d07..fb98a5e189 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -47,15 +47,26 @@ # updating global state via feature tests. ######################################################################## +# ----- @module proj.tcl ----- +# @section Project Helper APIs + ######################################################################## # $proj_ is an internal-use-only array for storing whatever generic # internal stuff we need stored. array set proj_ {} set proj_(isatty) [isatty? stdout] +######################################################################## +# @proj-warn msg +# +# Emits a warning message to stderr. proc proj-warn {msg} { puts stderr [proj-bold "WARNING: $msg"] } +######################################################################## +# @proj-error msg +# +# Emits an error message to stderr and exits with non-0. proc proj-fatal {msg} { show-notices puts stderr [proj-bold "ERROR: $msg"] @@ -63,6 +74,8 @@ proc proj-fatal {msg} { } ######################################################################## +# @proj-assert script +# # Kind of like a C assert if uplevel (eval) of $script is false, # triggers a fatal error. proc proj-assert {script} { @@ -75,6 +88,8 @@ proc proj-assert {script} { } ######################################################################## +# @proj-bold str +# # If this function believes that the current console might support # ANSI escape sequences then this returns $str wrapped in a sequence # to bold that text, else it returns $str as-is. @@ -86,6 +101,8 @@ proc proj-bold {str} { } ######################################################################## +# @proj-indented-notice ?-error? msg +# # Takes a multi-line message and emits it with consistent indentation # using [user-notice] (which means its rendering will (A) go to stderr # and (B) be delayed until the next time autosetup goes to output a @@ -162,6 +179,8 @@ proc proj-check-function-in-lib {function libs {otherlibs {}}} { } ######################################################################## +# @proj-search-for-header-dir ?-dirs LIST? ?-subdirs LIST? header +# # Searches for $header in a combination of dirs and subdirs, specified # by the -dirs {LIST} and -subdirs {LIST} flags (each of which have # sane defaults). Returns either the first matching dir or an empty @@ -193,7 +212,7 @@ proc proj-search-for-header-dir {header args} { } ######################################################################## -# Usage: proj-find-executable-path ?-v? binaryName +# @proj-find-executable-path ?-v? binaryName # # Works similarly to autosetup's [find-executable-path $binName] but: # @@ -220,6 +239,8 @@ proc proj-find-executable-path {args} { } ######################################################################## +# @proj-bin-define binName ?defName? +# # Uses [proj-find-executable-path $binName] to (verbosely) search for # a binary, sets a define (see below) to the result, and returns the # result (an empty string if not found). @@ -237,7 +258,7 @@ proc proj-bin-define {binName {defName {}}} { } ######################################################################## -# Usage: proj-first-bin-of bin... +# @proj-first-bin-of bin... # # Looks for the first binary found of the names passed to this # function. If a match is found, the full path to that binary is @@ -262,6 +283,8 @@ proc proj-first-bin-of {args} { } ######################################################################## +# @proj-opt-was-provided key +# # Returns 1 if the user specifically provided the given configure # flag, else 0. This can be used to distinguish between options which # have a default value and those which were explicitly provided by the @@ -281,6 +304,8 @@ proc proj-opt-was-provided {key} { } ######################################################################## +# @proj-opt-set flag ?val? +# # Force-set autosetup option $flag to $val. The value can be fetched # later with [opt-val], [opt-bool], and friends. # @@ -297,6 +322,8 @@ proc proj-opt-set {flag {val 1}} { } ######################################################################## +# @proj-val-truthy val +# # Returns 1 if $val appears to be a truthy value, else returns # 0. Truthy values are any of {1 on enabled yes} proc proj-val-truthy {val} { @@ -304,6 +331,8 @@ proc proj-val-truthy {val} { } ######################################################################## +# @proj-opt-truthy flag +# # Returns 1 if [opt-val $flag] appears to be a truthy value or # [opt-bool $flag] is true. See proj-val-truthy. proc proj-opt-truthy {flag} { @@ -317,6 +346,8 @@ proc proj-opt-truthy {flag} { } ######################################################################## +# @proj-if-opt-truthy boolFlag thenScript ?elseScript? +# # If [proj-opt-truthy $flag] is true, eval $then, else eval $else. proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} { if {[proj-opt-truthy $boolFlag]} { @@ -327,6 +358,8 @@ proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} { } ######################################################################## +# @proj-define-if-opt-truthy flag def ?msg? ?iftrue? ?iffalse? +# # If [proj-opt-truthy $flag] then [define $def $iftrue] else [define # $def $iffalse]. If $msg is not empty, output [msg-checking $msg] and # a [msg-results ...] which corresponds to the result. Returns 1 if @@ -354,7 +387,7 @@ proc proj-define-if-opt-truthy {flag def {msg ""} {iftrue 1} {iffalse 0}} { } ######################################################################## -# Args: [-v] optName defName {descr {}} +# @proj-opt-define-bool ?-v? optName defName ?descr? # # Checks [proj-opt-truthy $optName] and calls [define $defName X] # where X is 0 for false and 1 for true. descr is an optional @@ -392,6 +425,8 @@ proc proj-opt-define-bool {args} { } ######################################################################## +# @proj-check-module-loader +# # Check for module-loading APIs (libdl/libltdl)... # # Looks for libltdl or dlopen(), the latter either in -ldl or built in @@ -455,6 +490,8 @@ proc proj-check-module-loader {} { } ######################################################################## +# @proj-no-check-module-loader +# # Sets all flags which would be set by proj-check-module-loader to # empty/falsy values, as if those checks had failed to find a module # loader. Intended to be called in place of that function when @@ -466,6 +503,8 @@ proc proj-no-check-module-loader {} { } ######################################################################## +# @proj-file-conent ?-trim? filename +# # Opens the given file, reads all of its content, and returns it. If # the first arg is -trim, the contents of the file named by the second # argument are trimmed before returning them. @@ -484,6 +523,8 @@ proc proj-file-content {args} { } ######################################################################## +# @proj-file-conent filename +# # Returns the contents of the given file as an array of lines, with # the EOL stripped from each input line. proc proj-file-content-list {fname} { @@ -497,6 +538,8 @@ proc proj-file-content-list {fname} { } ######################################################################## +# @proj-check-compile-commands ?configFlag? +# # Checks the compiler for compile_commands.json support. If passed an # argument it is assumed to be the name of an autosetup boolean config # which controls whether to run/skip this check. @@ -506,9 +549,9 @@ proc proj-file-content-list {fname} { # # This test has a long history of false positive results because of # compilers reacting differently to the -MJ flag. -proc proj-check-compile-commands {{configOpt {}}} { +proc proj-check-compile-commands {{configFlag {}}} { msg-checking "compile_commands.json support... " - if {"" ne $configOpt && ![proj-opt-truthy $configOpt]} { + if {"" ne $configFlag && ![proj-opt-truthy $configFlag]} { msg-result "explicitly disabled" define MAKE_COMPILATION_DB no return 0 @@ -529,15 +572,15 @@ proc proj-check-compile-commands {{configOpt {}}} { } ######################################################################## +# @proj-touch filename +# # Runs the 'touch' command on one or more files, ignoring any errors. proc proj-touch {filename} { catch { exec touch {*}$filename } } ######################################################################## -# Usage: -# -# proj-make-from-dot-in ?-touch? filename(s)... +# @proj-make-from-dot-in ?-touch? filename... # # Uses [make-template] to create makefile(-like) file(s) $filename # from $filename.in but explicitly makes the output read-only, to @@ -569,6 +612,8 @@ proc proj-make-from-dot-in {args} { } ######################################################################## +# @proj-check-profile-flag ?flagname? +# # Checks for the boolean configure option named by $flagname. If set, # it checks if $CC seems to refer to gcc. If it does (or appears to) # then it defines CC_PROFILE_FLAG to "-pg" and returns 1, else it @@ -599,6 +644,8 @@ proc proj-check-profile-flag {{flagname profile}} { } ######################################################################## +# @proj-looks-like-windows ?key? +# # Returns 1 if this appears to be a Windows environment (MinGw, # Cygwin, MSys), else returns 0. The optional argument is the name of # an autosetup define which contains platform name info, defaulting to @@ -610,7 +657,7 @@ proc proj-check-profile-flag {{flagname profile}} { proc proj-looks-like-windows {{key host}} { global autosetup switch -glob -- [get-define $key] { - *-*-ming* - *-*-cygwin - *-*-msys { + *-*-ming* - *-*-cygwin - *-*-msys - *windows* { return 1 } } @@ -626,6 +673,8 @@ proc proj-looks-like-windows {{key host}} { } ######################################################################## +# @proj-looks-like-mac ?key? +# # Looks at either the 'host' (==compilation target platform) or # 'build' (==the being-built-on platform) define value and returns if # if that value seems to indicate that it represents a Mac platform, @@ -642,6 +691,8 @@ proc proj-looks-like-mac {{key host}} { } ######################################################################## +# @proj-exe-extension +# # Checks autosetup's "host" and "build" defines to see if the build # host and target are Windows-esque (Cygwin, MinGW, MSys). If the # build environment is then BUILD_EXEEXT is [define]'d to ".exe", else @@ -661,6 +712,8 @@ proc proj-exe-extension {} { } ######################################################################## +# @proj-dll-extension +# # Works like proj-exe-extension except that it defines BUILD_DLLEXT # and TARGET_DLLEXT to one of (.so, ,dll, .dylib). # @@ -685,6 +738,8 @@ proc proj-dll-extension {} { } ######################################################################## +# @proj-lib-extension +# # Static-library counterpart of proj-dll-extension. Defines # BUILD_LIBEXT and TARGET_LIBEXT to the conventional static library # extension for the being-built-on resp. the target platform. @@ -704,6 +759,8 @@ proc proj-lib-extension {} { } ######################################################################## +# @proj-file-extensions +# # Calls all of the proj-*-extension functions. proc proj-file-extensions {} { proj-exe-extension @@ -712,6 +769,8 @@ proc proj-file-extensions {} { } ######################################################################## +# @proj-affirm-files-exist ?-v? filename... +# # Expects a list of file names. If any one of them does not exist in # the filesystem, it fails fatally with an informative message. # Returns the last file name it checks. If the first argument is -v @@ -735,6 +794,8 @@ proc proj-affirm-files-exist {args} { } ######################################################################## +# @proj-check-emsdk +# # Emscripten is used for doing in-tree builds of web-based WASM stuff, # as opposed to WASI-based WASM or WASM binaries we import from other # places. This is only set up for Unix-style OSes and is untested @@ -802,6 +863,8 @@ proc proj-check-emsdk {} { } ######################################################################## +# @proj-check-rpath +# # Tries various approaches to handling the -rpath link-time # flag. Defines LDFLAGS_RPATH to that/those flag(s) or an empty # string. Returns 1 if it finds an option, else 0. @@ -844,6 +907,8 @@ proc proj-check-rpath {} { } ######################################################################## +# @proj-check-soname ?libname? +# # Checks whether CC supports the -Wl,soname,lib... flag. If so, it # returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, to # which the client would need to append "libwhatever.N". If not, it @@ -984,6 +1049,8 @@ proc proj-dump-defs-json {file args} { } ######################################################################## +# @proj-xfer-option-aliases map +# # Expects a list of pairs of configure flags which have been # registered with autosetup, in this form: # @@ -1049,6 +1116,8 @@ proc proj-redefine-cc-for-build {} { } ######################################################################## +# @proj-which-linenoise headerFile +# # Attempts to determine whether the given linenoise header file is of # the "antirez" or "msteveb" flavor. It returns 2 for msteveb, else 1 # (it does not validate that the header otherwise contains the @@ -1063,8 +1132,9 @@ proc proj-which-linenoise {dotH} { } ######################################################################## +# @proj-remap-autoconf-dir-vars # -# "Re-export" the autoconf-conventional --XYZdir flags into something +# "Re-map" the autoconf-conventional --XYZdir flags into something # which is more easily overridable from a make invocation. # # Based off of notes in . @@ -1134,6 +1204,8 @@ proc proj-remap-autoconf-dir-vars {} { } ######################################################################## +# @proj-env-file flag ?default? +# # If a file named .env-$flag exists, this function returns a # trimmed copy of its contents, else it returns $dflt. The intended # usage is that things like developer-specific CFLAGS preferences can @@ -1147,6 +1219,8 @@ proc proj-env-file {flag {dflt ""}} { } ######################################################################## +# @proj-get-env var ?default? +# # Extracts the value of "environment" variable $var from the first of # the following places where it's defined: # diff --git a/manifest b/manifest index e4c205c753..4069de9c00 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\s--with-emsdk\sflag\sto\suse\sa\sdefault\svalue\sof\s'auto',\smeaning\sto\ssearch\sthe\senvironment\sfor\sit,\sand\sto\sfail\sfatally\sif\s--with-emsdk\sis\sexplicitly\sprovided\sbut\sthe\sSDK\sis\snot\sfound. -D 2024-11-06T02:59:59.807 +C Add\sautosetup/README.md\s-\smaintenance-related\sdocs\sfor\sSQLite\sdevelopers\s(e.g.\show\sto\supdate\sautosetup).\sStart\smarking\sup\sthe\sproj.tcl\sAPIs\swith\sautosetup's\sdoc\smarkup\sso\sthat\sthey\sappear\sin\sthe\s./configure\s--reference\soutput. +D 2024-11-06T04:38:05.379 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 4a5115da298b51f0332fda72933976bded86700c94e30d75066e665795d638d7 +F auto.def 062b05538bc09779962a5265125aa289152f6abbb1ebaded9b22e8969b151d75 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -37,6 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e +F autosetup/README.md 94a117db60b2a8efbfed58e548809631f1941a8df9c3c6a356080771b772e31c F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -49,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 57b9c794d01124c91af840b3ba0ef1e991e815c9a872fa451baff0dc03e9f84a +F autosetup/proj.tcl b3a0621b6e98b9e87813ba7a15a64f92708527dd8efc99a764846c16336aadf0 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2199,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8b58cf9bbd3090c60f1ee7468cdeeb0b0fa4560d1e51a5fd0bef43692d10fe04 -R caf12b590890f202527bfa9f99549a98 +P 9724b747caa926bca09653ea6ac3c0f7869824c9a476eb81f03e1a6763552da1 +R 22b44d94fb3a53e904cadda0982c176f U stephan -Z 9566a0d488cad676e06a60ec48a87114 +Z e3f63aefb44fb343dd26a948d9892eb7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 95cc89888f..2c99362207 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9724b747caa926bca09653ea6ac3c0f7869824c9a476eb81f03e1a6763552da1 +aa6213767f0d7e63c753e33aadb95cbeb8e522c22f2fe1bbfa4df66bea6e3380 From 199925a3529eafd41321c5a5673b4493df9a3a48 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 6 Nov 2024 05:54:27 +0000 Subject: [PATCH 289/522] Add a section to autosetup/README.md describing the motivations for the more glaring design decisions. FossilOrigin-Name: c0940a822a63bff74585bd37401eca92f74ddf9fe95748d2474039ee9b2bd9b6 --- autosetup/README.md | 90 ++++++++++++++++++++++++++++++++++++++++++--- main.mk | 4 +- manifest | 14 +++---- manifest.uuid | 2 +- 4 files changed, 95 insertions(+), 15 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index 8bb2a8c3ae..8b989754a4 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -10,6 +10,7 @@ build infrastructure. It is not an [Autosetup][] reference. - [Autosetup API Reference](#apiref) - [API Tips](#apitips) - [Ensuring TCL Compatibility](#tclcompat) +- [Design Conventions](#conventions) - [Updating Autosetup](#updating) ------------------------------------------------------------------------ @@ -36,6 +37,7 @@ projects) and all have a `proj-` name prefix. The latter is the main configure script driver and contains related functions which are specific to this tree. + Autosetup API Tips ======================================================================== @@ -69,7 +71,7 @@ In (mostly) alphabetical order: - **`proj-indented-notice ?-error? msg`**\ Breaks its `msg` argument into lines, trims them, and emits them - with consistent indentation. If the `-error` flag is used, it them + with consistent indentation. If the `-error` flag is used, it then exits with non-0. This will stick out starkly from normal output and is intended to be used only for important notices. @@ -88,6 +90,15 @@ In (mostly) alphabetical order: Returns 1 if `$value` is "truthy," i.e. one of (1, on, enabled, yes). +- **`sqlite-add-feature-flag ?-shell? FLAG...`**\ + Adds the given feature flag to the CFLAGS which are specific to building + the library. It's intended to be passed one or more `-DSQLITE_ENABLE_...`, + or similar, flags. If the `-shell` flag is used then it also passes + its arguments to `sqlite-add-shell-opt`. This is a no-op if `FLAG` + is not provided or is empty. + +- **`sqlite-add-shell-opt FLAG...`**\ + The shell-specific counterpart of `sqlite-add-feature-flag`. Ensuring TCL Compatibility @@ -106,8 +117,9 @@ By default, the configure script will search for an available `tclsh` compiling the copy of `jimsh0.c` included in the source tree. There are two simple ways to ensure that the configure process uses -JimTCL instead of the canonical `tclsh`, and either approach ensures -configure script compatibility: +JimTCL instead of the canonical `tclsh`, and either approach provides +equally high assurances about configure script compatibility across +TCL implementations: 1. Build on a system with no `tclsh` installed. In that case, the configure process will fall back to building the in-tree copy of @@ -128,6 +140,74 @@ utility APIs must not use `[file normalize]`, but autosetup provides a TCL implementation of `[file-normalize]` (note the dash) for portable use in the configure script. + + +Design Conventions +======================================================================== + +This section describes the motivations for the most glaring of the +build's design decisions, in particular how they deviate from +historical, or even widely-conventional, practices. + +Do Not Update Global Shared State +------------------------------------------------------------------------ + +In both the legacy Autotools-driven build and in common Autosetup +usage, feature tests performed by the configure script may ammend +values to global flags such as `CFLAGS`, `LDFLAGS`, and `LIBS`. +That's appropriate for a makefile which builds a single deliverable, +but less so for makefiles which produce multiple deliverables, as it's +unlikely that every single deliverable will require the same core set +of those flags. In addition, that approach can make it difficult to +determine the origin of any given change to those flags because those +changes are hidden behind voodoo performed outside the immediate +visibility of the configure script's maintainer. It can also force the +maintainers of the configure script to place tests in a specific order +so that the resulting flags get applied at the correct time. + +> A real-life example of the latter point: before the approach + described below was taken to collecting build-time flags, the test + for `-rflag` had to come _after_ the test for zlib because the + results of the `-rflag` test implicitly modified the `CFLAGS`, + breaking the zlib feature test. Because the feature tests no longer + (intentionally) modify global state, that is not an issue. + +Cases where feature tests modify global state in such a way that it +may impact later feature tests are either (A) very intentionally +defined to do so (e.g. the `--with-wasi-sdk` flag needs to modify the +build tool chain) or (B) are oversights (i.e. bugs). + +This tree's configure script, utility APIs, +[`Makefile.in`](/file/Makefile.in), and [`main.mk`](/file/main.mk) +therefore strive to separate the results of any given feature test +into its own well-defined variables. For example: + +- The linker flags for zlib are exported from the configure script as + `LDFLAGS_ZLIB`, which `Makefile.in` and `main.mk` then expose as + `LDFLAGS.zlib`. +- `CFLAGS_READLINE` (a.k.a. `CFLAGS.readline`) contains the `CFLAGS` + needed for including `libreadline`, `libedit`, or `linenoise`, and + `LDFLAGS_READLINE` (a.k.a. `LDFLAGS.readline`) is its link-time + counterpart. + +It is then up to the Makefile to apply and order the flags however is +appropriate. + +> Sidebar: the `X_Y` convention is used used on the configure-script + side because that process exports those flags as C `#define`s to + `sqlite_cfg.h`, where dots are not permitted. The `X.y` convention + is used in the Makefile side primarily because the person who did + the initial port finds that easier on the eyes and fingers. + +At the end of the configure script, the global `CFLAGS` _ideally_ +holds only flags which are either relevant to all targets or, failing +that, will have no unintended side-effects on any targets. That said: +clients frequently pass custom `CFLAGS` to `./configure` or `make` to +set library-level feature toggles, e.g. `-DSQLITE_OMIT_FOO`, in which +case there is no practical way to avoid "polluting" the builds of +arbitrary makefile targets with those. _C'est la vie._ + + Updating Autosetup ======================================================================== @@ -158,7 +238,7 @@ configure process, and check it in. [Autosetup]: https://msteveb.github.io/autosetup/ -[auto.def]: ../auto.def?mimetype=text/plain +[auto.def]: /file/auto.def [autosetup-git]: https://github.com/msteveb/autosetup -[proj.tcl]: ./proj.tcl?mimetype=text/plain +[proj.tcl]: /file/autosetup/proj.tcl [JimTCL]: https://jim.tcl.tk diff --git a/main.mk b/main.mk index bcb642398e..2dc7f9ce78 100644 --- a/main.mk +++ b/main.mk @@ -165,8 +165,8 @@ LDFLAGS.icu ?= # -licui18n -licuuc -licudata LDFLAGS.soname.libsqlite3 ?= # libreadline (or a workalike): # To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE=1 -LDFLAGS.readline ?= -lreadline # these vary wildly across platforms -CFLAGS.readline ?= -I$(prefix)/include/readline +LDFLAGS.readline ?= -lreadline # these vary across platforms +CFLAGS.readline ?= -I$(prefix)/include # ^^^ When using linenoise instead of readline, do something like: # SHELL_OPT += -DHAVE_LINENOISE=1 # CFLAGS.readline = -I$(HOME)/linenoise $(HOME)/linenoise/linenoise.c diff --git a/manifest b/manifest index 4069de9c00..6d5872463f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sautosetup/README.md\s-\smaintenance-related\sdocs\sfor\sSQLite\sdevelopers\s(e.g.\show\sto\supdate\sautosetup).\sStart\smarking\sup\sthe\sproj.tcl\sAPIs\swith\sautosetup's\sdoc\smarkup\sso\sthat\sthey\sappear\sin\sthe\s./configure\s--reference\soutput. -D 2024-11-06T04:38:05.379 +C Add\sa\ssection\sto\sautosetup/README.md\sdescribing\sthe\smotivations\sfor\sthe\smore\sglaring\sdesign\sdecisions. +D 2024-11-06T05:54:27.295 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 94a117db60b2a8efbfed58e548809631f1941a8df9c3c6a356080771b772e31c +F autosetup/README.md 1dfdbe705c95400a722f0a012b6780ad2c7f12948d15cbdcbf95e030b46c4824 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ef087df40894cf2c024ec5f4d763853616c9616b073fb86b71146f11fa003af3 +F main.mk 949721d1f7400fd9f2c9a8818d66eed7b4c5937c9fd2635f8364755858ddcc78 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9724b747caa926bca09653ea6ac3c0f7869824c9a476eb81f03e1a6763552da1 -R 22b44d94fb3a53e904cadda0982c176f +P aa6213767f0d7e63c753e33aadb95cbeb8e522c22f2fe1bbfa4df66bea6e3380 +R 31c89bc32b0e171b0e74463a095b8565 U stephan -Z e3f63aefb44fb343dd26a948d9892eb7 +Z 316096fa02be870ff4dfd5f1350db8c8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2c99362207..ef952f7545 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa6213767f0d7e63c753e33aadb95cbeb8e522c22f2fe1bbfa4df66bea6e3380 +c0940a822a63bff74585bd37401eca92f74ddf9fe95748d2474039ee9b2bd9b6 From 2e29bcd5421250740ee3c9fa3260609bada818f5 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 6 Nov 2024 06:06:43 +0000 Subject: [PATCH 290/522] Split the motivation of the makefile var naming convention into its doc own section. FossilOrigin-Name: bf42b93cc7a4f8de2308fa4e5a798a62797bc95d95e4b0bd06035c74413fa828 --- autosetup/README.md | 38 ++++++++++++++++++++++++++++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index 8b989754a4..330a98de5b 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -11,6 +11,8 @@ build infrastructure. It is not an [Autosetup][] reference. - [API Tips](#apitips) - [Ensuring TCL Compatibility](#tclcompat) - [Design Conventions](#conventions) + - Symbolic Names of Feature Flags + - Do Not Update Global Shared State - [Updating Autosetup](#updating) ------------------------------------------------------------------------ @@ -149,6 +151,36 @@ This section describes the motivations for the most glaring of the build's design decisions, in particular how they deviate from historical, or even widely-conventional, practices. +Symbolic Names of Feature Flags +------------------------------------------------------------------------ + +Historically, the project's makefile has exclusively used +`UPPER_UNDERSCORE` form for makefile variables. This build, however, +primarily uses `X.y` format, where `X` is often a category label, +e.g. `CFLAGS` and `y` is the specific instance of that category, +e.g. `CFLAGS.readline`. + +When the configure script exports flags for consumption by filtered +files, e.g. [`Makefile.in`](/file/Makefile.in) and the generated +`sqlite_cfg.h`, it does so in the more conventional `X_Y` form because +those flags get exported as as C `#define`s to `sqlite_cfg.h`, where +dots are not permitted. + +The `X.y` convention is used in the makefiles primarily because the +person who did the initial port finds that considerably easier on the +eyes and fingers. In practice, the `X_Y` form of such exports is used +exactly once in `Makefile.in`, where it's translated into into `X.y` +form for consumption by `Makefile.in` and +[`main.mk`](/file/main.mk). For example: + +> +``` +LDFLAGS.shobj = @SHOBJ_LDFLAGS@ +LDFLAGS.zlib = @LDFLAGS_ZLIB@ +LDFLAGS.math = @LDFLAGS_MATH@ +``` + + Do Not Update Global Shared State ------------------------------------------------------------------------ @@ -193,12 +225,6 @@ into its own well-defined variables. For example: It is then up to the Makefile to apply and order the flags however is appropriate. -> Sidebar: the `X_Y` convention is used used on the configure-script - side because that process exports those flags as C `#define`s to - `sqlite_cfg.h`, where dots are not permitted. The `X.y` convention - is used in the Makefile side primarily because the person who did - the initial port finds that easier on the eyes and fingers. - At the end of the configure script, the global `CFLAGS` _ideally_ holds only flags which are either relevant to all targets or, failing that, will have no unintended side-effects on any targets. That said: diff --git a/manifest b/manifest index 6d5872463f..372a422444 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\ssection\sto\sautosetup/README.md\sdescribing\sthe\smotivations\sfor\sthe\smore\sglaring\sdesign\sdecisions. -D 2024-11-06T05:54:27.295 +C Split\sthe\smotivation\sof\sthe\smakefile\svar\snaming\sconvention\sinto\sits\sdoc\sown\ssection. +D 2024-11-06T06:06:43.692 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 1dfdbe705c95400a722f0a012b6780ad2c7f12948d15cbdcbf95e030b46c4824 +F autosetup/README.md 3e2d2e0897a77891586d58b09a5d6a195531d276ebcb015d0a282445ce657a8d F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P aa6213767f0d7e63c753e33aadb95cbeb8e522c22f2fe1bbfa4df66bea6e3380 -R 31c89bc32b0e171b0e74463a095b8565 +P c0940a822a63bff74585bd37401eca92f74ddf9fe95748d2474039ee9b2bd9b6 +R cacb6cd838f2b39823094500120f81fe U stephan -Z 316096fa02be870ff4dfd5f1350db8c8 +Z 0c92d49380ea6a167e75c10d69c8359c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ef952f7545..6795433953 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0940a822a63bff74585bd37401eca92f74ddf9fe95748d2474039ee9b2bd9b6 +bf42b93cc7a4f8de2308fa4e5a798a62797bc95d95e4b0bd06035c74413fa828 From ebb3e03b6d3637222005636c3843d6d4d07d2dda Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 6 Nov 2024 06:44:35 +0000 Subject: [PATCH 291/522] Minor doc tweaks and typo fixes. FossilOrigin-Name: 406d9122b75990722ab79fdf42d4528d670645d8f778ca0b5a2a35fa1dc106c4 --- autosetup/README.md | 4 ++-- autosetup/proj.tcl | 11 ++++++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index 330a98de5b..32e90080e5 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -199,8 +199,8 @@ so that the resulting flags get applied at the correct time. > A real-life example of the latter point: before the approach described below was taken to collecting build-time flags, the test - for `-rflag` had to come _after_ the test for zlib because the - results of the `-rflag` test implicitly modified the `CFLAGS`, + for `-rpath` had to come _after_ the test for zlib because the + results of the `-rpath` test implicitly modified the `CFLAGS`, breaking the zlib feature test. Because the feature tests no longer (intentionally) modify global state, that is not an issue. diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index fb98a5e189..5f44cf72cb 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -126,6 +126,8 @@ proc proj-indented-notice {args} { } ######################################################################## +# @proj-is-cross-compiling +# # Returns 1 if cross-compiling, else 0. proc proj-is-cross-compiling {} { return [expr {[get-define host] ne [get-define build]}] @@ -167,9 +169,12 @@ proc proj-strip-hash-comments_ {val} { } ######################################################################## -# A proxy for cc-check-function-in-lib which "undoes" any changes that -# routine makes to the LIBS define. Returns the result of -# cc-check-function-in-lib. +# @proj-check-function-in-lib +# +# A proxy for cc-check-function-in-lib which does not make any global +# changes to the LIBS define. Returns the result of +# cc-check-function-in-lib (i.e. true or false). The resulting linker +# flags are stored in ${lib_${function}}. proc proj-check-function-in-lib {function libs {otherlibs {}}} { set found 0 define-push {LIBS} { diff --git a/manifest b/manifest index 372a422444..0602686fef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Split\sthe\smotivation\sof\sthe\smakefile\svar\snaming\sconvention\sinto\sits\sdoc\sown\ssection. -D 2024-11-06T06:06:43.692 +C Minor\sdoc\stweaks\sand\stypo\sfixes. +D 2024-11-06T06:44:35.358 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 3e2d2e0897a77891586d58b09a5d6a195531d276ebcb015d0a282445ce657a8d +F autosetup/README.md bec9faf93df0451c7fc98f2af21770886841640565d027dd07f2f96c60651a7b F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -50,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl b3a0621b6e98b9e87813ba7a15a64f92708527dd8efc99a764846c16336aadf0 +F autosetup/proj.tcl 504fb46e15a0c6b4b161484a0a24f62b9c165fb901d189c0e523d9a93f1b24c2 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c0940a822a63bff74585bd37401eca92f74ddf9fe95748d2474039ee9b2bd9b6 -R cacb6cd838f2b39823094500120f81fe +P bf42b93cc7a4f8de2308fa4e5a798a62797bc95d95e4b0bd06035c74413fa828 +R 17278f4a0cd6af5e62ab09d724fcee60 U stephan -Z 0c92d49380ea6a167e75c10d69c8359c +Z de533e530a0ec603057ff86b4723ff1a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6795433953..2cb155ff2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf42b93cc7a4f8de2308fa4e5a798a62797bc95d95e4b0bd06035c74413fa828 +406d9122b75990722ab79fdf42d4528d670645d8f778ca0b5a2a35fa1dc106c4 From 6da414ef417b50d1162806ec8e901382970323fe Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 6 Nov 2024 07:20:20 +0000 Subject: [PATCH 292/522] When constructing the auto-reconfigure commands, only quote args which look like they need it. Minor doc updates. FossilOrigin-Name: d4fbd34f7a4b0e6179cb06114d148fbc5d30b8dc8db0b764f4347dd50ff591ba --- auto.def | 30 ++++++++++++------- autosetup/README.md | 70 ++++++++++++++++++++++++--------------------- manifest | 14 ++++----- manifest.uuid | 2 +- 4 files changed, 65 insertions(+), 51 deletions(-) diff --git a/auto.def b/auto.def index 0f33f5b225..88c08bef09 100644 --- a/auto.def +++ b/auto.def @@ -1,4 +1,4 @@ -#/usr/bin/tclsh +#/do/not/tclsh # ^^^ help out editors which guess this file's content type. # # This is the main autosetup-compatible configure script for the @@ -227,15 +227,25 @@ msg-result "Source dir = $srcdir" msg-result "Build dir = $::autosetup(builddir)" msg-result "Configuring SQLite version $PACKAGE_VERSION" -# -# SQLITE_AUTORECONFIG contains make target rules for re-running the -# configure script with the same arguments it was initially invoked -# with. This can be used to automatically reconfigure -# -define-append SQLITE_AUTORECONFIG cd '$::autosetup(builddir)' && '$srcdir/configure' -#{*}$::autosetup(argv) breaks with --flag='val with spaces', so... -foreach arg $::autosetup(argv) { - define-append SQLITE_AUTORECONFIG '$arg' +if {1} { + # + # SQLITE_AUTORECONFIG contains make target rules for re-running the + # configure script with the same arguments it was initially invoked + # with. This can be used to automatically reconfigure + # + proc squote {arg} { + # Wrap $arg in single-quotes if it looks like it might need that + # to avoid mis-handling as a shell argument. We assume that $arg + # will never contain any single-quote characters. + if {[string match {*[ &;$*"]*} $arg]} { return '$arg' } + return $arg + } + define-append SQLITE_AUTORECONFIG cd [squote $::autosetup(builddir)] && [squote $srcdir/configure] + #{*}$::autosetup(argv) breaks with --flag='val with spaces', so... + foreach arg $::autosetup(argv) { + define-append SQLITE_AUTORECONFIG [squote $arg] + } + rename squote "" } # Are we cross-compiling? diff --git a/autosetup/README.md b/autosetup/README.md index 32e90080e5..b9453574fe 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -161,7 +161,7 @@ e.g. `CFLAGS` and `y` is the specific instance of that category, e.g. `CFLAGS.readline`. When the configure script exports flags for consumption by filtered -files, e.g. [`Makefile.in`](/file/Makefile.in) and the generated +files, e.g. [Makefile.in][] and the generated `sqlite_cfg.h`, it does so in the more conventional `X_Y` form because those flags get exported as as C `#define`s to `sqlite_cfg.h`, where dots are not permitted. @@ -169,9 +169,8 @@ dots are not permitted. The `X.y` convention is used in the makefiles primarily because the person who did the initial port finds that considerably easier on the eyes and fingers. In practice, the `X_Y` form of such exports is used -exactly once in `Makefile.in`, where it's translated into into `X.y` -form for consumption by `Makefile.in` and -[`main.mk`](/file/main.mk). For example: +exactly once in [Makefile.in][], where it's translated into into `X.y` +form for consumption by [Makefile.in][] and [main.mk][]. For example: > ``` @@ -185,37 +184,40 @@ Do Not Update Global Shared State ------------------------------------------------------------------------ In both the legacy Autotools-driven build and in common Autosetup -usage, feature tests performed by the configure script may ammend -values to global flags such as `CFLAGS`, `LDFLAGS`, and `LIBS`. -That's appropriate for a makefile which builds a single deliverable, -but less so for makefiles which produce multiple deliverables, as it's -unlikely that every single deliverable will require the same core set -of those flags. In addition, that approach can make it difficult to -determine the origin of any given change to those flags because those -changes are hidden behind voodoo performed outside the immediate -visibility of the configure script's maintainer. It can also force the -maintainers of the configure script to place tests in a specific order -so that the resulting flags get applied at the correct time. - -> A real-life example of the latter point: before the approach - described below was taken to collecting build-time flags, the test - for `-rpath` had to come _after_ the test for zlib because the - results of the `-rpath` test implicitly modified the `CFLAGS`, - breaking the zlib feature test. Because the feature tests no longer - (intentionally) modify global state, that is not an issue. - -Cases where feature tests modify global state in such a way that it -may impact later feature tests are either (A) very intentionally -defined to do so (e.g. the `--with-wasi-sdk` flag needs to modify the -build tool chain) or (B) are oversights (i.e. bugs). - -This tree's configure script, utility APIs, -[`Makefile.in`](/file/Makefile.in), and [`main.mk`](/file/main.mk) -therefore strive to separate the results of any given feature test -into its own well-defined variables. For example: +usage, feature tests performed by the configure script may amend +global flags such as `CFLAGS`, `LDFLAGS`, and `LIBS`. That's +appropriate for a makefile which builds a single deliverable, less +so for makefiles which produce multiple deliverables. Drawbacks +of that approach include: + +- It's unlikely that every single deliverable will require the same + core set of those flags. +- It can be difficult to determine the origin of any given change to + that global state because those changes are hidden behind voodoo performed + outside the immediate visibility of the configure script's + maintainer. +- It can force the maintainers of the configure script to place tests + in a specific order so that the resulting flags get applied at + the correct time.\ + (A real-life example: before the approach described below was taken + to collecting build-time flags, the test for `-rpath` had to come + _after_ the test for zlib because the results of the `-rpath` test + implicitly modified the `CFLAGS`, breaking the zlib feature + test. Because the feature tests no longer (intentionally) modify + global state, that is not an issue.) + +In this build, cases where feature tests modify global state in such a +way that it may impact later feature tests are either (A) very +intentionally defined to do so (e.g. the `--with-wasi-sdk` has +invasive side-effects) or (B) are oversights (i.e. bugs). + +This tree's [configure script][auto.def], [utility APIs][proj.tcl], +[Makefile.in][], and [main.mk][] therefore strive to separate the +results of any given feature test into its own well-defined +variables. For example: - The linker flags for zlib are exported from the configure script as - `LDFLAGS_ZLIB`, which `Makefile.in` and `main.mk` then expose as + `LDFLAGS_ZLIB`, which [Makefile.in][] and [main.mk][] then expose as `LDFLAGS.zlib`. - `CFLAGS_READLINE` (a.k.a. `CFLAGS.readline`) contains the `CFLAGS` needed for including `libreadline`, `libedit`, or `linenoise`, and @@ -267,4 +269,6 @@ configure process, and check it in. [auto.def]: /file/auto.def [autosetup-git]: https://github.com/msteveb/autosetup [proj.tcl]: /file/autosetup/proj.tcl +[Makefile.in]: /file/Makefile.in +[main.mk]: /file/main.mk [JimTCL]: https://jim.tcl.tk diff --git a/manifest b/manifest index 0602686fef..c450b0aa8f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sdoc\stweaks\sand\stypo\sfixes. -D 2024-11-06T06:44:35.358 +C When\sconstructing\sthe\sauto-reconfigure\scommands,\sonly\squote\sargs\swhich\slook\slike\sthey\sneed\sit.\sMinor\sdoc\supdates. +D 2024-11-06T07:20:20.567 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 062b05538bc09779962a5265125aa289152f6abbb1ebaded9b22e8969b151d75 +F auto.def 05eedbf203a070fc84d9d26071f7ddf2a30f2118ab0204db46e91dbfec8a50b8 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md bec9faf93df0451c7fc98f2af21770886841640565d027dd07f2f96c60651a7b +F autosetup/README.md e6a686c3959fc565f9310f10f0d038440b1715591b6a90fc594160e8c361a5b6 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bf42b93cc7a4f8de2308fa4e5a798a62797bc95d95e4b0bd06035c74413fa828 -R 17278f4a0cd6af5e62ab09d724fcee60 +P 406d9122b75990722ab79fdf42d4528d670645d8f778ca0b5a2a35fa1dc106c4 +R d119d74839c372da88adc458ca3c56bf U stephan -Z de533e530a0ec603057ff86b4723ff1a +Z 3e647edf4dd8fa5473ff129830ab4868 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2cb155ff2d..20a2e64608 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -406d9122b75990722ab79fdf42d4528d670645d8f778ca0b5a2a35fa1dc106c4 +d4fbd34f7a4b0e6179cb06114d148fbc5d30b8dc8db0b764f4347dd50ff591ba From 598d0d14980a23bff264313b280e99662072136b Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 6 Nov 2024 08:29:47 +0000 Subject: [PATCH 293/522] Minor doc tweaks. FossilOrigin-Name: 2919a61bd4f8cb4f53462d4807cbc04ac5f71dd437cd693538754cf3f17d00cc --- autosetup/README.md | 25 +++++++++++++++++-------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index b9453574fe..502c901448 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -74,8 +74,8 @@ In (mostly) alphabetical order: - **`proj-indented-notice ?-error? msg`**\ Breaks its `msg` argument into lines, trims them, and emits them with consistent indentation. If the `-error` flag is used, it then - exits with non-0. This will stick out starkly from normal output - and is intended to be used only for important notices. + exits with a non-0 result code. This will stick out starkly from + normal output and is intended to be used only for important notices. - **`proj-opt-truthy flag`**\ Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on, @@ -179,16 +179,20 @@ LDFLAGS.zlib = @LDFLAGS_ZLIB@ LDFLAGS.math = @LDFLAGS_MATH@ ``` +(That first one is defined by autosetup, and thus applies "LDFLAGS" as +the suffix rather than the prefix. Which is more legible is a matter +of taste, for which there is no accounting.) + Do Not Update Global Shared State ------------------------------------------------------------------------ In both the legacy Autotools-driven build and in common Autosetup usage, feature tests performed by the configure script may amend -global flags such as `CFLAGS`, `LDFLAGS`, and `LIBS`. That's -appropriate for a makefile which builds a single deliverable, less -so for makefiles which produce multiple deliverables. Drawbacks -of that approach include: +global flags such as `CFLAGS`, `LDFLAGS`, and `LIBS`[^as-cflags]. That's +appropriate for a makefile which builds a single deliverable, but less +so for makefiles which produce multiple deliverables. Drawbacks of +that approach include: - It's unlikely that every single deliverable will require the same core set of those flags. @@ -198,11 +202,11 @@ of that approach include: maintainer. - It can force the maintainers of the configure script to place tests in a specific order so that the resulting flags get applied at - the correct time.\ + the correct time and/or in the correct order.\ (A real-life example: before the approach described below was taken to collecting build-time flags, the test for `-rpath` had to come _after_ the test for zlib because the results of the `-rpath` test - implicitly modified the `CFLAGS`, breaking the zlib feature + implicitly modified global state which broke the zlib feature test. Because the feature tests no longer (intentionally) modify global state, that is not an issue.) @@ -236,6 +240,11 @@ case there is no practical way to avoid "polluting" the builds of arbitrary makefile targets with those. _C'est la vie._ +[^as-cflags]: But see this article for a detailed discussion of how + autosetup currently deals specifically with CFLAGS: + + + Updating Autosetup ======================================================================== diff --git a/manifest b/manifest index c450b0aa8f..874d61f2ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sconstructing\sthe\sauto-reconfigure\scommands,\sonly\squote\sargs\swhich\slook\slike\sthey\sneed\sit.\sMinor\sdoc\supdates. -D 2024-11-06T07:20:20.567 +C Minor\sdoc\stweaks. +D 2024-11-06T08:29:47.976 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md e6a686c3959fc565f9310f10f0d038440b1715591b6a90fc594160e8c361a5b6 +F autosetup/README.md fd7d8b3cd25ddeb6f6041be14a17923a64c30c1855825224d34dc2c28fa8ee94 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 406d9122b75990722ab79fdf42d4528d670645d8f778ca0b5a2a35fa1dc106c4 -R d119d74839c372da88adc458ca3c56bf +P d4fbd34f7a4b0e6179cb06114d148fbc5d30b8dc8db0b764f4347dd50ff591ba +R 0b25478245094cdc9d825ea4c9f1d6d5 U stephan -Z 3e647edf4dd8fa5473ff129830ab4868 +Z 3fe0453285c895a787d757f74d8262d1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 20a2e64608..f536e1b854 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4fbd34f7a4b0e6179cb06114d148fbc5d30b8dc8db0b764f4347dd50ff591ba +2919a61bd4f8cb4f53462d4807cbc04ac5f71dd437cd693538754cf3f17d00cc From 7e3e0311826a740e521ae23a232bdfad9969f3d1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Nov 2024 10:09:21 +0000 Subject: [PATCH 294/522] Fix typo in the LICENSE.md file. FossilOrigin-Name: 0588cc5c2fad980aa67402f4fe959a499d711ff23903a521af1b1abc4586c802 --- LICENSE.md | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 5382a66842..ebfc077603 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -19,7 +19,7 @@ that are public domain include the following: * All of the SQLite extension source code and test cases in the [ext/ directory](https://sqlite.org/src/tree/ext?type=tree&expand) * All code that ends up in the "sqlite3.c" and "sqlite3.h" build products - that actually implements the SQLite RDBMS. + that actually implement the SQLite RDBMS. * All of the code used to compile the [command-line interface](https://sqlite.org/cli.html) * All of the code used to build various utility programs such as diff --git a/manifest b/manifest index 874d61f2ba..f862b41acd 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Minor\sdoc\stweaks. -D 2024-11-06T08:29:47.976 +C Fix\stypo\sin\sthe\sLICENSE.md\sfile. +D 2024-11-06T10:09:21.914 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea -F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 +F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in 3a54957d16c3f4666922f170a19b4b51dc13be039c29394dd38caa95ade5d731 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d4fbd34f7a4b0e6179cb06114d148fbc5d30b8dc8db0b764f4347dd50ff591ba -R 0b25478245094cdc9d825ea4c9f1d6d5 -U stephan -Z 3fe0453285c895a787d757f74d8262d1 +P 2919a61bd4f8cb4f53462d4807cbc04ac5f71dd437cd693538754cf3f17d00cc +R e657929838382908e594a0464cd69699 +U drh +Z 5889a5c1931f6955993ec7647ef0ded1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f536e1b854..ecd381094b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2919a61bd4f8cb4f53462d4807cbc04ac5f71dd437cd693538754cf3f17d00cc +0588cc5c2fad980aa67402f4fe959a499d711ff23903a521af1b1abc4586c802 From 9243eb4ab87474676480bde48644341d340498de Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 6 Nov 2024 12:13:04 +0000 Subject: [PATCH 295/522] Elaborate on how autosetup selects a tclsh to use. FossilOrigin-Name: d3887895a33742fb1fc97235cf897d295b237a9fb5a84031826f9c1018106f18 --- autosetup/README.md | 54 ++++++++++++++++++++++++++------------------- manifest | 14 ++++++------ manifest.uuid | 2 +- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index 502c901448..8f0f5601e7 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -114,33 +114,41 @@ script runs in JimTCL without using any JimTCL-specific features, then it's a certainty that it will run in canonical TCL as well. The opposite, however, is not _always_ the case. -By default, the configure script will search for an available `tclsh` -(under several common names, e.g. `tclsh8.6`) before falling back to -compiling the copy of `jimsh0.c` included in the source tree. - -There are two simple ways to ensure that the configure process uses -JimTCL instead of the canonical `tclsh`, and either approach provides -equally high assurances about configure script compatibility across -TCL implementations: - -1. Build on a system with no `tclsh` installed. In that case, the - configure process will fall back to building the in-tree copy of - JimTCL. +When [`./configure`](/file/configure) is run, it goes through a +bootstrapping process to find a suitable TCL with which to run the +autosetup framework. The first step involves [finding or building a +TCL shell](/file/autosetup/autosetup-find-tclsh). That will first +search for an available `tclsh` (under several common names, +e.g. `tclsh8.6`) before falling back to compiling the copy of +`jimsh0.c` included in the source tree. i.e. it will prefer to use a +system-installed TCL for running the configure script. Once it finds +(or builds) a TCL shell, it then runs [a sanity test to ensure that +the shell is suitable](/file/autosetup/autosetup-test-tclsh) before +using it to run the main autosetup app. + +There are two simple ways to ensure that running of the configure +process uses JimTCL instead of the canonical `tclsh`, and either +approach provides equally high assurances about configure script +compatibility across TCL implementations: + +1. Build on a system with no `tclsh` installed in the `$PATH`. In that + case, the configure process will fall back to building the in-tree + copy of JimTCL. 2. Manually build `./jimsh0` in the top of the checkout with:\ `cc -o jimsh0 autosetup/jimsh0.c`\ With that in place, the configure script will prefer to use that - before looking for a system-level `tclsh`. Note that `make distclean` - will remove that file. + before looking for a system-level `tclsh`. Be aware, though, that + `make distclean` will remove that file. **Note that `jimsh0` is distinctly different** from the `jimsh` which gets built for code-generation purposes. The latter requires non-default build flags to enable features which are -platform-dependent, most notably to make its `[file normalize]` -work. This means, for example, that the configure script and its -utility APIs must not use `[file normalize]`, but autosetup provides a -TCL implementation of `[file-normalize]` (note the dash) for portable -use in the configure script. +platform-dependent, most notably to make its `[file normalize]` work. +This means, for example, that the configure script and its utility +APIs must not use `[file normalize]`, but autosetup provides a TCL +implementation of `[file-normalize]` (note the dash) for portable use +in the configure script. @@ -189,7 +197,7 @@ Do Not Update Global Shared State In both the legacy Autotools-driven build and in common Autosetup usage, feature tests performed by the configure script may amend -global flags such as `CFLAGS`, `LDFLAGS`, and `LIBS`[^as-cflags]. That's +global flags such as `LIBS`, `LDFLAGS`, and `CFLAGS`[^as-cflags]. That's appropriate for a makefile which builds a single deliverable, but less so for makefiles which produce multiple deliverables. Drawbacks of that approach include: @@ -212,7 +220,7 @@ that approach include: In this build, cases where feature tests modify global state in such a way that it may impact later feature tests are either (A) very -intentionally defined to do so (e.g. the `--with-wasi-sdk` has +intentionally defined to do so (e.g. the `--with-wasi-sdk` flag has invasive side-effects) or (B) are oversights (i.e. bugs). This tree's [configure script][auto.def], [utility APIs][proj.tcl], @@ -241,8 +249,8 @@ arbitrary makefile targets with those. _C'est la vie._ [^as-cflags]: But see this article for a detailed discussion of how - autosetup currently deals specifically with CFLAGS: - + autosetup currently deals specifically with CFLAGS: + diff --git a/manifest b/manifest index f862b41acd..f6a7cb99e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\sLICENSE.md\sfile. -D 2024-11-06T10:09:21.914 +C Elaborate\son\show\sautosetup\sselects\sa\stclsh\sto\suse. +D 2024-11-06T12:13:04.398 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md fd7d8b3cd25ddeb6f6041be14a17923a64c30c1855825224d34dc2c28fa8ee94 +F autosetup/README.md 78f434bc13029a7ddf4d62fb0c82216f1dceaee448239022a1ce49230925b4c9 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2919a61bd4f8cb4f53462d4807cbc04ac5f71dd437cd693538754cf3f17d00cc -R e657929838382908e594a0464cd69699 -U drh -Z 5889a5c1931f6955993ec7647ef0ded1 +P 0588cc5c2fad980aa67402f4fe959a499d711ff23903a521af1b1abc4586c802 +R 38a47456c93afcec3fbbb28bb999fc81 +U stephan +Z 0201db4089d5c5c84f67e4e19c93d1c5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ecd381094b..a175748b0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0588cc5c2fad980aa67402f4fe959a499d711ff23903a521af1b1abc4586c802 +d3887895a33742fb1fc97235cf897d295b237a9fb5a84031826f9c1018106f18 From 8acaa6d039199a11231f087790500c72397d791a Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 6 Nov 2024 16:20:16 +0000 Subject: [PATCH 296/522] Add tests for xInstToken() and prefix queries with various fts5 configurations. FossilOrigin-Name: 9cc04331a01760189d88697233009dbe8a60eda589792ad01b56300499e9f54d --- ext/fts5/test/fts5origintext6.test | 209 +++++++++++++++++++++++++++++ manifest | 11 +- manifest.uuid | 2 +- 3 files changed, 216 insertions(+), 6 deletions(-) create mode 100644 ext/fts5/test/fts5origintext6.test diff --git a/ext/fts5/test/fts5origintext6.test b/ext/fts5/test/fts5origintext6.test new file mode 100644 index 0000000000..7b27e310b9 --- /dev/null +++ b/ext/fts5/test/fts5origintext6.test @@ -0,0 +1,209 @@ +# 2014 Jan 08 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Tests focused on phrase queries. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5origintext6 + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +proc insert_data {tbl} { + db eval " + INSERT INTO $tbl (rowid, x, y) VALUES + (1, 'ChH BDd HhG efc BjJ BGi GBG FdD','ciJ AFf ADf fBJ fhC GFI JEH fcA'), + (2, 'deg AIG Fie jII cCd Hbf igF fEE','GeA Ija gJg EDc HFi DDI dCf aDd'), + (3, 'IJC hga deC Jfa Aeg hfh CcH dfb','ajD hgC Jaf IfH CHe jIG AjD adF'), + (4, 'FiH GJH IDA AiG bBc CGG Eih bIH','hHg JaH aii IHE Ggd gcH gji CGc'), + (5, 'ceg CAd jFI GAB BGg EeC IdH acG','bBC eIG ifH eDE Adj bjb GCj ebA'), + (6, 'Eac Fbh aFF Eea jeG EIj HCc JJH','hbd giE Gfe eiI dEF abE cJf cAb'), + (7, 'dic hAc jEC AiG FEF jHc HiD HBI','aEd ebE Gfi AJG EBA faj GiG jjE'), + (8, 'Fca iEe EgE jjJ gce ijf EGc EBi','gaI dhH bFg CFc HeC CjI Jfg ccH'), + (9, 'cfd iaa HCf iHJ HjG ffh ABb ibi','CfG bia Dai eii Ejg Jeg fCg hDb'), + (10, 'Jjf hJC IID HJj bGB EbJ cgg eBj','jci jhi JAF jIg Bei Bcd cAC AJd'), + (11, 'egG Cdi bFf fEB hfH jDH jia Efd','FAd eCg fAi aiC baC eJG acF iGE'), + (12, 'Ada Gde CJI ADG gJA Cbb ccF iAB','eAE ajC FBB ccd Jgh fJg ieg hGE'), + (13, 'gBb fDG Jdd HdD fiJ Bed Cig iGg','heC FeI iaj gdg ebB giC HaD FIe'), + (14, 'FiI iDd Ffe igI bgB EJf FHG hDF','cjC AeI abf Fah cbJ ffH jEb aib'), + (15, 'jaF hBI jIH Gdh FEc Fij hgj jFh','dGA ADH feh AAI AfJ DbC gBi hGH'), + (16, 'gjH BGg iGj aFE CAH edI idf HEH','hIf DDg fjB hGi cHF BCH FjG Bgd'), + (17, 'iaI JGH hji gcj Dda eeG jDd CBi','cHg jeh caG gIc feF ihG hgJ Abj'), + (18, 'jHI iDB eFf AiH EFB CDb IAj GbC','Ghe dEI gdI jai gib dAG BIa djb'), + (19, 'abI fHG Ccf aAc FDa fiC agF bdB','afi hde IgE bGF cfg DHD diE aca'), + (20, 'IFh eDJ jfh cDg dde JGJ GAf fIJ','IBa EfH faE aeI FIF baJ FGj EIH'), + (21, 'Dee bFC bBA dEI CEj aJI ghA dCH','hBA ddA HJh dfj egI Dij dFE bGE'), + (22, 'JFE BCj FgA afc Jda FGD iHJ HDh','eAI jHe BHD Gah bbD Bgj gbh eGB'), + (23, 'edE CJE FjG aFI edA Cea FId iFe','ABG jcA ddj EEc Dcg hAI agA biA'), + (24, 'AgE cfc eef cGh aFB DcH efJ hcH','eGF HaB diG fgi bdc iGJ FGJ fFB'), + (25, 'aCa AgI GhC DDI hGJ Hgc Gcg bbG','iID Fga jHa jIj idj DFD bAC AFJ'), + (26, 'gjC JGh Fge faa eCA iGG gHE Gai','bDi hFE BbI DHD Adb Fgi hCa Hij'), + (27, 'Eji jEI jhF DFC afH cDh AGc dHA','IDe GcA ChF DIb Bif HfH agD DGh'), + (28, 'gDD AEE Dfg ICf Cbi JdE jgH eEi','eEb dBG FDE jgf cAI FaJ jaA cDd'), + (29, 'cbe Gec hgB Egi bca dHg bAJ jBf','EFB DgD GJc fDb EeE bBA GFC Hbe'), + (30, 'Adc eHB afI hDc Bhh baE hcJ BBd','JAH deg bcF Dab Bgj Gbb JHi FIB'), + (31, 'agF dIj AJJ Hfg cCG hED Igc fHC','JEf eia dHf Ggc Agj geD bEE Gei'), + (32, 'DAd cCe cbJ FjG gJe gba dJA GCf','eAf hFc bGE ABI hHA IcE abF CCE'), + (33, 'fFh jJe DhJ cDJ EBi AfD eFI IhG','fEG GCc Bjd EFF ggg CFe EHd ciB'), + (34, 'Ejb BjI eAF HaD eEJ FaG Eda AHC','Iah hgD EJG fdD cIE Daj IFf eJh'), + (35, 'aHG eCe FjA djJ dAJ jiJ IaE GGB','Acg iEF JfB FIC Eei ggj dic Iii'), + (36, 'Fdb EDF GaF JjB ehH IgC hgi DCG','cag DHI Fah hAJ bbh egG Hia hgJ'), + (37, 'HGg icC JEC AFJ Ddh dhi hfC Ich','fEg bED Bff hCJ EiA cIf bfG cGA'), + (38, 'aEJ jGI BCi FaA ebA BHj cIJ GcC','dCH ADd bGB cFE AgF geD cbG jIc'), + (39, 'JFB bBi heA BFA hgB Ahj EIE CgI','EIJ JFG FJE GeA Hdg HeH ACh GiA'), + (40, 'agB DDC CED igC Dfc DhI eiC fHi','dAB dcg iJF cej Fcc cAc AfB Fdd'), + (41, 'BdF DHj Ege hcG DEd eFa dCf gBb','FBG ChB cej iGd Hbh fCc Ibe Abh'), + (42, 'Bgc DjI cbC jGD bdb hHB IJA IJH','heg cii abb IGf eDe hJc dii fcE'), + (43, 'fhf ECa FiA aDh Jbf CiB Jhe ajD','GFE bIF aeD gDE BIE Jea DfC BEc'), + (44, 'GjE dBj DbJ ICF aDh EEH Ejb jFb','dJj aEc IBg bEG Faf fjA hjf FAF'), + (45, 'BfA efd IIJ AHG dDF eGg dIJ Gcb','Bfj jeb Ahc dAE ACH Dfb ieb dhC'), + (46, 'Ibj ege geC dJh CIi hbD EAG fGA','DEb BFe Bjg FId Fhg HeF JAc BbE'), + (47, 'dhB afC hgG bEJ aIe Cbe iEE JCD','bdg Ajc FGA jbh Jge iAj fIA jbE'), + (48, 'egH iDi bfH iiI hGC jFF Hfd AHB','bjE Beb iCc haB gIH Dea bga dfd'), + (49, 'jgf chc jGc Baj HBb jdE hgh heI','FFB aBd iEB EIG HGf Bbj EIi JbI'), + (50, 'jhe EGi ajA fbH geh EHe FdC bij','jDE bBC gbH HeE dcH iBH IFE AHi'), + (51, 'aCb JiD cgJ Bjj iAI Hbe IAF FhH','ijf bhE Jdf FED dCH bbG HcJ ebH'); + " +} + +foreach_detail_mode $testprefix { +foreach external {0 1 2} { + reset_db + + proc tokens {cmd} { + set ret [list] + for {set iTok 0} {$iTok < [$cmd xInstCount]} {incr iTok} { + set txt [$cmd xInstToken $iTok 0] + set txt [string map [list "\0" "."] $txt] + lappend ret $txt + } + set ret + } + sqlite3_fts5_create_function db tokens tokens + sqlite3_fts5_register_origintext db + + set E(0) internal + set E(1) external + set E(2) contentless + set e $E($external) + + db eval { CREATE TABLE ex(x, y) } + switch -- $external { + 0 { + do_execsql_test 1.$e.0 { + CREATE VIRTUAL TABLE ft USING fts5( + x, y, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL% + ); + } + } + + 1 { + do_execsql_test 1.$e.0 { + CREATE VIRTUAL TABLE ft USING fts5( + x, y, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%, + content=ex + ); + } + } + + 2 { + do_execsql_test 1.$e.0 { + CREATE VIRTUAL TABLE ft USING fts5( + x, y, tokenize="origintext unicode61", tokendata=1, detail=%DETAIL%, + content= + ); + } + } + } + insert_data ex + insert_data ft + + proc prefixquery {prefix bInst bYOnly} { + set ret [list] + db eval { SELECT rowid, x, y FROM ex ORDER BY rowid } { + set row [list] + set bSeen 0 + + set T [concat $x $y] + if {$bYOnly} { set T $y } + + foreach w $T { + if {[string match -nocase $prefix $w]} { + set bSeen 1 + if {$bInst} { + set v [string tolower $w] + if {$w != $v} { append v ".$w" } + lappend row $v + } + } + } + + if {$bSeen} { + lappend ret $rowid + lappend ret $row + } + } + + set ret + } + + proc do_prefixquery_test {tn prefix} { + set bInst [expr {$::e!="contentless" || "%DETAIL%"=="full"}] + set expect [prefixquery $prefix $bInst 0] + set expect2 [prefixquery $prefix $bInst 1] + + uplevel [list do_execsql_test $tn.1 " + SELECT rowid, tokens(ft) FROM ft('$prefix') + " $expect] + uplevel [list do_execsql_test $tn.2 " + SELECT rowid, tokens(ft) FROM ft(fts5_insttoken('$prefix')) + " $expect] + db eval { INSERT INTO ft(ft, rank) VALUES('insttoken', 1) } + uplevel [list do_execsql_test $tn.3 " + SELECT rowid, tokens(ft) FROM ft('$prefix') + " $expect] + db eval { INSERT INTO ft(ft, rank) VALUES('insttoken', 0) } + + if {"%DETAIL%"!="none"} { + uplevel [list do_execsql_test $tn.4 " + SELECT rowid, tokens(ft) FROM ft('y: $prefix') + " $expect2] + uplevel [list do_execsql_test $tn.5 " + SELECT rowid, tokens(ft) FROM ft(fts5_insttoken('y: $prefix')) + " $expect2] + db eval { INSERT INTO ft(ft, rank) VALUES('insttoken', 1) } + uplevel [list do_execsql_test $tn.6 " + SELECT rowid, tokens(ft) FROM ft('y: $prefix') + " $expect2] + db eval { INSERT INTO ft(ft, rank) VALUES('insttoken', 0) } + } + } + + do_prefixquery_test 1.$e.1 a* + do_prefixquery_test 1.$e.2 b* + do_prefixquery_test 1.$e.3 c* + do_prefixquery_test 1.$e.4 d* + do_prefixquery_test 1.$e.5 e* + do_prefixquery_test 1.$e.6 f* + do_prefixquery_test 1.$e.7 g* + do_prefixquery_test 1.$e.8 h* + do_prefixquery_test 1.$e.9 i* + do_prefixquery_test 1.$e.10 j* +}} + + + +finish_test + diff --git a/manifest b/manifest index 603ced6491..d34164b757 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\san\sfts5\stable\sor\squery\sto\sbe\sconfigured\sto\scollect\sxInstToken\sdata\sfor\sany\sprefix\sterms\sas\spart\sof\sthe\sfirst\sparse\sof\sthe\smain\sindex,\sif\sany. -D 2024-11-02T19:10:50.264 +C Add\stests\sfor\sxInstToken()\sand\sprefix\squeries\swith\svarious\sfts5\sconfigurations. +D 2024-11-06T16:20:16.715 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 @@ -219,6 +219,7 @@ F ext/fts5/test/fts5origintext2.test f4505ff79bf7369f2b8b10b9cef7476049d844e20b3 F ext/fts5/test/fts5origintext3.test 4988b6375acc3bbb0515667765f57e389caf449814af9c1095c053f7de2b4223 F ext/fts5/test/fts5origintext4.test 0d3ef0a8038f471dbc83001c34fe5f7ae39b571bfc209670771eb28bc0fc50e8 F ext/fts5/test/fts5origintext5.test ee12b440ec335e5b422d1668aca0051b52ff28b6ee67073e8bbc29f509fd562b +F ext/fts5/test/fts5origintext6.test 09eb1347cb0dceaebbebf3d3e6bd5d24c7c1006efddc2984540450324bbdafa4 F ext/fts5/test/fts5phrase.test bb2554bb61d15f859678c96dc89a7de415cd5fc3b7b54c29b82a0d0ad138091c F ext/fts5/test/fts5plan.test f8b0d752a818059a934cdc96c0f77de058a67a0a57bb3a8181d28307ab5b1626 F ext/fts5/test/fts5porter.test 15b514fac8690b58e99c330efe5bf5615bc43f2fae4a3cca3f923dbaff55a0c0 @@ -2199,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 790c56d493c66a2136e24d349d169639809d70bfab6996975a403be568a267a5 -R 71ba4975c4c76073cda6dd2f314d94d1 +P 46929ae92b26f02bc70de9931b21a8a7cf9a2453d5fb07f68b712f62e28e9152 +R a22fb948708e266e2094d3645362e84e U dan -Z 95da39a03d7bb4b9bc58c6dbf7b809e5 +Z 3041da3c7f9ea1d87e0998786f60280f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 94e1307210..20c99b7fae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46929ae92b26f02bc70de9931b21a8a7cf9a2453d5fb07f68b712f62e28e9152 +9cc04331a01760189d88697233009dbe8a60eda589792ad01b56300499e9f54d From 19d87fa8482d1c67615ef37643898e6927be9b44 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Nov 2024 19:19:49 +0000 Subject: [PATCH 297/522] Fix an FTS3 corruption test case that depends on the specific pseudo-random byte sequence generated by sqlite3_randomness(), which is different on big-endian platforms than it is on little-endian platforms. FossilOrigin-Name: 6216bfcb74273b7893735e265d3f04d1362fa625cd60cebccb866ce7d6c50e01 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/fts3corrupt4.test | 30 ++++++++++++++++++++++++++---- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 70e40545a1..e87ed57197 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Re-phrase\ssome\s(#if\s!SQLITE_CORE)\sto\s(#ifndef\sSQLITE_CORE),\sas\sdiscussed\sin\sforum:cea40371c5e34b09\s|\sfor\spost\scea40371c5e34b09]. -D 2024-11-06T12:58:31.469 +C Fix\san\sFTS3\scorruption\stest\scase\sthat\sdepends\son\sthe\sspecific\spseudo-random\nbyte\ssequence\sgenerated\sby\ssqlite3_randomness(),\swhich\sis\sdifferent\son\nbig-endian\splatforms\sthan\sit\sis\son\slittle-endian\splatforms. +D 2024-11-06T19:19:49.300 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1189,7 +1189,7 @@ F test/fts3conf.test c9cd45433b6787d48a43e84949aa2eb8b3b3d242bac7276731c1476290d F test/fts3corrupt.test 6732477c5ace050c5758a40a8b5706c8c0cccd416b9c558e0e15224805a40e57 F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test a451033ae31db9c5979a7612dee80fb4f221db104a2eeeabd1c9adcc8e8fe95a +F test/fts3corrupt4.test c7f414fe29b97a478d15c90382c4ae077a2bbd2283bf8c63bf66dadaaed3edb8 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525 F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf @@ -2200,9 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d3887895a33742fb1fc97235cf897d295b237a9fb5a84031826f9c1018106f18 cd82e4c0f5f8ff16468b909d84dd5545c0456f624db61a4d112467a7cafed2fc -R 2ce6f48a525cff0a5e55030616b254d4 -T +closed cd82e4c0f5f8ff16468b909d84dd5545c0456f624db61a4d112467a7cafed2fc Closed\sby\sintegrate-merge. -U stephan -Z 49b3cdd634f6b6d641022069d2594f18 +P 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9 +R fca9e17da314094528f1ce35ee0eadb3 +U drh +Z d5ae46fbd1e85e01ddb44833f789fc17 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 58fda30e8b..0090ab059a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9 +6216bfcb74273b7893735e265d3f04d1362fa625cd60cebccb866ce7d6c50e01 diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index d09060d6cd..01effa0850 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -4403,10 +4403,32 @@ do_catchsql_test 25.5 { INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ; } {0 {}} -do_catchsql_test 25.6 { - INSERT INTO t1(t1) SELECT x FROM t2; - INSERT INTO t1(t1) SELECT x FROM t2; -} {1 {database disk image is malformed}} +if {$tcl_platform(byteOrder)=="littleEndian"} { + # The SQLITE_CORRUPT error depends on the specific random byte + # sequence generated by SQLite's PRNG. But the SQLite PRNG + # uses ChaCha20, which generates a different byte sequence on + # big-endian and little-endian platforms. The SQLITE_CORRUPT + # error only comes up when the pseudo-random byte sequence is + # the one generated on little-endian platforms. + # + # See Forum thread: + # https://sqlite.org/forum/forumpost/b5f89d813babfd88 + # + do_catchsql_test 25.6a { + INSERT INTO t1(t1) SELECT x FROM t2; + } {1 {database disk image is malformed}} + do_catchsql_test 25.6b { + INSERT INTO t1(t1) SELECT x FROM t2; + } {1 {database disk image is malformed}} +} else { + do_catchsql_test 25.6a { + INSERT INTO t1(t1) SELECT x FROM t2; + } {0 {}} + do_catchsql_test 25.6b { + INSERT INTO t1(t1) SELECT x FROM t2; + } {0 {}} +} + #------------------------------------------------------------------------- reset_db From 347e4833f9e8fe5e89374e50e8b0e68c4e1a941a Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 05:26:09 +0000 Subject: [PATCH 298/522] For platforms where tclsh is found but tclConfig.sh is not, set HAVE_TCL to 0. We can't build the TCL components on those. Problem reported in [forum:5106aee3a8|forum post 5106aee3a8]. FossilOrigin-Name: 04d2576b2e516fc5f5ba719d6bb01d25fd3b06b1c2d26acbec32bcdd65e9a01c --- auto.def | 10 +++++++--- autosetup/proj.tcl | 7 +++---- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/auto.def b/auto.def index 88c08bef09..59a4aae3fe 100644 --- a/auto.def +++ b/auto.def @@ -635,10 +635,14 @@ proc sqlite-check-tcl {} { }; # find TCLLIBDIR if {[file exists $with_tclsh]} { - msg-result "Using tclsh: $with_tclsh" - define HAVE_TCL 1 + if {$cfg ne ""} { + msg-result "Using tclsh: $with_tclsh" + define HAVE_TCL 1 + } else { + proj-warn "Found tclsh but no tclConfig.sh, so cannot build TCL components." + } } else { - proj-warn "Cannot find a usable tclsh, so cannot run tests." + proj-warn "Cannot find a usable tclsh, so cannot build TCL components." } show-notices }; # sqlite-check-tcl diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 5f44cf72cb..98ee998ebc 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -1152,7 +1152,7 @@ proc proj-which-linenoise {dotH} { # In that make invocation, $(libdir) would, at make-time, normally be # hard-coded to /foo/lib, rather than /blah/lib. That happens because # the autosetup exports conventional $prefix-based values for the -# numerious autoconfig-compatible XYZdir vars at configure-time. What +# numerous autoconfig-compatible XYZdir vars at configure-time. What # we would normally want, however, is that --libdir derives from the # make-time $(prefix). The distinction between configure-time and # make-time is the significant factor there. @@ -1169,11 +1169,10 @@ proc proj-which-linenoise {dotH} { # reference, e.g. libdir=${exec_prefix}/lib. Ergo, if # --exec-prefix=FOO is passed to configure, libdir will still derive, # at make-time, from whatever exec_prefix is passed to make, and will -# use FOO if exec_prefix is not overridden. Without this +# use FOO if exec_prefix is not overridden at make-time. Without this # post-processing, libdir would be cemented in as FOO/lib at -# configure-time, so would be tedious to override properly via a make +# configure-time, so could be tedious to override properly via a make # invocation. -# proc proj-remap-autoconf-dir-vars {} { set prefix [get-define prefix] set exec_prefix [get-define exec_prefix $prefix] diff --git a/manifest b/manifest index e87ed57197..079ede813e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sFTS3\scorruption\stest\scase\sthat\sdepends\son\sthe\sspecific\spseudo-random\nbyte\ssequence\sgenerated\sby\ssqlite3_randomness(),\swhich\sis\sdifferent\son\nbig-endian\splatforms\sthan\sit\sis\son\slittle-endian\splatforms. -D 2024-11-06T19:19:49.300 +C For\splatforms\swhere\stclsh\sis\sfound\sbut\stclConfig.sh\sis\snot,\sset\sHAVE_TCL\sto\s0.\sWe\scan't\sbuild\sthe\sTCL\scomponents\son\sthose.\sProblem\sreported\sin\s[forum:5106aee3a8|forum\spost\s5106aee3a8]. +D 2024-11-07T05:26:09.487 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 05eedbf203a070fc84d9d26071f7ddf2a30f2118ab0204db46e91dbfec8a50b8 +F auto.def 7d4399cfcf2d05abe17ee62f7164b02a435a5c6f4f7a4581c126510a9ac83ef5 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -50,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 504fb46e15a0c6b4b161484a0a24f62b9c165fb901d189c0e523d9a93f1b24c2 +F autosetup/proj.tcl 2ee715f7fa7386879af0c651a22f9d451f980b8f2fed37d94f28b5b03cf5d703 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9 -R fca9e17da314094528f1ce35ee0eadb3 -U drh -Z d5ae46fbd1e85e01ddb44833f789fc17 +P 6216bfcb74273b7893735e265d3f04d1362fa625cd60cebccb866ce7d6c50e01 +R ebdad56d0bb2add7c241926e4c52fbe3 +U stephan +Z 365df9597782f382d765b4f7c83a4a0c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0090ab059a..65e4c9a375 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6216bfcb74273b7893735e265d3f04d1362fa625cd60cebccb866ce7d6c50e01 +04d2576b2e516fc5f5ba719d6bb01d25fd3b06b1c2d26acbec32bcdd65e9a01c From 968dc2489a57fac0bf93d24c1f6bd6c8c95bec56 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 06:00:14 +0000 Subject: [PATCH 299/522] Change several 'file exists' checks for tclsh to file-isexec because that checks for .exe extensions on Windows. FossilOrigin-Name: 052a1b4d7cb43b7f65028c41e9a7a17b533c834d8f620fbc7bc0adddb1fdb843 --- auto.def | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/auto.def b/auto.def index 59a4aae3fe..46ea9f6107 100644 --- a/auto.def +++ b/auto.def @@ -634,7 +634,7 @@ proc sqlite-check-tcl {} { #msg-debug "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" }; # find TCLLIBDIR - if {[file exists $with_tclsh]} { + if {[file-isexec $with_tclsh]} { if {$cfg ne ""} { msg-result "Using tclsh: $with_tclsh" define HAVE_TCL 1 @@ -695,7 +695,7 @@ proc sqlite-determine-codegen-tcl {} { # _fullpath() is a Windows API define-append CFLAGS_JIMSH -DHAVE__FULLPATH define BTCLSH "\$(JIMSH)" - } elseif {[file exists [get-define TCLSH_CMD]]} { + } elseif {[file-isexec [get-define TCLSH_CMD]]} { set cgtcl [get-define TCLSH_CMD] define BTCLSH "\$(TCLSH_CMD)" } else { @@ -713,7 +713,7 @@ proc sqlite-determine-codegen-tcl {} { } } set cgtcl [get-define TCLSH_CMD] - if {![file exists $cgtcl]} { + if {![file-isexec $cgtcl]} { proj-fatal "Cannot find a tclsh to use for code generation." } define BTCLSH "\$(TCLSH_CMD)" diff --git a/manifest b/manifest index 079ede813e..38c1aef4f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\splatforms\swhere\stclsh\sis\sfound\sbut\stclConfig.sh\sis\snot,\sset\sHAVE_TCL\sto\s0.\sWe\scan't\sbuild\sthe\sTCL\scomponents\son\sthose.\sProblem\sreported\sin\s[forum:5106aee3a8|forum\spost\s5106aee3a8]. -D 2024-11-07T05:26:09.487 +C Change\sseveral\s'file\sexists'\schecks\sfor\stclsh\sto\sfile-isexec\sbecause\sthat\schecks\sfor\s.exe\sextensions\son\sWindows. +D 2024-11-07T06:00:14.892 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 7d4399cfcf2d05abe17ee62f7164b02a435a5c6f4f7a4581c126510a9ac83ef5 +F auto.def 61da56c0147852d5ec7a86eb96d968f1351cfada821ea54f090cec01e9cabb16 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6216bfcb74273b7893735e265d3f04d1362fa625cd60cebccb866ce7d6c50e01 -R ebdad56d0bb2add7c241926e4c52fbe3 +P 04d2576b2e516fc5f5ba719d6bb01d25fd3b06b1c2d26acbec32bcdd65e9a01c +R 37857bf341f005fe9a1012fdd57752f9 U stephan -Z 365df9597782f382d765b4f7c83a4a0c +Z cfe6f62fa97b31ccaf6d0632d55f4017 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 65e4c9a375..69d80bd6e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04d2576b2e516fc5f5ba719d6bb01d25fd3b06b1c2d26acbec32bcdd65e9a01c +052a1b4d7cb43b7f65028c41e9a7a17b533c834d8f620fbc7bc0adddb1fdb843 From 197fa124d7396c0595a277caeb7d0cf89858878a Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 06:02:05 +0000 Subject: [PATCH 300/522] Add mention of file-isexec in autosetup/README.md. FossilOrigin-Name: f469356749b62b3ce4161b40ed105d60867a366a389efa583fe9607a13426803 --- autosetup/README.md | 5 +++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index 8f0f5601e7..c67709e0c5 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -51,6 +51,11 @@ found in [proj.tcl][]. In (mostly) alphabetical order: +- **`file-isexec filename`**\ + Should be used in place of `[file executable]`, as it will also + check for `${filename}.exe` on Windows platforms. However, on such + platforms is also assumes that _any_ existing file is executable. + - **`get-env VAR ?default?`**\ Will fetch an "environment variable" from the first of either: (A) a KEY=VALUE passed to the configure diff --git a/manifest b/manifest index 38c1aef4f7..76ca282253 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sseveral\s'file\sexists'\schecks\sfor\stclsh\sto\sfile-isexec\sbecause\sthat\schecks\sfor\s.exe\sextensions\son\sWindows. -D 2024-11-07T06:00:14.892 +C Add\smention\sof\sfile-isexec\sin\sautosetup/README.md. +D 2024-11-07T06:02:05.347 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 78f434bc13029a7ddf4d62fb0c82216f1dceaee448239022a1ce49230925b4c9 +F autosetup/README.md c2f4356d1ce44b44d7420c236afa548bf7a584a8a89b1eaa765b575232927896 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 04d2576b2e516fc5f5ba719d6bb01d25fd3b06b1c2d26acbec32bcdd65e9a01c -R 37857bf341f005fe9a1012fdd57752f9 +P 052a1b4d7cb43b7f65028c41e9a7a17b533c834d8f620fbc7bc0adddb1fdb843 +R 44b9bde08584eb60e3c1ac7b538f4ce9 U stephan -Z cfe6f62fa97b31ccaf6d0632d55f4017 +Z 32ba8fe39d3740f9d9fe595729b68f87 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 69d80bd6e8..fe5637dca4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -052a1b4d7cb43b7f65028c41e9a7a17b533c834d8f620fbc7bc0adddb1fdb843 +f469356749b62b3ce4161b40ed105d60867a366a389efa583fe9607a13426803 From d9345f33126bd882515ddb8d102c4049aed9f73d Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 07:31:25 +0000 Subject: [PATCH 301/522] When --with-linenoise refers to the msteveb flavor and jimsh is the TCL used for code generation, enable linenoise in jimsh. Remove some dead auto.def code. FossilOrigin-Name: 0d558318172dddc8d5c5842625ddf09866ae09cac9cf28731be44db86b5e0fb1 --- auto.def | 31 ++++++++----------------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/auto.def b/auto.def index 46ea9f6107..3e768b65c1 100644 --- a/auto.def +++ b/auto.def @@ -666,12 +666,13 @@ sqlite-check-tcl # - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible # jimsh. The defaults may be pass on to configure as # CFLAGS_JIMSH=... +set useJimForCodeGen 0 proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}] set cgtcl [opt-val with-tclsh jimsh] set flagsToRestore {CC CFLAGS CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} - define-push $flagsToRestore { + define-push $flagsToRestore { # We have to swap CC to CC_FOR_BUILD for purposes of the various # [cc-...] tests below. Recall that --with-wasi-sdk may have # swapped out CC with one which is not appropriate for this block. @@ -691,10 +692,12 @@ proc sqlite-determine-codegen-tcl {} { if {$sysh && [cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE_REALPATH define BTCLSH "\$(JIMSH)" + set ::useJimForCodeGen 1 } elseif {$sysh && [cc-check-functions _fullpath]} { # _fullpath() is a Windows API define-append CFLAGS_JIMSH -DHAVE__FULLPATH define BTCLSH "\$(JIMSH)" + set ::useJimForCodeGen 1 } elseif {[file-isexec [get-define TCLSH_CMD]]} { set cgtcl [get-define TCLSH_CMD] define BTCLSH "\$(TCLSH_CMD)" @@ -845,6 +848,10 @@ proc sqlite-check-line-editing {} { define CFLAGS_READLINE "-I$dirLn $lnC" define HAVE_LINENOISE $lnVal sqlite-add-shell-opt -DHAVE_LINENOISE=$lnVal + if {$::useJimForCodeGen && 2 == $lnVal} { + define-append CFLAGS_JIMSH -DUSE_LINENOISE [get-define CFLAGS_READLINE] + user-notice "Adding linenoise support to jimsh." + } return "linenoise ($flavor)" } elseif {[opt-bool editline]} { # libedit mimics libreadline and on some systems does not have its @@ -997,7 +1004,6 @@ proc sqlite-check-line-editing {} { if {$failIfNotFound} { proj-fatal "Explicit --$editLibName failed to find a matching library." } - return "none" }; # sqlite-check-line-editing msg-result "Line-editing support for the sqlite3 shell: [sqlite-check-line-editing]" @@ -1187,27 +1193,6 @@ if {"" ne $oFF} { } unset oFF -######################################################################## -# Maybe extend JimTCL a bit. As of this writing (2024-09-27) it only -# needs (-DHAVE_REALPATH or -DHAVE__FULLPATH) and -DHAVE_DIRENT_H to -# be compatible with our code generators. It can, however, be slightly -# extended via easy-to-detect features, should we need them. -if {0 && "" ne [get-define CFLAGS_JIMSH]} { - foreach jimFunc {opendir fsync isascii} { - if {[cc-check-functions $jimFunc]} { - define-append CFLAGS_JIMSH -DHAVE_[string toupper $jimFunc] - } - } - #These are hard-coded into jimsh0.c, so we must not -D them: - #foreach jimDef {HAVE_UNISTD_H HAVE_DIRENT_H} { - # if {[is-defined $jimDef]} { - # define-append CFLAGS_JIMSH -D$jimDef - # } - #} - define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available -}; # JimTCL - - ######################################################################## # "Re-export" the autoconf-conventional --XYZdir flags into something # which is more easily overridable from a make invocation. See the docs diff --git a/manifest b/manifest index 76ca282253..9321db618c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smention\sof\sfile-isexec\sin\sautosetup/README.md. -D 2024-11-07T06:02:05.347 +C When\s--with-linenoise\srefers\sto\sthe\smsteveb\sflavor\sand\sjimsh\sis\sthe\sTCL\sused\sfor\scode\sgeneration,\senable\slinenoise\sin\sjimsh.\sRemove\ssome\sdead\sauto.def\scode. +D 2024-11-07T07:31:25.397 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 61da56c0147852d5ec7a86eb96d968f1351cfada821ea54f090cec01e9cabb16 +F auto.def e05db4c72b2a2797f3a53ae4bb26dbca6252dedf8c8f2990d0bff9adeef3fcc3 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 052a1b4d7cb43b7f65028c41e9a7a17b533c834d8f620fbc7bc0adddb1fdb843 -R 44b9bde08584eb60e3c1ac7b538f4ce9 +P f469356749b62b3ce4161b40ed105d60867a366a389efa583fe9607a13426803 +R f42449771a357ea3eeabd0c3a3bc0370 U stephan -Z 32ba8fe39d3740f9d9fe595729b68f87 +Z fc12fb834027eddc0e5138b6f2cef0fc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fe5637dca4..b6b163c254 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f469356749b62b3ce4161b40ed105d60867a366a389efa583fe9607a13426803 +0d558318172dddc8d5c5842625ddf09866ae09cac9cf28731be44db86b5e0fb1 From 00e863c48e943af2f8fc07de9e6d31b6f1d45c98 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 08:29:58 +0000 Subject: [PATCH 302/522] Document the purpose of a global auto.def var added in [0d558318172d]. FossilOrigin-Name: f5b6604716826b2057e969a8c0d099325b22eac42f1da65ec367671fc6625639 --- auto.def | 5 +++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index 3e768b65c1..4d530d7429 100644 --- a/auto.def +++ b/auto.def @@ -666,13 +666,14 @@ sqlite-check-tcl # - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible # jimsh. The defaults may be pass on to configure as # CFLAGS_JIMSH=... -set useJimForCodeGen 0 +set useJimForCodeGen 0 ; # Set to 1 when using jimsh for code generation. + # May affect later decisions. proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}] set cgtcl [opt-val with-tclsh jimsh] set flagsToRestore {CC CFLAGS CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} - define-push $flagsToRestore { + define-push $flagsToRestore { # We have to swap CC to CC_FOR_BUILD for purposes of the various # [cc-...] tests below. Recall that --with-wasi-sdk may have # swapped out CC with one which is not appropriate for this block. diff --git a/manifest b/manifest index 9321db618c..a555167b72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\s--with-linenoise\srefers\sto\sthe\smsteveb\sflavor\sand\sjimsh\sis\sthe\sTCL\sused\sfor\scode\sgeneration,\senable\slinenoise\sin\sjimsh.\sRemove\ssome\sdead\sauto.def\scode. -D 2024-11-07T07:31:25.397 +C Document\sthe\spurpose\sof\sa\sglobal\sauto.def\svar\sadded\sin\s[0d558318172d]. +D 2024-11-07T08:29:58.913 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def e05db4c72b2a2797f3a53ae4bb26dbca6252dedf8c8f2990d0bff9adeef3fcc3 +F auto.def 98bba5513da76ef172c6d9bc9225bb42da8a33e8d6c15a5992061fd8fa1e4a1b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f469356749b62b3ce4161b40ed105d60867a366a389efa583fe9607a13426803 -R f42449771a357ea3eeabd0c3a3bc0370 +P 0d558318172dddc8d5c5842625ddf09866ae09cac9cf28731be44db86b5e0fb1 +R 5d6ca70a882e670f62252acdee03d8e1 U stephan -Z fc12fb834027eddc0e5138b6f2cef0fc +Z 8d1397a1cc0f102a32067d207ce6cbe0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b6b163c254..9300dfb3d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d558318172dddc8d5c5842625ddf09866ae09cac9cf28731be44db86b5e0fb1 +f5b6604716826b2057e969a8c0d099325b22eac42f1da65ec367671fc6625639 From 4c3139d7eeda28cc7e566388f2a2098d9450aa30 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 08:57:38 +0000 Subject: [PATCH 303/522] Add some internal docs to auto.def explaining certain passages. FossilOrigin-Name: 4749967e1b85675580eda2e92f4463c022e3ff929390a8f5b59f614f3975e158 --- auto.def | 19 ++++++++++++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/auto.def b/auto.def index 4d530d7429..87a9670cae 100644 --- a/auto.def +++ b/auto.def @@ -635,8 +635,8 @@ proc sqlite-check-tcl {} { }; # find TCLLIBDIR if {[file-isexec $with_tclsh]} { + msg-result "Using tclsh: $with_tclsh" if {$cfg ne ""} { - msg-result "Using tclsh: $with_tclsh" define HAVE_TCL 1 } else { proj-warn "Found tclsh but no tclConfig.sh, so cannot build TCL components." @@ -672,7 +672,7 @@ proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}] set cgtcl [opt-val with-tclsh jimsh] - set flagsToRestore {CC CFLAGS CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} + set flagsToRestore {CC CFLAGS AS_CFLAGS CPPFLAGS AS_CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} define-push $flagsToRestore { # We have to swap CC to CC_FOR_BUILD for purposes of the various # [cc-...] tests below. Recall that --with-wasi-sdk may have @@ -680,6 +680,9 @@ proc sqlite-determine-codegen-tcl {} { # Per consulation with autosetup's creator, doing this properly # requires us to [define-push] the whole $flagsToRestore list # (plus a few others which are not relevant in this tree). + # + # These will get set to their previous values at the end of this + # block. foreach flag $flagsToRestore {define $flag ""} define CC [get-define CC_FOR_BUILD] if {"jimsh" ne $cgtcl} { @@ -690,12 +693,22 @@ proc sqlite-determine-codegen-tcl {} { # These headers are technically optional for JimTCL but necessary if # we want to use it for code generation: set sysh [cc-check-includes dirent.h sys/time.h] + # jimsh0.c hard-codes #define's for HAVE_DIRENT_H and + # HAVE_SYS_TIME_H on the platforms it supports, so we do not + # need to add -D... flags for those. We check for them here only + # so that we can avoid the situation that we later, at + # make-time, try to compile jimsh but it then fails due to + # missing headers (i.e. fail earlier rather than later). if {$sysh && [cc-check-functions realpath]} { define-append CFLAGS_JIMSH -DHAVE_REALPATH define BTCLSH "\$(JIMSH)" set ::useJimForCodeGen 1 } elseif {$sysh && [cc-check-functions _fullpath]} { - # _fullpath() is a Windows API + # _fullpath() is a Windows API. It's not entirely clear + # whether we need to add {-DHAVE_SYS_TIME_H -DHAVE_DIRENT_H} + # to CFLAGS_JIMSH in this case. On MinGW32 we definitely do + # not want to because it already hard-codes them. On _MSC_VER + # builds it does not. define-append CFLAGS_JIMSH -DHAVE__FULLPATH define BTCLSH "\$(JIMSH)" set ::useJimForCodeGen 1 diff --git a/manifest b/manifest index a555167b72..94016ad484 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Document\sthe\spurpose\sof\sa\sglobal\sauto.def\svar\sadded\sin\s[0d558318172d]. -D 2024-11-07T08:29:58.913 +C Add\ssome\sinternal\sdocs\sto\sauto.def\sexplaining\scertain\spassages. +D 2024-11-07T08:57:38.576 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 98bba5513da76ef172c6d9bc9225bb42da8a33e8d6c15a5992061fd8fa1e4a1b +F auto.def 8d10658f2d06b0a8ddd558dfff3c111fc2b01b81d88a1bd059544abcf6e3f453 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0d558318172dddc8d5c5842625ddf09866ae09cac9cf28731be44db86b5e0fb1 -R 5d6ca70a882e670f62252acdee03d8e1 +P f5b6604716826b2057e969a8c0d099325b22eac42f1da65ec367671fc6625639 +R e6f5780ae9a523afdaecc8222f6bc4aa U stephan -Z 8d1397a1cc0f102a32067d207ce6cbe0 +Z ffd0c5323b1c2405e83633da2cf2458a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9300dfb3d2..46b7fa9517 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5b6604716826b2057e969a8c0d099325b22eac42f1da65ec367671fc6625639 +4749967e1b85675580eda2e92f4463c022e3ff929390a8f5b59f614f3975e158 From b4afb2fb2fc594840f14b1e9bd9bdbfa237be54a Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 09:36:01 +0000 Subject: [PATCH 304/522] Extend the list of "truthy" config values to include "true". Related doc updates. FossilOrigin-Name: 4455718e485a31100ce3eb4ac5aeb7437c667d7994c6d2abfb38ad8bd1976d6e --- autosetup/README.md | 19 ++++++++++++------- autosetup/proj.tcl | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index c67709e0c5..016cf658de 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -68,9 +68,14 @@ In (mostly) alphabetical order: trimmed contents. This can be used, e.g., to set a developer's local preferences for the default `CFLAGS`. -- **`proj-define-if-opt-truthy flag defineName checkingMsg ?yesVal=1? ?noVal=0?`**\ - Defines `defineName` to either `yesVal` or `noVal`, depending on - whether `--flag` is truthy or not. +- **`proj-define-if-opt-truthy flag defineName ?checkingMsg? ?yesVal=1? ?noVal=0?`**\ + `[define $defineName]` to either `$yesVal` or `$noVal`, depending on + whether `--$flag` is truthy or not. `$checkingMsg` is a + human-readable description of the check being made, e.g. "enable foo + bar baz?" If no `checkingMsg` is provided, the operation is silent.\ + Potential TODO: change the final two args to `-yes` and `-no` + flags. They're rarely needed, though: search [auto.def][] for + `TSTRNNR_OPTS` for an example of where they are used. - **`proj-if-opt-truthy flag thenScript ?elseScript?`**\ Evals `thenScript` if the given `--flag` is truthy, else it @@ -84,18 +89,18 @@ In (mostly) alphabetical order: - **`proj-opt-truthy flag`**\ Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on, - enabled, yes). + enabled, yes, true). - **`proj-opt-was-provided FLAG`**\ Returns 1 if `--FLAG` was explicitly provided to configure, else 0. This distinction can be used to determine, e.g., whether `--with-readline` was provided or whether we're searching for readline by default. In the former case, failure to find it should - be treated as fatal. + be treated as fatal, where in the latter case it's not. - **`proj-val-truthy value`**\ - Returns 1 if `$value` is "truthy," i.e. one of (1, on, enabled, - yes). + Returns 1 if `$value` is "truthy," See `proj-opt-truthy` for the definition + of "truthy." - **`sqlite-add-feature-flag ?-shell? FLAG...`**\ Adds the given feature flag to the CFLAGS which are specific to building diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 98ee998ebc..a1138a94ed 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -330,9 +330,9 @@ proc proj-opt-set {flag {val 1}} { # @proj-val-truthy val # # Returns 1 if $val appears to be a truthy value, else returns -# 0. Truthy values are any of {1 on enabled yes} +# 0. Truthy values are any of {1 on true yes enabled} proc proj-val-truthy {val} { - expr {$val in {1 on enabled yes}} + expr {$val in {1 on true yes enabled}} } ######################################################################## diff --git a/manifest b/manifest index 94016ad484..1dbba36489 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssome\sinternal\sdocs\sto\sauto.def\sexplaining\scertain\spassages. -D 2024-11-07T08:57:38.576 +C Extend\sthe\slist\sof\s"truthy"\sconfig\svalues\sto\sinclude\s"true".\sRelated\sdoc\supdates. +D 2024-11-07T09:36:01.761 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md c2f4356d1ce44b44d7420c236afa548bf7a584a8a89b1eaa765b575232927896 +F autosetup/README.md 4c5ad38e4ff0a222efad63a81d2977dce46f3dd5393be48a8163f318a34fab25 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -50,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 2ee715f7fa7386879af0c651a22f9d451f980b8f2fed37d94f28b5b03cf5d703 +F autosetup/proj.tcl d4795a130eedb21d7f2acea0e28cf647e477b6e555817ac4497d62bbaf7b6c23 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f5b6604716826b2057e969a8c0d099325b22eac42f1da65ec367671fc6625639 -R e6f5780ae9a523afdaecc8222f6bc4aa +P 4749967e1b85675580eda2e92f4463c022e3ff929390a8f5b59f614f3975e158 +R 254ea4169e8fc19f66e402a223747df9 U stephan -Z ffd0c5323b1c2405e83633da2cf2458a +Z 47a15cd94d3d423b454caccbe768acf6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 46b7fa9517..8eb5d1a249 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4749967e1b85675580eda2e92f4463c022e3ff929390a8f5b59f614f3975e158 +4455718e485a31100ce3eb4ac5aeb7437c667d7994c6d2abfb38ad8bd1976d6e From 88e6a942ad0cc9b9a5f6b78c8e42fd58064403d6 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 10:07:20 +0000 Subject: [PATCH 305/522] Autosetup doc touchups. FossilOrigin-Name: 574515290058ddfaf39a4221fa0f7a99222c4b040dd455348550816b18492c20 --- autosetup/README.md | 9 +++++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index 016cf658de..74e31be583 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -46,8 +46,9 @@ Autosetup API Tips This section briefly covers only APIs which are frequently useful in day-to-day maintenance and might not be immediately recognized as such -obvious from a casual perusal of `auto.def`. Their complete docs can be -found in [proj.tcl][]. +obvious from a casual perusal of [auto.def][]. The complete docs of +those with `proj-` prefix can be found in [proj.tcl][]. The others are +scattered around [the TCL files in ./autosetup](/dir/autosetup). In (mostly) alphabetical order: @@ -58,8 +59,8 @@ In (mostly) alphabetical order: - **`get-env VAR ?default?`**\ Will fetch an "environment variable" - from the first of either: (A) a KEY=VALUE passed to the configure - script or (B) the system's environment variables. Not to be confused + from the first of either: (1) a KEY=VALUE passed to the configure + script or (2) the system's environment variables. Not to be confused with `getenv`, which only does the latter and is rarely, if ever, useful in this tree. - **`proj-get-env VAR ?default?`**\ diff --git a/manifest b/manifest index 1dbba36489..b244713acb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extend\sthe\slist\sof\s"truthy"\sconfig\svalues\sto\sinclude\s"true".\sRelated\sdoc\supdates. -D 2024-11-07T09:36:01.761 +C Autosetup\sdoc\stouchups. +D 2024-11-07T10:07:20.454 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 4c5ad38e4ff0a222efad63a81d2977dce46f3dd5393be48a8163f318a34fab25 +F autosetup/README.md 6357282be27622b8ce37b46717a5088dc2148a8f3e2ef48bbe465a333f0c70ac F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4749967e1b85675580eda2e92f4463c022e3ff929390a8f5b59f614f3975e158 -R 254ea4169e8fc19f66e402a223747df9 +P 4455718e485a31100ce3eb4ac5aeb7437c667d7994c6d2abfb38ad8bd1976d6e +R d0d397e19e3c3c321a06f160c598ae0c U stephan -Z 47a15cd94d3d423b454caccbe768acf6 +Z 58542c19f6b9c96b806ce35d9c28577d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8eb5d1a249..1493670673 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4455718e485a31100ce3eb4ac5aeb7437c667d7994c6d2abfb38ad8bd1976d6e +574515290058ddfaf39a4221fa0f7a99222c4b040dd455348550816b18492c20 From c00d89d599c3422a23873a9a1ddae7dafd96f456 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Nov 2024 12:03:53 +0000 Subject: [PATCH 306/522] Further improvements to the ".mode json" output in the CLI. FossilOrigin-Name: 6201b5707f8c895028f9c08cb4f83d33a16a91bf04ed3830ac51aa763d6b7205 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b244713acb..d5cc26c78e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Autosetup\sdoc\stouchups. -D 2024-11-07T10:07:20.454 +C Further\simprovements\sto\sthe\s".mode\sjson"\soutput\sin\sthe\sCLI. +D 2024-11-07T12:03:53.321 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -779,7 +779,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in bb8ca98e903ea1dc60cee7e0a82017879662a2e4ce1f43889da87e8d4d774a5d +F src/shell.c.in bb97e0afcc4a73b73f38cc868330854a2df109095a7a10182ddfdd261fbec312 F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4455718e485a31100ce3eb4ac5aeb7437c667d7994c6d2abfb38ad8bd1976d6e -R d0d397e19e3c3c321a06f160c598ae0c -U stephan -Z 58542c19f6b9c96b806ce35d9c28577d +P 574515290058ddfaf39a4221fa0f7a99222c4b040dd455348550816b18492c20 +R d6d415bcc0f47f8fdfd469ff669d9a21 +U drh +Z 19d583f7d9e9d1ca3ecd4ff7c1dcf90f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1493670673..5d85b4470e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -574515290058ddfaf39a4221fa0f7a99222c4b040dd455348550816b18492c20 +6201b5707f8c895028f9c08cb4f83d33a16a91bf04ed3830ac51aa763d6b7205 diff --git a/src/shell.c.in b/src/shell.c.in index 180768b7fb..874f448f67 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2109,7 +2109,7 @@ static void output_c_string(FILE *out, const char *z){ ** Output the given string as quoted according to JSON quoting rules. */ static void output_json_string(FILE *out, const char *z, i64 n){ - char c; + unsigned char c; static const char *zq = "\""; static long ctrlMask = ~0L; static const char *zDQBS = "\"\\"; @@ -2129,7 +2129,7 @@ static void output_json_string(FILE *out, const char *z, i64 n){ z = pcEnd; } if( z >= pcLimit ) break; - c = *(z++); + c = (unsigned char)*(z++); switch( c ){ case '"': case '\\': cbsSay = (char)c; @@ -2144,7 +2144,7 @@ static void output_json_string(FILE *out, const char *z, i64 n){ if( cbsSay ){ ace[1] = cbsSay; sqlite3_fputs(ace, out); - }else if( c<=0x1f || c==0x7f ){ + }else if( c<=0x1f || c>=0x7f ){ sqlite3_fprintf(out, "\\u%04x", c); }else{ ace[1] = (char)c; From c7882b975ed90f55afd40fb56c895aed10b3790c Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 15:04:15 +0000 Subject: [PATCH 307/522] tcl configuration: --with-tcl=prefix is equivalent to passing the --prefix dir to it. If --with-tcl or --enable-tcl are explicitly passed in and tclConfig.sh is not found, fail fatally. When TCL is either explicitly disabled or default search for it fails non-fatally, be more explicit about which components are not available. FossilOrigin-Name: c5389d39a90047683e80ae9081d5d10aaa95da00dfc8a133b4a1a6949a11620d --- auto.def | 149 ++++++++++++++++++++++---------------------- autosetup/README.md | 23 +++++-- autosetup/proj.tcl | 38 +++++++---- main.mk | 5 +- manifest | 20 +++--- manifest.uuid | 2 +- 6 files changed, 134 insertions(+), 103 deletions(-) diff --git a/auto.def b/auto.def index 87a9670cae..01badb8b53 100644 --- a/auto.def +++ b/auto.def @@ -150,18 +150,17 @@ set flags { # --with-tcl=DIR may be either a dir containing tclConfig.sh or a # dir one level up from that from which we can derive a dir # containing tclConfig.sh. - with-tcl:DIR => {Root of path containing tclConfig.sh} + with-tcl: => {Root of path containing tclConfig.sh} # If --with-tclsh=X given, it is used for (A) trying to find # tclConfig.sh and (B) all TCL-based code generation. Warning: if # its containing dir has multiple tclsh versions, it may select the # wrong tclConfig.sh! with-tclsh:PATH => {Full pathname of tclsh to use} - # --disable-tcl only disables building of the SQLite TCL extension, - # not the requirement for TCL. This tree requires TCL for code - # generation but can use the in-tree copy of autosetup/jimsh0.c for - # that. The SQLite TCL extension and, by extension, the test code - # require a canonical tclsh. - tcl=1 => {Disable components which require TCL-dev} + # --disable-tcl disables building of components which require TCL, + # including tests. This tree requires TCL for code generation but + # can use the in-tree copy of autosetup/jimsh0.c for that. The + # SQLite TCL extension and the test code require a canonical tclsh. + tcl=1 => {Disable components which require TCL} # # readline=1 => {Disable readline support} @@ -466,22 +465,26 @@ proj-if-opt-truthy with-debug { # # - TCLLIBDIR is the dir to which libtclsqlite3 gets installed. # -# - TCLLIB_RPATH = the -rpath flag specific to libtclsqlite3, which -# will usually differ from the rpath used by the rest of the lib. -# # - BTCLSH = the path to the tcl interpreter used for in-tree code # generation. It may be jimtcl or the canonical tclsh but may not # be empty - this tree requires TCL to generated numerous # components. # +# If --tcl or --with-tcl are provided but no TCL is found, this +# function fails fatally. If they are not explicitly provided then +# failure to find TCL is not fatal but a loud warning will be emitted. +# proc sqlite-check-tcl {} { define TCLSH_CMD false ; # Significant is that it exits with non-0 define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search define TCLLIBDIR "" ; # Installation dir for TCL extension lib - define TCLLIB_RPATH "" ; # rpath for TCL extension lib define TCL_CONFIG_SH ""; # full path to tclConfig.sh if {![opt-bool tcl]} { - msg-result "TCL disabled via --disable-tcl. Will not be able to run tests." + proj-indented-notice { + NOTE: TCL is disabled via --disable-tcl. This means that none + of the TCL-based components, including tests and sqlite3_analyzer, + will be built. + } return } # TODO: document the steps this is taking. @@ -491,6 +494,9 @@ proc sqlite-check-tcl {} { set use_tcl 1 set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] + if {"prefix" eq $with_tcl} { + set with_tcl [get-define prefix] + } msg-debug "sqlite-check-tcl: use_tcl ${use_tcl}" msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" msg-debug "sqlite-check-tcl: with_tcl=$with_tcl" @@ -501,9 +507,10 @@ proc sqlite-check-tcl {} { msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" } + set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases if {"" ne $with_tclsh} { - # --with-tclsh was provided. Validate it and use it to trump any - # value passed via --with-tcl=DIR. + # --with-tclsh was provided or found above. Validate it and use it + # to trump any value passed via --with-tcl=DIR. if {![file isfile $with_tclsh]} { proj-fatal "TCL shell $with_tclsh is not a file" } elseif {![file-isexec $with_tclsh]} { @@ -512,23 +519,23 @@ proc sqlite-check-tcl {} { define TCLSH_CMD $with_tclsh #msg-result "Using tclsh: $with_tclsh" } - if {[catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} { + if {$doConfigLookup && + [catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} { set with_tcl $result } if {"" ne $with_tcl && [file isdir $with_tcl]} { msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl" } else { - proj-warn "$with_tclsh is unable to recommand a tclConfig.sh" + proj-warn "$with_tclsh is unable to recommend a tclConfig.sh" set use_tcl 0 } } - set cfg "" set tclSubdirs {tcl9.0 tcl8.6 lib} - while {1} { - if {$use_tcl} { - if {"" ne $with_tcl} { - # Ensure that we can find tclConfig.sh under ${with_tcl}/... + while {$use_tcl} { + if {"" ne $with_tcl} { + # Ensure that we can find tclConfig.sh under ${with_tcl}/... + if {$doConfigLookup} { if {[file readable "${with_tcl}/tclConfig.sh"]} { set cfg "${with_tcl}/tclConfig.sh" } else { @@ -539,39 +546,31 @@ proc sqlite-check-tcl {} { } } } - if {"" eq $cfg} { - proj-fatal "No tclConfig.sh found under ${with_tcl}" - } + } + if {"" eq $cfg} { + proj-fatal "No tclConfig.sh found under ${with_tcl}" + } + } else { + # If we have not yet found a tclConfig.sh file, look in + # $libdir which is set automatically by autosetup or by the + # --prefix command-line option. See + # https://sqlite.org/forum/forumpost/e04e693439a22457 + set libdir [get-define libdir] + if {[file readable "${libdir}/tclConfig.sh"]} { + set cfg "${libdir}/tclConfig.sh" } else { - # If we have not yet found a tclConfig.sh file, look in - # $libdir which is set automatically by autosetup or by the - # --prefix command-line option. See - # https://sqlite.org/forum/forumpost/e04e693439a22457 - set libdir [get-define libdir] - if {[file readable "${libdir}/tclConfig.sh"]} { - set cfg "${libdir}/tclConfig.sh" - } else { - foreach i $tclSubdirs { - if {[file readable "${libdir}/$i/tclConfig.sh"]} { - set cfg "${libdir}/$i/tclConfig.sh" - break - } - } - } - if {![file readable $cfg]} { - proj-indented-notice { - WARNING: Cannot find a usable tclConfig.sh file. Use - --with-tcl=DIR to specify a directory where tclConfig.sh - can be found. SQLite does not use TCL internally, but TCL - is required for testing. + foreach i $tclSubdirs { + if {[file readable "${libdir}/$i/tclConfig.sh"]} { + set cfg "${libdir}/$i/tclConfig.sh" + break } - break } } - msg-result "Using tclConfig.sh: $cfg" - } else { - proj-warn "Unable to run tests because no tclConfig.sh file could be located" + if {![file readable $cfg]} { + break + } } + msg-result "Using tclConfig.sh: $cfg" break } define TCL_CONFIG_SH $cfg @@ -581,6 +580,8 @@ proc sqlite-check-tcl {} { eval [exec "${srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] if {"" eq $with_tclsh && $cfg ne ""} { + # We have tclConfig.sh but no tclsh. Attempt to locate a tclsh + # based on info from tclConfig.sh. proj-assert {expr {"" ne [get-define TCL_EXEC_PREFIX]}} set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] if {![file-isexec $with_tclsh]} { @@ -594,20 +595,19 @@ proc sqlite-check-tcl {} { } define TCLSH_CMD $with_tclsh if {$use_tcl} { - # Set up the TCLLIBDIR and TCLLIB_RPATH + # Set up the TCLLIBDIR # # 2024-10-28: calculation of TCLLIBDIR is now done via the shell - # in the main.mk (search it for T.tcllibdir) so that + # in main.mk (search it for T.tcl.env.sh) so that # static/hand-written makefiles which import main.mk do not have # to define that before importing main.mk. Even so, we export - # TCLLIBDIR from here for the benefit of those who want to provide - # it at configure-time and have it "stick", without having to - # provide it on each make invocation or set it in their - # environment. + # TCLLIBDIR from here, which will cause the makefile to use this + # one rather than to re-calculate it at make-time. set tcllibdir [get-env TCLLIBDIR ""] if {"" eq $tcllibdir} { # Attempt to extract TCLLIBDIR from TCL's $auto_path - if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { + if {"" ne $with_tclsh && + [catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { foreach i $result { if {[file isdir $i]} { set tcllibdir $i/sqlite3 @@ -615,23 +615,13 @@ proc sqlite-check-tcl {} { } } } else { - proj-warn "Cannot determine TCLLIBDIR" + proj-warn "Cannot determine TCLLIBDIR." + # The makefile will fail fatally in this case if a target is + # invoked which requires TCLLIBDIR. } } - set tclrpath "" - if {"" ne $tcllibdir} { - set rp [get-define SH_LINKRPATH] - set tclrpath [string map [list "%s" $tcllibdir] $rp] - # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the - # rpath but (A) it includes an unexpand var ref to - # ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B) - # that flag is inherently compiler-dependent so it's not as - # portable as tclConfig.sh assumes. We'll instead use the rpath - # flag which autosetup determines for the current compiler. - } + #if {"" ne $tcllibdir} { msg-result "TCLLIBDIR = ${tcllibdir}"; } define TCLLIBDIR $tcllibdir - define TCLLIB_RPATH $tclrpath - #msg-debug "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" }; # find TCLLIBDIR if {[file-isexec $with_tclsh]} { @@ -639,12 +629,23 @@ proc sqlite-check-tcl {} { if {$cfg ne ""} { define HAVE_TCL 1 } else { - proj-warn "Found tclsh but no tclConfig.sh, so cannot build TCL components." + proj-warn "Found tclsh but no tclConfig.sh." } - } else { - proj-warn "Cannot find a usable tclsh, so cannot build TCL components." } show-notices + if {![get-define HAVE_TCL] && + ([proj-opt-was-provided tcl] || [proj-opt-was-provided with-tcl])} { + proj-fatal "TCL support was requested but no tclConfig.sh could be found." + } + if {"" eq $cfg} { + proj-assert {expr {0 == [get-define HAVE_TCL]}} + proj-indented-notice { + WARNING: Cannot find a usable tclConfig.sh file. Use + --with-tcl=DIR to specify a directory where tclConfig.sh can be + found. SQLite does not use TCL internally, but some optional + components require TCL, including tests and sqlite3_analyzer. + } + } }; # sqlite-check-tcl sqlite-check-tcl @@ -977,7 +978,7 @@ proc sqlite-check-line-editing {} { # Alert the user that, despite outward appearances, we won't be # linking to the GPL'd libreadline. Presumably that distinction is # significant for those using --editline. - proj-indented-notice { + proj-indented-notice -notice { NOTE: the local libedit but uses so we will compile with -DHAVE_READLINE=1 but will link with libedit. diff --git a/autosetup/README.md b/autosetup/README.md index 74e31be583..696569a423 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -78,15 +78,19 @@ In (mostly) alphabetical order: flags. They're rarely needed, though: search [auto.def][] for `TSTRNNR_OPTS` for an example of where they are used. +- **`proj-fatal msg`**\ + Emits `$msg` to stderr and exits with non-zero. + - **`proj-if-opt-truthy flag thenScript ?elseScript?`**\ Evals `thenScript` if the given `--flag` is truthy, else it evals the optional `elseScript`. -- **`proj-indented-notice ?-error? msg`**\ +- **`proj-indented-notice ?-error? ?-notice? msg`**\ Breaks its `msg` argument into lines, trims them, and emits them - with consistent indentation. If the `-error` flag is used, it then - exits with a non-0 result code. This will stick out starkly from - normal output and is intended to be used only for important notices. + with consistent indentation. Exactly how it emits depends on the + flags passed to it (or not), as covered in its docs. This will stick + out starkly from normal output and is intended to be used only for + important notices. - **`proj-opt-truthy flag`**\ Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on, @@ -103,6 +107,10 @@ In (mostly) alphabetical order: Returns 1 if `$value` is "truthy," See `proj-opt-truthy` for the definition of "truthy." +- **`proj-warn msg`**\ + Emits `$msg` to stderr. Closely-related is autosetup's `user-notice` + (described below). + - **`sqlite-add-feature-flag ?-shell? FLAG...`**\ Adds the given feature flag to the CFLAGS which are specific to building the library. It's intended to be passed one or more `-DSQLITE_ENABLE_...`, @@ -113,6 +121,13 @@ In (mostly) alphabetical order: - **`sqlite-add-shell-opt FLAG...`**\ The shell-specific counterpart of `sqlite-add-feature-flag`. +- **`user-notice msg`**\ + Queues `$msg` to be sent to stderr, but not until either + `show-notices` is called or the next time autosetup would output + something. This can be used to generate warnings between a "checking + for..." message and its resulting "yes/no/whatever" message in such + a way as to not spoil layout of such messages. + Ensuring TCL Compatibility ======================================================================== diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index a1138a94ed..91a7ca77b1 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -61,7 +61,7 @@ set proj_(isatty) [isatty? stdout] # # Emits a warning message to stderr. proc proj-warn {msg} { - puts stderr [proj-bold "WARNING: $msg"] + puts stderr "WARNING: $msg" } ######################################################################## # @proj-error msg @@ -69,7 +69,7 @@ proc proj-warn {msg} { # Emits an error message to stderr and exits with non-0. proc proj-fatal {msg} { show-notices - puts stderr [proj-bold "ERROR: $msg"] + puts stderr "ERROR: $msg" exit 1 } @@ -101,23 +101,37 @@ proc proj-bold {str} { } ######################################################################## -# @proj-indented-notice ?-error? msg +# @proj-indented-notice ?-error? ?-notice? msg # -# Takes a multi-line message and emits it with consistent indentation -# using [user-notice] (which means its rendering will (A) go to stderr -# and (B) be delayed until the next time autosetup goes to output a -# message). +# Takes a multi-line message and emits it with consistent indentation. # -# If its first argument is -error then it renders the message -# immediately and then exits. +# If the -notice flag it used then it emits using [user-notice], which +# means its rendering will (A) go to stderr and (B) be delayed until +# the next time autosetup goes to output a message. If -notice +# is not used, it will send the message to stdout without delay. +# +# If the -error flag is provided then it renders the message +# immediately to stderr and then exits. proc proj-indented-notice {args} { set fErr "" - if {"-error" eq [lindex $args 0]} { - set args [lassign $args fErr] + set outFunc "puts" + while {[llength $args] > 1} { + switch -exact -- [lindex $args 0] { + -error { + set args [lassign $args fErr] + } + -notice { + set args [lassign $args -] + set outFunc "user-notice" + } + default { + break + } + } } set lines [split [join $args] \n] foreach line $lines { - user-notice " [string trimleft $line]" + $outFunc " [string trimleft $line]" } if {"" ne $fErr} { show-notices diff --git a/main.mk b/main.mk index 2dc7f9ce78..faf8e34c3b 100644 --- a/main.mk +++ b/main.mk @@ -1465,6 +1465,7 @@ install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl $(INSTALL) $(libtclsqlite3.SO) "$(DESTDIR)$$TCLLIBDIR"; \ $(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$$TCLLIBDIR" install-tcl-0 install-tcl-: + @echo "TCL support disabled, so not installing $(libtclsqlite3.SO)" install-tcl: install-tcl-$(HAVE_TCL) install: install-tcl @@ -1699,7 +1700,7 @@ sqltclsh$(T.exe): $(T.tcl.env.sh) sqltclsh.c $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. -xbin: sqltclsh$(T.exe) +xbin: sqltclsh$(T.exe) sqlite3_analyzer$(T.exe) sqlite3_expert$(T.exe): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c @@ -1910,7 +1911,7 @@ install-rsync: sqlite3_rsync$(T.exe) $(install-dir.bin) #install: install-rsync install-man1: $(install-dir.man1) - $(INSTALL.noexec) $(TOP)/sqlite3.1 "$(install-dir.man1)" + $(INSTALL.noexec) "$(TOP)/sqlite3.1" "$(install-dir.man1)" install: install-man1 # diff --git a/manifest b/manifest index d5cc26c78e..53d31b6908 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprovements\sto\sthe\s".mode\sjson"\soutput\sin\sthe\sCLI. -D 2024-11-07T12:03:53.321 +C tcl\sconfiguration:\s--with-tcl=prefix\sis\sequivalent\sto\spassing\sthe\s--prefix\sdir\sto\sit.\sIf\s--with-tcl\sor\s--enable-tcl\sare\sexplicitly\spassed\sin\sand\stclConfig.sh\sis\snot\sfound,\sfail\sfatally.\sWhen\sTCL\sis\seither\sexplicitly\sdisabled\sor\sdefault\ssearch\sfor\sit\sfails\snon-fatally,\sbe\smore\sexplicit\sabout\swhich\scomponents\sare\snot\savailable. +D 2024-11-07T15:04:15.370 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 8d10658f2d06b0a8ddd558dfff3c111fc2b01b81d88a1bd059544abcf6e3f453 +F auto.def 994745e992211047879521fa05742b9eaedafe8f2600a7b8d784c32e6afa41fa F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 6357282be27622b8ce37b46717a5088dc2148a8f3e2ef48bbe465a333f0c70ac +F autosetup/README.md 0fd0e5f83122a5ba12896540f2804921c90165dd475323adf57369b5baad91be F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -50,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl d4795a130eedb21d7f2acea0e28cf647e477b6e555817ac4497d62bbaf7b6c23 +F autosetup/proj.tcl f125ba46b08b2ae0aa4afc4c3547fdd6c9487a609e0147217e62b2e4ec5d5e0e F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 949721d1f7400fd9f2c9a8818d66eed7b4c5937c9fd2635f8364755858ddcc78 +F main.mk beaeb83b8239bf4f9747e1dbd5316536feb9a961c689c9917cf5afb4859feafb F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 574515290058ddfaf39a4221fa0f7a99222c4b040dd455348550816b18492c20 -R d6d415bcc0f47f8fdfd469ff669d9a21 -U drh -Z 19d583f7d9e9d1ca3ecd4ff7c1dcf90f +P 6201b5707f8c895028f9c08cb4f83d33a16a91bf04ed3830ac51aa763d6b7205 +R 159b8b906d14c083582767b8ea344e43 +U stephan +Z a561785360eeb191a2906420651521c2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5d85b4470e..80e093e1e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6201b5707f8c895028f9c08cb4f83d33a16a91bf04ed3830ac51aa763d6b7205 +c5389d39a90047683e80ae9081d5d10aaa95da00dfc8a133b4a1a6949a11620d From 6e6820148a35d001ea0be7a3db9e5a34236de29b Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 15:23:54 +0000 Subject: [PATCH 308/522] Doc touchups in the line-editing feature check code. FossilOrigin-Name: bb5656bdc905947df205432e108ca6724393061a27028e23bf35b4bf48505d4f --- auto.def | 28 ++++++++++++++-------------- autosetup/README.md | 2 +- autosetup/proj.tcl | 1 + manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/auto.def b/auto.def index 01badb8b53..8e17e63405 100644 --- a/auto.def +++ b/auto.def @@ -791,7 +791,7 @@ if {1} { # - HAVE_LINENOISE to 0, 1, or 2 # - HAVE_EDITLINE to 0 or 1 # -# Only one of ^^^ those will be set to 1. +# Only one of ^^^ those will be set to non-0. # # - LDFLAGS_READLINE = linker flags or empty string # @@ -807,7 +807,8 @@ if {1} { # # Order of checks: # -# 1) --with-linenoise trumps all others +# 1) --with-linenoise trumps all others and skips all of the +# complexities involved with the remaining options. # # 2) --editline trumps --readline # @@ -815,7 +816,7 @@ if {1} { # # 4) Default to automatic search for optional readline # -# 5) Try to find readline resp. editline. If it's not found AND the +# 5) Try to find readline or editline. If it's not found AND the # corresponding --FEATURE flag was explicitly given, fail fatally, # else fail silently. proc sqlite-check-line-editing {} { @@ -825,7 +826,9 @@ proc sqlite-check-line-editing {} { define HAVE_EDITLINE 0 define LDFLAGS_READLINE "" define CFLAGS_READLINE "" - set failIfNotFound 0 ; # Set to 1 for explicit --FEATURE requests + set failIfNotFound 0 ; # Gets set to 1 for explicit --FEATURE requests + # so that we know whether to fail fatally or not + # if the library is not found. set libsForReadline {readline edit} ; # -l names to check for readline(). # The libedit check changes this. set editLibName "readline" ; # "readline" or "editline" @@ -874,8 +877,8 @@ proc sqlite-check-line-editing {} { # # shell.c historically expects HAVE_EDITLINE to be set for # libedit, but it then expects to see , which - # some system's don't actually have, despite having libedit. If - # we end up finding below, we will use + # some system's don't actually have despite having libedit. If we + # end up finding below, we will use # -DHAVE_EDITLINE=1, else we will use -DHAVE_READLINE=1. In either # case, we will link against libedit. set failIfNotFound 1 @@ -899,11 +902,9 @@ proc sqlite-check-line-editing {} { } else { set v [file dirname $v] if {[string match */readline $v]} { - # Special case: if the path includes .../readline/readline.h, set - # the -I to one dir up from that because our sources include - # or . Reminder: if - # auto.def is being run by jimsh0 then [file normalize] will not - # work! + # Special case: if the path includes .../readline/readline.h, + # set the -I to one dir up from that because our sources + # #include or . set v [file dirname $v] } proj-opt-set with-readline-cflags "-I$v" @@ -978,7 +979,7 @@ proc sqlite-check-line-editing {} { # Alert the user that, despite outward appearances, we won't be # linking to the GPL'd libreadline. Presumably that distinction is # significant for those using --editline. - proj-indented-notice -notice { + proj-indented-notice { NOTE: the local libedit but uses so we will compile with -DHAVE_READLINE=1 but will link with libedit. @@ -1009,8 +1010,7 @@ proc sqlite-check-line-editing {} { return 0; } }]} { - user-notice "WARNING: readline-style completion disabled due to rl_completion_matches() signature mismatch" - show-notices + proj-warn "readline-style completion disabled due to rl_completion_matches() signature mismatch" sqlite-add-shell-opt -DSQLITE_OMIT_READLINE_COMPLETION } return $editLibName diff --git a/autosetup/README.md b/autosetup/README.md index 696569a423..f80a46aad0 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -126,7 +126,7 @@ In (mostly) alphabetical order: `show-notices` is called or the next time autosetup would output something. This can be used to generate warnings between a "checking for..." message and its resulting "yes/no/whatever" message in such - a way as to not spoil layout of such messages. + a way as to not spoil the layout of such messages. Ensuring TCL Compatibility diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 91a7ca77b1..b2c527e622 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -61,6 +61,7 @@ set proj_(isatty) [isatty? stdout] # # Emits a warning message to stderr. proc proj-warn {msg} { + show-notices puts stderr "WARNING: $msg" } ######################################################################## diff --git a/manifest b/manifest index 53d31b6908..902eb0341a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C tcl\sconfiguration:\s--with-tcl=prefix\sis\sequivalent\sto\spassing\sthe\s--prefix\sdir\sto\sit.\sIf\s--with-tcl\sor\s--enable-tcl\sare\sexplicitly\spassed\sin\sand\stclConfig.sh\sis\snot\sfound,\sfail\sfatally.\sWhen\sTCL\sis\seither\sexplicitly\sdisabled\sor\sdefault\ssearch\sfor\sit\sfails\snon-fatally,\sbe\smore\sexplicit\sabout\swhich\scomponents\sare\snot\savailable. -D 2024-11-07T15:04:15.370 +C Doc\stouchups\sin\sthe\sline-editing\sfeature\scheck\scode. +D 2024-11-07T15:23:54.771 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 994745e992211047879521fa05742b9eaedafe8f2600a7b8d784c32e6afa41fa +F auto.def 8adbbcff2808b47c6ea7e55c8303e89e9364906a73dd2ffc55f8171e74366393 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 0fd0e5f83122a5ba12896540f2804921c90165dd475323adf57369b5baad91be +F autosetup/README.md 8f2f1cc05913a9d1267f32eb8325f77b3ac6b45cd7d8f6149667efcd90ddbcaa F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -50,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl f125ba46b08b2ae0aa4afc4c3547fdd6c9487a609e0147217e62b2e4ec5d5e0e +F autosetup/proj.tcl 5afbe391eae951567752ba8f0b4ecc05acd5a261e4417161623adda448154ad5 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6201b5707f8c895028f9c08cb4f83d33a16a91bf04ed3830ac51aa763d6b7205 -R 159b8b906d14c083582767b8ea344e43 +P c5389d39a90047683e80ae9081d5d10aaa95da00dfc8a133b4a1a6949a11620d +R 54316963f5f6d26ad35729ed06088c2e U stephan -Z a561785360eeb191a2906420651521c2 +Z e2fe9fb1c41d92d4fc9e1c534eca8ef3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 80e093e1e3..a80268072a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5389d39a90047683e80ae9081d5d10aaa95da00dfc8a133b4a1a6949a11620d +bb5656bdc905947df205432e108ca6724393061a27028e23bf35b4bf48505d4f From ee9950d09bdcd292f3c97d3be6432d8b6617823c Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 7 Nov 2024 16:59:15 +0000 Subject: [PATCH 309/522] Extend the set of --flags which get cleared/unset when using --with-wasi-sdk. FossilOrigin-Name: 2a2419ef742c9f37c32be04d417337c1fa22503305d2df154fa38b2b69eae943 --- auto.def | 76 ++++++++++++++++++++++++++++----------------- autosetup/README.md | 11 ++++--- autosetup/proj.tcl | 3 +- manifest | 16 +++++----- manifest.uuid | 2 +- 5 files changed, 65 insertions(+), 43 deletions(-) diff --git a/auto.def b/auto.def index 8e17e63405..bf3a99c513 100644 --- a/auto.def +++ b/auto.def @@ -73,7 +73,7 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # --disable-readline ==> boolean false # # Trying to pass --readline or --readline=1 or --readline=0 will -# result in an "unrecognized option" error, despite the the options +# result in an "unrecognized option" error, despite the the [options] # call listing the flag as "readline". # # The behavior described above can lead lead to some confusion when @@ -91,7 +91,7 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # --enable-FLAG # # Non-boolean flags, in contrast, use the names specifically given to -# them in the 'options' invocation. e.g. "with-tcl" is the --with-tcl +# them in the [options] invocation. e.g. "with-tcl" is the --with-tcl # flag. Autosetup may, however, choose to automatically alter the help # text, as demonstrated here: # @@ -130,7 +130,7 @@ set flags { # # threadsafe=1 => {Disable mutexing} - with-tempstore:=no => {Use an in-ram database for temporary tables: never,no,yes,always} + with-tempstore:=no => {Use an in-RAM database for temporary tables: never,no,yes,always} largefile=1 => {Disable large file support} load-extension=1 => {Disable loading of external extensions} math=1 => {Disable math functions} @@ -251,12 +251,12 @@ if {1} { set isCrossCompiling [proj-is-cross-compiling] define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags. -define OPT_SHELL {} ; # CFLAGS for the sqlite3 CLI app +define OPT_SHELL {} ; # Feature-related CFLAGS for the sqlite3 CLI app ######################################################################## -# Adds $args, if not empty, to OPT_FEATURE_FLAGS. -# If the first arg is -shell then it strips that arg -# and passes the remaining args th sqlite-add-shell-opt -# in addition to adding them to OPT_FEATURE_FLAGS. +# Adds $args, if not empty, to OPT_FEATURE_FLAGS. If the first arg is +# -shell then it strips that arg and passes the remaining args the +# sqlite-add-shell-opt in addition to adding them to +# OPT_FEATURE_FLAGS. proc sqlite-add-feature-flag {args} { set shell "" if {"-shell" eq [lindex $args 0]} { @@ -328,23 +328,40 @@ proc sqlite-check-wasi-sdk {} { } msg-result "Checking WASI SDK directory \[$wasiSdkDir]... " #puts "prefix = [prefix $wasiSdkDir/bin {clang ld}]" - proj-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld}] + proj-affirm-files-exist -v {*}[prefix "$wasiSdkDir/bin/" {clang wasm-ld ar}] define HAVE_WASI_SDK 1 define WASI_SDK_DIR $wasiSdkDir # Disable numerous options which we know either can't work or are # not useful in this build... - msg-result "Using wasi-sdk clang. Disabling CLI shell and forcing:" + msg-result "Using wasi-sdk clang. Disabling CLI shell modifying config flags:" + # Boolean flags which must be switched off: foreach opt { editline gcov + icu-collations load-extension readline shared tcl threadsafe } { - msg-result " --disable-$opt" - proj-opt-set $opt 0 + if {[opt-bool $opt]} { + msg-result " --disable-$opt" + proj-opt-set $opt 0 + } + } + # Non-boolean flags which need to be cleared: + foreach opt { + with-emsdk + with-icu-config + with-icu-ldflags + with-linenoise + with-tcl + } { + if {[proj-opt-was-provided $opt]} { + msg-result " removing --$opt" + proj-opt-set $opt "" + } } # Remember that we now have a discrepancy beteween # $::isCrossCompiling and [proj-is-cross-compiling]. @@ -410,8 +427,9 @@ if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { } proj-check-rpath ; # Determine proper rpath-handling flag -if {0 && [proj-check-soname libsqlite3.so.3]} { - # It's not yet clear whether we gain anything from setting -soname +if {[proj-check-soname libsqlite3.so.3]} { + # It's not yet clear whether we gain anything from setting -soname, + # but not having it has been a source of anxiety for some users. define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]libsqlite3.so.3 } else { define LDFLAGS_SONAME_LIBSQLITE3 "" @@ -768,14 +786,14 @@ proj-if-opt-truthy threadsafe { if {1} { set ts [opt-val with-tempstore no] set tsn 1 - msg-checking "Use an in-ram database for temporary tables? " + msg-checking "Use an in-RAM database for temporary tables? " switch -- $ts { never { set tsn 0 } no { set tsn 1 } yes { set tsn 2 } always { set tsn 3 } default { - user-error "Invalid with-tempstore value \[$ts]. Use one of: never, no, yes, always" + user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always" } } msg-result $ts @@ -1179,8 +1197,8 @@ foreach {boolFlag featureFlag ifSetEvalThis} { } ######################################################################## -# Invert the above loop's logic for some explicit SQLITE_OMIT_... -# cases. If config option $boolFlag is set, [sqlite-add-feature-flag +# Invert the above loop's logic for some SQLITE_OMIT_... cases. If +# config option $boolFlag is false, [sqlite-add-feature-flag # $featureFlag], where $featureFlag is intended to be # -DSQLITE_OMIT_... foreach {boolFlag featureFlag} { @@ -1196,17 +1214,19 @@ foreach {boolFlag featureFlag} { ######################################################################### # Show the final feature flag sets: -set oFF [get-define OPT_FEATURE_FLAGS] -if {"" ne $oFF} { - define OPT_FEATURE_FLAGS [lsort -unique $oFF] - msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]" -} -set oFF [get-define OPT_SHELL] -if {"" ne $oFF} { - define OPT_SHELL [lsort -unique $oFF] - msg-result "Shell options: [get-define OPT_SHELL]" +if {1} { + set oFF [get-define OPT_FEATURE_FLAGS] + if {"" ne $oFF} { + define OPT_FEATURE_FLAGS [lsort -unique $oFF] + msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]" + } + set oFF [get-define OPT_SHELL] + if {"" ne $oFF} { + define OPT_SHELL [lsort -unique $oFF] + msg-result "Shell options: [get-define OPT_SHELL]" + } + unset oFF } -unset oFF ######################################################################## # "Re-export" the autoconf-conventional --XYZdir flags into something diff --git a/autosetup/README.md b/autosetup/README.md index f80a46aad0..1385f664fc 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -122,11 +122,12 @@ In (mostly) alphabetical order: The shell-specific counterpart of `sqlite-add-feature-flag`. - **`user-notice msg`**\ - Queues `$msg` to be sent to stderr, but not until either - `show-notices` is called or the next time autosetup would output - something. This can be used to generate warnings between a "checking - for..." message and its resulting "yes/no/whatever" message in such - a way as to not spoil the layout of such messages. + Queues `$msg` to be sent to stderr, but does not emit it until + either `show-notices` is called or the next time autosetup would + output something (it internally calls `show-notices`). This can be + used to generate warnings between a "checking for..." message and + its resulting "yes/no/whatever" message in such a way as to not + spoil the layout of such messages. Ensuring TCL Compatibility diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index b2c527e622..662ea5e8be 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -594,7 +594,8 @@ proc proj-check-compile-commands {{configFlag {}}} { ######################################################################## # @proj-touch filename # -# Runs the 'touch' command on one or more files, ignoring any errors. +# Runs the 'touch' external command on one or more files, ignoring any +# errors. proc proj-touch {filename} { catch { exec touch {*}$filename } } diff --git a/manifest b/manifest index 902eb0341a..ada1e9c77f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Doc\stouchups\sin\sthe\sline-editing\sfeature\scheck\scode. -D 2024-11-07T15:23:54.771 +C Extend\sthe\sset\sof\s--flags\swhich\sget\scleared/unset\swhen\susing\s--with-wasi-sdk. +D 2024-11-07T16:59:15.970 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 8adbbcff2808b47c6ea7e55c8303e89e9364906a73dd2ffc55f8171e74366393 +F auto.def 6fc759447a556c36ac78d426d9c243cd0e2896b25fb76965fb33d05e88e83b60 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 8f2f1cc05913a9d1267f32eb8325f77b3ac6b45cd7d8f6149667efcd90ddbcaa +F autosetup/README.md 839e78a356545cbf81c2924566db72508c7e92e8c0ef35a8520dd8f49743383b F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -50,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 5afbe391eae951567752ba8f0b4ecc05acd5a261e4417161623adda448154ad5 +F autosetup/proj.tcl 638db0bc38e0890610c8dd2dbabb80d3ddf19c9a77d4baad2f2ebf5fb74c384d F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c5389d39a90047683e80ae9081d5d10aaa95da00dfc8a133b4a1a6949a11620d -R 54316963f5f6d26ad35729ed06088c2e +P bb5656bdc905947df205432e108ca6724393061a27028e23bf35b4bf48505d4f +R 8db0443b3cc341b10691e841478e8610 U stephan -Z e2fe9fb1c41d92d4fc9e1c534eca8ef3 +Z c32c37eb256587dabe07c86fffbf93af # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a80268072a..9984ef2f34 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb5656bdc905947df205432e108ca6724393061a27028e23bf35b4bf48505d4f +2a2419ef742c9f37c32be04d417337c1fa22503305d2df154fa38b2b69eae943 From d42855e404e100ce8393eeafb0e55fcfcafd1c0b Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 7 Nov 2024 17:34:53 +0000 Subject: [PATCH 310/522] Fix an OOB write that could occur in fts3 when dealing with corrupt database records. FossilOrigin-Name: 108863ec7998e0a35569e3c6534b538f00d4ef87fdb316bd6a4a9a7a272bba47 --- ext/fts3/fts3.c | 2 +- main.mk | 1 - manifest | 17 ++-- manifest.uuid | 2 +- test/fts3corrupt7.test | 205 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 11 deletions(-) create mode 100644 test/fts3corrupt7.test diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 6c583f4814..e2174e6e3d 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -5518,7 +5518,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ nTmp += p->pRight->pPhrase->doclist.nList; } nTmp += p->pPhrase->doclist.nList; - aTmp = sqlite3_malloc64(nTmp*2); + aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX); if( !aTmp ){ *pRc = SQLITE_NOMEM; res = 0; diff --git a/main.mk b/main.mk index faf8e34c3b..77375d4e17 100644 --- a/main.mk +++ b/main.mk @@ -779,7 +779,6 @@ TESTSRC2 = \ $(TOP)/ext/fts3/fts3.c \ $(TOP)/ext/fts3/fts3_aux.c \ $(TOP)/ext/fts3/fts3_expr.c \ - $(TOP)/ext/fts3/fts3_term.c \ $(TOP)/ext/fts3/fts3_tokenizer.c \ $(TOP)/ext/fts3/fts3_write.c \ $(TOP)/ext/session/sqlite3session.c \ diff --git a/manifest b/manifest index ada1e9c77f..66ce5ef754 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extend\sthe\sset\sof\s--flags\swhich\sget\scleared/unset\swhen\susing\s--with-wasi-sdk. -D 2024-11-07T16:59:15.970 +C Fix\san\sOOB\swrite\sthat\scould\soccur\sin\sfts3\swhen\sdealing\swith\scorrupt\sdatabase\srecords. +D 2024-11-07T17:34:53.573 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -79,7 +79,7 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 59ae8c42ed3c39478faa6d122687e467ac34c98a63282e834f7df9cb5076c450 +F ext/fts3/fts3.c 070d6fec098d49d9b9572c6cd07fd7b82b8b33bf301514638f72dac8ad5a71ce F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682 F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk beaeb83b8239bf4f9747e1dbd5316536feb9a961c689c9917cf5afb4859feafb +F main.mk e9cdc9dd617abea4e60cb823bb18737753f8a4f31c03900c0d63bd569e1ef88b F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -1192,6 +1192,7 @@ F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cd F test/fts3corrupt4.test c7f414fe29b97a478d15c90382c4ae077a2bbd2283bf8c63bf66dadaaed3edb8 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525 +F test/fts3corrupt7.test ad11123257c9ee70b704c4534095e7c3032dd25ad78d5324f54b0b05970cdbec F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de @@ -2200,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bb5656bdc905947df205432e108ca6724393061a27028e23bf35b4bf48505d4f -R 8db0443b3cc341b10691e841478e8610 -U stephan -Z c32c37eb256587dabe07c86fffbf93af +P 2a2419ef742c9f37c32be04d417337c1fa22503305d2df154fa38b2b69eae943 +R 580b9efafd7ec3d49d176dafa65089bc +U dan +Z f282e2ce9844d566093a01c30fea97c9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9984ef2f34..1166dd478e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a2419ef742c9f37c32be04d417337c1fa22503305d2df154fa38b2b69eae943 +108863ec7998e0a35569e3c6534b538f00d4ef87fdb316bd6a4a9a7a272bba47 diff --git a/test/fts3corrupt7.test b/test/fts3corrupt7.test new file mode 100644 index 0000000000..2634047642 --- /dev/null +++ b/test/fts3corrupt7.test @@ -0,0 +1,205 @@ +# 2024 November 7 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# This file implements regression tests for SQLite library. The +# focus of this script is testing the FTS3 module. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/fts3_common.tcl +set testprefix fts3corrupt7 + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts3 { + finish_test + return +} + +sqlite3_fts3_may_be_corrupt 1 +database_may_be_corrupt +extra_schema_checks 0 + +#------------------------------------------------------------------------- +reset_db +do_test 1.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 28672 pagesize 4096 filename x.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 04 00 00 00 07 .....@ ........ +| 32: 00 00 00 02 00 00 00 01 00 00 00 04 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................ +| 96: 00 2e 82 40 0d 0e b1 00 06 0d a4 00 0f 8d 0f 21 ...@...........! +| 112: 0e b9 0d c8 0e 7e 0d a4 7d a4 00 00 00 00 00 00 .....~.......... +| 2512: 00 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 ................ +| 3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c ...........1tabl +| 3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB +| 3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01 LE t2(x).3...... +| 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72 .5tablet1_segdir +| 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE +| 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi +| 3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52 r'(level INTEGER +| 3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61 ,idx INTEGER,sta +| 3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 rt_block INTEGER +| 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc +| 3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c k INTEGER,end_bl +| 3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74 ock INTEGER,root +| 3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 BLOB,PRIMARY KE +| 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06 Y(level, idx))1. +| 3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74 ..E...indexsqlit +| 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s +| 3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72 egdir_1t1_segdir +| 3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01 .........f...##. +| 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen +| 3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52 tst1_segments.CR +| 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s +| 3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64 egments'(blockid +| 3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY +| 3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 KEY, block BLOB +| 3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74 )j...!!...tablet +| 3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont +| 3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE +| 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do +| 3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d cid INTEGER PRIM +| 3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20 ARY KEY, 'c0a', +| 3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06 'c1b', 'c2c')8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33 LE t1 USING fts3 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 39 00 00 00 00 00 (a,b,c)...9..... +| page 2 offset 4096 +| 0: 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 ................ +| 16: 00 00 00 00 02 00 00 00 00 05 00 00 00 03 02 00 ................ +| 32: 00 00 00 05 00 00 00 03 02 00 00 00 00 05 00 00 ................ +| 48: 00 03 02 00 00 00 00 05 00 00 00 03 02 00 00 00 ................ +| 64: 00 05 00 00 00 03 02 00 00 00 00 05 00 00 00 03 ................ +| 80: 02 00 00 00 00 05 00 00 00 03 02 00 00 00 00 05 ................ +| 96: 00 00 00 03 02 00 00 00 00 05 00 00 00 03 05 00 ................ +| 112: 00 00 03 03 00 00 00 23 02 00 00 00 00 03 00 00 .......#........ +| 128: 00 23 02 00 00 00 00 03 00 00 4d 5a 14 00 ae 7c .#........MZ...| +| 1088: 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 ................ +| page 3 offset 8192 +| 0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74 ....%.H........t +| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./.......... +| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$...... +| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb .......h.O.5.... +| 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$.. +| 80: 0b 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .H.............. +| 2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7f 00 .........?%..... +| 2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e .COMPILER=gcc-5. +| 2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 45 42 4.0 20160609 DEB +| 2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54 UG ENABLE DBSTAT +| 2944: 20 56 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53 VTAB ENABLE FTS +| 2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e 4 ENABLE FTS5 EN +| 2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41 ABLE GEOPOLY ENA +| 2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45 BLE JSON1 ENABLE +| 3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20 MEMSYS5 ENABLE +| 3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59 RTREE MAX MEMORY +| 3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c =50000000 OMIT L +| 3056: 4f 41 44 20 45 58 54 45 4e 53 49 4f 4e 20 54 48 OAD EXTENSION TH +| 3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f READSAFE=0.$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 00 00 IONXRTRIM....3.. +| 4016: 54 41 42 4c 45 20 74 31 28 61 20 49 4e 54 45 47 TABLE t1(a INTEG +| 4032: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 20 41 ER PRIMARY KEY A +| 4048: 55 54 4f 49 4e 43 52 45 4d 45 4e 54 2c 0a 62 2c UTOINCREMENT,.b, +| 4064: 63 2c 64 2c 65 2c 66 2c 67 2c 68 2c 6a 2c 6b 2c c,d,e,f,g,h,j,k, +| 4080: 6c 2c 6d 2c 6e 2c 6f 2c 70 2c 71 2c 72 2c 73 29 l,m,n,o,p,q,r,s) +| page 5 offset 16384 +| 0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00 ................ +| 2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33 ...........0 253 +| 2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36 ..0.%.....201606 +| 3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35 09.%....4.%....5 +| 3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a .%....0000000.%. +| 3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00 ...compiler.%... +| 3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75 .dbstat.%....ebu +| 3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09 g.%....enable.%. +| 3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f .........xtensio +| 3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03 n.%....fts4.%... +| 3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01 .5.%....gcc.%... +| 3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f .eopoly.%....jso +| 3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00 n1.%....load.%.. +| 3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79 ..max.%....emory +| 3184: 03 25 19 00 03 04 73 79 73 35 03 25 15 00 00 04 .%....sys5.%.... +| 3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03 omit.%....rtree. +| 3216: 25 01 00 d0 0a 07 68 72 65 61 64 73 61 66 65 03 %.....hreadsafe. +| 3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01 %....vtab.%...P. +| 3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30 ........0 835..0 +| 3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00 ................ +| 3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07 .....20160609... +| 3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05 .........4...... +| 3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04 ......5......... +| 3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04 ...0000000...... +| 3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02 ......binary<... +| 3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3376: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................ +| 3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 ................ +| 3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69 ...........compi +| 3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64 ler............d +| 3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01 bstat........... +| 3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00 .ebug........... +| 3472: 06 65 6e 61 62 6c 65 3f 07 02 00 01 02 00 01 02 .enable?........ +| 3488: 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 ................ +| 3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 ................ +| 3520: 02 00 01 02 00 01 02 00 01 02 00 01 02 00 01 02 ................ +| 3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f .........xtensio +| 3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73 n............fts +| 3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d 4............5.. +| 3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03 ..........gcc... +| 3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09 .........eopoly. +| 3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31 ...........json1 +| 3632: 09 13 03 00 01 03 01 01 03 00 00 04 6c 6f 61 64 ............load +| 3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09 ............max. +| 3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79 ...........emory +| 3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35 ............sys5 +| 3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61 ............noca +| 3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02 se<............. +| 3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................ +| 3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00 ................ +| 3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00 .omit........... +| 3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00 .rtree.......... +| 3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03 ..im<........... +| 3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 ................ +| 3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 ................ +| 3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02 ...threadsafe... +| 3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04 .........vtab... +| 3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................ +| 3968: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................ +| 3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................ +| 4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| 4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................ +| 4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................ +| 4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................ +| 4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00 ................ +| 4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09 ................ +| end x.db +}]} {} + +do_catchsql_test 1.1 { + SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'rtree NEAR rtree NEAR "json1 enable"'; +} {0 {}} + +finish_test From 6f95d9501583bd8be9354102d0e0e4031a44aa07 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 8 Nov 2024 05:26:26 +0000 Subject: [PATCH 311/522] Disable setting of the SONAME (enabled by [2a2419ef742]), as it's not clear whether blindly setting the SONAME, which now differs from its historical value, will cause more grief than it solves. Add a (disabled) experiment which permits setting (or not) the SONAME to the legacy or current values. This change is up for further change as experimentation proves whether we truly need/want the SONAME. See discussion in/around [forum:0c6fc6f46b2cb3|forum post 0c6fc6f46b2cb3]. FossilOrigin-Name: d931456805e7d5c3379ca68b97a0a1d4ab1eb80c5e90c169cf43fc8239247d25 --- auto.def | 44 +++++++++++++++++++++++++++++++++++++++----- autosetup/proj.tcl | 8 ++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/auto.def b/auto.def index bf3a99c513..8e2c1f8a93 100644 --- a/auto.def +++ b/auto.def @@ -195,6 +195,12 @@ set flags { gcov=0 => {Enable coverage testing using gcov} linemacros => {Enable #line macros in the amalgamation} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} + #soname:=none => {SONAME for libsqlite3.so} + #^^^ we "could", but arguably shouldn't, support clients passing a + # value of libsqlite3.so.0 for compatibility with clients which + # linked against a pre-3.48 build. + # Maybe we should support values of --soname=(none,auto,legacy), where auto means + # to use the 3.48+ value of libsqlite3.so.3.. # } if {"" ne $DUMP_DEFINES_JSON} { @@ -427,13 +433,41 @@ if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { } proj-check-rpath ; # Determine proper rpath-handling flag -if {[proj-check-soname libsqlite3.so.3]} { - # It's not yet clear whether we gain anything from setting -soname, - # but not having it has been a source of anxiety for some users. - define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]libsqlite3.so.3 -} else { + +######################################################################## +# It's not yet clear whether we gain anything from setting -soname, +# but not having it has been a source of anxiety for some users. +# Setting it to any value other than its historical value of +# libsqlite3.so.0 may (this is not certain) break dynamic linking of +# clients which initially linked against a legacy build. +# +# See discussion in/around: +# https://sqlite.org/forum/forumpost/0c6fc6f46b2cb3 +proc sqlite-check-soname {} { define LDFLAGS_SONAME_LIBSQLITE3 "" + if {[proj-opt-was-provided soname]} { + set soname [opt-val soname] + } else { + return 0 + } + switch -exact -- $soname { + none { return 0 } + auto - 3 { set soname libsqlite3.so.3 } + legacy - 0 { set soname libsqlite3.so.0 } + default { + proj-fatal "Invalid value for --soname. Use one of (none, auto, legacy)." + } + } + msg-debug "soname=$soname" + if {[proj-check-soname $soname]} { + define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]$soname + msg-result "Setting SONAME: [get-define LDFLAGS_SONAME_LIBSQLITE3]" + } else { + proj-fatal "This environment does not support SONAME." + } + return sqlite-check-soname "" } +sqlite-check-soname proj-define-if-opt-truthy shared ENABLE_SHARED "Build shared library?" diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 662ea5e8be..495352e5a9 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -319,6 +319,14 @@ proc proj-first-bin-of {args} { # passes --foo-bar to configure, even if that invocation would resolve # to the default value of baz. If the user does not explicitly pass in # --foo-bar (with or without a value) then this returns 0. +# +# Note: unlike most functions which deal with configure --flags, this +# one does not validate that $key refers to a pre-defined flag. i.e. +# it accepts arbitrary keys, even those not defined via an [options] +# call. [proj-opt-set] manipulates the internal list of flags, such +# that new options set via that function will cause this function to +# return true. (That's an unintended and unavoidable side-effect, not +# specifically a feature which should be made use of.) proc proj-opt-was-provided {key} { dict exists $::autosetup(optset) $key } diff --git a/manifest b/manifest index 66ce5ef754..6d5a9b5e3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sOOB\swrite\sthat\scould\soccur\sin\sfts3\swhen\sdealing\swith\scorrupt\sdatabase\srecords. -D 2024-11-07T17:34:53.573 +C Disable\ssetting\sof\sthe\sSONAME\s(enabled\sby\s[2a2419ef742]),\sas\sit's\snot\sclear\swhether\sblindly\ssetting\sthe\sSONAME,\swhich\snow\sdiffers\sfrom\sits\shistorical\svalue,\swill\scause\smore\sgrief\sthan\sit\ssolves.\sAdd\sa\s(disabled)\sexperiment\swhich\spermits\ssetting\s(or\snot)\sthe\sSONAME\sto\sthe\slegacy\sor\scurrent\svalues.\sThis\schange\sis\sup\sfor\sfurther\schange\sas\sexperimentation\sproves\swhether\swe\struly\sneed/want\sthe\sSONAME.\sSee\sdiscussion\sin/around\s[forum:0c6fc6f46b2cb3|forum\spost\s0c6fc6f46b2cb3]. +D 2024-11-08T05:26:26.094 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 6fc759447a556c36ac78d426d9c243cd0e2896b25fb76965fb33d05e88e83b60 +F auto.def d59912edf010b39c9643979668b298945e86d7cedcfd9f6e82bb6b67460c3750 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -50,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 638db0bc38e0890610c8dd2dbabb80d3ddf19c9a77d4baad2f2ebf5fb74c384d +F autosetup/proj.tcl 93e1d99ffa8a75fe2f488605c4d36cb57a75f1500bccc5c5954ae45eb7da89d7 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2a2419ef742c9f37c32be04d417337c1fa22503305d2df154fa38b2b69eae943 -R 580b9efafd7ec3d49d176dafa65089bc -U dan -Z f282e2ce9844d566093a01c30fea97c9 +P 108863ec7998e0a35569e3c6534b538f00d4ef87fdb316bd6a4a9a7a272bba47 +R f90970b8630851bf2dd23d5bfdfec6bf +U stephan +Z a7d1a2cb3cf805ad0ba907d86397dd96 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1166dd478e..49365159ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -108863ec7998e0a35569e3c6534b538f00d4ef87fdb316bd6a4a9a7a272bba47 +d931456805e7d5c3379ca68b97a0a1d4ab1eb80c5e90c169cf43fc8239247d25 From 3b306aac6e92bf50b40dceda2deab05c630f34f2 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 8 Nov 2024 06:22:15 +0000 Subject: [PATCH 312/522] Support clients passing in LDFLAGS to configure/make, but in a more limited form than the legacy build it (i.e. only to select targets rather than all targets). Rename make-side internal uses of CFLAGS to CFLAGS.env for consistency with the new LDFLAGS.env. See discussion in [forum:5fcbea40f3|forum thread 5fcbea40f3]. FossilOrigin-Name: a5e07e8063ad50f2cf46b6be568717adc9604bd6dbf926a526de43bda2996ad0 --- Makefile.in | 37 +++++++++++++++++++++++-------------- main.mk | 46 +++++++++++++++++++++++++++++++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/Makefile.in b/Makefile.in index 79154f3fed..4a70211430 100644 --- a/Makefile.in +++ b/Makefile.in @@ -117,13 +117,28 @@ CC = @CC@ B.cc = @CC_FOR_BUILD@ @BUILD_CFLAGS@ T.cc = $(CC) # -# CFLAGS is problematic because it is frequently overridden when -# invoking make, which loses things like -fPIC. So... let's avoid -# using it directly and instead add a level of indirection. We -# combine CFLAGS and CPPFLAGS here because that's the way the legacy -# build did it. +# $(CFLAGS) is problematic because it is frequently overridden when +# invoking make, which loses things like -fPIC. So... we avoid using +# it directly and instead add a level of indirection. We combine +# $(CFLAGS) and $(CPPFLAGS) here because that's the way the legacy +# build did it and many builds rely on that. See main.mk for more +# details. +# +# Historical note: the pre-3.48 build only honored CPPFLAGS at +# configure-time, and expanded them into the generated Makefile. There +# are, in that build, no uses of CPPFLAGS in the configure-expanded +# Makefile. Ergo: if a client configures with CPPFLAGS=... and then +# explicitly passes CFLAGS=... to make, the CPPFLAGS will be +# lost. That behavior is retained in 3.48+ because also honoring +# CPPFLAGS at make-time may have undesired side effects on any number +# of builds. # CFLAGS = @CFLAGS@ @CPPFLAGS@ +# +# $(LDFLAGS) is documented in main.mk. +# +LDFLAGS = @LDFLAGS@ + # # CFLAGS.core is documented in main.mk. # @@ -148,6 +163,9 @@ T.cc.sqlite = $(T.cc) @TARGET_DEBUG@ # Define -D_HAVE_SQLITE_CONFIG_H so that the code knows it # can include the generated sqlite_cfg.h. # +# main.mk will fill out T.cc.sqlite with additional flags common to +# all builds. +# T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # # -I$(prefix)/include is primarily so that the ICU @@ -155,9 +173,6 @@ T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite # T.cc.sqlite += -I$(prefix)/include -# -# main.mk will fill out T.cc.sqlite with some flags common to all builds. - # # $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH) # must start with a path component so that it can be invoked as a @@ -231,12 +246,6 @@ TCL_CONFIG_SH = @TCL_CONFIG_SH@ #TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@ #TCL_VERSION = @TCL_VERSION@ # -# $(TCLLIB_RPATH) is calculated by the configure script. Its counterpart -# in tclConfig.sh (TCL_LD_SEARCH_FLAGS) is defined in such a way as to -# make it incompatible with static makefiles. -# -#TCLLIB_RPATH = @TCLLIB_RPATH@ -# # $(TCLLIBDIR) = where to install the tcl plugin. If this is empty, it # is calculated at make-time by the targets which need it but we # export it here so that it can be set at configure-time, so that diff --git a/main.mk b/main.mk index 77375d4e17..5afd518693 100644 --- a/main.mk +++ b/main.mk @@ -263,17 +263,41 @@ all: sqlite3.h sqlite3.c ######################################################################## ######################################################################## +# +# $(CFLAGS.env) holds the environment-provided $(CFLAGS). # # $(CFLAGS) should ideally only contain flags which are relevant for # all binaries built for the target platform. However, many people # like to pass it to "make" without realizing that it applies to -# dozens of apps, and they override core flags when doing so. To help -# work around that, we expect core-most CFLAGS (only), e.g. -fPIC, to -# be set in $(CFLAGS.core). That enables people to pass their other -# CFLAGS without triggering, e.g., "recompile with -fPIC" errors. +# dozens of deliverables, and they override core flags (like -fPIC) +# when doing so. To help work around that, we expect all core-most +# CFLAGS, e.g. -fPIC, to be set in $(CFLAGS.core). That enables people +# to pass their other CFLAGS without triggering, e.g., "recompile with +# -fPIC" errors. +# +# Historical note: the pre-3.48 build does not honor CPPFLAGS passed +# to make, so we do not do so here. Both the legacy and 3.48+ builds +# support CPPFLAGS passed at configure-time. # CFLAGS.core ?= -T.cc += $(CFLAGS.core) $(CFLAGS) +CFLAGS.env = $(CFLAGS) +T.cc += $(CFLAGS.core) $(CFLAGS.env) + +# +# $(LDFLAGS.env) represents any LDFLAGS=... the client passes to +# make or configure. The historical build enabled passing-on of +# user-provided LDFLAGS, and some folks rely on that for obscure uses, +# so we do the same here, with the caveats that: +# +# 1) The legacy build applied such LDFLAGS to all link operations for +# all deliverables. +# +# 2) The 3.48+ build applies them (as of this writing) more +# selectively: search this file LDFLAGS.env to see where they're +# set. As of this writing, they only affect targets which use +# $(LDFLAGS.libsqlite3) - see that var's docs for details. +# +LDFLAGS.env = $(LDFLAGS) # # The difference between $(OPT_FEATURE_FLAGS) and $(OPTS) is that the @@ -346,8 +370,8 @@ T.link = $(T.cc.sqlite) $(T.link.extras) T.link.shared = $(T.link) $(LDFLAGS.shobj) # -# LDFLAGS.libsqlite3 should be used with any deliverable for which any -# of the following apply: +# $(LDFLAGS.libsqlite3) should be used with any deliverable for which +# any of the following apply: # # - Results in building libsqlite3.so # - Compiles sqlite3.c in to an application @@ -361,7 +385,8 @@ T.link.shared = $(T.link) $(LDFLAGS.shobj) LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ $(LDFLAGS.math) $(LDFLAGS.dlopen) \ - $(LDFLAGS.zlib) $(LDFLAGS.icu) + $(LDFLAGS.zlib) $(LDFLAGS.icu) \ + $(LDFLAGS.env) # # $(install-dir.XYZ) = dirs for installation. @@ -1474,7 +1499,10 @@ tclsqlite3.c: sqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c -CFLAGS.tclextension = $(CFLAGS.intree_includes) $(CFLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) +# +# $(CFLAGS.tclextension) = CFLAGS for the tclextension* targets. +# +CFLAGS.tclextension = $(CFLAGS.intree_includes) $(CFLAGS.env) $(OPT_FEATURE_FLAGS) $(OPTS) # # Build the SQLite TCL extension in a way that make it compatible # with whatever version of TCL is running as $TCLSH_CMD, possibly defined diff --git a/manifest b/manifest index 6d5a9b5e3f..b96c453c1b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Disable\ssetting\sof\sthe\sSONAME\s(enabled\sby\s[2a2419ef742]),\sas\sit's\snot\sclear\swhether\sblindly\ssetting\sthe\sSONAME,\swhich\snow\sdiffers\sfrom\sits\shistorical\svalue,\swill\scause\smore\sgrief\sthan\sit\ssolves.\sAdd\sa\s(disabled)\sexperiment\swhich\spermits\ssetting\s(or\snot)\sthe\sSONAME\sto\sthe\slegacy\sor\scurrent\svalues.\sThis\schange\sis\sup\sfor\sfurther\schange\sas\sexperimentation\sproves\swhether\swe\struly\sneed/want\sthe\sSONAME.\sSee\sdiscussion\sin/around\s[forum:0c6fc6f46b2cb3|forum\spost\s0c6fc6f46b2cb3]. -D 2024-11-08T05:26:26.094 +C Support\sclients\spassing\sin\sLDFLAGS\sto\sconfigure/make,\sbut\sin\sa\smore\slimited\sform\sthan\sthe\slegacy\sbuild\sit\s(i.e.\sonly\sto\sselect\stargets\srather\sthan\sall\stargets).\sRename\smake-side\sinternal\suses\sof\sCFLAGS\sto\sCFLAGS.env\sfor\sconsistency\swith\sthe\snew\sLDFLAGS.env.\sSee\sdiscussion\sin\s[forum:5fcbea40f3|forum\sthread\s5fcbea40f3]. +D 2024-11-08T06:22:15.700 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in 3a54957d16c3f4666922f170a19b4b51dc13be039c29394dd38caa95ade5d731 +F Makefile.in 007ddc95bc4954ea83219dae8205f124b6d4af247956de3d512af2efee79218a F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk e9cdc9dd617abea4e60cb823bb18737753f8a4f31c03900c0d63bd569e1ef88b +F main.mk 28f98d4289bd9b07c3b9b7ee66b7128e798bf5ff8a195b8bd585637f7abf9dd8 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 108863ec7998e0a35569e3c6534b538f00d4ef87fdb316bd6a4a9a7a272bba47 -R f90970b8630851bf2dd23d5bfdfec6bf +P d931456805e7d5c3379ca68b97a0a1d4ab1eb80c5e90c169cf43fc8239247d25 +R 17f80016988fb1a73179c22ffceb038b U stephan -Z a7d1a2cb3cf805ad0ba907d86397dd96 +Z a78bacddad60c62677dda4a3ed053059 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 49365159ca..d1bef5204e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d931456805e7d5c3379ca68b97a0a1d4ab1eb80c5e90c169cf43fc8239247d25 +a5e07e8063ad50f2cf46b6be568717adc9604bd6dbf926a526de43bda2996ad0 From 62801081f32a862c1c02c8c17c54f77b86a0ffd8 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 8 Nov 2024 07:37:12 +0000 Subject: [PATCH 313/522] More closely emulate the legacy build's handling of LDFLAGS, permitting them to be passed to configure but not to make. We cannot 100% enforce that because main.mk is not filtered by the configure script, so we instead add a level of indirection to make passing of LDFLAGS=... to make a no-op. FossilOrigin-Name: d1af9f31831dc99a808b916df4d414943f5d56796c8342411ee4a57abfde85e2 --- Makefile.in | 5 +++-- main.mk | 35 +++++++++++++++++++++-------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4a70211430..530d82e4f7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -135,9 +135,10 @@ T.cc = $(CC) # CFLAGS = @CFLAGS@ @CPPFLAGS@ # -# $(LDFLAGS) is documented in main.mk. +# $(LDFLAGS.configure) represents any LDFLAGS=... the client passes to +# configure. See main.mk. # -LDFLAGS = @LDFLAGS@ +LDFLAGS.configure = @LDFLAGS@ # # CFLAGS.core is documented in main.mk. diff --git a/main.mk b/main.mk index 5afd518693..b09de2a3b3 100644 --- a/main.mk +++ b/main.mk @@ -264,7 +264,8 @@ all: sqlite3.h sqlite3.c ######################################################################## # -# $(CFLAGS.env) holds the environment-provided $(CFLAGS). +# $(CFLAGS.env) holds the any $(CFLAGS) provided at configure- or +# make-time (the latter overriding the former). # # $(CFLAGS) should ideally only contain flags which are relevant for # all binaries built for the target platform. However, many people @@ -277,27 +278,33 @@ all: sqlite3.h sqlite3.c # # Historical note: the pre-3.48 build does not honor CPPFLAGS passed # to make, so we do not do so here. Both the legacy and 3.48+ builds -# support CPPFLAGS passed at configure-time. +# support CPPFLAGS passed at configure-time, and combines them with +# the configure-time CFLAGS. # CFLAGS.core ?= CFLAGS.env = $(CFLAGS) T.cc += $(CFLAGS.core) $(CFLAGS.env) # -# $(LDFLAGS.env) represents any LDFLAGS=... the client passes to -# make or configure. The historical build enabled passing-on of -# user-provided LDFLAGS, and some folks rely on that for obscure uses, -# so we do the same here, with the caveats that: +# $(LDFLAGS.configure) represents any LDFLAGS=... the client passes to +# the configure process. The historical build enabled passing-on of +# user-provided LDFLAGS at configure-time but not make-time. That +# behavior is not possible to fully emulate here because this makefile +# is not filtered by the configure script, so we instead +# "soft-enforce" it by using a level of indirection, which clients who +# read this can (but are not advised to!) bypass by passing +# LDFLAGS.configure=... to this makefile. (We do not guaranty this +# variable name to be stable, so do not rely on that capability!) # -# 1) The legacy build applied such LDFLAGS to all link operations for -# all deliverables. +# A significant difference from the legacy build: # -# 2) The 3.48+ build applies them (as of this writing) more -# selectively: search this file LDFLAGS.env to see where they're -# set. As of this writing, they only affect targets which use -# $(LDFLAGS.libsqlite3) - see that var's docs for details. +# The legacy build applied such LDFLAGS to all link operations for all +# deliverables. The 3.48+ build applies them (as of this writing) more +# selectively: search this file LDFLAGS.configure to see where they're +# set. As of this writing, they only affect targets which use +# $(LDFLAGS.libsqlite3) - see that var's docs for details. # -LDFLAGS.env = $(LDFLAGS) +LDFLAGS.configure ?= # # The difference between $(OPT_FEATURE_FLAGS) and $(OPTS) is that the @@ -386,7 +393,7 @@ LDFLAGS.libsqlite3 = \ $(LDFLAGS.rpath) $(LDFLAGS.pthread) \ $(LDFLAGS.math) $(LDFLAGS.dlopen) \ $(LDFLAGS.zlib) $(LDFLAGS.icu) \ - $(LDFLAGS.env) + $(LDFLAGS.configure) # # $(install-dir.XYZ) = dirs for installation. diff --git a/manifest b/manifest index b96c453c1b..6e36a7492d 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Support\sclients\spassing\sin\sLDFLAGS\sto\sconfigure/make,\sbut\sin\sa\smore\slimited\sform\sthan\sthe\slegacy\sbuild\sit\s(i.e.\sonly\sto\sselect\stargets\srather\sthan\sall\stargets).\sRename\smake-side\sinternal\suses\sof\sCFLAGS\sto\sCFLAGS.env\sfor\sconsistency\swith\sthe\snew\sLDFLAGS.env.\sSee\sdiscussion\sin\s[forum:5fcbea40f3|forum\sthread\s5fcbea40f3]. -D 2024-11-08T06:22:15.700 +C More\sclosely\semulate\sthe\slegacy\sbuild's\shandling\sof\sLDFLAGS,\spermitting\sthem\sto\sbe\spassed\sto\sconfigure\sbut\snot\sto\smake.\sWe\scannot\s100%\senforce\sthat\sbecause\smain.mk\sis\snot\sfiltered\sby\sthe\sconfigure\sscript,\sso\swe\sinstead\sadd\sa\slevel\sof\sindirection\sto\smake\spassing\sof\sLDFLAGS=...\sto\smake\sa\sno-op. +D 2024-11-08T07:37:12.419 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in 007ddc95bc4954ea83219dae8205f124b6d4af247956de3d512af2efee79218a +F Makefile.in 580a60aa8deb37060c7973d9399c51c4388f1e0ad0be6555dcd44bc8d2ac3260 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 28f98d4289bd9b07c3b9b7ee66b7128e798bf5ff8a195b8bd585637f7abf9dd8 +F main.mk e2a20a4612d8e1d1c3ad2e427d089e18f4831efdeab234dfeaa0a014e3a3d81d F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d931456805e7d5c3379ca68b97a0a1d4ab1eb80c5e90c169cf43fc8239247d25 -R 17f80016988fb1a73179c22ffceb038b +P a5e07e8063ad50f2cf46b6be568717adc9604bd6dbf926a526de43bda2996ad0 +R bf7c848547bcf2bdf4e3ecfac76baab4 U stephan -Z a78bacddad60c62677dda4a3ed053059 +Z 41894f1532ad89c47f894ee85a9664de # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d1bef5204e..3ffe554d46 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a5e07e8063ad50f2cf46b6be568717adc9604bd6dbf926a526de43bda2996ad0 +d1af9f31831dc99a808b916df4d414943f5d56796c8342411ee4a57abfde85e2 From a4093dcc06405288c3986aa0aa8535b3b494cc9a Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 8 Nov 2024 08:01:56 +0000 Subject: [PATCH 314/522] Add missing CFLAGS.intree_includes to T.compile.tcl to fix build of tclsqlite3. FossilOrigin-Name: bb3c6dc126896528328bb9f51a28a1d46d4549e687c93c16f2d164230c6b1684 --- main.mk | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index b09de2a3b3..b93ba4225c 100644 --- a/main.mk +++ b/main.mk @@ -1005,7 +1005,7 @@ T.tcl.env.source = . $(T.tcl.env.sh) || exit $$? # and $(T.link) which first invoke $(T.tcl.env.source). Any targets which used them # must have a dependency on $(T.tcl.env.sh) # -T.compile.tcl = $(T.tcl.env.source); $(T.compile) +T.compile.tcl = $(T.tcl.env.source); $(T.compile) $(CFLAGS.intree_includes) T.link.tcl = $(T.tcl.env.source); $(T.link) # @@ -1322,7 +1322,7 @@ window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON) $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/window.c tclsqlite.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) - $(T.compile.tcl) -DUSE_TCL_STUBS=1 $$TCL_INCLUDE_SPEC $(CFLAGS.intree_includes) \ + $(T.compile.tcl) -DUSE_TCL_STUBS=1 $$TCL_INCLUDE_SPEC \ -c $(TOP)/src/tclsqlite.c tclsqlite-shell.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) diff --git a/manifest b/manifest index 6e36a7492d..a6974ff105 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sclosely\semulate\sthe\slegacy\sbuild's\shandling\sof\sLDFLAGS,\spermitting\sthem\sto\sbe\spassed\sto\sconfigure\sbut\snot\sto\smake.\sWe\scannot\s100%\senforce\sthat\sbecause\smain.mk\sis\snot\sfiltered\sby\sthe\sconfigure\sscript,\sso\swe\sinstead\sadd\sa\slevel\sof\sindirection\sto\smake\spassing\sof\sLDFLAGS=...\sto\smake\sa\sno-op. -D 2024-11-08T07:37:12.419 +C Add\smissing\sCFLAGS.intree_includes\sto\sT.compile.tcl\sto\sfix\sbuild\sof\stclsqlite3. +D 2024-11-08T08:01:56.002 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk e2a20a4612d8e1d1c3ad2e427d089e18f4831efdeab234dfeaa0a014e3a3d81d +F main.mk 3ab4da6fd1383aa32173e72cc876d4313692e86fbd447e08f6575cfe68c35a40 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a5e07e8063ad50f2cf46b6be568717adc9604bd6dbf926a526de43bda2996ad0 -R bf7c848547bcf2bdf4e3ecfac76baab4 +P d1af9f31831dc99a808b916df4d414943f5d56796c8342411ee4a57abfde85e2 +R e7e6b5f1b00f47c5c5fd2d8a0d9c908a U stephan -Z 41894f1532ad89c47f894ee85a9664de +Z 83a8e5b16a3924a6c0e5c0fa6944ffd4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3ffe554d46..8dd270e64b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d1af9f31831dc99a808b916df4d414943f5d56796c8342411ee4a57abfde85e2 +bb3c6dc126896528328bb9f51a28a1d46d4549e687c93c16f2d164230c6b1684 From a700db9387dba38406d95addb487bd696e1112bd Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 8 Nov 2024 13:37:00 +0000 Subject: [PATCH 315/522] Add 'tcl' makefile target which builds all but tclextension (which does not have a well-defined name and dependencies). Improve the deps for .tclenv.sh to avoid getting a stale tclsh when re-configuring with a different --with-tcl(sh). FossilOrigin-Name: 1bd9de719b0944fdceec32103da3131a7d387820850ab03f652f813d840355b8 --- auto.def | 5 +++-- main.mk | 8 ++++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/auto.def b/auto.def index 8e2c1f8a93..dee555828b 100644 --- a/auto.def +++ b/auto.def @@ -531,6 +531,7 @@ proc sqlite-check-tcl {} { define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search define TCLLIBDIR "" ; # Installation dir for TCL extension lib define TCL_CONFIG_SH ""; # full path to tclConfig.sh + file delete -force ".tclenv.sh"; # ensure no stale state from previous configures. if {![opt-bool tcl]} { proj-indented-notice { NOTE: TCL is disabled via --disable-tcl. This means that none @@ -626,8 +627,8 @@ proc sqlite-check-tcl {} { break } define TCL_CONFIG_SH $cfg - # Export a subset of tclConfig.sh to the current TCL-space. If the - # config is not available, this emits empty-string entries for the + # Export a subset of tclConfig.sh to the current TCL-space. If $cfg + # is an empty string, this emits empty-string entries for the # various options we're interested in. eval [exec "${srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] diff --git a/main.mk b/main.mk index b93ba4225c..ffb46973e9 100644 --- a/main.mk +++ b/main.mk @@ -978,7 +978,7 @@ has_tclsh85: # It took half an hour to figure that out. # T.tcl.env.sh = ./.tclenv.sh -$(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST) +$(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST) config.log @if [ x = "x$(TCL_CONFIG_SH)" ]; then \ echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ fi @@ -991,6 +991,7 @@ $(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST) echo "TCLLIBDIR=$$ld/sqlite3"; \ fi > $@; \ echo ". \"$(TCL_CONFIG_SH)\" || exit \$$?" >> $@ + @echo "Created $@" # # $(T.tcl.env.source) is shell code to be run as part of any @@ -1334,6 +1335,7 @@ tclsqlite-stubs.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) tclsqlite3$(T.exe): $(T.tcl.env.sh) tclsqlite-shell.o $(libsqlite3.SO) $(T.link.tcl) -o $@ tclsqlite-shell.o \ $(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) +tcl: tclsqlite3$(T.exe) # Rules to build opcodes.c and opcodes.h # @@ -1476,6 +1478,7 @@ install: install-headers # pkgIndex.tcl: echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ +tcl: pkgIndex.tcl libtclsqlite3.SO = libtclsqlite3$(T.dll) $(libtclsqlite3.SO): $(T.tcl.env.sh) tclsqlite.o $(LIBOBJ) $(T.tcl.env.source); \ @@ -1488,7 +1491,8 @@ $(libtclsqlite3.SO): $(T.tcl.env.sh) tclsqlite.o $(LIBOBJ) $(libtclsqlite3.SO)-1: $(libtclsqlite3.SO) $(libtclsqlite3.SO)-0 $(libtclsqlite3.SO)-: libtcl: $(libtclsqlite3.SO)-$(HAVE_TCL) -all: libtcl +tcl: libtcl +all: tcl install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl $(T.tcl.env.source); \ diff --git a/manifest b/manifest index a6974ff105..4b8c7be259 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\sCFLAGS.intree_includes\sto\sT.compile.tcl\sto\sfix\sbuild\sof\stclsqlite3. -D 2024-11-08T08:01:56.002 +C Add\s'tcl'\smakefile\starget\swhich\sbuilds\sall\sbut\stclextension\s(which\sdoes\snot\shave\sa\swell-defined\sname\sand\sdependencies).\sImprove\sthe\sdeps\sfor\s.tclenv.sh\sto\savoid\sgetting\sa\sstale\stclsh\swhen\sre-configuring\swith\sa\sdifferent\s--with-tcl(sh). +D 2024-11-08T13:37:00.278 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d59912edf010b39c9643979668b298945e86d7cedcfd9f6e82bb6b67460c3750 +F auto.def b00e0676f9182d880a09b9f4941452324d836b7f9bfef72a98031df091be3b94 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 3ab4da6fd1383aa32173e72cc876d4313692e86fbd447e08f6575cfe68c35a40 +F main.mk 49204a0bfe3a534fcf524dddbb40ef2c5c637b5ea5c1d9411edaf42fbb1deae1 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d1af9f31831dc99a808b916df4d414943f5d56796c8342411ee4a57abfde85e2 -R e7e6b5f1b00f47c5c5fd2d8a0d9c908a +P bb3c6dc126896528328bb9f51a28a1d46d4549e687c93c16f2d164230c6b1684 +R 79a87714e3698b70dc08f54a2c6c7778 U stephan -Z 83a8e5b16a3924a6c0e5c0fa6944ffd4 +Z 32ca490816a904f0ccca59c9c1e56034 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8dd270e64b..23d72ef322 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb3c6dc126896528328bb9f51a28a1d46d4549e687c93c16f2d164230c6b1684 +1bd9de719b0944fdceec32103da3131a7d387820850ab03f652f813d840355b8 From 4441897daac7cb0ce9b06f7f997ba8fc9679a6f8 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 8 Nov 2024 14:34:33 +0000 Subject: [PATCH 316/522] Remove one dep from .tclenv.sh which is only valid for configure-driven builds, not static makefiles. FossilOrigin-Name: 22986767da8f086daaa6dc760c15e6aedcc5d2d6033937ac2f112ee5750d7fdb --- main.mk | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/main.mk b/main.mk index ffb46973e9..e4dcbc2a28 100644 --- a/main.mk +++ b/main.mk @@ -978,7 +978,7 @@ has_tclsh85: # It took half an hour to figure that out. # T.tcl.env.sh = ./.tclenv.sh -$(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST) config.log +$(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST) @if [ x = "x$(TCL_CONFIG_SH)" ]; then \ echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ fi diff --git a/manifest b/manifest index 4b8c7be259..e76d28bd56 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s'tcl'\smakefile\starget\swhich\sbuilds\sall\sbut\stclextension\s(which\sdoes\snot\shave\sa\swell-defined\sname\sand\sdependencies).\sImprove\sthe\sdeps\sfor\s.tclenv.sh\sto\savoid\sgetting\sa\sstale\stclsh\swhen\sre-configuring\swith\sa\sdifferent\s--with-tcl(sh). -D 2024-11-08T13:37:00.278 +C Remove\sone\sdep\sfrom\s.tclenv.sh\swhich\sis\sonly\svalid\sfor\sconfigure-driven\sbuilds,\snot\sstatic\smakefiles. +D 2024-11-08T14:34:33.911 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 49204a0bfe3a534fcf524dddbb40ef2c5c637b5ea5c1d9411edaf42fbb1deae1 +F main.mk af87776a921824639555d040d7a917de0f295b3dfa70079105b4fb42fdf425c3 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bb3c6dc126896528328bb9f51a28a1d46d4549e687c93c16f2d164230c6b1684 -R 79a87714e3698b70dc08f54a2c6c7778 +P 1bd9de719b0944fdceec32103da3131a7d387820850ab03f652f813d840355b8 +R 893eb86bb8e20c86cb402dee09f37203 U stephan -Z 32ca490816a904f0ccca59c9c1e56034 +Z 6964dc53af456b95e9c89bd288941f5a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 23d72ef322..67f53fa9c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1bd9de719b0944fdceec32103da3131a7d387820850ab03f652f813d840355b8 +22986767da8f086daaa6dc760c15e6aedcc5d2d6033937ac2f112ee5750d7fdb From 23cfa0138ec8671feb15cfd86d7d75488d87cf48 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 8 Nov 2024 20:44:16 +0000 Subject: [PATCH 317/522] Fix an assert() failure in sqlite3recover.c. FossilOrigin-Name: f52bb19281b189508f5c31305cbd4a5651f3e036a4ee753c64488b0c7e5d2e4d --- ext/recover/recovercorrupt2.test | 54 +++++++++++++++++++++++++++++++- ext/recover/sqlite3recover.c | 2 ++ manifest | 16 +++++----- manifest.uuid | 2 +- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/ext/recover/recovercorrupt2.test b/ext/recover/recovercorrupt2.test index 6c216308f0..ab6c94804d 100644 --- a/ext/recover/recovercorrupt2.test +++ b/ext/recover/recovercorrupt2.test @@ -525,7 +525,6 @@ do_test 7.1 { } {1 {file is not a database}} reset_db -breakpoint do_test 8.0 { sqlite3 db {} db deserialize [decode_hexdb { @@ -552,5 +551,58 @@ do_test 8.1 { list [catch { $R finish } msg] $msg } {0 {}} +reset_db +do_test 9.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 16384 pagesize 4096t 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 ........ +| 32: 00 00 00 0r 00 00 00 00 00 00 00 06 00 00 00 04 .. +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ........ +| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a .......j +| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00 . +| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..tablet +| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6econ +| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 +| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 ) +| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WOWID^.. +| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 6tt_d +| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a z +| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.ABLE ' +| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20id +| 3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 +| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEYB)].. +| 3744: 17 23 23 01 81 B1 74 61 62 6c 65 74 74 74 5f 63 _c +| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e o_conten +| 3776: 7 04 01 03 00 011 54 45 20 54 41 42 4c 45 20 27 t.CRLE ' +| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 +| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INIMARY +| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 7EY(s +| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 T +| 3936: 48 4f 55 54 20 52 4f 57 49 4 58 58 02 07 17 1d 1d .. +| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 .tt_data +| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 2ATE +| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 ' +| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (iR PRIM +| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42k B +| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c +| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettTE VI +| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 t +| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 U5(a, b) +| page 4 offset 12288 +| 0: 0a 00 00 00 03 0f ea 00 0f fa 0f f2 0f ea 00 00 ........ +| 4064: 00 00 00 00 00 00 00 00 00 00 07 04 01 01 01 05 .. +| 4080: 06 03 07 04 01 01 01 03 04 02 05 04 09 01 09 02 ........ +| end ro2.t +}]} {} + +do_test 9.1 { + set R [sqlite3_recover_init db main test.db2] + catch { $R run } + list [catch { $R finish } msg] $msg +} {0 {}} + + finish_test diff --git a/ext/recover/sqlite3recover.c b/ext/recover/sqlite3recover.c index b16c09827e..58d726f599 100644 --- a/ext/recover/sqlite3recover.c +++ b/ext/recover/sqlite3recover.c @@ -1825,6 +1825,8 @@ static int recoverWriteDataStep(sqlite3_recover *p){ recoverError(p, SQLITE_NOMEM, 0); } p1->nVal = iField+1; + }else if( pTab->nCol==0 ){ + p1->nVal = pTab->nCol; } p1->iPrevCell = iCell; p1->iPrevPage = iPage; diff --git a/manifest b/manifest index e76d28bd56..afa9295a67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sone\sdep\sfrom\s.tclenv.sh\swhich\sis\sonly\svalid\sfor\sconfigure-driven\sbuilds,\snot\sstatic\smakefiles. -D 2024-11-08T14:34:33.911 +C Fix\san\sassert()\sfailure\sin\ssqlite3recover.c. +D 2024-11-08T20:44:16.924 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -512,7 +512,7 @@ F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3 F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1ca7141334022a79f32e F ext/recover/recovercorrupt.test 64c081ad1200ae77b447da99eb724785d6bf71715f394543dc7689642e92bf49 -F ext/recover/recovercorrupt2.test 1418f1710debc24ff38276cedfcea234beb37a34205708e7e3e6d76cc4a979db +F ext/recover/recovercorrupt2.test 7347ccc9c36a925d99b56689c791423b45294834198f17575183fd500f52d85d F ext/recover/recovercorrupt3.test 2e7b9a1b528ca23ed382cec6f64e3fcbbd0f8e852add7562397fd8df83f335d5 F ext/recover/recovercorrupt4.test 3e2794145dad2517c018cb68b96f59d4d55b18b3d6271e1d37852cfd7a30b50c F ext/recover/recoverfault.test 9d9f88eeb222615a25e7514f234c950d46bee20d24cd8db49d8fff8d650dcfe1 @@ -522,7 +522,7 @@ F ext/recover/recoverpgsz.test 88766fcb810e52ee05335c456d4e5fb06d02b73d3ccb48c52 F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411 F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486 -F ext/recover/sqlite3recover.c e822ecbb05a04a5c85d1309765fcd6cf392d100d02d2227cd7720c9d6921a17a +F ext/recover/sqlite3recover.c 788438a6735108d14ca82cf39c59abf8cde2ee384b962fb93e975eb24f2732fe F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959 F ext/recover/test_recover.c 072260d7452a3b81aba995b2b3269e7ec2aa7f06725544ba4c25b1b0a1dbc61a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1bd9de719b0944fdceec32103da3131a7d387820850ab03f652f813d840355b8 -R 893eb86bb8e20c86cb402dee09f37203 -U stephan -Z 6964dc53af456b95e9c89bd288941f5a +P 22986767da8f086daaa6dc760c15e6aedcc5d2d6033937ac2f112ee5750d7fdb +R 6e0cc6db960e922136e512712813d155 +U dan +Z fa49496fb1b74fa0bc26b3e4367b5508 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 67f53fa9c0..f31c40453e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -22986767da8f086daaa6dc760c15e6aedcc5d2d6033937ac2f112ee5750d7fdb +f52bb19281b189508f5c31305cbd4a5651f3e036a4ee753c64488b0c7e5d2e4d From 4ddeccfc15ad88e93824a48d5c99a1d5f67289bf Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 8 Nov 2024 20:57:45 +0000 Subject: [PATCH 318/522] Increase the minimum SQLITE_LENGTH_LIMIT from 1 to 30 to avoid problems doing simple things like converting strings into integers. See also [8fd5b8ec4ab9b555]. FossilOrigin-Name: 6aa01707af4bd96f0f173f9e87f2398be7e6f246f59baa117092849a626b2d61 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/main.c | 4 ++-- src/sqliteLimit.h | 1 + test/sqllimits1.test | 7 +++++++ 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index afa9295a67..fbfc2dcb49 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sfailure\sin\ssqlite3recover.c. -D 2024-11-08T20:44:16.924 +C Increase\sthe\sminimum\sSQLITE_LENGTH_LIMIT\sfrom\s1\sto\s30\sto\savoid\sproblems\sdoing\nsimple\sthings\slike\sconverting\sstrings\sinto\sintegers.\s\sSee\salso\n[8fd5b8ec4ab9b555]. +D 2024-11-08T20:57:45.905 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -741,7 +741,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70 F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 -F src/main.c f6daba376adac080fe9287c6746fb15e12c7e47d022f2e9f2986ed364b7e0329 +F src/main.c 9f4286302727f58fddc03a820d24cb7618a1e27473501792fbe979726f846d1f F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 @@ -784,7 +784,7 @@ F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1 -F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 +F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153 @@ -1681,7 +1681,7 @@ F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb F test/sqldiff1.test 1b7ab4f312442c5cc6b3a5f299fa8ca051416d1dd173cb1126fd51bf64f2c3fb -F test/sqllimits1.test dee96a51b83ef866d06ec3c687d4c951d97b02549facc5be88c9dfcb215b98bf +F test/sqllimits1.test 7fa5027c2686e0a752f9a35616966eabfb9959ce041701b091932692c4bb6448 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/starschema1.test a84205f97fe278a015ac39546c86b97228d22043af28f3a2ef809e8d5637ce1d F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 22986767da8f086daaa6dc760c15e6aedcc5d2d6033937ac2f112ee5750d7fdb -R 6e0cc6db960e922136e512712813d155 -U dan -Z fa49496fb1b74fa0bc26b3e4367b5508 +P f52bb19281b189508f5c31305cbd4a5651f3e036a4ee753c64488b0c7e5d2e4d +R fbe7cd1f1cb69bd427dfee96434016cb +U drh +Z 0e7a084b0ad14438b0af8216e7c6c0bb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f31c40453e..a978933a64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f52bb19281b189508f5c31305cbd4a5651f3e036a4ee753c64488b0c7e5d2e4d +6aa01707af4bd96f0f173f9e87f2398be7e6f246f59baa117092849a626b2d61 diff --git a/src/main.c b/src/main.c index 2dbd8dce19..ff2a408d77 100644 --- a/src/main.c +++ b/src/main.c @@ -2925,8 +2925,8 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ if( newLimit>=0 ){ /* IMP: R-52476-28732 */ if( newLimit>aHardLimit[limitId] ){ newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ - }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){ - newLimit = 1; + }else if( newLimitaLimit[limitId] = newLimit; } diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index abf59e1b3a..c7185b1c52 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -23,6 +23,7 @@ #ifndef SQLITE_MAX_LENGTH # define SQLITE_MAX_LENGTH 1000000000 #endif +#define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */ /* ** This is the maximum number of diff --git a/test/sqllimits1.test b/test/sqllimits1.test index 14d39e6911..e6283e4e4a 100644 --- a/test/sqllimits1.test +++ b/test/sqllimits1.test @@ -75,6 +75,13 @@ do_test sqllimits1-1.23 { sqlite3_limit db SQLITE_LIMIT_TOOBIG 123 } {-1} +# Minimum value for SQLITE_LIMIT_LENGTH is 30 +# +do_test sqllimits1-1.30 { + sqlite3_limit db SQLITE_LIMIT_LENGTH 1 + sqlite3_limit db SQLITE_LIMIT_LENGTH 1000000000 +} 30 + # Decrease all limits by half. Verify that the new limits take. # From 497f84885bf7902e9a50aa754d115d6f4641b3d1 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 9 Nov 2024 06:35:09 +0000 Subject: [PATCH 319/522] Remove an unused lib import from auto.def. FossilOrigin-Name: 53a71981abf5aaca01e86ff87c3779d7dcc6661c80e1f2bf74515f49993b6a0d --- auto.def | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index dee555828b..5807c97bb9 100644 --- a/auto.def +++ b/auto.def @@ -12,7 +12,7 @@ # # JimTCL: https://jim.tcl.tk # -use cc cc-db cc-shared cc-lib proj pkg-config +use cc cc-db cc-shared cc-lib proj # $DUMP_DEFINES_TXT is the file emitted by --dump-defines, intended # only for build debugging and not part of the public build interface. diff --git a/manifest b/manifest index fbfc2dcb49..deff1e8144 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sminimum\sSQLITE_LENGTH_LIMIT\sfrom\s1\sto\s30\sto\savoid\sproblems\sdoing\nsimple\sthings\slike\sconverting\sstrings\sinto\sintegers.\s\sSee\salso\n[8fd5b8ec4ab9b555]. -D 2024-11-08T20:57:45.905 +C Remove\san\sunused\slib\simport\sfrom\sauto.def. +D 2024-11-09T06:35:09.223 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def b00e0676f9182d880a09b9f4941452324d836b7f9bfef72a98031df091be3b94 +F auto.def a492afaded87fafe42d8918feea2ecab350255f67ad10aabfde1d24ba4b3abd9 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f52bb19281b189508f5c31305cbd4a5651f3e036a4ee753c64488b0c7e5d2e4d -R fbe7cd1f1cb69bd427dfee96434016cb -U drh -Z 0e7a084b0ad14438b0af8216e7c6c0bb +P 6aa01707af4bd96f0f173f9e87f2398be7e6f246f59baa117092849a626b2d61 +R f82809283533c2d2df4dff56889b1896 +U stephan +Z 931530be01836132512787f4705bb638 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a978933a64..009a41a9d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6aa01707af4bd96f0f173f9e87f2398be7e6f246f59baa117092849a626b2d61 +53a71981abf5aaca01e86ff87c3779d7dcc6661c80e1f2bf74515f49993b6a0d From 5c792a484db9abc3a6879225f0dd1a59d4a28021 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 9 Nov 2024 09:19:29 +0000 Subject: [PATCH 320/522] Remove three unused files from autosetup/. FossilOrigin-Name: 906563a7e07fca81effb31a77ee5d7cdacd4cc6157e16e1139da70c92716869a --- autosetup/default.auto | 25 --------------- autosetup/tmake.auto | 73 ------------------------------------------ autosetup/tmake.tcl | 52 ------------------------------ manifest | 13 +++----- manifest.uuid | 2 +- 5 files changed, 6 insertions(+), 159 deletions(-) delete mode 100644 autosetup/default.auto delete mode 100644 autosetup/tmake.auto delete mode 100644 autosetup/tmake.tcl diff --git a/autosetup/default.auto b/autosetup/default.auto deleted file mode 100644 index b36e0f8dc9..0000000000 --- a/autosetup/default.auto +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2012 WorkWare Systems http://www.workware.net.au/ -# All rights reserved - -# Auto-load module for 'make' build system integration - -use init - -autosetup_add_init_type make {Simple "make" build system} { - autosetup_check_create auto.def \ -{# Initial auto.def created by 'autosetup --init=make' - -use cc - -# Add any user options here -options { -} - -make-config-header config.h -make-template Makefile.in -} - - if {![file exists Makefile.in]} { - puts "Note: I don't see Makefile.in. You will probably need to create one." - } -} diff --git a/autosetup/tmake.auto b/autosetup/tmake.auto deleted file mode 100644 index 448d317229..0000000000 --- a/autosetup/tmake.auto +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 2016 WorkWare Systems http://www.workware.net.au/ -# All rights reserved - -# Auto-load module for 'tmake' build system integration - -use init - -autosetup_add_init_type tmake "Tcl-based tmake build system" { - autosetup_check_create auto.def \ -{# Initial auto.def created by 'autosetup --init=tmake' -# vim:set syntax=tcl: - -use cc cc-lib cc-db cc-shared -use tmake - -# Add any user options here -# Really want a --configure that takes over the rest of the command line -options { -} - -cc-check-tools ar ranlib - -set objdir [get-env BUILDDIR objdir] - -make-config-header $objdir/include/autoconf.h -make-tmake-settings $objdir/settings.conf {[A-Z]*} *dir lib_* -} - - autosetup_check_create project.spec \ -{# Initial project.spec created by 'autosetup --init=tmake' - -tmake-require-version 0.7.3 - -# vim:set syntax=tcl: -define? DESTDIR _install - -# XXX If configure creates additional/different files than include/autoconf.h -# that should be reflected here -Autosetup include/autoconf.h - -# e.g. for autoconf.h -IncludePaths include - -ifconfig !CONFIGURED { - # Not configured, so don't process subdirs - AutoSubDirs off - # And don't process this file any further - ifconfig false -} -} - - set configure [readfile configure] - # XXX Do we need also need to support a system install of tmake? - if {[string first {#@TMAKEUPDATED@} $configure] < 0} { - if {[regsub {#@@INITCHECK@@#} $configure \ - {test -z "$TMAKE" -a -x "$dir/tmake" \&\& exec "$dir/tmake" --force --configure "$@"; #@TMAKEUPDATED@} configure]} { - writefile configure $configure\n - exec chmod +x configure - puts "Updated configure to invoke local tmake." - if {![file exec autosetup/tmake]} { - puts "Warning: autosetup/tmake is missing." - puts " Install it with: tmake --install=autosetup" - } - } else { - puts "Warning: configure isn't created by a recent autosetup, not updating." - } - } else { - puts "I see configure for tmake already exists." - } - if {![file exists build.spec]} { - puts "Note: I don't see build.spec. Try running: tmake --genie" - } -} diff --git a/autosetup/tmake.tcl b/autosetup/tmake.tcl deleted file mode 100644 index 3269193aa7..0000000000 --- a/autosetup/tmake.tcl +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/ -# All rights reserved - -# @synopsis: -# -# The 'tmake' module makes it easy to support the tmake build system. -# -# The following variables are set: -# -## CONFIGURED - to indicate that the project is configured - -use system - -options {} - -define CONFIGURED - -# @make-tmake-settings outfile patterns ... -# -# Examines all defined variables which match the given patterns (defaults to '*') -# and writes a tmake-compatible .conf file defining those variables. -# For example, if 'ABC' is '"3 monkeys"' and 'ABC' matches a pattern, then the file will include: -# -## define ABC {3 monkeys} -# -# If the file would be unchanged, it is not written. -# -# Typical usage is: -# -## make-tmake-settings [get-env BUILDDIR objdir]/settings.conf {[A-Z]*} -proc make-tmake-settings {file args} { - file mkdir [file dirname $file] - set lines {} - - if {[llength $args] == 0} { - set args * - } - - foreach n [lsort [dict keys [all-defines]]] { - foreach p $args { - if {[string match $p $n]} { - set value [get-define $n] - lappend lines "define $n [list $value]" - break - } - } - } - set buf [join $lines \n] - write-if-changed $file $buf { - msg-result "Created $file" - } -} diff --git a/manifest b/manifest index deff1e8144..309633a1ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\slib\simport\sfrom\sauto.def. -D 2024-11-09T06:35:09.223 +C Remove\sthree\sunused\sfiles\sfrom\sautosetup/. +D 2024-11-09T09:19:29.627 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -47,13 +47,10 @@ F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034 F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360 F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f -F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba F autosetup/proj.tcl 93e1d99ffa8a75fe2f488605c4d36cb57a75f1500bccc5c5954ae45eb7da89d7 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 -F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f -F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -2201,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6aa01707af4bd96f0f173f9e87f2398be7e6f246f59baa117092849a626b2d61 -R f82809283533c2d2df4dff56889b1896 +P 53a71981abf5aaca01e86ff87c3779d7dcc6661c80e1f2bf74515f49993b6a0d +R 7277c238d4f5631fe2de582f05e930b6 U stephan -Z 931530be01836132512787f4705bb638 +Z 343d6685aa510740ee80b7b0b05658f8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 009a41a9d5..d17fb6237b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53a71981abf5aaca01e86ff87c3779d7dcc6661c80e1f2bf74515f49993b6a0d +906563a7e07fca81effb31a77ee5d7cdacd4cc6157e16e1139da70c92716869a From e9b04e524bb7e6768de8f3e6b390ec659733ab99 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 9 Nov 2024 10:23:04 +0000 Subject: [PATCH 321/522] Simplify usage of proj-assert by making the expr prefix implicit. Add an optional description arg to proj-assert, defaulting to the body of the assertion script. FossilOrigin-Name: ada7b36c37c59ea02e54462b0eb8b93ff6ab45863edfd67b19f1e1a7bb2f97de --- auto.def | 10 +++++----- autosetup/proj.tcl | 19 +++++++++++++------ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/auto.def b/auto.def index 5807c97bb9..b395e66ebe 100644 --- a/auto.def +++ b/auto.def @@ -543,7 +543,7 @@ proc sqlite-check-tcl {} { # TODO: document the steps this is taking. global srcdir msg-result "Checking for a suitable tcl... " - proj-assert {proj-opt-truthy tcl} + proj-assert [proj-opt-truthy tcl] set use_tcl 1 set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] @@ -635,7 +635,7 @@ proc sqlite-check-tcl {} { if {"" eq $with_tclsh && $cfg ne ""} { # We have tclConfig.sh but no tclsh. Attempt to locate a tclsh # based on info from tclConfig.sh. - proj-assert {expr {"" ne [get-define TCL_EXEC_PREFIX]}} + proj-assert {"" ne [get-define TCL_EXEC_PREFIX]} set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] if {![file-isexec $with_tclsh]} { set with_tclsh2 [get-define TCL_EXEC_PREFIX]/bin/tclsh @@ -691,7 +691,7 @@ proc sqlite-check-tcl {} { proj-fatal "TCL support was requested but no tclConfig.sh could be found." } if {"" eq $cfg} { - proj-assert {expr {0 == [get-define HAVE_TCL]}} + proj-assert {0 == [get-define HAVE_TCL]} proj-indented-notice { WARNING: Cannot find a usable tclConfig.sh file. Use --with-tcl=DIR to specify a directory where tclConfig.sh can be @@ -1042,8 +1042,8 @@ proc sqlite-check-line-editing {} { set rlInc [join $rlInc] define LDFLAGS_READLINE $rlLib define CFLAGS_READLINE $rlInc - proj-assert {expr {$editLibDef in {HAVE_READLINE HAVE_EDITLINE}}} - proj-assert {expr {$editLibName in {readline editline}}} + proj-assert {$editLibDef in {HAVE_READLINE HAVE_EDITLINE}} + proj-assert {$editLibName in {readline editline}} sqlite-add-shell-opt -D${editLibDef}=1 msg-result "Using $editLibName flags: $rlInc $rlLib" # Check whether rl_completion_matches() has a signature we can use diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 495352e5a9..450f9b4d2f 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -77,14 +77,21 @@ proc proj-fatal {msg} { ######################################################################## # @proj-assert script # -# Kind of like a C assert if uplevel (eval) of $script is false, -# triggers a fatal error. -proc proj-assert {script} { +# Kind of like a C assert: if uplevel (eval) of [expr {$script}] is +# false, a fatal error is triggered. The error message, by default, +# includes the body of the failed assertion, but if $descr is set then +# that is used instead. +proc proj-assert {script {descr ""}} { if {1 == [get-env proj-assert 0]} { - msg-result [proj-bold "asserting: [string trim $script]"] + msg-result [proj-bold "asserting: $script"] } - if {![uplevel 1 $script]} { - proj-fatal "Assertion failed: $script" + set x {expr } + append x \{ $script \} + if {![uplevel 1 $x]} { + if {"" eq $descr} { + set descr $script + } + proj-fatal "Assertion failed: $descr" } } diff --git a/manifest b/manifest index 309633a1ab..d36672438a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthree\sunused\sfiles\sfrom\sautosetup/. -D 2024-11-09T09:19:29.627 +C Simplify\susage\sof\sproj-assert\sby\smaking\sthe\sexpr\sprefix\simplicit.\sAdd\san\soptional\sdescription\sarg\sto\sproj-assert,\sdefaulting\sto\sthe\sbody\sof\sthe\sassertion\sscript. +D 2024-11-09T10:23:04.469 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a492afaded87fafe42d8918feea2ecab350255f67ad10aabfde1d24ba4b3abd9 +F auto.def 79e9b88684035320ba6cba53c1d6117320ff9cb937286179d0408fb69716e482 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 93e1d99ffa8a75fe2f488605c4d36cb57a75f1500bccc5c5954ae45eb7da89d7 +F autosetup/proj.tcl 6b7939cc1afbef71327c684999278b0a0f71e9c6ad39b7a27b3e79101a0c67de F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 53a71981abf5aaca01e86ff87c3779d7dcc6661c80e1f2bf74515f49993b6a0d -R 7277c238d4f5631fe2de582f05e930b6 +P 906563a7e07fca81effb31a77ee5d7cdacd4cc6157e16e1139da70c92716869a +R 80ec48dbf7e84a814515b0c1aedd20af U stephan -Z 343d6685aa510740ee80b7b0b05658f8 +Z 18ce4bb625331a3aaef20d9b98a0b830 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d17fb6237b..5e89fd1d2c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -906563a7e07fca81effb31a77ee5d7cdacd4cc6157e16e1139da70c92716869a +ada7b36c37c59ea02e54462b0eb8b93ff6ab45863edfd67b19f1e1a7bb2f97de From f1b88ec9539b6135754adeff130715f92e97de53 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 9 Nov 2024 14:34:20 +0000 Subject: [PATCH 322/522] Fix a deps problem, introduced in [1bd9de719], which breaks the build on systems where HAVE_TCL=0. FossilOrigin-Name: 7953a8bdcba7242c98f786283270d7b3f8830058a29f2d810457eef697855325 --- main.mk | 16 ++++++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/main.mk b/main.mk index e4dcbc2a28..21dd01cfde 100644 --- a/main.mk +++ b/main.mk @@ -981,8 +981,8 @@ T.tcl.env.sh = ./.tclenv.sh $(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST) @if [ x = "x$(TCL_CONFIG_SH)" ]; then \ echo 'TCL_CONFIG_SH must be set to point to a "tclConfig.sh"' 1>&2; exit 1; \ - fi - @if [ x != "x$(TCLLIBDIR)" ]; then echo TCLLIBDIR="$(TCLLIBDIR)"; else \ + fi; \ + if [ x != "x$(TCLLIBDIR)" ]; then echo TCLLIBDIR="$(TCLLIBDIR)"; else \ ld= ; \ for d in `echo "puts stdout \\$$auto_path" | $(TCLSH_CMD)`; do \ if [ -d "$$d" ]; then ld=$$d; break; fi; \ @@ -990,8 +990,8 @@ $(T.tcl.env.sh): $(TCLSH_CMD) $(TCL_CONFIG_SH) $(MAKEFILE_LIST) if [ x = "x$$ld" ]; then echo "Cannot determine TCLLIBDIR" 1>&2; exit 1; fi; \ echo "TCLLIBDIR=$$ld/sqlite3"; \ fi > $@; \ - echo ". \"$(TCL_CONFIG_SH)\" || exit \$$?" >> $@ - @echo "Created $@" + echo ". \"$(TCL_CONFIG_SH)\" || exit \$$?" >> $@; \ + echo "Created $@" # # $(T.tcl.env.source) is shell code to be run as part of any @@ -1335,7 +1335,9 @@ tclsqlite-stubs.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) tclsqlite3$(T.exe): $(T.tcl.env.sh) tclsqlite-shell.o $(libsqlite3.SO) $(T.link.tcl) -o $@ tclsqlite-shell.o \ $(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) -tcl: tclsqlite3$(T.exe) +tclsqlite3$(T.exe)-1: tclsqlite3$(T.exe) +tclsqlite3$(T.exe)-0 tclsqlite3$(T.exe)-: +tcl: tclsqlite3$(T.exe)-$(HAVE_TCL) # Rules to build opcodes.c and opcodes.h # @@ -1478,7 +1480,9 @@ install: install-headers # pkgIndex.tcl: echo 'package ifneeded sqlite3 $(PACKAGE_VERSION) [list load [file join $$dir libtclsqlite3[info sharedlibextension]] sqlite3]' > $@ -tcl: pkgIndex.tcl +pkgIndex.tcl-1: pkgIndex.tcl +pkgIndex.tcl-0 pkgIndex.tcl-: +tcl: pkgIndex.tcl-$(HAVE_TCL) libtclsqlite3.SO = libtclsqlite3$(T.dll) $(libtclsqlite3.SO): $(T.tcl.env.sh) tclsqlite.o $(LIBOBJ) $(T.tcl.env.source); \ diff --git a/manifest b/manifest index d36672438a..b458d79dd1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\susage\sof\sproj-assert\sby\smaking\sthe\sexpr\sprefix\simplicit.\sAdd\san\soptional\sdescription\sarg\sto\sproj-assert,\sdefaulting\sto\sthe\sbody\sof\sthe\sassertion\sscript. -D 2024-11-09T10:23:04.469 +C Fix\sa\sdeps\sproblem,\sintroduced\sin\s[1bd9de719],\swhich\sbreaks\sthe\sbuild\son\ssystems\swhere\sHAVE_TCL=0. +D 2024-11-09T14:34:20.060 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk af87776a921824639555d040d7a917de0f295b3dfa70079105b4fb42fdf425c3 +F main.mk efb8f627c5793126ff7a86d698676f4e6509a296b0b113ec284e6f723561f0bc F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 906563a7e07fca81effb31a77ee5d7cdacd4cc6157e16e1139da70c92716869a -R 80ec48dbf7e84a814515b0c1aedd20af +P ada7b36c37c59ea02e54462b0eb8b93ff6ab45863edfd67b19f1e1a7bb2f97de +R bf8863b8add1d028b446d64a9e7551d4 U stephan -Z 18ce4bb625331a3aaef20d9b98a0b830 +Z 22d08ab5c31638260d1b0957cd0fc1f8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5e89fd1d2c..13fe96534d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ada7b36c37c59ea02e54462b0eb8b93ff6ab45863edfd67b19f1e1a7bb2f97de +7953a8bdcba7242c98f786283270d7b3f8830058a29f2d810457eef697855325 From a864ac1c5a11fcc7cfb980dc565ec66c9b63445d Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 9 Nov 2024 17:54:51 +0000 Subject: [PATCH 323/522] Fix a case in fts3 where a corrupt database record was not being handled correctly. FossilOrigin-Name: cbcb53759b9510379e2159d14b73c9746e611df550b0bd05887bd4a480b519a8 --- ext/fts3/fts3.c | 5 +++ manifest | 16 ++++----- manifest.uuid | 2 +- test/fts3corrupt7.test | 75 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 9 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index e2174e6e3d..e58f256a48 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -2344,10 +2344,15 @@ static int fts3PoslistPhraseMerge( if( *p1==POS_COLUMN ){ p1++; p1 += fts3GetVarint32(p1, &iCol1); + /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN + ** entry, so this is actually end-of-doclist. */ + if( iCol1==0 ) return 0; } if( *p2==POS_COLUMN ){ p2++; p2 += fts3GetVarint32(p2, &iCol2); + /* As above, iCol2==0 indicates corruption. */ + if( iCol2==0 ) return 0; } while( 1 ){ diff --git a/manifest b/manifest index b458d79dd1..7523e7ff64 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sdeps\sproblem,\sintroduced\sin\s[1bd9de719],\swhich\sbreaks\sthe\sbuild\son\ssystems\swhere\sHAVE_TCL=0. -D 2024-11-09T14:34:20.060 +C Fix\sa\scase\sin\sfts3\swhere\sa\scorrupt\sdatabase\srecord\swas\snot\sbeing\shandled\scorrectly. +D 2024-11-09T17:54:51.146 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -76,7 +76,7 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 070d6fec098d49d9b9572c6cd07fd7b82b8b33bf301514638f72dac8ad5a71ce +F ext/fts3/fts3.c 9f8ce82bbf4ec0636e6170e58f17b04817fa4c39b2d5126ac06f005d485f6d5e F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682 F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 @@ -1189,7 +1189,7 @@ F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cd F test/fts3corrupt4.test c7f414fe29b97a478d15c90382c4ae077a2bbd2283bf8c63bf66dadaaed3edb8 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525 -F test/fts3corrupt7.test ad11123257c9ee70b704c4534095e7c3032dd25ad78d5324f54b0b05970cdbec +F test/fts3corrupt7.test 1da31776e24bb91d3c028e663456b61280b121a74496ccf2fef3fe33790ad2b0 F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ada7b36c37c59ea02e54462b0eb8b93ff6ab45863edfd67b19f1e1a7bb2f97de -R bf8863b8add1d028b446d64a9e7551d4 -U stephan -Z 22d08ab5c31638260d1b0957cd0fc1f8 +P 7953a8bdcba7242c98f786283270d7b3f8830058a29f2d810457eef697855325 +R dc6de33b7db28edd8329e8f40b308bbe +U dan +Z 426b1d51434e7f07ff383bb0a9b3ae87 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 13fe96534d..675d0be210 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7953a8bdcba7242c98f786283270d7b3f8830058a29f2d810457eef697855325 +cbcb53759b9510379e2159d14b73c9746e611df550b0bd05887bd4a480b519a8 diff --git a/test/fts3corrupt7.test b/test/fts3corrupt7.test index 2634047642..6cf9c9a9dc 100644 --- a/test/fts3corrupt7.test +++ b/test/fts3corrupt7.test @@ -202,4 +202,79 @@ do_catchsql_test 1.1 { SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'rtree NEAR rtree NEAR "json1 enable"'; } {0 {}} +#------------------------------------------------------------------------- +reset_db +do_test 1.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 24576 pagesize 4096 filename crash-10b0f1037e9c85.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 00 00 00 40 20 20 00 00 00 01 00 00 00 07 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................ +| 96: 00 2e 82 40 0d 00 00 00 06 00 00 00 0f 8d 0f 21 ...@...........! +| 112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00 .....~.......... +| 3488: 00 00 00 00 21 ff 06 17 10 10 01 30 74 61 62 6c ....!......0tabl +| 3504: 65 74 32 74 32 00 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB +| 3520: 4c 45 20 74 32 28 70 29 81 33 00 07 17 1f 1f 01 LE t2(p).3...... +| 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72 .5tablet1_segdir +| 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE +| 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi +| 3584: 72 27 28 6c 65 76 65 6c 20 09 4e 50 45 47 45 50 r'(level .NPEGEP +| 3600: 2c 69 64 78 20 09 4e 50 45 47 45 50 2c 73 74 61 ,idx .NPEGEP,sta +| 3616: 72 74 5f 62 6c 6f 63 6b 20 09 4e 50 45 47 45 50 rt_block .NPEGEP +| 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc +| 3648: 6b 20 09 4e 50 45 47 45 50 2c 65 6e 64 5f 62 6c k .NPEGEP,end_bl +| 3664: 6f 63 6b 20 09 4e 50 45 47 45 50 2c 72 6f 6f 74 ock .NPEGEP,root +| 3680: 20 42 0c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 B.OB,PRIMARY KE +| 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 00 Y(level, idx))1. +| 3712: 06 17 45 1f 01 00 00 00 00 00 00 73 71 6c 69 74 ..E........sqlit +| 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s +| 3744: 65 67 64 69 72 5f 31 00 00 00 00 00 00 00 00 00 egdir_1......... +| 3760: 06 00 00 00 00 00 00 00 00 66 00 07 17 23 23 01 .........f...##. +| 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen +| 3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 00 43 52 tst1_segments.CR +| 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s +| 3824: 65 67 6d 65 6e 74 73 27 28 0c 6f 63 6b 09 64 0a egments'(.ock.d. +| 3840: 20 09 4e 50 45 47 45 50 20 50 50 09 04 31 50 09 .NPEGEP PP..1P. +| 3856: 20 0b 45 09 0c 20 62 0c 6f 63 6b 20 42 0c 4f 42 .E.. b.ock B.OB +| 3872: 29 6a 00 07 17 20 20 01 81 1f 74 61 62 6c 65 74 )j... ...tablet +| 3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont +| 3904: 65 6e 74 00 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE +| 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do +| 3936: 09 64 20 09 4e 50 45 47 45 50 20 50 50 09 0d 0c .d .NPEGEP PP... +| 3952: 50 09 20 0b 45 09 0c 20 27 03 03 01 27 0c 20 0a P. .E.. '...'. . +| 3968: 27 03 01 02 27 0c 20 27 03 02 03 27 29 38 00 06 '...'. '...')8.. +| 3984: 17 10 10 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33 LE t1 USING fts3 +| page 5 offset 16384 +| 0: 0d 00 00 00 02 00 00 00 00 00 0b a0 00 00 00 00 ................ +| 2976: 82 0a 02 08 00 00 00 00 17 84 06 00 00 00 00 00 ................ +| 2992: 00 01 00 04 00 00 00 00 00 08 00 00 00 00 00 00 ................ +| 3008: 00 00 03 00 00 00 00 01 00 03 00 00 00 00 01 00 ................ +| 3024: 03 00 00 00 00 07 00 00 00 00 00 00 00 03 00 00 ................ +| 3040: 00 00 08 00 00 00 00 00 00 00 00 03 00 00 00 00 ................ +| 3056: 06 00 00 00 00 00 00 03 00 00 00 00 04 00 00 00 ................ +| 3072: 00 03 00 00 00 00 06 65 6e 61 62 6c 65 09 25 09 .......enable.%. +| 3088: 05 04 04 04 04 00 00 00 08 00 00 00 00 00 00 00 ................ +| 3104: 00 03 00 00 00 00 04 00 00 00 00 03 00 00 00 00 ................ +| 3120: 01 00 03 00 00 00 00 03 00 00 00 03 00 00 00 00 ................ +| 3136: 06 00 00 00 00 00 00 03 00 00 00 00 05 6a 73 6f .............jso +| 3152: 6e 31 03 25 13 00 00 04 00 00 00 00 03 00 00 00 n1.%............ +| 3168: 00 03 00 00 00 03 00 00 00 00 05 00 00 00 00 00 ................ +| 3184: 03 00 00 00 00 04 00 00 00 00 03 00 00 00 00 04 ................ +| 3200: 00 00 00 00 03 00 00 00 00 05 72 74 72 65 65 03 ..........rtree. +| 3216: 25 01 00 0d 0a 07 08 01 ff ff ff ff ff 01 00 00 %............... +| page 6 offset 20480 +| 0: 0a 00 00 00 02 00 00 00 0f fb 0f f5 00 00 00 00 ................ +| 4080: 00 00 00 00 00 05 04 09 00 01 02 04 00 00 00 00 ................ +| end crash-10b0f1037e9c85.db +}]} {} + +do_catchsql_test 2.1 { + SELECT 0 FROM t1 WHERE t1 MATCH 'rtree NEAR rtree"json1 enable"'; +} {1 {database disk image is malformed}} + finish_test From 45c2b1804f8288eab469efec7f94e3731731bdb7 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 11 Nov 2024 09:37:19 +0000 Subject: [PATCH 324/522] Rename proj-define-if-opt-truthy to the more accurate, and less verbose, proj-define-for-opt. FossilOrigin-Name: 05073350087b368312515134bdf9a266eb8289a065f208421fe08aa38b562d4b --- auto.def | 12 ++++++------ autosetup/proj.tcl | 4 ++-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/auto.def b/auto.def index b395e66ebe..eda38ec497 100644 --- a/auto.def +++ b/auto.def @@ -469,21 +469,21 @@ proc sqlite-check-soname {} { } sqlite-check-soname -proj-define-if-opt-truthy shared ENABLE_SHARED "Build shared library?" +proj-define-for-opt shared ENABLE_SHARED "Build shared library?" -if {![proj-define-if-opt-truthy static ENABLE_STATIC \ +if {![proj-define-for-opt static ENABLE_STATIC \ "Build static library?"]} { proj-warn "Static lib build may be implicitly re-activated by other components, e.g. some test apps." } -proj-define-if-opt-truthy amalgamation USE_AMALGAMATION "Use amalgamation for builds?" +proj-define-for-opt amalgamation USE_AMALGAMATION "Use amalgamation for builds?" -proj-define-if-opt-truthy gcov USE_GCOV "Use gcov?" +proj-define-for-opt gcov USE_GCOV "Use gcov?" -proj-define-if-opt-truthy test-status TSTRNNR_OPTS \ +proj-define-for-opt test-status TSTRNNR_OPTS \ "test-runner flags:" {--status} {} -proj-define-if-opt-truthy linemacros AMALGAMATION_LINE_MACROS \ +proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \ "Use #line macros in the amalgamation:" msg-checking "SQLITE_DEBUG build? " diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 450f9b4d2f..136d4b0360 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -393,13 +393,13 @@ proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} { } ######################################################################## -# @proj-define-if-opt-truthy flag def ?msg? ?iftrue? ?iffalse? +# @proj-define-for-opt flag def ?msg? ?iftrue? ?iffalse? # # If [proj-opt-truthy $flag] then [define $def $iftrue] else [define # $def $iffalse]. If $msg is not empty, output [msg-checking $msg] and # a [msg-results ...] which corresponds to the result. Returns 1 if # the opt-truthy check passes, else 0. -proc proj-define-if-opt-truthy {flag def {msg ""} {iftrue 1} {iffalse 0}} { +proc proj-define-for-opt {flag def {msg ""} {iftrue 1} {iffalse 0}} { if {"" ne $msg} { msg-checking "$msg " } diff --git a/manifest b/manifest index 7523e7ff64..5721be1b38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scase\sin\sfts3\swhere\sa\scorrupt\sdatabase\srecord\swas\snot\sbeing\shandled\scorrectly. -D 2024-11-09T17:54:51.146 +C Rename\sproj-define-if-opt-truthy\sto\sthe\smore\saccurate,\sand\sless\sverbose,\sproj-define-for-opt. +D 2024-11-11T09:37:19.361 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 79e9b88684035320ba6cba53c1d6117320ff9cb937286179d0408fb69716e482 +F auto.def dd7d48438426327c37f51f8e289492058744656e2da03197c31e4fb76398050c F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 6b7939cc1afbef71327c684999278b0a0f71e9c6ad39b7a27b3e79101a0c67de +F autosetup/proj.tcl 9772d3f89634089add92e2238551a59a5c764d501327f6eb433dca7f98138802 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7953a8bdcba7242c98f786283270d7b3f8830058a29f2d810457eef697855325 -R dc6de33b7db28edd8329e8f40b308bbe -U dan -Z 426b1d51434e7f07ff383bb0a9b3ae87 +P cbcb53759b9510379e2159d14b73c9746e611df550b0bd05887bd4a480b519a8 +R 21d3e08c91a6853936b86b0f2f4dc906 +U stephan +Z b492bf4b216d126b978d56037a0f80c3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 675d0be210..4a9d6e3b57 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cbcb53759b9510379e2159d14b73c9746e611df550b0bd05887bd4a480b519a8 +05073350087b368312515134bdf9a266eb8289a065f208421fe08aa38b562d4b From d29a369fe29cec9f0007d4498218acce4722968f Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 11 Nov 2024 09:53:40 +0000 Subject: [PATCH 325/522] Doc update to account for [05073350087b]. FossilOrigin-Name: b81976c520fbad0bbdbbb877fe85691bcda25c12cf5597cfe224fb6306cd65b3 --- autosetup/README.md | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index 1385f664fc..91bcad3d76 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -69,7 +69,7 @@ In (mostly) alphabetical order: trimmed contents. This can be used, e.g., to set a developer's local preferences for the default `CFLAGS`. -- **`proj-define-if-opt-truthy flag defineName ?checkingMsg? ?yesVal=1? ?noVal=0?`**\ +- **`define-for-opt flag defineName ?checkingMsg? ?yesVal=1? ?noVal=0?`**\ `[define $defineName]` to either `$yesVal` or `$noVal`, depending on whether `--$flag` is truthy or not. `$checkingMsg` is a human-readable description of the check being made, e.g. "enable foo diff --git a/manifest b/manifest index 5721be1b38..97cc598ec6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sproj-define-if-opt-truthy\sto\sthe\smore\saccurate,\sand\sless\sverbose,\sproj-define-for-opt. -D 2024-11-11T09:37:19.361 +C Doc\supdate\sto\saccount\sfor\s[05073350087b]. +D 2024-11-11T09:53:40.171 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 839e78a356545cbf81c2924566db72508c7e92e8c0ef35a8520dd8f49743383b +F autosetup/README.md f12fd1556b50ff33ebf5c1476f4640c6010b3093ba8d75ba12b5417884011d5e F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cbcb53759b9510379e2159d14b73c9746e611df550b0bd05887bd4a480b519a8 -R 21d3e08c91a6853936b86b0f2f4dc906 +P 05073350087b368312515134bdf9a266eb8289a065f208421fe08aa38b562d4b +R 3e7bc73740255e6a3248a16815c573a3 U stephan -Z b492bf4b216d126b978d56037a0f80c3 +Z 9ae48f5cefd523f44e5eeeffcff1033d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4a9d6e3b57..8f6b05ac06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -05073350087b368312515134bdf9a266eb8289a065f208421fe08aa38b562d4b +b81976c520fbad0bbdbbb877fe85691bcda25c12cf5597cfe224fb6306cd65b3 From e4d4d73397f46f9803ba222a7237d56f2d73bb2c Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Nov 2024 17:02:29 +0000 Subject: [PATCH 326/522] Use Win32 APIs to read/write the console in Windows unless the SQLITE_USE_STDIO_FOR_CONSOLE option is defined. This is an attempt to get the build working on MinGW. FossilOrigin-Name: abfe488ed67e2e3510c230e656ecf203afa549ebd1d1872442f1fadc97d0817e --- ext/misc/sqlite3_stdio.c | 47 ++++++++++++++++++++++++++++++---------- manifest | 14 ++++++------ manifest.uuid | 2 +- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/ext/misc/sqlite3_stdio.c b/ext/misc/sqlite3_stdio.c index 729504629b..97c3551da2 100644 --- a/ext/misc/sqlite3_stdio.c +++ b/ext/misc/sqlite3_stdio.c @@ -148,10 +148,20 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){ */ wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) ); if( b1==0 ) return 0; - _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); - if( fgetws(b1, sz/4, in)==0 ){ - sqlite3_free(b1); - return 0; +#ifndef SQLITE_USE_STDIO_FOR_CONSOLE + DWORD nRead = 0; + if( IsConsole(in) + && ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz, &nRead, 0) + ){ + b1[nRead] = 0; + }else +#endif + { + _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); + if( fgetws(b1, sz/4, in)==0 ){ + sqlite3_free(b1); + return 0; + } } WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0); sqlite3_free(b1); @@ -207,20 +217,33 @@ int sqlite3_fputs(const char *z, FILE *out){ ** any translation. */ return fputs(z, out); }else{ - /* When writing to the command-prompt in Windows, it is necessary - ** to use O_U8TEXT to render Unicode U+0080 and greater. Go ahead - ** use O_U8TEXT for everything in text mode. + /* One must use UTF16 in order to get unicode support when writing + ** to the console on Windows. */ int sz = (int)strlen(z); wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) ); if( b1==0 ) return 0; sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); b1[sz] = 0; - _setmode(_fileno(out), _O_U8TEXT); - if( UseBinaryWText(out) ){ - piecemealOutput(b1, sz, out); - }else{ - fputws(b1, out); + +#ifndef SQLITE_STDIO_FOR_CONSOLE + DWORD nWr = 0; + if( IsConsole(out) + && WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0) + ){ + /* If writing to the console, then the WriteConsoleW() is all we + ** need to do. */ + }else +#endif + { + /* For non-console I/O, or if SQLITE_USE_STDIO_FOR_CONSOLE is defined + ** then write using the standard library. */ + _setmode(_fileno(out), _O_U8TEXT); + if( UseBinaryWText(out) ){ + piecemealOutput(b1, sz, out); + }else{ + fputws(b1, out); + } } sqlite3_free(b1); return 0; diff --git a/manifest b/manifest index 97cc598ec6..c3003f93ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Doc\supdate\sto\saccount\sfor\s[05073350087b]. -D 2024-11-11T09:53:40.171 +C Use\sWin32\sAPIs\sto\sread/write\sthe\sconsole\sin\sWindows\sunless\sthe\nSQLITE_USE_STDIO_FOR_CONSOLE\soption\sis\sdefined.\s\sThis\sis\san\sattempt\sto\sget\nthe\sbuild\sworking\son\sMinGW. +D 2024-11-11T17:02:29.626 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -438,7 +438,7 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 -F ext/misc/sqlite3_stdio.c c34b4aba8aec6c1ca7058a7a6319a37ab629135091600aee202390a8cd20e842 +F ext/misc/sqlite3_stdio.c 5657afb6ec81bef31790973528980af778e0e1388a93db780d33007336efe6e6 F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 05073350087b368312515134bdf9a266eb8289a065f208421fe08aa38b562d4b -R 3e7bc73740255e6a3248a16815c573a3 -U stephan -Z 9ae48f5cefd523f44e5eeeffcff1033d +P b81976c520fbad0bbdbbb877fe85691bcda25c12cf5597cfe224fb6306cd65b3 +R 7eaee2fd29a0a62fa15ab30f7e1400c5 +U drh +Z f4fb9c4d51373a0a4c48f856c51e2978 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8f6b05ac06..663b7cfc67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b81976c520fbad0bbdbbb877fe85691bcda25c12cf5597cfe224fb6306cd65b3 +abfe488ed67e2e3510c230e656ecf203afa549ebd1d1872442f1fadc97d0817e From 074cad302637e991ef4f024303bed87340897b86 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 11 Nov 2024 18:15:50 +0000 Subject: [PATCH 327/522] Wrap some exceptionally long lines in main.mk. Add option to override LDFLAGS on the sqlite3.dll target. Audit: all targets for which it is hypothetically relevant can now inherit user-supplied LDFLAGS, but only those provided to the configure script, not at make-time, in order to mimic the historical build's restriction in that regard. FossilOrigin-Name: 073080cae3ea0d12b133d9c9ae98413bb32870a9738c98b89bc345181be81f23 --- main.mk | 55 +++++++++++++++++++++++++++++++-------------------- manifest | 14 ++++++------- manifest.uuid | 2 +- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/main.mk b/main.mk index 21dd01cfde..8cc37ff775 100644 --- a/main.mk +++ b/main.mk @@ -1334,7 +1334,8 @@ tclsqlite-stubs.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) tclsqlite3$(T.exe): $(T.tcl.env.sh) tclsqlite-shell.o $(libsqlite3.SO) $(T.link.tcl) -o $@ tclsqlite-shell.o \ - $(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) + $(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC \ + $(LDFLAGS.libsqlite3) tclsqlite3$(T.exe)-1: tclsqlite3$(T.exe) tclsqlite3$(T.exe)-0 tclsqlite3$(T.exe)-: tcl: tclsqlite3$(T.exe)-$(HAVE_TCL) @@ -1731,7 +1732,8 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c - $(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC $(LDFLAGS.libsqlite3) + $(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC \ + $(LDFLAGS.libsqlite3) sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl \ @@ -1739,14 +1741,15 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(T.exe): $(T.tcl.env.sh) sqltclsh.c - $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) + $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) \ + $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. xbin: sqltclsh$(T.exe) sqlite3_analyzer$(T.exe) sqlite3_expert$(T.exe): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c - $(T.link) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ + $(T.link) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS.libsqlite3) xbin: sqlite3_expert$(T.exe) @@ -1764,16 +1767,17 @@ sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ sqlite3_checker$(T.exe): $(T.tcl.env.sh) sqlite3_checker.c - $(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) + $(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC \ + $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) xbin: sqlite3_checker$(T.exe) dbdump$(T.exe): $(TOP)/ext/misc/dbdump.c sqlite3.o $(T.link) -DDBDUMP_STANDALONE -o $@ \ - $(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3) + $(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: dbdump$(T.exe) dbtotxt$(T.exe): $(TOP)/tool/dbtotxt.c - $(T.link)-o $@ $(TOP)/tool/dbtotxt.c + $(T.link)-o $@ $(TOP)/tool/dbtotxt.c $(LDFLAGS.configure) xbin: dbtotxt$(T.exe) showdb$(T.exe): $(TOP)/tool/showdb.c sqlite3.o @@ -1793,20 +1797,23 @@ showwal$(T.exe): $(TOP)/tool/showwal.c sqlite3.o xbin: showwal$(T.exe) showshm$(T.exe): $(TOP)/tool/showshm.c - $(T.link) -o $@ $(TOP)/tool/showshm.c + $(T.link) -o $@ $(TOP)/tool/showshm.c $(LDFLAGS.configure) xbin: showshm$(T.exe) index_usage$(T.exe): $(TOP)/tool/index_usage.c sqlite3.o - $(T.link) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS.libsqlite3) + $(T.link) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o \ + $(LDFLAGS.libsqlite3) xbin: index_usage$(T.exe) # Reminder: changeset does not build without -DSQLITE_ENABLE_SESSION changeset$(T.exe): $(TOP)/ext/session/changeset.c sqlite3.o - $(T.link) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS.libsqlite3) + $(T.link) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o \ + $(LDFLAGS.libsqlite3) xbin: changeset$(T.exe) changesetfuzz$(T.exe): $(TOP)/ext/session/changesetfuzz.c sqlite3.o - $(T.link) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(LDFLAGS.libsqlite3) + $(T.link) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o \ + $(LDFLAGS.libsqlite3) xbin: changesetfuzz$(T.exe) rollback-test$(T.exe): $(TOP)/tool/rollback-test.c sqlite3.o @@ -1818,7 +1825,7 @@ atrc$(T.exe): $(TOP)/test/atrc.c sqlite3.o xbin: atrc$(T.exe) LogEst$(T.exe): $(TOP)/tool/logest.c sqlite3.h - $(T.link) -I. -o $@ $(TOP)/tool/logest.c + $(T.link) -I. -o $@ $(TOP)/tool/logest.c $(LDFLAGS.configure) xbin: LogEst$(T.exe) wordcount$(T.exe): $(TOP)/test/wordcount.c sqlite3.o @@ -1826,17 +1833,20 @@ wordcount$(T.exe): $(TOP)/test/wordcount.c sqlite3.o xbin: wordcount$(T.exe) speedtest1$(T.exe): $(TOP)/test/speedtest1.c sqlite3.c Makefile - $(T.link) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS.libsqlite3) + $(T.link) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c \ + $(LDFLAGS.libsqlite3) xbin: speedtest1$(T.exe) startup$(T.exe): $(TOP)/test/startup.c sqlite3.c - $(T.link) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3) + $(T.link) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 \ + -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3) xbin: startup$(T.exe) KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ kvtest$(T.exe): $(TOP)/test/kvtest.c sqlite3.c - $(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3) + $(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c \ + $(LDFLAGS.libsqlite3) xbin: kvtest$(T.exe) # @@ -1847,7 +1857,8 @@ rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o $(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) loadfts$(T.exe): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) - $(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3) + $(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) \ + -o $@ $(LDFLAGS.libsqlite3) xbin: loadfts$(T.exe) # This target will fail if the SQLite amalgamation contains any exported @@ -1893,7 +1904,8 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \ $(TOP)/test/tt3_lookaside1.c threadtest3$(T.exe): sqlite3.o $(THREADTEST3_SRC) - $(T.link) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(LDFLAGS.libsqlite3) + $(T.link) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o \ + -o $@ $(LDFLAGS.libsqlite3) xbin: threadtest3$(T.exe) threadtest: threadtest3$(T.exe) @@ -1983,7 +1995,7 @@ verify-source: ./src-verify$(B.exe) fuzzershell$(T.exe): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(T.link) -o $@ $(FUZZERSHELL_OPT) \ - $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS.libsqlite3) + $(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS.libsqlite3) fuzzy: fuzzershell$(T.exe) xbin: fuzzershell$(T.exe) @@ -2021,7 +2033,7 @@ run-fuzzcheck: fuzzcheck$(T.exe) fuzzcheck-asan$(T.exe) fuzzcheck-ubsan$(T.exe) ossshell$(T.exe): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(T.link) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ - $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS.libsqlite3) + $(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS.libsqlite3) fuzzy: ossshell$(T.exe) xbin: ossshell$(T.exe) @@ -2030,7 +2042,8 @@ sessionfuzz$(T.exe): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h fuzzy: sessionfuzz$(T.exe) dbfuzz$(T.exe): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h - $(T.link) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS.libsqlite3) + $(T.link) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c \ + $(LDFLAGS.libsqlite3) fuzzy: dbfuzz$(T.exe) xbin: dbfuzz$(T.exe) @@ -2172,7 +2185,7 @@ sqlite3.def: $(LIBOBJ) sqlite3.dll: $(LIBOBJ) sqlite3.def $(T.cc.sqlite) $(LDFLAGS.shobj) -o $@ sqlite3.def \ - -Wl,"--strip-all" $(LIBOBJ) + -Wl,"--strip-all" $(LIBOBJ) $(LDFLAGS.configure) # # Emit a list of commonly-used targets diff --git a/manifest b/manifest index c3003f93ed..7dd4be8871 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sWin32\sAPIs\sto\sread/write\sthe\sconsole\sin\sWindows\sunless\sthe\nSQLITE_USE_STDIO_FOR_CONSOLE\soption\sis\sdefined.\s\sThis\sis\san\sattempt\sto\sget\nthe\sbuild\sworking\son\sMinGW. -D 2024-11-11T17:02:29.626 +C Wrap\ssome\sexceptionally\slong\slines\sin\smain.mk.\sAdd\soption\sto\soverride\sLDFLAGS\son\sthe\ssqlite3.dll\starget.\sAudit:\sall\stargets\sfor\swhich\sit\sis\shypothetically\srelevant\scan\snow\sinherit\suser-supplied\sLDFLAGS,\sbut\sonly\sthose\sprovided\sto\sthe\sconfigure\sscript,\snot\sat\smake-time,\sin\sorder\sto\smimic\sthe\shistorical\sbuild's\srestriction\sin\sthat\sregard. +D 2024-11-11T18:15:50.014 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk efb8f627c5793126ff7a86d698676f4e6509a296b0b113ec284e6f723561f0bc +F main.mk cd92df46e074ce11466d43530cfe23cef48ac541aee4714181369e3fe92df05a F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b81976c520fbad0bbdbbb877fe85691bcda25c12cf5597cfe224fb6306cd65b3 -R 7eaee2fd29a0a62fa15ab30f7e1400c5 -U drh -Z f4fb9c4d51373a0a4c48f856c51e2978 +P abfe488ed67e2e3510c230e656ecf203afa549ebd1d1872442f1fadc97d0817e +R 24df96c9d99772830356798614acfd48 +U stephan +Z 28b6529814c584cc2748223194d7bea5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 663b7cfc67..24c1159da9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abfe488ed67e2e3510c230e656ecf203afa549ebd1d1872442f1fadc97d0817e +073080cae3ea0d12b133d9c9ae98413bb32870a9738c98b89bc345181be81f23 From be46f935dc3d2e5a033d5427f636fa3c521e06d2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Nov 2024 19:07:58 +0000 Subject: [PATCH 328/522] Add the ".dbtotxt" command to the CLI. FossilOrigin-Name: b43acf5a8cd4a5efbb90b71af7710084f49bb90ffe4f56de168e8c3a6b679124 --- manifest | 14 +++---- manifest.uuid | 2 +- src/shell.c.in | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7dd4be8871..7154ba0838 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Wrap\ssome\sexceptionally\slong\slines\sin\smain.mk.\sAdd\soption\sto\soverride\sLDFLAGS\son\sthe\ssqlite3.dll\starget.\sAudit:\sall\stargets\sfor\swhich\sit\sis\shypothetically\srelevant\scan\snow\sinherit\suser-supplied\sLDFLAGS,\sbut\sonly\sthose\sprovided\sto\sthe\sconfigure\sscript,\snot\sat\smake-time,\sin\sorder\sto\smimic\sthe\shistorical\sbuild's\srestriction\sin\sthat\sregard. -D 2024-11-11T18:15:50.014 +C Add\sthe\s".dbtotxt"\scommand\sto\sthe\sCLI. +D 2024-11-11T19:07:58.682 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -776,7 +776,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in bb97e0afcc4a73b73f38cc868330854a2df109095a7a10182ddfdd261fbec312 +F src/shell.c.in 2b684d9cdad2351e6cabe25ea3a64ac743eb4cda9837bdbc6096d240c4533ab6 F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P abfe488ed67e2e3510c230e656ecf203afa549ebd1d1872442f1fadc97d0817e -R 24df96c9d99772830356798614acfd48 -U stephan -Z 28b6529814c584cc2748223194d7bea5 +P 073080cae3ea0d12b133d9c9ae98413bb32870a9738c98b89bc345181be81f23 +R 6bdbd63031b22370793e2437aff7acb5 +U drh +Z d185df0f51d41a6d3859bb43f39c0c62 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 24c1159da9..b4972f3476 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -073080cae3ea0d12b133d9c9ae98413bb32870a9738c98b89bc345181be81f23 +b43acf5a8cd4a5efbb90b71af7710084f49bb90ffe4f56de168e8c3a6b679124 diff --git a/src/shell.c.in b/src/shell.c.in index 874f448f67..3fb608ff7f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -4951,6 +4951,7 @@ static const char *(azHelp[]) = { #if SQLITE_SHELL_HAVE_RECOVER ".dbinfo ?DB? Show status information about the database", #endif + ".dbtotxt Hex dump of the database file", ".dump ?OBJECTS? Render database content as SQL", " Options:", " --data-only Output only INSERT statements", @@ -6622,6 +6623,101 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ } #endif /* SQLITE_SHELL_HAVE_RECOVER */ +/* +** Implementation of the ".dbtotxt" command. +** +** Return 1 on error, 2 to exit, and 0 otherwise. +*/ +static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){ + sqlite3_stmt *pStmt = 0; + sqlite3_int64 nPage = 0; + int pgSz = 0; + const char *zFilename; + const char *zTail; + char *zName = 0; + int rc, i, j; + unsigned char bShow[256]; /* Characters ok to display */ + + memset(bShow, '.', sizeof(bShow)); + for(i=' '; i<='~'; i++){ + if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i; + } + rc = sqlite3_prepare_v2(p->db, "PRAGMA page_size", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; + pgSz = sqlite3_column_int(pStmt, 0); + sqlite3_finalize(pStmt); + pStmt = 0; + if( pgSz<512 || pgSz>65536 || (pgSz&(pgSz-1))!=0 ) goto dbtotxt_error; + rc = sqlite3_prepare_v2(p->db, "PRAGMA page_count", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; + nPage = sqlite3_column_int64(pStmt, 0); + sqlite3_finalize(pStmt); + pStmt = 0; + if( nPage<1 ) goto dbtotxt_error; + rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + if( sqlite3_step(pStmt)!=SQLITE_ROW ){ + zTail = zFilename = "unk.db"; + }else{ + zFilename = (const char*)sqlite3_column_text(pStmt, 2); + if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; + zTail = strrchr(zFilename, '/'); +#if defined(_WIN32) + if( zTail==0 ) zTail = strrchr(zFilename, '\\'); +#endif + if( zTail ) zFilename = zTail; + } + zName = strdup(zTail); + shell_check_oom(zName); + sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n", + nPage*pgSz, pgSz, zName); + sqlite3_finalize(pStmt); + pStmt = 0; + rc = sqlite3_prepare_v2(p->db, + "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0); + const u8 *aData = sqlite3_column_blob(pStmt, 1); + int seenPageLabel = 0; + for(i=0; iout, "| page %lld offset %lld\n", pgno, pgno*pgSz); + seenPageLabel = 1; + } + sqlite3_fprintf(p->out, "| %5d:", i); + for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]); + sqlite3_fprintf(p->out, " "); + for(j=0; j<16; j++){ + unsigned char c = (unsigned char)aLine[j]; + sqlite3_fprintf(p->out, "%c", bShow[c]); + } + sqlite3_fprintf(p->out, "\n"); + } + } + sqlite3_finalize(pStmt); + sqlite3_fprintf(p->out, "| end %s\n", zName); + free(zName); + return 0; + +dbtotxt_error: + if( rc ){ + sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db)); + } + sqlite3_finalize(pStmt); + free(zName); + return 1; +} + /* ** Print the given string as an error message. */ @@ -8799,6 +8895,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){ + rc = shell_dbtotxt_command(p, nArg, azArg); + }else + if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){ if( nArg==2 ){ p->autoEQPtest = 0; From 0cd2ffffb71ef91c7a3d643f454dc00cf87424d4 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 11 Nov 2024 19:49:26 +0000 Subject: [PATCH 329/522] Fix the fts5 trigram tokenizer so that it handles non-nul-terminated strings. FossilOrigin-Name: 84f4e37178a65e3128ac0240d37ac40df08b4050ab070d10707e35d11dcbeb10 --- ext/fts5/fts5_tcl.c | 22 +++++++++++++++++----- ext/fts5/fts5_tokenize.c | 9 ++++++--- ext/fts5/test/fts5trigram.test | 12 ++++++++++++ manifest | 18 +++++++++--------- manifest.uuid | 2 +- 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index 247b4f0e90..25cd5c0633 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -730,8 +730,9 @@ static int SQLITE_TCLAPI f5tTokenize( int objc, Tcl_Obj *CONST objv[] ){ - char *zText; - Tcl_Size nText; + char *pCopy = 0; + char *zText = 0; + Tcl_Size nText = 0; sqlite3 *db = 0; fts5_api *pApi = 0; Fts5Tokenizer *pTok = 0; @@ -778,22 +779,33 @@ static int SQLITE_TCLAPI f5tTokenize( return TCL_ERROR; } + if( nText>0 ){ + pCopy = sqlite3_malloc(nText); + if( pCopy==0 ){ + tokenizer.xDelete(pTok); + Tcl_AppendResult(interp, "error in sqlite3_malloc()", (char*)0); + return TCL_ERROR; + }else{ + memcpy(pCopy, zText, nText); + } + } + pRet = Tcl_NewObj(); Tcl_IncrRefCount(pRet); ctx.bSubst = (objc==5); ctx.pRet = pRet; - ctx.zInput = zText; + ctx.zInput = pCopy; rc = tokenizer.xTokenize( - pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, zText,(int)nText, xTokenizeCb2 + pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, pCopy,(int)nText, xTokenizeCb2 ); tokenizer.xDelete(pTok); + sqlite3_free(pCopy); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "error in tokenizer.xTokenize()", (char*)0); Tcl_DecrRefCount(pRet); return TCL_ERROR; } - Tcl_Free((void*)azArg); Tcl_SetObjResult(interp, pRet); Tcl_DecrRefCount(pRet); diff --git a/ext/fts5/fts5_tokenize.c b/ext/fts5/fts5_tokenize.c index f9581b080c..f10c2379de 100644 --- a/ext/fts5/fts5_tokenize.c +++ b/ext/fts5/fts5_tokenize.c @@ -1354,7 +1354,7 @@ static int fts5TriTokenize( int ii; const unsigned char *zIn = (const unsigned char*)pText; const unsigned char *zEof = &zIn[nText]; - u32 iCode; + u32 iCode = 0; int aStart[3]; /* Input offset of each character in aBuf[] */ UNUSED_PARAM(unusedFlags); @@ -1363,8 +1363,8 @@ static int fts5TriTokenize( for(ii=0; ii<3; ii++){ do { aStart[ii] = zIn - (const unsigned char*)pText; + if( zIn>=zEof ) return SQLITE_OK; READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) return SQLITE_OK; if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); }while( iCode==0 ); WRITE_UTF8(zOut, iCode); @@ -1385,8 +1385,11 @@ static int fts5TriTokenize( /* Read characters from the input up until the first non-diacritic */ do { iNext = zIn - (const unsigned char*)pText; + if( zIn>=zEof ){ + iCode = 0; + break; + } READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); }while( iCode==0 ); diff --git a/ext/fts5/test/fts5trigram.test b/ext/fts5/test/fts5trigram.test index 5048f8beea..377e3f7813 100644 --- a/ext/fts5/test/fts5trigram.test +++ b/ext/fts5/test/fts5trigram.test @@ -350,5 +350,17 @@ do_execsql_test 11.1 { INSERT INTO t4 VALUES( str('') ); } +do_test 12.0 { + sqlite3_fts5_tokenize db trigram "abcd" +} {abc 0 3 bcd 1 4} + +do_test 12.1 { + sqlite3_fts5_tokenize db trigram "a" +} {} + +do_test 12.2 { + sqlite3_fts5_tokenize db trigram "" +} {} + finish_test diff --git a/manifest b/manifest index 7154ba0838..4b02cc873e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".dbtotxt"\scommand\sto\sthe\sCLI. -D 2024-11-11T19:07:58.682 +C Fix\sthe\sfts5\strigram\stokenizer\sso\sthat\sit\shandles\snon-nul-terminated\sstrings. +D 2024-11-11T19:49:26.299 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -113,10 +113,10 @@ F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6 F ext/fts5/fts5_main.c 50eb059e51d730e8e0c77df4e568b018079e112a755c094488b0d5b1aa06afbb F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c -F ext/fts5/fts5_tcl.c aee6ae6d0c6968564c392bf0d09aaabb4d8bea9ca69fd224dc9b44243324acbf +F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b -F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9 +F ext/fts5/fts5_tokenize.c 87ab719f0556172da3414f1741c11bb4d333ebecde157945a55478bfe6e46c44 F ext/fts5/fts5_unicode2.c 6f9b0fb79a8facaed76628ffd4eb9c16d7f2b84b52872784f617cf3422a9b043 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0 @@ -248,7 +248,7 @@ F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test 7937cec672b148223fff8746d21d3e7ed0965fd7caf35ccdc888a005bb452f98 F ext/fts5/test/fts5tokenizer2.test ddb8b10fbe4b84b2a75812671f127774c1d2e3e2bf82d2e0e4f0bb1cd8a2b2d6 F ext/fts5/test/fts5tokenizer3.test eea778f7bb7024c3e904e28915f9d53286141671b138722148be22a9c758bdc3 -F ext/fts5/test/fts5trigram.test 9927c9e9b35116ea00748c8e41d9cbc2b95a6c90845cd82a59c11fedfd16404a +F ext/fts5/test/fts5trigram.test a55fde7065ae69a0f82c5a7a5bf5286a97de11ae4bff6537fd3e27ca9a01416f F ext/fts5/test/fts5trigram2.test 6fde9de7f63a6b4aa18dc731be56dbd6be4e755c9b13dcd55479e200d1df0e61 F ext/fts5/test/fts5ubsan.test 9a2dcf399dc8d0e0de661f0d93884d1d27e5b7f0693cfceb97dd24d818df5dd2 F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 073080cae3ea0d12b133d9c9ae98413bb32870a9738c98b89bc345181be81f23 -R 6bdbd63031b22370793e2437aff7acb5 -U drh -Z d185df0f51d41a6d3859bb43f39c0c62 +P b43acf5a8cd4a5efbb90b71af7710084f49bb90ffe4f56de168e8c3a6b679124 +R 823df7bdc2f581383fdd27b861d3511c +U dan +Z 55fb3f376e1035a7680545a25c6be334 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b4972f3476..4728648ef5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b43acf5a8cd4a5efbb90b71af7710084f49bb90ffe4f56de168e8c3a6b679124 +84f4e37178a65e3128ac0240d37ac40df08b4050ab070d10707e35d11dcbeb10 From 7b32f84ebf5cf6ff0515a124abbc028e5890a6bc Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Nov 2024 21:11:02 +0000 Subject: [PATCH 330/522] Clarify the documentation to make it clear that rows inserted by a CREATE TABLE AS SELECT statement are not counted by sqlite3_count64(). [forum:/forumpost/1e6cde5648|Forum post 1e6cde5648]. FossilOrigin-Name: 5c5982e3937acdcda43d6c5b46a95b82bc1839c3558a4b9ae9022384e0f13f04 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4b02cc873e..69b914c33e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sfts5\strigram\stokenizer\sso\sthat\sit\shandles\snon-nul-terminated\sstrings. -D 2024-11-11T19:49:26.299 +C Clarify\sthe\sdocumentation\sto\smake\sit\sclear\sthat\srows\sinserted\sby\sa\nCREATE\sTABLE\sAS\sSELECT\sstatement\sare\snot\scounted\sby\ssqlite3_count64().\n[forum:/forumpost/1e6cde5648|Forum\spost\s1e6cde5648]. +D 2024-11-11T21:11:02.572 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -777,7 +777,7 @@ F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe F src/shell.c.in 2b684d9cdad2351e6cabe25ea3a64ac743eb4cda9837bdbc6096d240c4533ab6 -F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399 +F src/sqlite.h.in 9952b3dd29b77c4d5e3d8186e15a7cc00c18499286f8feb8673667e171d4e47f F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b43acf5a8cd4a5efbb90b71af7710084f49bb90ffe4f56de168e8c3a6b679124 -R 823df7bdc2f581383fdd27b861d3511c -U dan -Z 55fb3f376e1035a7680545a25c6be334 +P 84f4e37178a65e3128ac0240d37ac40df08b4050ab070d10707e35d11dcbeb10 +R ebb063815b76e438d20c82a6562aec3f +U drh +Z 07dfe22a2ca581c055864ed191d60160 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4728648ef5..51cd254d77 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84f4e37178a65e3128ac0240d37ac40df08b4050ab070d10707e35d11dcbeb10 +5c5982e3937acdcda43d6c5b46a95b82bc1839c3558a4b9ae9022384e0f13f04 diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 77d928024d..df1493b662 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2631,10 +2631,14 @@ void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** The two functions are identical except for the type of the return value -** and that if the number of rows modified by the most recent INSERT, UPDATE +** and that if the number of rows modified by the most recent INSERT, UPDATE, ** or DELETE is greater than the maximum value supported by type "int", then ** the return value of sqlite3_changes() is undefined. ^Executing any other ** type of SQL statement does not modify the value returned by these functions. +** For the purposes of this interface, a CREATE TABLE AS SELECT statement +** does not count as an INSERT, UPDATE or DELETE statement and hence the rows +** added to the new table by the CREATE TABLE AS SELECT statement are not +** counted. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], From 92e9fa6fe887fc5cad73b4251ce06e295d7a0d2c Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 12 Nov 2024 13:37:00 +0000 Subject: [PATCH 331/522] Ensure that the sqlite3_index_info.idxStr string coming back from FTS5 is always zero-terminated, even if the xBestIndex call fails with an SQLITE_CONSTRAINT error. FossilOrigin-Name: a4e976a030851357049e672bbc0ff66d9cc152b3d5f8e03fff36a7c6f060a755 --- ext/fts5/fts5_main.c | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 5713fccdd1..5c49d91b0d 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -632,6 +632,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an ** unusable plan. Return SQLITE_CONSTRAINT. */ + idxStr[iIdxStr] = 0; return SQLITE_CONSTRAINT; }else{ if( iCol==nCol+1 ){ diff --git a/manifest b/manifest index 69b914c33e..3f8029a141 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarify\sthe\sdocumentation\sto\smake\sit\sclear\sthat\srows\sinserted\sby\sa\nCREATE\sTABLE\sAS\sSELECT\sstatement\sare\snot\scounted\sby\ssqlite3_count64().\n[forum:/forumpost/1e6cde5648|Forum\spost\s1e6cde5648]. -D 2024-11-11T21:11:02.572 +C Ensure\sthat\sthe\ssqlite3_index_info.idxStr\sstring\scoming\sback\sfrom\sFTS5\nis\salways\szero-terminated,\seven\sif\sthe\sxBestIndex\scall\sfails\swith\san\nSQLITE_CONSTRAINT\serror. +D 2024-11-12T13:37:00.957 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -111,7 +111,7 @@ F ext/fts5/fts5_config.c a6633d88596758941c625b526075b85d3d9fd1089d8d9eab5db6e8a F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6 -F ext/fts5/fts5_main.c 50eb059e51d730e8e0c77df4e568b018079e112a755c094488b0d5b1aa06afbb +F ext/fts5/fts5_main.c 0b60324001e26d79e8a12e544883792f59a58717f6dce9fb1f8878f0e0196530 F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 84f4e37178a65e3128ac0240d37ac40df08b4050ab070d10707e35d11dcbeb10 -R ebb063815b76e438d20c82a6562aec3f +P 5c5982e3937acdcda43d6c5b46a95b82bc1839c3558a4b9ae9022384e0f13f04 +R a8158a869a0e1a27dcea5157bd0de42b U drh -Z 07dfe22a2ca581c055864ed191d60160 +Z e86eabfe737b94dd2259bd3879949a73 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 51cd254d77..956680e510 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c5982e3937acdcda43d6c5b46a95b82bc1839c3558a4b9ae9022384e0f13f04 +a4e976a030851357049e672bbc0ff66d9cc152b3d5f8e03fff36a7c6f060a755 From 1b37bc0e668a0bfefbd0a71bdcae25017b29b5fa Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Nov 2024 14:58:35 +0000 Subject: [PATCH 332/522] Add the SQLITE_FCNTL_NULL_IO file-control. FossilOrigin-Name: f0e917fcf51b59f8ccfe5b9341937341d0e6016eb275d6c33dcb10b0b301a9da --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os_unix.c | 5 +++++ src/os_win.c | 5 +++++ src/sqlite.h.in | 6 ++++++ 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3f8029a141..eeed2863da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\ssqlite3_index_info.idxStr\sstring\scoming\sback\sfrom\sFTS5\nis\salways\szero-terminated,\seven\sif\sthe\sxBestIndex\scall\sfails\swith\san\nSQLITE_CONSTRAINT\serror. -D 2024-11-12T13:37:00.957 +C Add\sthe\sSQLITE_FCNTL_NULL_IO\sfile-control. +D 2024-11-13T14:58:35.917 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -759,8 +759,8 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c c84a3add1e480499261a41d77d3f87d18f27aaebec6376655c177a3886a5b67c -F src/os_win.c 69fa1aaff68270423c85cff4327ba17ef99a1eb017e1a2bfb97416d9b8398b05 +F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6 +F src/os_win.c db4baa8f62bbfe3967c71b008cea31a8f2ff337c1667ff4d8a677e697315ff0d F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a @@ -777,7 +777,7 @@ F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe F src/shell.c.in 2b684d9cdad2351e6cabe25ea3a64ac743eb4cda9837bdbc6096d240c4533ab6 -F src/sqlite.h.in 9952b3dd29b77c4d5e3d8186e15a7cc00c18499286f8feb8673667e171d4e47f +F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5c5982e3937acdcda43d6c5b46a95b82bc1839c3558a4b9ae9022384e0f13f04 -R a8158a869a0e1a27dcea5157bd0de42b +P a4e976a030851357049e672bbc0ff66d9cc152b3d5f8e03fff36a7c6f060a755 +R cbde25c924d15d902cdf437d5236e99e U drh -Z e86eabfe737b94dd2259bd3879949a73 +Z 9feaba1d713c9ff220e94d51317a455c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 956680e510..5cd62d912c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4e976a030851357049e672bbc0ff66d9cc152b3d5f8e03fff36a7c6f060a755 +f0e917fcf51b59f8ccfe5b9341937341d0e6016eb275d6c33dcb10b0b301a9da diff --git a/src/os_unix.c b/src/os_unix.c index 8cc1886745..b1996278c8 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3987,6 +3987,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } #endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + case SQLITE_FCNTL_NULL_IO: { + osClose(pFile->h); + pFile->h = -1; + return SQLITE_OK; + } case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; diff --git a/src/os_win.c b/src/os_win.c index 97743412e9..4d245263fe 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3599,6 +3599,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } #endif + case SQLITE_FCNTL_NULL_IO: { + (void)osCloseHandle(pFile->h); + pFile->h = NULL; + return SQLITE_OK; + } case SQLITE_FCNTL_TEMPFILENAME: { char *zTFile = 0; int rc = winGetTempname(pFile->pVfs, &zTFile); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index df1493b662..b84938b45c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1100,6 +1100,11 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +**
      • [[SQLITE_FCNTL_NULL_IO]] +** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor +** or file handle for the [sqlite3_file] object such that it will no longer +** read or write to the database file. +** **
      • [[SQLITE_FCNTL_WAL_BLOCK]] ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might ** be advantageous to block on the next WAL lock if the lock is not immediately @@ -1253,6 +1258,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +#define SQLITE_FCNTL_NULL_IO 43 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE From 31c160ab8f7b0c8f4a1a19ea5d9c6abe5083b37c Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Nov 2024 16:08:02 +0000 Subject: [PATCH 333/522] Add the test/fork-test.c test program. FossilOrigin-Name: 0611e2b0cf3f33c28cc9ff6c5da7ebba2033bcbda5b1072a30021a3e1fb4e738 --- manifest | 11 +- manifest.uuid | 2 +- test/fork-test.c | 310 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+), 6 deletions(-) create mode 100644 test/fork-test.c diff --git a/manifest b/manifest index eeed2863da..3fd0f2dc1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_FCNTL_NULL_IO\sfile-control. -D 2024-11-13T14:58:35.917 +C Add\sthe\stest/fork-test.c\stest\sprogram. +D 2024-11-13T16:08:02.102 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1154,6 +1154,7 @@ F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d0 F test/fkey8.test 51deda7f1a1448bca95875e4a6e1a3a75b4bd7215e924e845bd60de60e4d84bf F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/fordelete.test ba98f14446b310f9c9d935b97ec748753d0144a28b356ba30d1f4f6958fdde5c +F test/fork-test.c 9ac2e6423a1d38df3d6be0e8ac15608b545de21e2b19d9d876254c5931b63edb F test/format4.test eeae341953db8b6bda7f549044797c3278a6cc345d11ada81471671b654f8ef4 F test/fp-speed-1.c b37de94eba034e1703668816225f54510ec60fb0685406608cc707afe6b8234d F test/fpconv1.test d5d8aa0c427533006c112fb1957cdd1ea68c1d0709470dabb9ca02c2e4c06ad8 @@ -2198,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a4e976a030851357049e672bbc0ff66d9cc152b3d5f8e03fff36a7c6f060a755 -R cbde25c924d15d902cdf437d5236e99e +P f0e917fcf51b59f8ccfe5b9341937341d0e6016eb275d6c33dcb10b0b301a9da +R 6602510d12e6c22a0b1d041f1323efab U drh -Z 9feaba1d713c9ff220e94d51317a455c +Z a609b555f7a83a611caf3857959d5dfd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5cd62d912c..c86cacfebd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0e917fcf51b59f8ccfe5b9341937341d0e6016eb275d6c33dcb10b0b301a9da +0611e2b0cf3f33c28cc9ff6c5da7ebba2033bcbda5b1072a30021a3e1fb4e738 diff --git a/test/fork-test.c b/test/fork-test.c new file mode 100644 index 0000000000..8a9b4b4afa --- /dev/null +++ b/test/fork-test.c @@ -0,0 +1,310 @@ +/* +** The program demonstrates how a child process created using fork() +** can continue to use SQLite for a database that the parent had opened and +** and was writing into when the fork() occurred. +** +** This program executes the following steps: +** +** 1. Create a new database file. Open it, and populate it. +** 2. Start a transaction and make changes. +** ^-- close the transaction prior to fork() if --commit-before-fork +** 3. Fork() +** 4. In the child, close the database connection. Special procedures +** are needed to close the database connection in the child. See the +** implementation below. +** 5. Commit the transaction in the parent. +** 6. Verify that the transaction committed in the parent. +** 7. In the child, after a delay to allow time for (5) and (6), +** open a new database connection and verify that the transaction +** committed by (5) is seen. +** 8. Add make further changes and commit them in the child, using the +** new database connection. +** 9. In the parent, after a delay to account for (8), verify that +** the new transaction added by (8) can be seen. +** +** Usage: +** +** fork-test FILENAME [options] +** +** Options: +** +** --wal Run the database in WAL mode +** --vfstrace Enable VFS tracing for debugging +** --commit-before-fork COMMIT prior to the fork() in step 3 +** --delay-after-4 N Pause for N seconds after step 4 +** +** How To Compile: +** +** gcc -O0 -g -Wall -I$(SQLITESRC) \ +** f1.c $(SQLITESRC)/ext/misc/vfstrace.c $(SQLITESRC/sqlite3.c \ +** -ldl -lpthread -lm +** +** Test procedure: +** +** (1) Run "fork-test x1.db". Verify no I/O errors occur and that +** both parent and child see all three rows in the t1 table. +** +** (2) Repeat (1) adding the --wal option. +** +** (3) Repeat (1) and (2) adding the --commit-before-fork option. +** +** (4) Repeat all prior steps adding the --delay-after-4 option with +** a timeout of 15 seconds or so. Then, while both parent and child +** are paused, run the CLI against the x1.db database from a separate +** window and verify that all the correct file locks are still working +** correctly. +** +** Take-Aways: +** +** * If a process has open SQLite database connections when it fork()s, +** the child can call exec() and all it well. Nothing special needs +** to happen. +** +** * If a process has open SQLite database connections when it fork()s, +** the child can do anything that does not involve using SQLite without +** causing problems in the parent. No special actions are needed in +** the child. +** +** * If a process has open SQLite database connections when it fork()s, +** the child can call sqlite3_close() on those database connections +** as long as there were no pending write transactions when the fork() +** occurred. +** +** * If a process has open SQLite database connections that are in the +** middle of a write transaction and then the processes fork()s, the +** child process should close the database connections using the +** procedures demonstrated in Step 4 below before trying to do anything +** else with SQLite. +** +** * If a child process can safely close SQLite database connections that +** it inherited via fork() using the procedures shown in Step 4 below +** even if the database connections were not involved in a write +** transaction at the time of the fork(). The special procedures are +** required if a write transaction was active. They are optional +** otherwise. No harm results from using the special procedures when +** they are not necessary. +** +** * Child processes that use SQLite should open their own database +** connections. They should not attempt to use a database connection +** that is inherited from the parent. +*/ +#include +#include +#include +#include +#include +#include +#include +#include "sqlite3.h" + +/* +** Process ID of the parent +*/ +static pid_t parentPid = 0; + +/* +** Return either "parent" or "child", as appropriate. +*/ +static const char *whoAmI(void){ + return getpid()==parentPid ? "parent" : "child"; +} + +/* +** This is an sqlite3_exec() callback routine that prints all results. +*/ +static int execCallback(void *pNotUsed, int nCol, char **aVal, char **aCol){ + int i; + const char *zWho = whoAmI(); + for(i=0; ipMethods && pJrnl->pMethods->xFileControl ){ + pJrnl->pMethods->xFileControl(pJrnl, SQLITE_FCNTL_NULL_IO, 0); + } + } + sqlite3_close(db); + /* + ** End of special close procedures for SQLite database connections + ** inherited via fork(). + ***********************************************************************/ + + printf("%s: database connection closed\n", whoAmI()); fflush(stdout); + }else{ + /* Pause the parent briefly to give the child a chance to close its + ** database connection */ + sleep(1); + } + + if( nDelayAfter4>0 ){ + printf("%s: Delay for %d seconds\n", whoAmI(), nDelayAfter4); + fflush(stdout); + sleep(nDelayAfter4); + printf("%s: Continue after %d delay\n", whoAmI(), nDelayAfter4); + fflush(stdout); + } + + /** Step 5 **/ + if( child!=0 ){ + printf("Step 5:\n"); + if( !bCommitBeforeFork ) sqlExec(db, "COMMIT", 0); + sqlExec(db, "SELECT x FROM t1;", 1); + } + + + /** Step 7 **/ + if( child==0 ){ + sleep(2); + printf("Steps 7 and 8:\n"); + rc = sqlite3_open(zFilename, &db); + if( rc ){ + printf("Child unable to reopen the database. rc = %d\n", rc); + exit(1); + } + sqlExec(db, "SELECT * FROM t1;", 1); + + /** Step 8 **/ + sqlExec(db, "INSERT INTO t1 VALUES('Third row');", 0); + sqlExec(db, "SELECT * FROM t1;", 1); + sleep(1); + return 0; + } + c2 = wait(&status); + printf("Process %d finished with status %d\n", c2, status); + + /** Step 9 */ + if( child!=0 ){ + printf("Step 9:\n"); + sqlExec(db, "SELECT * FROM t1;", 1); + } + + return 0; +} From 26c080a04b03db08c160a34d1616ceb72cde3c5e Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Nov 2024 18:04:49 +0000 Subject: [PATCH 334/522] Fix a memory leak in the ".dump" command of the CLI that can occur if an error other than database corruption is seen while trying to query the database. FossilOrigin-Name: 2560cc7072c923f534a5de1e15d2b0dd4ac5faf0a8876d9e3bf9804345585444 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3fd0f2dc1e..b73a3696f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\stest/fork-test.c\stest\sprogram. -D 2024-11-13T16:08:02.102 +C Fix\sa\smemory\sleak\sin\sthe\s".dump"\scommand\sof\sthe\sCLI\sthat\scan\soccur\sif\san\nerror\sother\sthan\sdatabase\scorruption\sis\sseen\swhile\strying\sto\squery\sthe\ndatabase. +D 2024-11-13T18:04:49.647 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -776,7 +776,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 2b684d9cdad2351e6cabe25ea3a64ac743eb4cda9837bdbc6096d240c4533ab6 +F src/shell.c.in 45e69e4e69576847a5b49aeac624c9ffad5666697ce037d38bc331a56733765f F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f0e917fcf51b59f8ccfe5b9341937341d0e6016eb275d6c33dcb10b0b301a9da -R 6602510d12e6c22a0b1d041f1323efab +P 0611e2b0cf3f33c28cc9ff6c5da7ebba2033bcbda5b1072a30021a3e1fb4e738 +R ae1e95a303369ff7949c51518d63ae67 U drh -Z a609b555f7a83a611caf3857959d5dfd +Z 5eaa8df8893f82fa2c87e2122f21eb00 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c86cacfebd..51a212af44 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0611e2b0cf3f33c28cc9ff6c5da7ebba2033bcbda5b1072a30021a3e1fb4e738 +2560cc7072c923f534a5de1e15d2b0dd4ac5faf0a8876d9e3bf9804345585444 diff --git a/src/shell.c.in b/src/shell.c.in index 3fb608ff7f..722d8d49dc 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -4886,9 +4886,9 @@ static int run_schema_dump_query( }else{ rc = SQLITE_CORRUPT; } - sqlite3_free(zErr); free(zQ2); } + sqlite3_free(zErr); return rc; } From 104ab7e81fa819d7e0a9c4232977e2812f358100 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Nov 2024 18:23:18 +0000 Subject: [PATCH 335/522] Enhance the vfstrace.c extension to show symbolic names for the various SHM locks. FossilOrigin-Name: c0dd7de8f1e8eb745a8beff086d8b40b289c2dd75fe099a86ccc2bd0581f5e9a --- ext/misc/vfstrace.c | 21 +++++++++++++++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/ext/misc/vfstrace.c b/ext/misc/vfstrace.c index b7c8175eeb..25d5e9b28b 100644 --- a/ext/misc/vfstrace.c +++ b/ext/misc/vfstrace.c @@ -624,6 +624,16 @@ static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){ ** Shared-memory operations. */ static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ + static const char *azLockName[] = { + "WRITE", + "CKPT", + "RECOVER", + "READ0", + "READ1", + "READ2", + "READ3", + "READ4", + }; vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; @@ -637,8 +647,15 @@ static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ if( flags & ~(0xf) ){ sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags); } - vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)", - pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]); + if( ofst>=0 && ofstzVfsName, p->zFName, ofst, azLockName[ofst], + n, &zLck[1]); + }else{ + vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=5d,n=%d,%s)", + pInfo->zVfsName, p->zFName, ofst, + n, &zLck[1]); + } rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); vfstrace_print_errcode(pInfo, " -> %s\n", rc); return rc; diff --git a/manifest b/manifest index b73a3696f6..22d5ef6cc2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smemory\sleak\sin\sthe\s".dump"\scommand\sof\sthe\sCLI\sthat\scan\soccur\sif\san\nerror\sother\sthan\sdatabase\scorruption\sis\sseen\swhile\strying\sto\squery\sthe\ndatabase. -D 2024-11-13T18:04:49.647 +C Enhance\sthe\svfstrace.c\sextension\sto\sshow\ssymbolic\snames\sfor\sthe\svarious\nSHM\slocks. +D 2024-11-13T18:23:18.773 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -450,7 +450,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917 F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d -F ext/misc/vfstrace.c ac76a4ac4d907774fd423cc2b61410c756f9d0782e27cf6032e058594accaaca +F ext/misc/vfstrace.c 72b7cda31777173b0ca78c6c92968c17aba635682205945e394fff27b377bb81 F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0611e2b0cf3f33c28cc9ff6c5da7ebba2033bcbda5b1072a30021a3e1fb4e738 -R ae1e95a303369ff7949c51518d63ae67 +P 2560cc7072c923f534a5de1e15d2b0dd4ac5faf0a8876d9e3bf9804345585444 +R 5d29f4bc70b99f0334d8d6e56e448522 U drh -Z 5eaa8df8893f82fa2c87e2122f21eb00 +Z 8e77042ea0a98703802cf67ef314193e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 51a212af44..446d6d59f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2560cc7072c923f534a5de1e15d2b0dd4ac5faf0a8876d9e3bf9804345585444 +c0dd7de8f1e8eb745a8beff086d8b40b289c2dd75fe099a86ccc2bd0581f5e9a From 3b5669854164160f648b143fc26adf79ebc087b0 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 14 Nov 2024 12:09:09 +0000 Subject: [PATCH 336/522] configure: avoid performing multiple checks for -lm on behalf of --enable-fts4 and --enable-fts5. FossilOrigin-Name: 6940caa192fa0cc84dbd24191a940aec96c304c68e60ead8f239e85d093e01e0 --- auto.def | 17 +++++++++-------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/auto.def b/auto.def index eda38ec497..fddcff08a3 100644 --- a/auto.def +++ b/auto.def @@ -718,7 +718,7 @@ sqlite-check-tcl # to an unexpanded makefile var name. # # - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible -# jimsh. The defaults may be pass on to configure as +# jimsh. The defaults may be passed on to configure as # CFLAGS_JIMSH=... set useJimForCodeGen 0 ; # Set to 1 when using jimsh for code generation. # May affect later decisions. @@ -818,7 +818,7 @@ proj-if-opt-truthy threadsafe { ######################################################################## # Do we want temporary databases in memory? # -if {1} { +apply {{} { set ts [opt-val with-tempstore no] set tsn 1 msg-checking "Use an in-RAM database for temporary tables? " @@ -833,8 +833,7 @@ if {1} { } msg-result $ts define TEMP_STORE $tsn - unset ts tsn -} +}} ######################################################################## # sqlite-check-line-editing jumps through proverbial hoops to try to @@ -1185,11 +1184,13 @@ sqlite-check-emsdk # the required linker flags (which may be empty even if the math APIs # are found, depending on the OS). proc affirm-have-math {featureName} { - if {![msg-quiet proj-check-function-in-lib log m]} { - user-error "Missing math APIs for $featureName" + if {"" eq [get-define LDFLAGS_MATH ""]} { + if {![msg-quiet proj-check-function-in-lib log m]} { + user-error "Missing math APIs for $featureName" + } + define LDFLAGS_MATH [get-define lib_log ""] + undefine lib_log } - define LDFLAGS_MATH [get-define lib_log ""] - undefine lib_log } ######################################################################## diff --git a/manifest b/manifest index 22d5ef6cc2..07716f5a0b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\svfstrace.c\sextension\sto\sshow\ssymbolic\snames\sfor\sthe\svarious\nSHM\slocks. -D 2024-11-13T18:23:18.773 +C configure:\savoid\sperforming\smultiple\schecks\sfor\s-lm\son\sbehalf\sof\s--enable-fts4\sand\s--enable-fts5. +D 2024-11-14T12:09:09.948 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def dd7d48438426327c37f51f8e289492058744656e2da03197c31e4fb76398050c +F auto.def 82d2276abaf7f590b700fa0c2db952a76a6ecac53d98f54a72d969269d31db36 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2560cc7072c923f534a5de1e15d2b0dd4ac5faf0a8876d9e3bf9804345585444 -R 5d29f4bc70b99f0334d8d6e56e448522 -U drh -Z 8e77042ea0a98703802cf67ef314193e +P c0dd7de8f1e8eb745a8beff086d8b40b289c2dd75fe099a86ccc2bd0581f5e9a +R 892e60ac59326933dc516a31c2821f96 +U stephan +Z f6f990db909fc14949365b2f71d1a958 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 446d6d59f6..cadad5f64a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0dd7de8f1e8eb745a8beff086d8b40b289c2dd75fe099a86ccc2bd0581f5e9a +6940caa192fa0cc84dbd24191a940aec96c304c68e60ead8f239e85d093e01e0 From f154cef8f204139ae22a0b9f9da0506d0d4178ed Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 14 Nov 2024 12:23:05 +0000 Subject: [PATCH 337/522] Document the if block at the end of sqlite-check-tcl. FossilOrigin-Name: 6bfd09408b9a51c0cbdb28f901a79c9774da755294d7eb67d88e4c42c5652830 --- auto.def | 4 ++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/auto.def b/auto.def index fddcff08a3..8466fc779a 100644 --- a/auto.def +++ b/auto.def @@ -686,6 +686,10 @@ proc sqlite-check-tcl {} { } } show-notices + # If TCL is not found: if it was explicitly requested then fail + # fatally, else just emit a warning. If we can find the APIs needed + # to generate a working JimTCL then that will suffice for build-time + # TCL purposes (see: proc sqlite-determine-codegen-tcl). if {![get-define HAVE_TCL] && ([proj-opt-was-provided tcl] || [proj-opt-was-provided with-tcl])} { proj-fatal "TCL support was requested but no tclConfig.sh could be found." diff --git a/manifest b/manifest index 07716f5a0b..f4236a85e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C configure:\savoid\sperforming\smultiple\schecks\sfor\s-lm\son\sbehalf\sof\s--enable-fts4\sand\s--enable-fts5. -D 2024-11-14T12:09:09.948 +C Document\sthe\sif\sblock\sat\sthe\send\sof\ssqlite-check-tcl. +D 2024-11-14T12:23:05.149 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 82d2276abaf7f590b700fa0c2db952a76a6ecac53d98f54a72d969269d31db36 +F auto.def 7dbe7bebe9c3bea4de674053339964b4b26cff5e2fdc20948acc723b5080bffd F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c0dd7de8f1e8eb745a8beff086d8b40b289c2dd75fe099a86ccc2bd0581f5e9a -R 892e60ac59326933dc516a31c2821f96 +P 6940caa192fa0cc84dbd24191a940aec96c304c68e60ead8f239e85d093e01e0 +R a630c6439d1fbf64015d5e1115d0f02b U stephan -Z f6f990db909fc14949365b2f71d1a958 +Z 28b305c9589a667cd87e3823cca8351c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cadad5f64a..258ecf84b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6940caa192fa0cc84dbd24191a940aec96c304c68e60ead8f239e85d093e01e0 +6bfd09408b9a51c0cbdb28f901a79c9774da755294d7eb67d88e4c42c5652830 From c87d7bede0f0e350fc27c0817ab67788252597e8 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 14 Nov 2024 14:38:16 +0000 Subject: [PATCH 338/522] Fix a problem with window functions min() and max() when used with a FILTER clause. Forum post [forum:/forumpost/e9126d554a | e9126d554a]. FossilOrigin-Name: d15fb0f75e64bbfdb8df0c0d0358aafbbd7d5e2048df676dafe1abd5e9917f2a --- manifest | 20 +++++++-------- manifest.uuid | 2 +- src/window.c | 30 +++++++++++----------- test/window8.tcl | 62 ++++++++++++++++++++++++++++++++++++++++++++++ test/window8.test | 63 +++++++++++++++++++++++++++++++++++++++++++++++ test/window9.test | 58 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 210 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index f4236a85e5..01eec35bff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Document\sthe\sif\sblock\sat\sthe\send\sof\ssqlite-check-tcl. -D 2024-11-14T12:23:05.149 +C Fix\sa\sproblem\swith\swindow\sfunctions\smin()\sand\smax()\swhen\sused\swith\sa\sFILTER\sclause.\sForum\spost\s[forum:/forumpost/e9126d554a\s|\se9126d554a]. +D 2024-11-14T14:38:16.785 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -863,7 +863,7 @@ F src/where.c 4de9e7ca5f49e4a21c1d733e2b2fbbc8b62b1a157a58a562c569da84cfcb005b F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca F src/wherecode.c 81b9af89f4f85c8097d0da6a31499f015eabc4d3584963d30ba7b7b782e26514 F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f -F src/window.c 499d48f315a09242dc68f2fac635ed27dcf6bbb0d9ab9084857898c64489e975 +F src/window.c 6c386af5972a58f9a9847bba9d7ca70c4c682391ab8478d94a6e046b22a0dbb3 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9 @@ -2067,9 +2067,9 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652 F test/window6.test 311de885bd7e453134fa6747680bfb4a1be87c91720bf58703db945891e7d30b F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd -F test/window8.tcl 5e02e41d9d9a80f597063aed1a381eb19d1d0ef677a4f0df352c5365cf23f79c -F test/window8.test 4ab16817414af0c904abe2ebdf88eb6c2b00058b84f9748c6174ff11fc45f1ed -F test/window9.test 349c71eab4288a1ffc19e2f65872ec2c37e6cf8a1dda2ad300364b7450ae4836 +F test/window8.tcl c57364e64d816f6e26df60437e1202e2c1031c7b818a1a67535d1006862a026a +F test/window8.test 3d931e58802b8ab8063da00f0cf30aa3351640238a952c0efb5a129e2349a4bb +F test/window9.test 7b98a7916dd87763ea35f56ea023e3b29e99744582204ccf2937a3bac411cd4d F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be F test/windowB.test aad7c31739999f68a98a813cfd78390918fc70f56d2d925317a1523cab548ecf F test/windowC.test 6fd75f5bb2f1343d34e470e36e68f0ff638d8a42f6aa7d99471261b31a0d42f2 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6940caa192fa0cc84dbd24191a940aec96c304c68e60ead8f239e85d093e01e0 -R a630c6439d1fbf64015d5e1115d0f02b -U stephan -Z 28b305c9589a667cd87e3823cca8351c +P 6bfd09408b9a51c0cbdb28f901a79c9774da755294d7eb67d88e4c42c5652830 +R 4dbd1e8b72bd923323c250178cad8662 +U dan +Z 283ba5d1ed32af60aeb437d70b951d46 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 258ecf84b0..a40565627e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6bfd09408b9a51c0cbdb28f901a79c9774da755294d7eb67d88e4c42c5652830 +d15fb0f75e64bbfdb8df0c0d0358aafbbd7d5e2048df676dafe1abd5e9917f2a diff --git a/src/window.c b/src/window.c index d4083beeb3..acc6ea8546 100644 --- a/src/window.c +++ b/src/window.c @@ -1670,6 +1670,7 @@ static void windowAggStep( int regArg; int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); int i; + int addrIf = 0; assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); @@ -1686,6 +1687,18 @@ static void windowAggStep( } regArg = reg; + if( pWin->pFilter ){ + int regTmp; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); + assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regTmp); + } + if( pMWin->regStartRowid==0 && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) @@ -1705,25 +1718,13 @@ static void windowAggStep( } sqlite3VdbeJumpHere(v, addrIsNull); }else if( pWin->regApp ){ + assert( pWin->pFilter==0 ); assert( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ); assert( bInverse==0 || bInverse==1 ); sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); }else if( pFunc->xSFunc!=noopStepFunc ){ - int addrIf = 0; - if( pWin->pFilter ){ - int regTmp; - assert( ExprUseXList(pWin->pOwner) ); - assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); - assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); - regTmp = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); - addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); - VdbeCoverage(v); - sqlite3ReleaseTempReg(pParse, regTmp); - } - if( pWin->bExprArgs ){ int iOp = sqlite3VdbeCurrentAddr(v); int iEnd; @@ -1754,8 +1755,9 @@ static void windowAggStep( if( pWin->bExprArgs ){ sqlite3ReleaseTempRange(pParse, regArg, nArg); } - if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } + + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } } diff --git a/test/window8.tcl b/test/window8.tcl index 69ad0ad263..fcb18249ae 100644 --- a/test/window8.tcl +++ b/test/window8.tcl @@ -489,6 +489,68 @@ execsql_test 9.2 { FROM t1 } +========== + +execsql_test 10.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER, b INTEGER); + INSERT INTO t1 VALUES (10, 1), + (20, -1), + (5, 2), + (15, 0), + (25, 3); +} + +execsql_test 10.1 { + SELECT + a, b, MIN(a) FILTER(WHERE b > 0) OVER win + FROM t1 + WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING); +} + +execsql_test 10.2 { + SELECT + a, b, MIN(a) FILTER(WHERE b > 0) OVER win + FROM t1 + WINDOW win AS (); +} + +execsql_test 10.3 { + SELECT + a, b, MIN(a) FILTER(WHERE b > 0) OVER win + FROM t1 + WINDOW win AS (ORDER BY a); +} + +execsql_test 10.4 { + SELECT + a, b, MIN(a) OVER win + FROM t1 + WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING); +} + +========== + +execsql_test 11.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER, b INTEGER); + INSERT INTO t2 VALUES(1, 12); + INSERT INTO t2 VALUES(2, 10); + INSERT INTO t2 VALUES(3, 15); + INSERT INTO t2 VALUES(4, 22); + INSERT INTO t2 VALUES(5, 1); + INSERT INTO t2 VALUES(6, 4); + INSERT INTO t2 VALUES(7, 7); + INSERT INTO t2 VALUES(8, 6); + INSERT INTO t2 VALUES(9, 22); + INSERT INTO t2 VALUES(10, 2); +} + +execsql_test 11.1 { + SELECT a, min(b) FILTER (WHERE a%2 != 0) OVER win + FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING); +} finish_test diff --git a/test/window8.test b/test/window8.test index 0c5d39badb..b1b28f1c2f 100644 --- a/test/window8.test +++ b/test/window8.test @@ -6540,4 +6540,67 @@ do_execsql_test 9.2 { FROM t1 } {} +#========================================================================== + +do_execsql_test 10.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER, b INTEGER); + INSERT INTO t1 VALUES (10, 1), + (20, -1), + (5, 2), + (15, 0), + (25, 3); +} {} + +do_execsql_test 10.1 { + SELECT + a, b, MIN(a) FILTER(WHERE b > 0) OVER win + FROM t1 + WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING); +} {5 2 5 10 1 5 15 0 10 20 -1 25 25 3 25} + +do_execsql_test 10.2 { + SELECT + a, b, MIN(a) FILTER(WHERE b > 0) OVER win + FROM t1 + WINDOW win AS (); +} {10 1 5 20 -1 5 5 2 5 15 0 5 25 3 5} + +do_execsql_test 10.3 { + SELECT + a, b, MIN(a) FILTER(WHERE b > 0) OVER win + FROM t1 + WINDOW win AS (ORDER BY a); +} {5 2 5 10 1 5 15 0 5 20 -1 5 25 3 5} + +do_execsql_test 10.4 { + SELECT + a, b, MIN(a) OVER win + FROM t1 + WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING); +} {5 2 5 10 1 5 15 0 10 20 -1 15 25 3 20} + +#========================================================================== + +do_execsql_test 11.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER, b INTEGER); + INSERT INTO t2 VALUES(1, 12); + INSERT INTO t2 VALUES(2, 10); + INSERT INTO t2 VALUES(3, 15); + INSERT INTO t2 VALUES(4, 22); + INSERT INTO t2 VALUES(5, 1); + INSERT INTO t2 VALUES(6, 4); + INSERT INTO t2 VALUES(7, 7); + INSERT INTO t2 VALUES(8, 6); + INSERT INTO t2 VALUES(9, 22); + INSERT INTO t2 VALUES(10, 2); +} {} + +do_execsql_test 11.1 { + SELECT a, min(b) FILTER (WHERE a%2 != 0) OVER win + FROM t2 + WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING); +} {1 12 2 12 3 1 4 1 5 1 6 1 7 1 8 7 9 7 10 22} + finish_test diff --git a/test/window9.test b/test/window9.test index 4b8e4fa58f..0548624f82 100644 --- a/test/window9.test +++ b/test/window9.test @@ -282,4 +282,62 @@ do_catchsql_test 9.1 { FROM t1 } {1 {frame ending offset must be a non-negative number}} +#-------------------------------------------------------------------------- +reset_db + +do_execsql_test 10.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 'a'); + INSERT INTO t1 VALUES(2, 'b'); + INSERT INTO t1 VALUES(3, 'c'); + INSERT INTO t1 VALUES(4, 'd'); + INSERT INTO t1 VALUES(5, 'e'); + INSERT INTO t1 VALUES(6, 'f'); +} + +do_execsql_test 10.1 { + SELECT a, min(b) OVER win + FROM t1 + WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING) +} { + 1 a + 2 a + 3 a + 4 b + 5 c + 6 d +} + +do_execsql_test 10.2 { + SELECT a, min(b) FILTER (WHERE a%2) OVER win + FROM t1 + WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING) +} { + 1 a + 2 a + 3 a + 4 c + 5 c + 6 e +} + +do_execsql_test 10.3 { + SELECT a, min(b) FILTER (WHERE (a%2)=0) OVER win + FROM t1 + WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING) +} { + 1 b + 2 b + 3 b + 4 b + 5 d + 6 d +} + +do_catchsql_test 10.4 { + SELECT a, nth_value(b, 1) FILTER (WHERE (a%2)=0) OVER win + FROM t1 + WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING) +} {1 {FILTER clause may only be used with aggregate window functions}} + finish_test From 752df4c49b92ff78ff86a5fa33759da6d08b5d9b Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 14 Nov 2024 15:25:05 +0000 Subject: [PATCH 339/522] Remove unused sqlite_cfg.h.in (sqlite_cfg.h gets generated without an input template). FossilOrigin-Name: 6148f2d39237a85edb399e5c2beb305dccd99ca8c0cf143e8c2ddc0fc1d9e916 --- manifest | 13 ++-- manifest.uuid | 2 +- sqlite_cfg.h.in | 194 ------------------------------------------------ 3 files changed, 7 insertions(+), 202 deletions(-) delete mode 100644 sqlite_cfg.h.in diff --git a/manifest b/manifest index 01eec35bff..3162cddcf1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\swindow\sfunctions\smin()\sand\smax()\swhen\sused\swith\sa\sFILTER\sclause.\sForum\spost\s[forum:/forumpost/e9126d554a\s|\se9126d554a]. -D 2024-11-14T14:38:16.785 +C Remove\sunused\ssqlite_cfg.h.in\s(sqlite_cfg.h\sgets\sgenerated\swithout\san\sinput\stemplate). +D 2024-11-14T15:25:05.834 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -706,7 +706,6 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 -F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb F src/attach.c f35bb8cc1fcdde8f6815a7ef09ae413bcac71821d530796800ba24b3c7da1e80 @@ -2199,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6bfd09408b9a51c0cbdb28f901a79c9774da755294d7eb67d88e4c42c5652830 -R 4dbd1e8b72bd923323c250178cad8662 -U dan -Z 283ba5d1ed32af60aeb437d70b951d46 +P d15fb0f75e64bbfdb8df0c0d0358aafbbd7d5e2048df676dafe1abd5e9917f2a +R d6d753c19cf72fb017b2468f8e1184ee +U stephan +Z 38d02b611518b292e9e6ae3697162b25 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a40565627e..4e12ecd2e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d15fb0f75e64bbfdb8df0c0d0358aafbbd7d5e2048df676dafe1abd5e9917f2a +6148f2d39237a85edb399e5c2beb305dccd99ca8c0cf143e8c2ddc0fc1d9e916 diff --git a/sqlite_cfg.h.in b/sqlite_cfg.h.in deleted file mode 100644 index be6329e341..0000000000 --- a/sqlite_cfg.h.in +++ /dev/null @@ -1,194 +0,0 @@ -/* sqlite_cfg.h.in - autosetup input template for sqlite_cfg.h. */ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_DLFCN_H*/ -@if HAVE_DLFCN_H -#define HAVE_DLFCN_H @HAVE_DLFCN_H@ -@endif - -/* Define to 1 if you have the `fdatasync' function. */ -/*#undef HAVE_FDATASYNC*/ -#define HAVE_FDATASYNC @HAVE_FDATASYNC@ - -/* Define to 1 if you have the `gmtime_r' function. */ -/*#undef HAVE_GMTIME_R*/ -#define HAVE_GMTIME_R @HAVE_GMTIME_R@ - -/* Define to 1 if the system has the type `int16_t'. */ -/*#undef HAVE_INT16_T*/ -#define HAVE_INT16_T @HAVE_INT16_T@ - -/* Define to 1 if the system has the type `int32_t'. */ -/*#undef HAVE_INT32_T*/ -#define HAVE_INT32_T @HAVE_INT32_T@ - -/* Define to 1 if the system has the type `int64_t'. */ -/*#undef HAVE_INT64_T*/ -#define HAVE_INT64_T @HAVE_INT64_T@ - -/* Define to 1 if the system has the type `int8_t'. */ -/*#undef HAVE_INT8_T*/ -#define HAVE_INT8_T @HAVE_INT8_T@ - -/* Define to 1 if the system has the type `intptr_t'. */ -/*#undef HAVE_INTPTR_T*/ -#define HAVE_INTPTR_T @HAVE_INTPTR_T@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_INTTYPES_H*/ -#define HAVE_INTTYPES_H @HAVE_INTTYPES_H@ - -/* Define to 1 if you have the `isnan' function. */ -/*#undef HAVE_ISNAN*/ -#define HAVE_ISNAN @HAVE_ISNAN@ - -/* Define to 1 if you have the `localtime_r' function. */ -/*#undef HAVE_LOCALTIME_R*/ -#define HAVE_LOCALTIME_R @HAVE_LOCALTIME_R@ - -/* Define to 1 if you have the `localtime_s' function. */ -/*#undef HAVE_LOCALTIME_S*/ -#define HAVE_LOCALTIME_S @HAVE_LOCALTIME_S@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_MALLOC_H*/ -#define HAVE_MALLOC_H @HAVE_MALLOC_H@ - -/* Define to 1 if you have the `malloc_usable_size' function. */ -/*#undef HAVE_MALLOC_USABLE_SIZE*/ -#define HAVE_MALLOC_USABLE_SIZE @HAVE_MALLOC_USABLE_SIZE@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_MEMORY_H*/ -#define HAVE_MEMORY_H @HAVE_MEMORY_H@ - -/* Define to 1 if you have the `pread' function. */ -/*#undef HAVE_PREAD*/ -#define HAVE_PREAD @HAVE_PREAD@ - -/* Define to 1 if you have the `pread64' function. */ -/*#undef HAVE_PREAD64*/ -#define HAVE_PREAD64 @HAVE_PREAD64@ - -/* Define to 1 if you have the `pwrite' function. */ -/*#undef HAVE_PWRITE*/ -#define HAVE_PWRITE @HAVE_PWRITE@ - -/* Define to 1 if you have the `pwrite64' function. */ -/*#undef HAVE_PWRITE64*/ -#define HAVE_PWRITE64 @HAVE_PWRITE64@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_STDINT_H*/ -#define HAVE_STDINT_H @HAVE_STDINT_H@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_STDLIB_H*/ -#define HAVE_STDLIB_H @HAVE_STDLIB_H@ - -/* Define to 1 if you have the `strchrnul' function. */ -/*#undef HAVE_STRCHRNUL*/ -#define HAVE_STRCHRNUL @HAVE_STRCHRNUL@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_STRINGS_H*/ -#define HAVE_STRINGS_H @HAVE_STRINGS_H@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_STRING_H*/ -#define HAVE_STRING_H @HAVE_STRING_H@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_SYS_STAT_H*/ -#define HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_SYS_TYPES_H*/ -#define HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ - -/* Define to 1 if the system has the type `uint16_t'. */ -/*#undef HAVE_UINT16_T*/ -#define HAVE_UINT16_T @HAVE_UINT16_T@ - -/* Define to 1 if the system has the type `uint32_t'. */ -/*#undef HAVE_UINT32_T*/ -#define HAVE_UINT32_T @HAVE_UINT32_T@ - -/* Define to 1 if the system has the type `uint64_t'. */ -/*#undef HAVE_UINT64_T*/ -#define HAVE_UINT64_T @HAVE_UINT64_T@ - -/* Define to 1 if the system has the type `uint8_t'. */ -/*#undef HAVE_UINT8_T*/ -#define HAVE_UINT8_T @HAVE_UINT8_T@ - -/* Define to 1 if the system has the type `uintptr_t'. */ -/*#undef HAVE_UINTPTR_T*/ -#define HAVE_UINTPTR_T @HAVE_UINTPTR_T@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_UNISTD_H*/ -#define HAVE_UNISTD_H @HAVE_UNISTD_H@ - -/* Define to 1 if you have the `usleep' function. */ -/*#undef HAVE_USLEEP*/ -#define HAVE_USLEEP @HAVE_USLEEP@ - -/* Define to 1 if you have the `utime' function. */ -/*#undef HAVE_UTIME*/ -#define HAVE_UTIME @HAVE_UTIME@ - -/* Define to 1 if you have the header file. */ -/*#undef HAVE_ZLIB_H*/ -#define HAVE_ZLIB_H @HAVE_ZLIB_H@ - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -/*#undef LT_OBJDIR*/ -/*#define LT_OBJDIR @LT_OBJDIR@*/ - -/* Define to the address where bug reports for this package should be sent. */ -/*#undef PACKAGE_BUGREPORT*/ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -/*#undef PACKAGE_NAME*/ -#define PACKAGE_NAME "sqlite" - -/* Define to the full name and version of this package. */ -/*#undef PACKAGE_STRING*/ -#define PACKAGE_STRING "sqlite @RELEASE@" - -/* Define to the one symbol short name of this package. */ -/*#undef PACKAGE_TARNAME*/ -#define PACKAGE_TARNAME "sqlite" - -/* Define to the home page for this package. */ -/*#undef PACKAGE_URL*/ -#define PACKAGE_URL @PACKAGE_URL@ - -/* Define to the version of this package. */ -/*#undef PACKAGE_VERSION*/ -#define PACKAGE_VERSION @VERSION@ - -/* Define to 1 if you have the ANSI C header files. */ -/*#undef STDC_HEADERS*/ -#define STDC_HEADERS 1 /* @STDC_HEADERS@ */ - -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/*#undef _FILE_OFFSET_BITS*/ -/*#define _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@*/ -/*@if _FILE_OFFSET_BITS != ""*/ -/*#define _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@*/ -/*@endif*/ - -/* Define for large files, on AIX-style hosts. */ -/*#undef _LARGE_FILES*/ -/*@if _LARGE_FILES*/ -/*#define _LARGE_FILES @_LARGE_FILES@*/ -/*@endif*/ From ea13658566361027e414925b2cb3206bfd147d53 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Nov 2024 15:55:19 +0000 Subject: [PATCH 340/522] Remove some obsolete macros from the CLI. FossilOrigin-Name: 5c4eb625709eda24b11a0437b150a60fc1497c136a4a2ab2b9d559d893dd397a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 9 ++------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 01eec35bff..ebaec925f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\swindow\sfunctions\smin()\sand\smax()\swhen\sused\swith\sa\sFILTER\sclause.\sForum\spost\s[forum:/forumpost/e9126d554a\s|\se9126d554a]. -D 2024-11-14T14:38:16.785 +C Remove\ssome\sobsolete\smacros\sfrom\sthe\sCLI. +D 2024-11-14T15:55:19.992 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -776,7 +776,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 45e69e4e69576847a5b49aeac624c9ffad5666697ce037d38bc331a56733765f +F src/shell.c.in c61d7af58e678d479f1450e4ea236d2d6ac3bb16a636030104f210303b30d563 F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6bfd09408b9a51c0cbdb28f901a79c9774da755294d7eb67d88e4c42c5652830 -R 4dbd1e8b72bd923323c250178cad8662 -U dan -Z 283ba5d1ed32af60aeb437d70b951d46 +P d15fb0f75e64bbfdb8df0c0d0358aafbbd7d5e2048df676dafe1abd5e9917f2a +R ea2490bd05c4dad29cbfefcd8763a20e +U drh +Z 85890363a91293052a9bfcb213db9376 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a40565627e..bff9245613 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d15fb0f75e64bbfdb8df0c0d0358aafbbd7d5e2048df676dafe1abd5e9917f2a +5c4eb625709eda24b11a0437b150a60fc1497c136a4a2ab2b9d559d893dd397a diff --git a/src/shell.c.in b/src/shell.c.in index 722d8d49dc..55fba9d82d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -13276,15 +13276,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ char *zHome; char *zHistory; int nHistory; -#if CIO_WIN_WC_XLATE -# define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "") -#else -# define SHELL_CIO_CHAR_SET "" -#endif sqlite3_fprintf(stdout, - "SQLite version %s %.19s%s\n" /*extra-version-info*/ + "SQLite version %s %.19s\n" /*extra-version-info*/ "Enter \".help\" for usage hints.\n", - sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET); + sqlite3_libversion(), sqlite3_sourceid()); if( warnInmemoryDb ){ sputz(stdout, "Connected to a "); printBold("transient in-memory database"); From 98be43ed73f34f5f3de87ea9fa47bb03e40f1da4 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 14 Nov 2024 16:00:45 +0000 Subject: [PATCH 341/522] Fix a state makefile dependency which refered to the now-removed sqlite_cfg.h.in. FossilOrigin-Name: 9a726b4be8ddd4b388478024a0952cfd4f0b9f665ab69119a6de0b996ac72216 --- Makefile.in | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 530d82e4f7..390e707478 100644 --- a/Makefile.in +++ b/Makefile.in @@ -308,7 +308,7 @@ sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF) @touch $@ install: install-pc # defined in main.mk -sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF) +sqlite_cfg.h: $(AS_AUTO_DEF) $(AS_AUTORECONFIG) @touch $@ diff --git a/manifest b/manifest index 3162cddcf1..9bcd6b3714 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Remove\sunused\ssqlite_cfg.h.in\s(sqlite_cfg.h\sgets\sgenerated\swithout\san\sinput\stemplate). -D 2024-11-14T15:25:05.834 +C Fix\sa\sstate\smakefile\sdependency\swhich\srefered\sto\sthe\snow-removed\ssqlite_cfg.h.in. +D 2024-11-14T16:00:45.775 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in 580a60aa8deb37060c7973d9399c51c4388f1e0ad0be6555dcd44bc8d2ac3260 +F Makefile.in d941328627467c1bc2f13861b0bf5dc1e0c4669c072eec20b37285777f41d289 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d15fb0f75e64bbfdb8df0c0d0358aafbbd7d5e2048df676dafe1abd5e9917f2a -R d6d753c19cf72fb017b2468f8e1184ee +P 6148f2d39237a85edb399e5c2beb305dccd99ca8c0cf143e8c2ddc0fc1d9e916 +R c8ff2644822f8bbab8e63072254a5a68 U stephan -Z 38d02b611518b292e9e6ae3697162b25 +Z 54ae5ab64b4869b51425727dae4b6b51 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4e12ecd2e7..6eabf1aec3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6148f2d39237a85edb399e5c2beb305dccd99ca8c0cf143e8c2ddc0fc1d9e916 +9a726b4be8ddd4b388478024a0952cfd4f0b9f665ab69119a6de0b996ac72216 From c096d6add6a0f5c8338272c0d5b29c28511b3fc1 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 14 Nov 2024 17:52:59 +0000 Subject: [PATCH 342/522] Add --enable-dev configure flag which sets various other flags. FossilOrigin-Name: ea79c363a42484357ac4ac3422f3466e5bc5cb56e5b2a06a3dc4ec90fea1c190 --- auto.def | 11 +++++++++++ manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index 8466fc779a..90f11f1ee9 100644 --- a/auto.def +++ b/auto.def @@ -194,6 +194,7 @@ set flags { test-status => {Enable status of tests} gcov=0 => {Enable coverage testing using gcov} linemacros => {Enable #line macros in the amalgamation} + dev => {Enable dev-mode build: automatically enables certain other flags} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} #soname:=none => {SONAME for libsqlite3.so} #^^^ we "could", but arguably shouldn't, support clients passing a @@ -469,6 +470,16 @@ proc sqlite-check-soname {} { } sqlite-check-soname +proj-if-opt-truthy dev { + # --enable-dev needs to come early so that the downstream tests + # which check for these flags will show the user their updated + # state. + proj-opt-set all 1 + proj-opt-set debug 1 + proj-opt-set amalgamation 0 + define CFLAGS [get-env CFLAGS {-O0 -g}] +} + proj-define-for-opt shared ENABLE_SHARED "Build shared library?" if {![proj-define-for-opt static ENABLE_STATIC \ diff --git a/manifest b/manifest index b9f21671b1..cf36dbfee1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunused\ssqlite_cfg.h.in\sfrom\sthe\sbuild. -D 2024-11-14T16:06:36.424 +C Add\s--enable-dev\sconfigure\sflag\swhich\ssets\svarious\sother\sflags. +D 2024-11-14T17:52:59.923 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 7dbe7bebe9c3bea4de674053339964b4b26cff5e2fdc20948acc723b5080bffd +F auto.def 0201703bd03a1e998646f47e8ca0c7b89a219ff2ab87139fdfc34b820d230981 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,9 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5c4eb625709eda24b11a0437b150a60fc1497c136a4a2ab2b9d559d893dd397a 9a726b4be8ddd4b388478024a0952cfd4f0b9f665ab69119a6de0b996ac72216 -R a15407640daa9f3a9447a9e78becdb8b -T +closed 9a726b4be8ddd4b388478024a0952cfd4f0b9f665ab69119a6de0b996ac72216 Closed\sby\sintegrate-merge. +P bba54e26de56ddf804990f5cd9a1978a14580f06c5771a79803907013df8491e +R 52449d4304f2eea2db488af261c0c62f U stephan -Z 19ed65a5f5fcf67d42d45f2f1b7e12e4 +Z 77b9d9984833e746e00359840a52aebd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 40230bb725..86860b0279 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bba54e26de56ddf804990f5cd9a1978a14580f06c5771a79803907013df8491e +ea79c363a42484357ac4ac3422f3466e5bc5cb56e5b2a06a3dc4ec90fea1c190 From 59c80e05333cfc23861481c8cd3000b847e92ace Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Nov 2024 19:06:00 +0000 Subject: [PATCH 343/522] Add new makefile target "sqlite3d" (where the "d" means either "development" or "debug") that always uses separate source files, regardless of the --disable-amalgmation setting. FossilOrigin-Name: 91da205beb7e5cab7a76be98e4cfddc4fb4c07022825ea645bc97f331c6bcdaa --- main.mk | 13 +++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/main.mk b/main.mk index 8cc37ff775..61e0514822 100644 --- a/main.mk +++ b/main.mk @@ -1915,12 +1915,25 @@ threadtest5: sqlite3.c $(TOP)/test/threadtest5.c $(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3) xbin: threadtest5 +# The standard CLI is built using the amalgamation since it uses +# special compile-time options that are interpreted by individual +# source files within the amalgamation. +# sqlite3$(T.exe): shell.c sqlite3.c $(T.link) -o $@ \ shell.c sqlite3.c \ $(CFLAGS.readline) $(SHELL_OPT) \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) +# The "sqlite3d" CLI is build using separate source files. This +# is useful during development and debugging. +# +sqlite3d$(T.exe): shell.c $(LIBOBJS0) + $(T.link) -o $@ \ + shell.c $(LIBOBJS0) \ + $(CFLAGS.readline) $(SHELL_OPT) \ + $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) + # # Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the # semantics of 0 and 1 are confusingly swapped here. diff --git a/manifest b/manifest index cf36dbfee1..73fd9d1401 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s--enable-dev\sconfigure\sflag\swhich\ssets\svarious\sother\sflags. -D 2024-11-14T17:52:59.923 +C Add\snew\smakefile\starget\s"sqlite3d"\s(where\sthe\s"d"\smeans\seither\s"development"\sor\n"debug")\sthat\salways\suses\sseparate\ssource\sfiles,\sregardless\sof\sthe\s\n--disable-amalgmation\ssetting. +D 2024-11-14T19:06:00.821 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk cd92df46e074ce11466d43530cfe23cef48ac541aee4714181369e3fe92df05a +F main.mk 51e0eb180616a4863865e785bab5a4687326df5e9c0be3ab6005b775bd292f5b F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bba54e26de56ddf804990f5cd9a1978a14580f06c5771a79803907013df8491e -R 52449d4304f2eea2db488af261c0c62f -U stephan -Z 77b9d9984833e746e00359840a52aebd +P ea79c363a42484357ac4ac3422f3466e5bc5cb56e5b2a06a3dc4ec90fea1c190 +R f73cd6f3e9db5bb5c6986a07c9399aad +U drh +Z 85bc26d605e98ed3bdc053f173922b85 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 86860b0279..5bc74f1324 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea79c363a42484357ac4ac3422f3466e5bc5cb56e5b2a06a3dc4ec90fea1c190 +91da205beb7e5cab7a76be98e4cfddc4fb4c07022825ea645bc97f331c6bcdaa From 009601d5340e1b55cb589a4fdec7b101a455ff3f Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 14 Nov 2024 19:25:23 +0000 Subject: [PATCH 344/522] Remove $prefix/include from the default -I path because it can cause the build to pick up an unintended copy of sqlite3.h. Extend the ICU configure support (the origin of -I$prefix/include) to enable fetching the -I path from icu-config and apply it only to those objects which need it. FossilOrigin-Name: f778dfdd6d6a4975c903d8ca0ebfb4fa917d543289136ea0ab740cb47d2510c1 --- Makefile.in | 6 +----- auto.def | 16 ++++++++++++---- main.mk | 7 ++++--- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Makefile.in b/Makefile.in index 390e707478..7bb0d80b5b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -153,6 +153,7 @@ LDFLAGS.dlopen = @LDFLAGS_DLOPEN@ LDFLAGS.readline = @LDFLAGS_READLINE@ CFLAGS.readline = @CFLAGS_READLINE@ LDFLAGS.icu = @LDFLAGS_ICU@ +CFLAGS.icu = @CFLAGS_ICU@ LDFLAGS.soname.libsqlite3 = @LDFLAGS_SONAME_LIBSQLITE3@ ENABLE_SHARED = @ENABLE_SHARED@ ENABLE_STATIC = @ENABLE_STATIC@ @@ -168,11 +169,6 @@ T.cc.sqlite = $(T.cc) @TARGET_DEBUG@ # all builds. # T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite -# -# -I$(prefix)/include is primarily so that the ICU -# headers can be found. -# -T.cc.sqlite += -I$(prefix)/include # # $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH) diff --git a/auto.def b/auto.def index 90f11f1ee9..f8d0758ead 100644 --- a/auto.def +++ b/auto.def @@ -182,7 +182,9 @@ set flags { # with-icu-ldflags:LDFLAGS => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} - with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU and fetch linker flags from the given icu-config binary} + with-icu-cflags:CFLAGS + => {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU. e.g. -I/usr/local/include} + with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU and fetch ldflags and cflags flags from the given icu-config binary} icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=... or --with-icu-config} # # @@ -362,6 +364,7 @@ proc sqlite-check-wasi-sdk {} { with-emsdk with-icu-config with-icu-ldflags + with-icu-cflags with-linenoise with-tcl } { @@ -1122,6 +1125,7 @@ proj-if-opt-truthy math { # Handles these flags: # # --with-icu-ldflags=LDFLAGS +# --with-icu-cflags=CFLAGS # --with-icu-config[=/path/to/icu-config] # --enable-icu-collations # @@ -1134,6 +1138,7 @@ proj-if-opt-truthy math { # opt-in feature. proc sqlite-check-icu {} { define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]] + define CFLAGS_ICU [join [opt-val with-icu-cflags ""]] # Flags sets seen in the wild for ICU: # - -licui18n -licuuc -licudata # - -licui18n -licuuc @@ -1155,14 +1160,17 @@ proc sqlite-check-icu {} { proj-fatal "$bin --ldflags returned no data" } define-append LDFLAGS_ICU $x + set x [exec $bin --cppflags] + define-append CFLAGS_ICU $x } else { proj-fatal "--with-icu-config=$bin does not refer to an executable" } } - set flags [define LDFLAGS_ICU [string trim [get-define LDFLAGS_ICU]]] - if {"" ne $flags} { + set ldflags [define LDFLAGS_ICU [string trim [get-define LDFLAGS_ICU]]] + set cflags [define CFLAGS_ICU [string trim [get-define CFLAGS_ICU]]] + if {"" ne $ldflags} { sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU - msg-result "Enabling ICU support with libs: $flags" + msg-result "Enabling ICU support with libs ($ldflags) and cflags ($cflags)" if {[opt-bool icu-collations]} { msg-result "Enabling ICU collations." sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU_COLLATIONS diff --git a/main.mk b/main.mk index 61e0514822..b6a18e14bc 100644 --- a/main.mk +++ b/main.mk @@ -162,6 +162,7 @@ LDFLAGS.pthread ?= -lpthread LDFLAGS.dlopen ?= -ldl LDFLAGS.shobj ?= -shared LDFLAGS.icu ?= # -licui18n -licuuc -licudata +CFLAGS.icu ?= LDFLAGS.soname.libsqlite3 ?= # libreadline (or a workalike): # To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE=1 @@ -1922,7 +1923,7 @@ xbin: threadtest5 sqlite3$(T.exe): shell.c sqlite3.c $(T.link) -o $@ \ shell.c sqlite3.c \ - $(CFLAGS.readline) $(SHELL_OPT) \ + $(CFLAGS.readline) $(SHELL_OPT) $(CFLAGS.icu) \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) # The "sqlite3d" CLI is build using separate source files. This @@ -2137,7 +2138,7 @@ shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(B.tclsh) # has_tclsh84 # DEPS_EXT_COMMON = $(DEPS_OBJ_COMMON) $(EXTHDR) icu.o: $(TOP)/ext/icu/icu.c $(DEPS_EXT_COMMON) - $(T.cc.extension) -c $(TOP)/ext/icu/icu.c + $(T.cc.extension) -c $(TOP)/ext/icu/icu.c $(CFLAGS.icu) fts3.o: $(TOP)/ext/fts3/fts3.c $(DEPS_EXT_COMMON) $(T.cc.extension) -c $(TOP)/ext/fts3/fts3.c @@ -2152,7 +2153,7 @@ fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(DEPS_EXT_COMMON) $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_hash.c fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(DEPS_EXT_COMMON) - $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_icu.c + $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_icu.c $(CFLAGS.icu) fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(DEPS_EXT_COMMON) $(T.cc.extension) -c $(TOP)/ext/fts3/fts3_porter.c diff --git a/manifest b/manifest index 73fd9d1401..dfd8873d8e 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\snew\smakefile\starget\s"sqlite3d"\s(where\sthe\s"d"\smeans\seither\s"development"\sor\n"debug")\sthat\salways\suses\sseparate\ssource\sfiles,\sregardless\sof\sthe\s\n--disable-amalgmation\ssetting. -D 2024-11-14T19:06:00.821 +C Remove\s$prefix/include\sfrom\sthe\sdefault\s-I\spath\sbecause\sit\scan\scause\sthe\sbuild\sto\spick\sup\san\sunintended\scopy\sof\ssqlite3.h.\sExtend\sthe\sICU\sconfigure\ssupport\s(the\sorigin\sof\s-I$prefix/include)\sto\senable\sfetching\sthe\s-I\spath\sfrom\sicu-config\sand\sapply\sit\sonly\sto\sthose\sobjects\swhich\sneed\sit. +D 2024-11-14T19:25:23.540 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in d941328627467c1bc2f13861b0bf5dc1e0c4669c072eec20b37285777f41d289 +F Makefile.in 6b8dd4c654bd0bddc2ac4d38e57521482896ebc6249a1a445a180100bc60826f F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 0201703bd03a1e998646f47e8ca0c7b89a219ff2ab87139fdfc34b820d230981 +F auto.def f40c5130bb6a719439300c4e186cd77ebc6cfd6b9c78f65eee8978fbcb26bd05 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 51e0eb180616a4863865e785bab5a4687326df5e9c0be3ab6005b775bd292f5b +F main.mk b50bf0907d551b9596d0e4ce1e74c2179885364b87eb921fcf685521cba8d335 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ea79c363a42484357ac4ac3422f3466e5bc5cb56e5b2a06a3dc4ec90fea1c190 -R f73cd6f3e9db5bb5c6986a07c9399aad -U drh -Z 85bc26d605e98ed3bdc053f173922b85 +P 91da205beb7e5cab7a76be98e4cfddc4fb4c07022825ea645bc97f331c6bcdaa +R da94ff57aef6138935557e3d7da83893 +U stephan +Z 872305027d80572ab04100d3a42a5fa3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5bc74f1324..e41db9ab1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91da205beb7e5cab7a76be98e4cfddc4fb4c07022825ea645bc97f331c6bcdaa +f778dfdd6d6a4975c903d8ca0ebfb4fa917d543289136ea0ab740cb47d2510c1 From f121ffbde30a1a34e9e7aff389cf6766c9e1541d Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 14 Nov 2024 19:34:28 +0000 Subject: [PATCH 345/522] Fix typo in the handling of the new --dev flag which caused it to set the --debug flag instead of the --with-debug flag (the former is for autosetup's internal use). FossilOrigin-Name: 81202d2ab5963fdcf20555b6d0b31cc955ac27f1cd87656faea5c0611c9a2ee8 --- auto.def | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index f8d0758ead..611a786387 100644 --- a/auto.def +++ b/auto.def @@ -478,7 +478,7 @@ proj-if-opt-truthy dev { # which check for these flags will show the user their updated # state. proj-opt-set all 1 - proj-opt-set debug 1 + proj-opt-set with-debug 1 proj-opt-set amalgamation 0 define CFLAGS [get-env CFLAGS {-O0 -g}] } diff --git a/manifest b/manifest index dfd8873d8e..6154a16529 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\s$prefix/include\sfrom\sthe\sdefault\s-I\spath\sbecause\sit\scan\scause\sthe\sbuild\sto\spick\sup\san\sunintended\scopy\sof\ssqlite3.h.\sExtend\sthe\sICU\sconfigure\ssupport\s(the\sorigin\sof\s-I$prefix/include)\sto\senable\sfetching\sthe\s-I\spath\sfrom\sicu-config\sand\sapply\sit\sonly\sto\sthose\sobjects\swhich\sneed\sit. -D 2024-11-14T19:25:23.540 +C Fix\stypo\sin\sthe\shandling\sof\sthe\snew\s--dev\sflag\swhich\scaused\sit\sto\sset\sthe\s--debug\sflag\sinstead\sof\sthe\s--with-debug\sflag\s(the\sformer\sis\sfor\sautosetup's\sinternal\suse). +D 2024-11-14T19:34:28.930 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def f40c5130bb6a719439300c4e186cd77ebc6cfd6b9c78f65eee8978fbcb26bd05 +F auto.def d314af75944a40fdc466212d7f40e5056af843ace7f4025591d63fb942a26e27 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 91da205beb7e5cab7a76be98e4cfddc4fb4c07022825ea645bc97f331c6bcdaa -R da94ff57aef6138935557e3d7da83893 +P f778dfdd6d6a4975c903d8ca0ebfb4fa917d543289136ea0ab740cb47d2510c1 +R 8f1a4b67fcbeb88fc42130b5848bb2cd U stephan -Z 872305027d80572ab04100d3a42a5fa3 +Z 1bce6ce0c64505db6d931db182e302d9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e41db9ab1c..4f7ed134be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f778dfdd6d6a4975c903d8ca0ebfb4fa917d543289136ea0ab740cb47d2510c1 +81202d2ab5963fdcf20555b6d0b31cc955ac27f1cd87656faea5c0611c9a2ee8 From 75ed9f819ffd11d39d3637f349da51d721990c47 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 15 Nov 2024 10:07:57 +0000 Subject: [PATCH 346/522] An experiment in optionally using pkg-config to determine the libs to link in for ICU support, but its ldflags is missing one required lib on both Linux and OpenBSD. Keeping this for later reference, as it demonstrates how to use pkg-config from autosetup. FossilOrigin-Name: 09caa94c9e846f9b3669b3f1acbb26b24b8bfcc9e512f17ea074dd92745c2597 --- auto.def | 73 +++++++++++++++++++++++++++++++++------------------ manifest | 16 ++++++----- manifest.uuid | 2 +- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/auto.def b/auto.def index 611a786387..fe7d045e33 100644 --- a/auto.def +++ b/auto.def @@ -12,7 +12,7 @@ # # JimTCL: https://jim.tcl.tk # -use cc cc-db cc-shared cc-lib proj +use cc cc-db cc-shared cc-lib proj pkg-config # $DUMP_DEFINES_TXT is the file emitted by --dump-defines, intended # only for build debugging and not part of the public build interface. @@ -184,7 +184,7 @@ set flags { => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries} with-icu-cflags:CFLAGS => {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU. e.g. -I/usr/local/include} - with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU and fetch ldflags and cflags flags from the given icu-config binary} + with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config, /path/to/icu-config} icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=... or --with-icu-config} # # @@ -1126,16 +1126,25 @@ proj-if-opt-truthy math { # # --with-icu-ldflags=LDFLAGS # --with-icu-cflags=CFLAGS -# --with-icu-config[=/path/to/icu-config] +# --with-icu-config[=auto | pkg-config | /path/to/icu-config] # --enable-icu-collations # -# If both icu-ldflags and icu-config are provided, they are -# cumulative. If neither are provided, icu-collations is not honored -# and a warning is emitted if it is provided. +# --with-icu-config values: +# +# - auto: use the first one of (pkg-config, icu-config) found. +# - pkg-config: use only pkg-config to determine flags +# - /path/to/icu-config: use that to determine flags +# +# If --with-icu-config is used as neither pkg-config nor icu-config +# are found, fail fatally. +# +# If both --with-icu-ldflags and --with-icu-config are provided, they +# are cumulative. If neither are provided, icu-collations is not +# honored and a warning is emitted if it is provided. # # Design note: though we can automatically enable ICU if the -# icu-config binary is found, we specifically do not. ICU is always an -# opt-in feature. +# icu-config binary or (pkg-config icu-uc) are found, we specifically +# do not. ICU is always an opt-in feature. proc sqlite-check-icu {} { define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]] define CFLAGS_ICU [join [opt-val with-icu-cflags ""]] @@ -1144,33 +1153,45 @@ proc sqlite-check-icu {} { # - -licui18n -licuuc # - /usr/local/bin/icu-config --ldflags if {[proj-opt-was-provided with-icu-config]} { - set bin [opt-val with-icu-config] - if {"auto" eq $bin} { - set bin [proj-first-bin-of \ - [get-define prefix]/bin/icu-config \ - /usr/local/bin/icu-config \ - /usr/bin/icu-config] - if {"" eq $bin} { - proj-fatal "--with-icu-config=auto cannot find icu-config binary" + set icuConfigBin [opt-val with-icu-config] + set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config + if {[pkg-config-init 0] + && ("auto" eq $icuConfigBin || "pkg-config" eq $icuConfigBin)} { + if {[pkg-config icu-uc]} { + set tryIcuConfigBin 0 + define LDFLAGS_ICU [get-define PKG_ICU_UC_LDFLAGS] + define-append LDFLAGS_ICU [get-define PKG_ICU_UC_LIBS] + define CFLAGS_ICU [get-define PKG_ICU_UC_CFLAGS] } } - if {[file-isexec $bin]} { - set x [exec $bin --ldflags] - if {"" eq $x} { - proj-fatal "$bin --ldflags returned no data" + if {$tryIcuConfigBin} { + if {"auto" eq $icuConfigBin} { + set icuConfigBin [proj-first-bin-of \ + [get-define prefix]/bin/icu-config \ + /usr/local/bin/icu-config \ + /usr/bin/icu-config] + if {"" eq $icuConfigBin} { + proj-fatal "--with-icu-config=auto cannot find icu-config binary" + } + } + if {[file-isexec $icuConfigBin]} { + set x [exec $icuConfigBin --ldflags] + if {"" eq $x} { + proj-fatal "$icuConfigBin --ldflags returned no data" + } + define-append LDFLAGS_ICU $x + set x [exec $icuConfigBin --cppflags] + define-append CFLAGS_ICU $x + } else { + proj-fatal "--with-icu-config=$bin does not refer to an executable" } - define-append LDFLAGS_ICU $x - set x [exec $bin --cppflags] - define-append CFLAGS_ICU $x - } else { - proj-fatal "--with-icu-config=$bin does not refer to an executable" } } set ldflags [define LDFLAGS_ICU [string trim [get-define LDFLAGS_ICU]]] set cflags [define CFLAGS_ICU [string trim [get-define CFLAGS_ICU]]] if {"" ne $ldflags} { sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU - msg-result "Enabling ICU support with libs ($ldflags) and cflags ($cflags)" + msg-result "Enabling ICU support with flags: $ldflags $cflags" if {[opt-bool icu-collations]} { msg-result "Enabling ICU collations." sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU_COLLATIONS diff --git a/manifest b/manifest index 6154a16529..8d6dcfb860 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\shandling\sof\sthe\snew\s--dev\sflag\swhich\scaused\sit\sto\sset\sthe\s--debug\sflag\sinstead\sof\sthe\s--with-debug\sflag\s(the\sformer\sis\sfor\sautosetup's\sinternal\suse). -D 2024-11-14T19:34:28.930 +C An\sexperiment\sin\soptionally\susing\spkg-config\sto\sdetermine\sthe\slibs\sto\slink\sin\sfor\sICU\ssupport,\sbut\sits\sldflags\sis\smissing\sone\srequired\slib\son\sboth\sLinux\sand\sOpenBSD.\sKeeping\sthis\sfor\slater\sreference,\sas\sit\sdemonstrates\show\sto\suse\spkg-config\sfrom\sautosetup. +D 2024-11-15T10:07:57.846 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d314af75944a40fdc466212d7f40e5056af843ace7f4025591d63fb942a26e27 +F auto.def 70932f7acebcc439a811bb9c4117b31a28c7606a00f36bf729566a1c90ae4208 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,12 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f778dfdd6d6a4975c903d8ca0ebfb4fa917d543289136ea0ab740cb47d2510c1 -R 8f1a4b67fcbeb88fc42130b5848bb2cd +P 81202d2ab5963fdcf20555b6d0b31cc955ac27f1cd87656faea5c0611c9a2ee8 +R b6f94e3605bc6952a1abdeb693280714 +T *branch * autosetup-icu-pkg-config +T *sym-autosetup-icu-pkg-config * +T +closed * +T -sym-trunk * U stephan -Z 1bce6ce0c64505db6d931db182e302d9 +Z 244e7ce475b1c9a38fffc82237addd71 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4f7ed134be..0867bdbaf5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81202d2ab5963fdcf20555b6d0b31cc955ac27f1cd87656faea5c0611c9a2ee8 +09caa94c9e846f9b3669b3f1acbb26b24b8bfcc9e512f17ea074dd92745c2597 From aa85c8c854bbbb0ed8a421b9a812ad0a14dd7c83 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 15 Nov 2024 10:12:03 +0000 Subject: [PATCH 347/522] configure script doc additions for the ICU feature check. FossilOrigin-Name: 1925a68fc2323f0788aac9c3c2bb3005182eb3286037bc383181b6aa150d4270 --- auto.def | 15 ++++++++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/auto.def b/auto.def index 611a786387..759cf07fe0 100644 --- a/auto.def +++ b/auto.def @@ -1129,13 +1129,22 @@ proj-if-opt-truthy math { # --with-icu-config[=/path/to/icu-config] # --enable-icu-collations # -# If both icu-ldflags and icu-config are provided, they are -# cumulative. If neither are provided, icu-collations is not honored -# and a warning is emitted if it is provided. +# If --with-icu-config is provided but icu-config cannot be used fail +# fatally. If --with-icu-ldflags/cflags is/are provided, assume they +# are valid. +# +# If --with-icu-ldflags/cflags and --with-icu-config are provided, +# they are cumulative. If neither are provided, icu-collations is not +# honored and a warning is emitted if it is provided. # # Design note: though we can automatically enable ICU if the # icu-config binary is found, we specifically do not. ICU is always an # opt-in feature. +# +# Maintenance reminder: check-in 09caa94c9e84 added pkg-config support +# to this but the result fails to link on both Linux and OpenBSD +# (other systems were untested) because the pkg-config results are +# missing a required library. proc sqlite-check-icu {} { define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]] define CFLAGS_ICU [join [opt-val with-icu-cflags ""]] diff --git a/manifest b/manifest index 6154a16529..1ce6cea3c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\shandling\sof\sthe\snew\s--dev\sflag\swhich\scaused\sit\sto\sset\sthe\s--debug\sflag\sinstead\sof\sthe\s--with-debug\sflag\s(the\sformer\sis\sfor\sautosetup's\sinternal\suse). -D 2024-11-14T19:34:28.930 +C configure\sscript\sdoc\sadditions\sfor\sthe\sICU\sfeature\scheck. +D 2024-11-15T10:12:03.805 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def d314af75944a40fdc466212d7f40e5056af843ace7f4025591d63fb942a26e27 +F auto.def dbbaf480acd0c5b9f330580aec6a43f50e5c37a69b1e5bb3f722c0620f617094 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f778dfdd6d6a4975c903d8ca0ebfb4fa917d543289136ea0ab740cb47d2510c1 -R 8f1a4b67fcbeb88fc42130b5848bb2cd +P 81202d2ab5963fdcf20555b6d0b31cc955ac27f1cd87656faea5c0611c9a2ee8 +R f0c6d5bed8faeb01cfe709bf9d6cb9a1 U stephan -Z 1bce6ce0c64505db6d931db182e302d9 +Z 5ff845a37175f10e9a57fde007423669 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4f7ed134be..1bd2038e40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81202d2ab5963fdcf20555b6d0b31cc955ac27f1cd87656faea5c0611c9a2ee8 +1925a68fc2323f0788aac9c3c2bb3005182eb3286037bc383181b6aa150d4270 From ece4bf60ff0d55c2cf1459c8172b108c69dbb73e Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 15 Nov 2024 10:47:11 +0000 Subject: [PATCH 348/522] When checking pkg-config for ICU support use icu-io instead of icu-uc, as that contains all requires libs on Linux and BSD. FossilOrigin-Name: 6ca457542e1dceac2d68fe3d29ff1f0beb31a77ca3073bd7d8a6c62faabcdc1d --- auto.def | 22 ++++++++++++++-------- manifest | 16 ++++++---------- manifest.uuid | 2 +- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/auto.def b/auto.def index fe7d045e33..6cfc86b2b0 100644 --- a/auto.def +++ b/auto.def @@ -1152,26 +1152,32 @@ proc sqlite-check-icu {} { # - -licui18n -licuuc -licudata # - -licui18n -licuuc # - /usr/local/bin/icu-config --ldflags + # if {[proj-opt-was-provided with-icu-config]} { set icuConfigBin [opt-val with-icu-config] set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config - if {[pkg-config-init 0] - && ("auto" eq $icuConfigBin || "pkg-config" eq $icuConfigBin)} { - if {[pkg-config icu-uc]} { + if {"auto" eq $icuConfigBin || "pkg-config" eq $icuConfigBin} { + if {[pkg-config-init 0] && [pkg-config icu-io]} { + # Maintenance reminder: historical docs say to use both of + # (icu-io, icu-uc). icu-uc lacks a required lib and icu-io has + # all of them on tested OSes. set tryIcuConfigBin 0 - define LDFLAGS_ICU [get-define PKG_ICU_UC_LDFLAGS] - define-append LDFLAGS_ICU [get-define PKG_ICU_UC_LIBS] - define CFLAGS_ICU [get-define PKG_ICU_UC_CFLAGS] + define LDFLAGS_ICU [get-define PKG_ICU_IO_LDFLAGS] + define-append LDFLAGS_ICU [get-define PKG_ICU_IO_LIBS] + define CFLAGS_ICU [get-define PKG_ICU_IO_CFLAGS] + } elseif {"pkg-config" eq $icuConfigBin} { + proj-fatal "pkg-config cannot find package icu-io" + } else { + proj-assert {"auto" eq $icuConfigBin} } } if {$tryIcuConfigBin} { if {"auto" eq $icuConfigBin} { set icuConfigBin [proj-first-bin-of \ - [get-define prefix]/bin/icu-config \ /usr/local/bin/icu-config \ /usr/bin/icu-config] if {"" eq $icuConfigBin} { - proj-fatal "--with-icu-config=auto cannot find icu-config binary" + proj-fatal "--with-icu-config=auto cannot find (pkg-config icu-io) or icu-config binary" } } if {[file-isexec $icuConfigBin]} { diff --git a/manifest b/manifest index 8d6dcfb860..a461cdcc05 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C An\sexperiment\sin\soptionally\susing\spkg-config\sto\sdetermine\sthe\slibs\sto\slink\sin\sfor\sICU\ssupport,\sbut\sits\sldflags\sis\smissing\sone\srequired\slib\son\sboth\sLinux\sand\sOpenBSD.\sKeeping\sthis\sfor\slater\sreference,\sas\sit\sdemonstrates\show\sto\suse\spkg-config\sfrom\sautosetup. -D 2024-11-15T10:07:57.846 +C When\schecking\spkg-config\sfor\sICU\ssupport\suse\sicu-io\sinstead\sof\sicu-uc,\sas\sthat\scontains\sall\srequires\slibs\son\sLinux\sand\sBSD. +D 2024-11-15T10:47:11.414 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 70932f7acebcc439a811bb9c4117b31a28c7606a00f36bf729566a1c90ae4208 +F auto.def 1a12e32026291cfe082a9841ccc426db542593b8974f051f1b56823839b5a830 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,12 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 81202d2ab5963fdcf20555b6d0b31cc955ac27f1cd87656faea5c0611c9a2ee8 -R b6f94e3605bc6952a1abdeb693280714 -T *branch * autosetup-icu-pkg-config -T *sym-autosetup-icu-pkg-config * -T +closed * -T -sym-trunk * +P 09caa94c9e846f9b3669b3f1acbb26b24b8bfcc9e512f17ea074dd92745c2597 +R b87e57f1447c7c56c265c2868634f094 U stephan -Z 244e7ce475b1c9a38fffc82237addd71 +Z 7f13984488108361d5319553ed81989a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0867bdbaf5..4a5a83abdd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09caa94c9e846f9b3669b3f1acbb26b24b8bfcc9e512f17ea074dd92745c2597 +6ca457542e1dceac2d68fe3d29ff1f0beb31a77ca3073bd7d8a6c62faabcdc1d From 48c8447574de60699df68ee2f928c2d71a93cef2 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 15 Nov 2024 15:31:13 +0000 Subject: [PATCH 349/522] buildtclext.tcl: work around a case, reported in [forum:0683a49cb02f31a1|forum post 0683a49cb0], in which package maintainers edit their copy of tclConfig.sh to change the TCL_SHLIB_LD command. FossilOrigin-Name: e24a3efec8c168b69d665ab20e8d715210208e6cf291ac93549fdd175a9009d6 --- manifest | 13 ++++++------- manifest.uuid | 2 +- tool/buildtclext.tcl | 9 ++++++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 92cde3b804..e30f66e03f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C configure:\sadd\soptional\spkg-config\ssupport\sfor\sdetecting\sICU. -D 2024-11-15T10:53:57.203 +C buildtclext.tcl:\swork\saround\sa\scase,\sreported\sin\s[forum:0683a49cb02f31a1|forum\spost\s0683a49cb0],\sin\swhich\spackage\smaintainers\sedit\stheir\scopy\sof\stclConfig.sh\sto\schange\sthe\sTCL_SHLIB_LD\scommand. +D 2024-11-15T15:31:13.141 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2105,7 +2105,7 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e045 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x F tool/build-shell.sh 369c4b171cc877ad974fef691e4da782b4c1e99fe8f4361316c735f64d49280f -F tool/buildtclext.tcl b64d250517b148e644d26fcbc097851867a0df52cd4bafe9bcd94b8421e1428a +F tool/buildtclext.tcl f046701e0bfa7c70116555dd4c3fbd7a8b61779c10a9e7586936c77a118c4b09 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca @@ -2198,9 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1925a68fc2323f0788aac9c3c2bb3005182eb3286037bc383181b6aa150d4270 6ca457542e1dceac2d68fe3d29ff1f0beb31a77ca3073bd7d8a6c62faabcdc1d -R 02dd7c141e8d6d129c07207797697869 -T +closed 6ca457542e1dceac2d68fe3d29ff1f0beb31a77ca3073bd7d8a6c62faabcdc1d Closed\sby\sintegrate-merge. +P 3e5b8077c6c6ce72ecab3110eb45943b9765372df789088982dbd6046a7c2523 +R 94ae9c25b190024c5b115d0e3a9b04f4 U stephan -Z 467aed797000c9f6ea51561768e3c8cb +Z 33e57c416f120305271764524e72e9c6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1f254347f8..afec1a488e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e5b8077c6c6ce72ecab3110eb45943b9765372df789088982dbd6046a7c2523 +e24a3efec8c168b69d665ab20e8d715210208e6cf291ac93549fdd175a9009d6 diff --git a/tool/buildtclext.tcl b/tool/buildtclext.tcl index 6d9e4c3063..ba16fc3cde 100644 --- a/tool/buildtclext.tcl +++ b/tool/buildtclext.tcl @@ -107,7 +107,7 @@ if {$tcl_platform(platform)=="windows"} { set fd [open $LIBDIR/tclConfig.sh rb] set tclConfig [read $fd] close $fd - + # Extract parameter we will need from the tclConfig.sh file # set TCLMAJOR 8 @@ -140,14 +140,17 @@ if {$tcl_platform(platform)=="windows"} { if {[string length $OPTS]>1} { append LDFLAGS $OPTS } - set CMD [subst $cmd] if {$TCLMAJOR>8} { set OUT libtcl9sqlite$VERSION.$SUFFIX } else { set OUT libsqlite$VERSION.$SUFFIX } + set @ $OUT; # Workaround for https://sqlite.org/forum/forumpost/0683a49cb02f31a1 + # in which Gentoo edits their tclConfig.sh to include an soname + # linker flag which includes ${@} (the target file's name). + set CMD [subst $cmd] } - + # Show information about prior installs # if {$infoonly} { From e69b4d757e8fc97b031f30c741d473601435d211 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 15 Nov 2024 16:35:24 +0000 Subject: [PATCH 350/522] Generic auto.def cleanups. No functional differences. FossilOrigin-Name: 02aceb8c138b5b8f38c75aa0792efa12f14b002083df6141cf56ea0602d3174b --- auto.def | 71 ++++++++++++++++++++++----------------------------- manifest | 12 ++++----- manifest.uuid | 2 +- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/auto.def b/auto.def index 4871a98229..656ff53b4f 100644 --- a/auto.def +++ b/auto.def @@ -235,7 +235,7 @@ msg-result "Source dir = $srcdir" msg-result "Build dir = $::autosetup(builddir)" msg-result "Configuring SQLite version $PACKAGE_VERSION" -if {1} { +apply {{} { # # SQLITE_AUTORECONFIG contains make target rules for re-running the # configure script with the same arguments it was initially invoked @@ -248,13 +248,13 @@ if {1} { if {[string match {*[ &;$*"]*} $arg]} { return '$arg' } return $arg } - define-append SQLITE_AUTORECONFIG cd [squote $::autosetup(builddir)] && [squote $srcdir/configure] + define-append SQLITE_AUTORECONFIG cd [squote $::autosetup(builddir)] && [squote $::srcdir/configure] #{*}$::autosetup(argv) breaks with --flag='val with spaces', so... foreach arg $::autosetup(argv) { define-append SQLITE_AUTORECONFIG [squote $arg] } rename squote "" -} +}} # Are we cross-compiling? set isCrossCompiling [proj-is-cross-compiling] @@ -322,10 +322,20 @@ if {"" eq [proj-bin-define install]} { define CFLAGS [proj-get-env CFLAGS {-g -O2}] define BUILD_CFLAGS [proj-get-env BUILD_CFLAGS {-g}] +proj-if-opt-truthy dev { + # --enable-dev needs to come early so that the downstream tests + # which check for these flags will show the user their updated + # state. + proj-opt-set all 1 + proj-opt-set with-debug 1 + proj-opt-set amalgamation 0 + define CFLAGS [get-env CFLAGS {-O0 -g}] +} + ######################################################################## # Handle --with-wasi-sdk=DIR # -# This MUST be run early on because it may change the toolchain and +# This must be run early on because it may change the toolchain and # disable a number of config options. proc sqlite-check-wasi-sdk {} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] @@ -343,7 +353,7 @@ proc sqlite-check-wasi-sdk {} { # Disable numerous options which we know either can't work or are # not useful in this build... msg-result "Using wasi-sdk clang. Disabling CLI shell modifying config flags:" - # Boolean flags which must be switched off: + # Boolean (--enable-/--disable-) flags which must be switched off: foreach opt { editline gcov @@ -447,7 +457,7 @@ proj-check-rpath ; # Determine proper rpath-handling flag # # See discussion in/around: # https://sqlite.org/forum/forumpost/0c6fc6f46b2cb3 -proc sqlite-check-soname {} { +apply {{} { define LDFLAGS_SONAME_LIBSQLITE3 "" if {[proj-opt-was-provided soname]} { set soname [opt-val soname] @@ -469,19 +479,8 @@ proc sqlite-check-soname {} { } else { proj-fatal "This environment does not support SONAME." } - return sqlite-check-soname "" -} -sqlite-check-soname +}} -proj-if-opt-truthy dev { - # --enable-dev needs to come early so that the downstream tests - # which check for these flags will show the user their updated - # state. - proj-opt-set all 1 - proj-opt-set with-debug 1 - proj-opt-set amalgamation 0 - define CFLAGS [get-env CFLAGS {-O0 -g}] -} proj-define-for-opt shared ENABLE_SHARED "Build shared library?" @@ -718,7 +717,6 @@ proc sqlite-check-tcl {} { } } }; # sqlite-check-tcl - sqlite-check-tcl ######################################################################## @@ -1218,9 +1216,9 @@ proc sqlite-check-icu {} { sqlite-check-icu ######################################################################## -# Emscripten SDK for building the web-based wasm components. -# -proc sqlite-check-emsdk {} { +# Check for the Emscripten SDK for building the web-based wasm +# components. +apply {{} { set emccsh $::srcdir/tool/emcc.sh if {![get-define HAVE_WASI_SDK] && [proj-check-emsdk]} { define EMCC_WRAPPER $emccsh @@ -1230,8 +1228,7 @@ proc sqlite-check-emsdk {} { define EMCC_WRAPPER "" file delete -force $emccsh } -} -sqlite-check-emsdk +}} ######################################################################## # Check for log(3) in libm and die with an error if it is not @@ -1254,6 +1251,7 @@ proc affirm-have-math {featureName} { msg-result "Feature flags..." foreach {boolFlag featureFlag ifSetEvalThis} { all {} { + # The 'all' option must be first in this list. proj-opt-set fts4 proj-opt-set fts5 proj-opt-set geopoly @@ -1306,7 +1304,7 @@ foreach {boolFlag featureFlag} { ######################################################################### # Show the final feature flag sets: -if {1} { +apply {{} { set oFF [get-define OPT_FEATURE_FLAGS] if {"" ne $oFF} { define OPT_FEATURE_FLAGS [lsort -unique $oFF] @@ -1318,7 +1316,7 @@ if {1} { msg-result "Shell options: [get-define OPT_SHELL]" } unset oFF -} +}} ######################################################################## # "Re-export" the autoconf-conventional --XYZdir flags into something @@ -1337,20 +1335,13 @@ proj-remap-autoconf-dir-vars # Potential TODO (unclear): in sqlite3.pc.in, do we need to include # any CFLAGS_READLINE, CFLAGS_ZLIB, etc in its "Cflags:" section? proj-make-from-dot-in -touch Makefile sqlite3.pc -if {0} { - # Requires a hand-written sqlite_cfg.h.in... - proj-make-from-dot-in sqlite_cfg.h - # vs... -} else { - # Requires no input template... - make-config-header sqlite_cfg.h \ - -bare {SIZEOF_* HAVE_DECL_*} \ - -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG - TARGET_* USE_GCOV TCL_*} \ - -auto {HAVE_* PACKAGE_*} \ - -none * - proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@ -} +make-config-header sqlite_cfg.h \ + -bare {SIZEOF_* HAVE_DECL_*} \ + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG + TARGET_* USE_GCOV TCL_*} \ + -auto {HAVE_* PACKAGE_*} \ + -none * +proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@ ######################################################################## # Some build-dev/debug-only output diff --git a/manifest b/manifest index e30f66e03f..09e0189083 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C buildtclext.tcl:\swork\saround\sa\scase,\sreported\sin\s[forum:0683a49cb02f31a1|forum\spost\s0683a49cb0],\sin\swhich\spackage\smaintainers\sedit\stheir\scopy\sof\stclConfig.sh\sto\schange\sthe\sTCL_SHLIB_LD\scommand. -D 2024-11-15T15:31:13.141 +C Generic\sauto.def\scleanups.\sNo\sfunctional\sdifferences. +D 2024-11-15T16:35:24.257 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 538d9a162a8fe4811c0a4a22a2a07df40ea4c334f683b94231bfc2a18f14b913 +F auto.def a0f92f2d7762735da5f5728ffbcf44052d8b485b207ec87d13703b681dd7820f F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3e5b8077c6c6ce72ecab3110eb45943b9765372df789088982dbd6046a7c2523 -R 94ae9c25b190024c5b115d0e3a9b04f4 +P e24a3efec8c168b69d665ab20e8d715210208e6cf291ac93549fdd175a9009d6 +R c10328ada1a32fcd8e3a4906d06b0161 U stephan -Z 33e57c416f120305271764524e72e9c6 +Z 9ca9b894bda23cfd0311c07f841cb8fa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index afec1a488e..2f7809ee3d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e24a3efec8c168b69d665ab20e8d715210208e6cf291ac93549fdd175a9009d6 +02aceb8c138b5b8f38c75aa0792efa12f14b002083df6141cf56ea0602d3174b From 1adf87592f3d34874a0c91b1c44eaf33fde11e2b Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 15 Nov 2024 19:42:49 +0000 Subject: [PATCH 351/522] In the interest of minimizing downstream disruption, set the soname of libsqlite3.so to (by default) its legacy value of libsqlite3.so.0 and unconditionally create (or replace) a symlink with that name at install-time, in addition to the newer-named symlinks. FossilOrigin-Name: 0773677b553e032e992266c6c75e10565729238df3ef52b56602a92cf651bea7 --- Makefile.in | 2 +- auto.def | 41 +++++++++++++++++++++++++---------------- autosetup/proj.tcl | 9 ++++----- main.mk | 43 +++++++++++++++++++++++-------------------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 6 files changed, 63 insertions(+), 52 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7bb0d80b5b..500b5eb0b7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -154,7 +154,7 @@ LDFLAGS.readline = @LDFLAGS_READLINE@ CFLAGS.readline = @CFLAGS_READLINE@ LDFLAGS.icu = @LDFLAGS_ICU@ CFLAGS.icu = @CFLAGS_ICU@ -LDFLAGS.soname.libsqlite3 = @LDFLAGS_SONAME_LIBSQLITE3@ +LDFLAGS.libsqlite3.soname = @LDFLAGS_LIBSQLITE3_SONAME@ ENABLE_SHARED = @ENABLE_SHARED@ ENABLE_STATIC = @ENABLE_STATIC@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ diff --git a/auto.def b/auto.def index 656ff53b4f..4c55f91541 100644 --- a/auto.def +++ b/auto.def @@ -198,12 +198,7 @@ set flags { linemacros => {Enable #line macros in the amalgamation} dev => {Enable dev-mode build: automatically enables certain other flags} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} - #soname:=none => {SONAME for libsqlite3.so} - #^^^ we "could", but arguably shouldn't, support clients passing a - # value of libsqlite3.so.0 for compatibility with clients which - # linked against a pre-3.48 build. - # Maybe we should support values of --soname=(none,auto,legacy), where auto means - # to use the 3.48+ value of libsqlite3.so.3.. + soname:=legacy => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} # } if {"" ne $DUMP_DEFINES_JSON} { @@ -452,32 +447,46 @@ proj-check-rpath ; # Determine proper rpath-handling flag # It's not yet clear whether we gain anything from setting -soname, # but not having it has been a source of anxiety for some users. # Setting it to any value other than its historical value of -# libsqlite3.so.0 may (this is not certain) break dynamic linking of -# clients which initially linked against a legacy build. +# libsqlite3.so.0 may break dynamic linking of clients which initially +# linked against a legacy build (with its SONAME of libsqlite3.so.0). +# +# To be clear: the ABI has not changed between pre-3.48 and post-3.47 +# builds, but version number 0 (pre-3.48) was a historical remnant +# from libtool which "should" have always been version number 3 but +# was not, for reasons lost to history. +# +# If the goal is to reduce downstream disruption then we need to +# retain the SONAME libsqlite3.so.0. If the goal is to "pull the +# bandaid off" then switching libsqlite3.so.3 is arguably the right +# thing to do (at the very real risk of causing a fair amount of +# downstream disruption for package maintainers). # # See discussion in/around: # https://sqlite.org/forum/forumpost/0c6fc6f46b2cb3 apply {{} { - define LDFLAGS_SONAME_LIBSQLITE3 "" + define LDFLAGS_LIBSQLITE3_SONAME "" if {[proj-opt-was-provided soname]} { set soname [opt-val soname] } else { - return 0 + set soname legacy } switch -exact -- $soname { - none { return 0 } - auto - 3 { set soname libsqlite3.so.3 } - legacy - 0 { set soname libsqlite3.so.0 } + none { return 0 } + auto { set soname libsqlite3.so.3 } + legacy { set soname libsqlite3.so.0 } default { proj-fatal "Invalid value for --soname. Use one of (none, auto, legacy)." } } msg-debug "soname=$soname" if {[proj-check-soname $soname]} { - define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]$soname - msg-result "Setting SONAME: [get-define LDFLAGS_SONAME_LIBSQLITE3]" - } else { + define LDFLAGS_LIBSQLITE3_SONAME [get-define LDFLAGS_SONAME_PREFIX]$soname + msg-result "Setting SONAME: [get-define LDFLAGS_LIBSQLITE3_SONAME]" + } elseif {[proj-opt-was-provided soname]} { + # --soname was explicitly requested but not available, so fail fatally proj-fatal "This environment does not support SONAME." + } else { + msg-result "This environment does not support SONAME." } }} diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 136d4b0360..b3dc38e5f0 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -947,7 +947,7 @@ proc proj-check-rpath {} { # # Checks whether CC supports the -Wl,soname,lib... flag. If so, it # returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, to -# which the client would need to append "libwhatever.N". If not, it +# which the client would need to append "libwhatever.N". If not, it # returns 0 and defines LDFLAGS_SONAME_PREFIX to an empty string. # # The libname argument is only for purposes of running the flag @@ -1207,10 +1207,9 @@ proc proj-which-linenoise {dotH} { proc proj-remap-autoconf-dir-vars {} { set prefix [get-define prefix] set exec_prefix [get-define exec_prefix $prefix] - # Note that the ${...} here refers to make-side var derefs, not - # TCL-side vars. They must be formulated such that they are legal - # for use in (A) makefiles, (B) pkgconfig files, and (C) TCL's - # [subst] command. i.e. they must use the form ${X}. + # The following var derefs must be formulated such that they are + # legal for use in (A) makefiles, (B) pkgconfig files, and (C) TCL's + # [subst] command. i.e. they must use the form ${X}. foreach {flag makeVar makeDeref} { exec-prefix exec_prefix ${prefix} datadir datadir ${prefix}/share diff --git a/main.mk b/main.mk index b6a18e14bc..8fa0dee92e 100644 --- a/main.mk +++ b/main.mk @@ -1389,7 +1389,8 @@ all: lib # Dynamic libsqlite3 # $(libsqlite3.SO): $(LIBOBJ) - $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.soname.libsqlite3) $(LDFLAGS.libsqlite3) + $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.soname.libsqlite3) \ + $(LDFLAGS.libsqlite3) $(LDFLAGS.libsqlite3.soname) $(libsqlite3.SO)-1: $(libsqlite3.SO) $(libsqlite3.SO)-0 $(libsqlite3.SO)-: so: $(libsqlite3.SO)-$(ENABLE_SHARED) @@ -1401,9 +1402,13 @@ all: so # # - libsqlite3.so.$(PACKAGE_VERSION) # - libsqlite3.so.3 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) +# - libsqlite3.so.0 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) (see below) # - libsqlite3.so =symlink-> libsqlite3.so.3 # -# Regarding the historcal installation name of libsqlite3.so.0.8.6: +# The link named libsqlite3.so.0 is provided in an attempt to reduce +# downstream disruption when performing upgrades from pre-3.48 to a +# version 3.48 or higher. That name is considered a legacy remnant +# and will eventually be removed from this installation process. # # Historically libtool installed the library like so: # @@ -1417,13 +1422,12 @@ all: so # compatibility for systems which have libraries installed using those # conventions: # -# 1) If libsqlite3.so.0 is found in the target installation directory -# then it and libsqlite3.so.0.8.6 are re-linked to point to the -# newer-style names. We cannot retain both the old and new -# installation because they both share the high-level name -# $(libsqlite3.SO). The down-side of this is that it may well upset -# packaging tools when we replace libsqlite3.so (from a legacy -# package) with a new symlink. +# 1) If libsqlite3.so.0.8.6 is found in the target installation +# directory then it is re-linked to point to the newer-style +# names. We cannot retain both the old and new installation because +# they both share the high-level name $(libsqlite3.SO). The +# down-side of this is that it may upset packaging tools when we +# replace libsqlite3.so (from a legacy package) with a new symlink. # # 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links # to the legacy-style names are created. The primary intent of this @@ -1437,25 +1441,24 @@ all: so # install-so-1: $(install-dir.lib) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) "$(install-dir.lib)" - @echo "Setting up SO symlinks..."; \ + @echo "Setting up $(libsqlite3.SO) symlinks..."; \ cd "$(install-dir.lib)" || exit $$?; \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ + rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).0 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO) || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).3 || exit $$?; \ - ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ - ls -la $(libsqlite3.SO) $(libsqlite3.SO).3*; \ - if [ -e $(libsqlite3.SO).0 ]; then \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \ + ls -la $(libsqlite3.SO) $(libsqlite3.SO).[03]*; \ + if [ -e $(libsqlite3.SO).0.8.6 ]; then \ echo "ACHTUNG: legacy libtool-compatible install found. Re-linking it..."; \ - rm -f libsqlite3.la $(libsqlite3.SO).0* || exit $$?; \ - ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \ + rm -f libsqlite3.la $(libsqlite3.SO).0.8.6 || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ - ls -la $(libsqlite3.SO).0*; \ + ls -la $(libsqlite3.SO).0.8.6; \ elif [ x1 = "x$(INSTALL_SO_086_LINKS)" ]; then \ echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINKS=1"; \ - rm -f libsqlite3.la $(libsqlite3.SO).0* || exit $$?; \ - ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \ + rm -f libsqlite3.la $(libsqlite3.SO).0.8.6 || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ - ls -la $(libsqlite3.SO).0*; \ + ls -la $(libsqlite3.SO).0.8.6; \ fi install-so-0 install-so-: install-so: install-so-$(ENABLE_SHARED) diff --git a/manifest b/manifest index 09e0189083..83b23513ae 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Generic\sauto.def\scleanups.\sNo\sfunctional\sdifferences. -D 2024-11-15T16:35:24.257 +C In\sthe\sinterest\sof\sminimizing\sdownstream\sdisruption,\sset\sthe\ssoname\sof\slibsqlite3.so\sto\s(by\sdefault)\sits\slegacy\svalue\sof\slibsqlite3.so.0\sand\sunconditionally\screate\s(or\sreplace)\sa\ssymlink\swith\sthat\sname\sat\sinstall-time,\sin\saddition\sto\sthe\snewer-named\ssymlinks. +D 2024-11-15T19:42:49.439 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in 6b8dd4c654bd0bddc2ac4d38e57521482896ebc6249a1a445a180100bc60826f +F Makefile.in 2c90ab3183f810086878a784c323b7816238a5e6943d267c25a71edc623a05a3 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a0f92f2d7762735da5f5728ffbcf44052d8b485b207ec87d13703b681dd7820f +F auto.def ec2fa2ea6fd691af4a991e1906da314ce094d019b1b9d08563167b138114bbdc F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 9772d3f89634089add92e2238551a59a5c764d501327f6eb433dca7f98138802 +F autosetup/proj.tcl dd4cdf0c31967056bc2c1956b0601118182b7e143cffb184d79c6a625ae9ef87 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk b50bf0907d551b9596d0e4ce1e74c2179885364b87eb921fcf685521cba8d335 +F main.mk 579c3f70be718c97b82c12c14942305ed0c330619355aad26ed14a752f6daf57 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e24a3efec8c168b69d665ab20e8d715210208e6cf291ac93549fdd175a9009d6 -R c10328ada1a32fcd8e3a4906d06b0161 +P 02aceb8c138b5b8f38c75aa0792efa12f14b002083df6141cf56ea0602d3174b +R 5c04b60962f1254417c6b379054d3030 U stephan -Z 9ca9b894bda23cfd0311c07f841cb8fa +Z 553f27947bf815a9543e751ee4c1db5b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2f7809ee3d..8840572362 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02aceb8c138b5b8f38c75aa0792efa12f14b002083df6141cf56ea0602d3174b +0773677b553e032e992266c6c75e10565729238df3ef52b56602a92cf651bea7 From 178ce6287b827cf75fffa0ec89a8aa3d846a3c2a Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Nov 2024 20:39:41 +0000 Subject: [PATCH 352/522] Enhance the vfstrace extension such that the output can be controlled using the "PRAGMA vfstrace('...');" statement. See header comment on the source code for details. FossilOrigin-Name: 96105d33597765c23dbd490b3aa0c2273731d1970d7041720e9f043dbe3517b3 --- ext/misc/vfstrace.c | 202 +++++++++++++++++++++++++++++++++++++++++--- manifest | 14 +-- manifest.uuid | 2 +- 3 files changed, 199 insertions(+), 19 deletions(-) diff --git a/ext/misc/vfstrace.c b/ext/misc/vfstrace.c index 25d5e9b28b..3ca32dbd17 100644 --- a/ext/misc/vfstrace.c +++ b/ext/misc/vfstrace.c @@ -105,7 +105,27 @@ ** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that ** the shell.c source file will know to include the -vfstrace command-line ** option and (2) you must compile and link the three source files -** shell,c, test_vfstrace.c, and sqlite3.c. +** shell,c, test_vfstrace.c, and sqlite3.c. +** +** RUNTIME CONTROL OF VFSTRACE OUTPUT +** +** The application can use the "vfstrace" pragma to control which VFS +** APIs are traced. To disable all output: +** +** PRAGMA vfstrace('-all'); +** +** To enable all output (which is the default setting): +** +** PRAGMA vfstrace('+all'); +** +** Individual APIs can be enabled or disabled by name, with or without +** the initial "x" character. For example, to set up for tracing lock +** primatives only: +** +** PRAGMA vfstrace('-all, +Lock,Unlock,ShmLock'); +** +** The argument to the vfstrace pragma ignores capitalization and any +** characters other than alphabetics, '+', and '-'. */ #include #include @@ -119,6 +139,8 @@ typedef struct vfstrace_info vfstrace_info; struct vfstrace_info { sqlite3_vfs *pRootVfs; /* The underlying real VFS */ int (*xOut)(const char*, void*); /* Send output here */ + unsigned int mTrace; /* Mask of interfaces to trace */ + u8 bOn; /* Tracing on/off */ void *pOutArg; /* First argument to xOut */ const char *zVfsName; /* Name of this trace-VFS */ sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */ @@ -135,6 +157,38 @@ struct vfstrace_file { sqlite3_file *pReal; /* The real underlying file */ }; +/* +** Bit values for vfstrace_info.mTrace. +*/ +#define VTR_CLOSE 0x00000001 +#define VTR_READ 0x00000002 +#define VTR_WRITE 0x00000004 +#define VTR_TRUNC 0x00000008 +#define VTR_SYNC 0x00000010 +#define VTR_FSIZE 0x00000020 +#define VTR_LOCK 0x00000040 +#define VTR_UNLOCK 0x00000080 +#define VTR_CRL 0x00000100 +#define VTR_FCTRL 0x00000200 +#define VTR_SECSZ 0x00000400 +#define VTR_DEVCHAR 0x00000800 +#define VTR_SHMLOCK 0x00001000 +#define VTR_SHMMAP 0x00002000 +#define VTR_SHMBAR 0x00004000 +#define VTR_SHMUNMAP 0x00008000 +#define VTR_OPEN 0x00010000 +#define VTR_DELETE 0x00020000 +#define VTR_ACCESS 0x00040000 +#define VTR_FULLPATH 0x00080000 +#define VTR_DLOPEN 0x00100000 +#define VTR_DLERR 0x00200000 +#define VTR_DLSYM 0x00400000 +#define VTR_DLCLOSE 0x00800000 +#define VTR_RAND 0x01000000 +#define VTR_SLEEP 0x02000000 +#define VTR_CURTIME 0x04000000 +#define VTR_LASTERR 0x08000000 + /* ** Method declarations for vfstrace_file. */ @@ -199,11 +253,13 @@ static void vfstrace_printf( ){ va_list ap; char *zMsg; - va_start(ap, zFormat); - zMsg = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - pInfo->xOut(zMsg, pInfo->pOutArg); - sqlite3_free(zMsg); + if( pInfo->bOn ){ + va_start(ap, zFormat); + zMsg = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + pInfo->xOut(zMsg, pInfo->pOutArg); + sqlite3_free(zMsg); + } } /* @@ -302,6 +358,13 @@ static void strappend(char *z, int *pI, const char *zAppend){ *pI = i; } +/* +** Turn tracing output on or off according to mMask. +*/ +static void vfstraceOnOff(vfstrace_info *pInfo, unsigned int mMask){ + pInfo->bOn = (pInfo->mTrace & mMask)!=0; +} + /* ** Close an vfstrace-file. */ @@ -309,6 +372,7 @@ static int vfstraceClose(sqlite3_file *pFile){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_CLOSE); vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName); rc = p->pReal->pMethods->xClose(p->pReal); vfstrace_print_errcode(pInfo, " -> %s\n", rc); @@ -331,6 +395,7 @@ static int vfstraceRead( vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_READ); vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)", pInfo->zVfsName, p->zFName, iAmt, iOfst); rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); @@ -350,6 +415,7 @@ static int vfstraceWrite( vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_WRITE); vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)", pInfo->zVfsName, p->zFName, iAmt, iOfst); rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); @@ -364,6 +430,7 @@ static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_TRUNC); vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName, size); rc = p->pReal->pMethods->xTruncate(p->pReal, size); @@ -388,6 +455,7 @@ static int vfstraceSync(sqlite3_file *pFile, int flags){ if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){ sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags); } + vfstraceOnOff(pInfo, VTR_SYNC); vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName, &zBuf[1]); rc = p->pReal->pMethods->xSync(p->pReal, flags); @@ -402,6 +470,7 @@ static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_FSIZE); vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName); rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); vfstrace_print_errcode(pInfo, " -> %s,", rc); @@ -430,6 +499,7 @@ static int vfstraceLock(sqlite3_file *pFile, int eLock){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_LOCK); vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName, lockName(eLock)); rc = p->pReal->pMethods->xLock(p->pReal, eLock); @@ -444,6 +514,7 @@ static int vfstraceUnlock(sqlite3_file *pFile, int eLock){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_UNLOCK); vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName, lockName(eLock)); rc = p->pReal->pMethods->xUnlock(p->pReal, eLock); @@ -458,6 +529,7 @@ static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_CRL); vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)", pInfo->zVfsName, p->zFName); rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut); @@ -477,6 +549,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ char zBuf2[100]; char *zOp; char *zRVal = 0; + vfstraceOnOff(pInfo, VTR_FCTRL); switch( op ){ case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break; case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break; @@ -505,6 +578,79 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break; case SQLITE_FCNTL_PRAGMA: { const char *const* a = (const char*const*)pArg; + if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){ + const u8 *zArg = (const u8*)a[2]; + if( zArg[0]>='0' && zArg[0]<=9 ){ + pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0); + }else{ + static const struct { + const char *z; + unsigned int m; + } aKw[] = { + { "all", 0xffffffff }, + { "close", VTR_CLOSE }, + { "read", VTR_READ }, + { "write", VTR_WRITE }, + { "truncate", VTR_TRUNC }, + { "sync", VTR_SYNC }, + { "filesize", VTR_FSIZE }, + { "lock", VTR_LOCK }, + { "unlock", VTR_UNLOCK }, + { "checkreservedlock", VTR_CRL }, + { "filecontrol", VTR_FCTRL }, + { "sectorsize", VTR_SECSZ }, + { "devicecharacteristics", VTR_DEVCHAR }, + { "shmlock", VTR_SHMLOCK }, + { "shmmap", VTR_SHMMAP }, + { "shmummap", VTR_SHMUNMAP }, + { "shmbarrier", VTR_SHMBAR }, + { "open", VTR_OPEN }, + { "delete", VTR_DELETE }, + { "access", VTR_ACCESS }, + { "fullpathname", VTR_FULLPATH }, + { "dlopen", VTR_DLOPEN }, + { "dlerror", VTR_DLERR }, + { "dlsym", VTR_DLSYM }, + { "dlclose", VTR_DLCLOSE }, + { "randomness", VTR_RAND }, + { "sleep", VTR_SLEEP }, + { "currenttime", VTR_CURTIME }, + { "currenttimeint64", VTR_CURTIME }, + { "getlasterror", VTR_LASTERR }, + }; + int onOff = 1; + while( zArg[0] ){ + int jj, n; + while( zArg[0]!=0 && zArg[0]!='-' && zArg[0]!='+' + && !isalpha(zArg[0]) ) zArg++; + if( zArg[0]==0 ) break; + if( zArg[0]=='-' ){ + onOff = 0; + zArg++; + }else if( zArg[0]=='+' ){ + onOff = 1; + zArg++; + } + while( !isalpha(zArg[0]) ){ + if( zArg[0]==0 ) break; + zArg++; + } + if( zArg[0]=='x' && isalpha(zArg[1]) ) zArg++; + for(n=0; isalpha(zArg[n]); n++){} + for(jj=0; jjmTrace |= aKw[jj].m; + }else{ + pInfo->mTrace &= ~aKw[jj].m; + } + break; + } + } + zArg += n; + } + } + } sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]); zOp = zBuf; break; @@ -600,6 +746,7 @@ static int vfstraceSectorSize(sqlite3_file *pFile){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_SECSZ); vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName); rc = p->pReal->pMethods->xSectorSize(p->pReal); vfstrace_printf(pInfo, " -> %d\n", rc); @@ -613,6 +760,7 @@ static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_DEVCHAR); vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)", pInfo->zVfsName, p->zFName); rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal); @@ -639,6 +787,7 @@ static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ int rc; char zLck[100]; int i = 0; + vfstraceOnOff(pInfo, VTR_SHMLOCK); memcpy(zLck, "|0", 3); if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK"); if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK"); @@ -670,6 +819,7 @@ static int vfstraceShmMap( vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_SHMMAP); vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)", pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite); rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp); @@ -679,6 +829,7 @@ static int vfstraceShmMap( static void vfstraceShmBarrier(sqlite3_file *pFile){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; + vfstraceOnOff(pInfo, VTR_SHMBAR); vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName); p->pReal->pMethods->xShmBarrier(p->pReal); } @@ -686,6 +837,7 @@ static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){ vfstrace_file *p = (vfstrace_file *)pFile; vfstrace_info *pInfo = p->pInfo; int rc; + vfstraceOnOff(pInfo, VTR_SHMUNMAP); vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)", pInfo->zVfsName, p->zFName, delFlag); rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag); @@ -713,6 +865,7 @@ static int vfstraceOpen( p->zFName = zName ? fileTail(zName) : ""; p->pReal = (sqlite3_file *)&p[1]; rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags); + vfstraceOnOff(pInfo, VTR_OPEN); vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)", pInfo->zVfsName, p->zFName, flags); if( p->pReal->pMethods ){ @@ -758,6 +911,7 @@ static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; int rc; + vfstraceOnOff(pInfo, VTR_DELETE); vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)", pInfo->zVfsName, zPath, dirSync); rc = pRoot->xDelete(pRoot, zPath, dirSync); @@ -778,6 +932,7 @@ static int vfstraceAccess( vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; int rc; + vfstraceOnOff(pInfo, VTR_ACCESS); vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)", pInfo->zVfsName, zPath, flags); rc = pRoot->xAccess(pRoot, zPath, flags, pResOut); @@ -800,6 +955,7 @@ static int vfstraceFullPathname( vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; int rc; + vfstraceOnOff(pInfo, VTR_FULLPATH); vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")", pInfo->zVfsName, zPath); rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut); @@ -814,6 +970,7 @@ static int vfstraceFullPathname( static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_DLOPEN); vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath); return pRoot->xDlOpen(pRoot, zPath); } @@ -826,6 +983,7 @@ static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){ static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_DLERR); vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte); pRoot->xDlError(pRoot, nByte, zErrMsg); vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg); @@ -847,6 +1005,7 @@ static void (*vfstraceDlSym(sqlite3_vfs *pVfs,void *p,const char *zSym))(void){ static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_DLCLOSE); vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName); pRoot->xDlClose(pRoot, pHandle); } @@ -858,6 +1017,7 @@ static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){ static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_RAND); vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte); return pRoot->xRandomness(pRoot, nByte, zBufOut); } @@ -869,6 +1029,8 @@ static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_SLEEP); + vfstrace_printf(pInfo, "%s.xSleep(%d)\n", pInfo->zVfsName, nMicro); return pRoot->xSleep(pRoot, nMicro); } @@ -878,21 +1040,37 @@ static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){ static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; - return pRoot->xCurrentTime(pRoot, pTimeOut); + int rc; + vfstraceOnOff(pInfo, VTR_CURTIME); + vfstrace_printf(pInfo, "%s.xCurrentTime()", pInfo->zVfsName); + rc = pRoot->xCurrentTime(pRoot, pTimeOut); + vfstrace_printf(pInfo, " -> %.17g\n", *pTimeOut); + return rc; } static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; - return pRoot->xCurrentTimeInt64(pRoot, pTimeOut); + int rc; + vfstraceOnOff(pInfo, VTR_CURTIME); + vfstrace_printf(pInfo, "%s.xCurrentTimeInt64()", pInfo->zVfsName); + rc = pRoot->xCurrentTimeInt64(pRoot, pTimeOut); + vfstrace_printf(pInfo, " -> %lld\n", *pTimeOut); + return rc; } /* -** Return th3 most recent error code and message +** Return the most recent error code and message */ -static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){ +static int vfstraceGetLastError(sqlite3_vfs *pVfs, int nErr, char *zErr){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; - return pRoot->xGetLastError(pRoot, iErr, zErr); + int rc; + vfstraceOnOff(pInfo, VTR_LASTERR); + vfstrace_printf(pInfo, "%s.xGetLastError(%d,zBuf)", pInfo->zVfsName, nErr); + if( nErr ) zErr[0] = 0; + rc = pRoot->xGetLastError(pRoot, nErr, zErr); + vfstrace_printf(pInfo, " -> zBuf[] = \"%s\", rc = %d\n", nErr?zErr:"", rc); + return rc; } /* @@ -986,6 +1164,8 @@ int vfstrace_register( pInfo->pOutArg = pOutArg; pInfo->zVfsName = pNew->zName; pInfo->pTraceVfs = pNew; + pInfo->mTrace = 0xffffffff; + pInfo->bOn = 1; vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n", pInfo->zVfsName, pRoot->zName); return sqlite3_vfs_register(pNew, makeDefault); diff --git a/manifest b/manifest index 83b23513ae..29b2e2b3c9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sinterest\sof\sminimizing\sdownstream\sdisruption,\sset\sthe\ssoname\sof\slibsqlite3.so\sto\s(by\sdefault)\sits\slegacy\svalue\sof\slibsqlite3.so.0\sand\sunconditionally\screate\s(or\sreplace)\sa\ssymlink\swith\sthat\sname\sat\sinstall-time,\sin\saddition\sto\sthe\snewer-named\ssymlinks. -D 2024-11-15T19:42:49.439 +C Enhance\sthe\svfstrace\sextension\ssuch\sthat\sthe\soutput\scan\sbe\scontrolled\susing\nthe\s"PRAGMA\svfstrace('...');"\sstatement.\s\sSee\sheader\scomment\son\sthe\ssource\scode\nfor\sdetails. +D 2024-11-15T20:39:41.451 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -450,7 +450,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917 F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d -F ext/misc/vfstrace.c 72b7cda31777173b0ca78c6c92968c17aba635682205945e394fff27b377bb81 +F ext/misc/vfstrace.c 2f68da859f87be350ede0e8eb94f754219d406161c1595250fc0ca55907460f6 F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 02aceb8c138b5b8f38c75aa0792efa12f14b002083df6141cf56ea0602d3174b -R 5c04b60962f1254417c6b379054d3030 -U stephan -Z 553f27947bf815a9543e751ee4c1db5b +P 0773677b553e032e992266c6c75e10565729238df3ef52b56602a92cf651bea7 +R 1cea5b1a16b6733cdd9ac2dd470ae319 +U drh +Z 6b0f9afcc9547572803b9a01d3227a70 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8840572362..ed88184e81 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0773677b553e032e992266c6c75e10565729238df3ef52b56602a92cf651bea7 +96105d33597765c23dbd490b3aa0c2273731d1970d7041720e9f043dbe3517b3 From d676227f2cb8198f9f4a81d645445339301ba980 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 16 Nov 2024 09:00:31 +0000 Subject: [PATCH 353/522] configure: tiny simplification of proj-assert. FossilOrigin-Name: bfdc416b561937aa74483bf96c042e701e6f98997150f1f1a6b165cddd40d8d1 --- autosetup/proj.tcl | 3 +-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index b3dc38e5f0..863962c2f8 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -85,8 +85,7 @@ proc proj-assert {script {descr ""}} { if {1 == [get-env proj-assert 0]} { msg-result [proj-bold "asserting: $script"] } - set x {expr } - append x \{ $script \} + set x "expr \{ $script \}" if {![uplevel 1 $x]} { if {"" eq $descr} { set descr $script diff --git a/manifest b/manifest index 29b2e2b3c9..15d4d3ad5d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\svfstrace\sextension\ssuch\sthat\sthe\soutput\scan\sbe\scontrolled\susing\nthe\s"PRAGMA\svfstrace('...');"\sstatement.\s\sSee\sheader\scomment\son\sthe\ssource\scode\nfor\sdetails. -D 2024-11-15T20:39:41.451 +C configure:\stiny\ssimplification\sof\sproj-assert. +D 2024-11-16T09:00:31.001 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -49,7 +49,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl dd4cdf0c31967056bc2c1956b0601118182b7e143cffb184d79c6a625ae9ef87 +F autosetup/proj.tcl 96fe16b87c9feb9c1cf2682280f678c659bc52c09fca5de02afc2f7ec5bfb154 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0773677b553e032e992266c6c75e10565729238df3ef52b56602a92cf651bea7 -R 1cea5b1a16b6733cdd9ac2dd470ae319 -U drh -Z 6b0f9afcc9547572803b9a01d3227a70 +P 96105d33597765c23dbd490b3aa0c2273731d1970d7041720e9f043dbe3517b3 +R 76cc5d11312457148d81c8e1a251a987 +U stephan +Z 9236f9ec33c4a67897f49801bdbf86ed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ed88184e81..3b7d2efe37 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96105d33597765c23dbd490b3aa0c2273731d1970d7041720e9f043dbe3517b3 +bfdc416b561937aa74483bf96c042e701e6f98997150f1f1a6b165cddd40d8d1 From 4b24cb2a3afe69f55517bd8b9d958cbb5d1e951c Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 16 Nov 2024 10:42:33 +0000 Subject: [PATCH 354/522] Rename tool/tclConfigShToTcl.sh to tool/tclConfigShToAutoDef.sh in the name of pedantic correctness. FossilOrigin-Name: a7dd196d99ee7c75b92a03915f2b370e3f4c598eb8521b90af1cb5dd7f9ee49c --- auto.def | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- ...tclConfigShToTcl.sh => tclConfigShToAutoDef.sh} | 0 4 files changed, 9 insertions(+), 9 deletions(-) rename tool/{tclConfigShToTcl.sh => tclConfigShToAutoDef.sh} (100%) diff --git a/auto.def b/auto.def index 4c55f91541..919df0101f 100644 --- a/auto.def +++ b/auto.def @@ -652,7 +652,7 @@ proc sqlite-check-tcl {} { # Export a subset of tclConfig.sh to the current TCL-space. If $cfg # is an empty string, this emits empty-string entries for the # various options we're interested in. - eval [exec "${srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] + eval [exec "${srcdir}/tool/tclConfigShToAutoDef.sh" "$cfg"] if {"" eq $with_tclsh && $cfg ne ""} { # We have tclConfig.sh but no tclsh. Attempt to locate a tclsh diff --git a/manifest b/manifest index 15d4d3ad5d..f203e781dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C configure:\stiny\ssimplification\sof\sproj-assert. -D 2024-11-16T09:00:31.001 +C Rename\stool/tclConfigShToTcl.sh\sto\stool/tclConfigShToAutoDef.sh\sin\sthe\sname\sof\spedantic\scorrectness. +D 2024-11-16T10:42:33.822 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def ec2fa2ea6fd691af4a991e1906da314ce094d019b1b9d08563167b138114bbdc +F auto.def 94f0f4a697e8221d5c7ca561771a3afabb0e707922daad89b60908b87a8e399b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2189,8 +2189,8 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9 +F tool/tclConfigShToAutoDef.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x tool/tclConfigShToTcl.sh F tool/tclConfigShToMake.sh 7c065d81c2d178e15e45a77372c6e5a38b5a1b08755301cd6f20a3a862db7312 x -F tool/tclConfigShToTcl.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl fa2f37ab39b2a0087fafb6a7f3ce19503e25e624ffa8ed9951717ab72920c088 F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 96105d33597765c23dbd490b3aa0c2273731d1970d7041720e9f043dbe3517b3 -R 76cc5d11312457148d81c8e1a251a987 +P bfdc416b561937aa74483bf96c042e701e6f98997150f1f1a6b165cddd40d8d1 +R ad6c57c80354771f347efbb55126765b U stephan -Z 9236f9ec33c4a67897f49801bdbf86ed +Z ff27965bc7c5248a616703d2fb15edca # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3b7d2efe37..2201200f83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfdc416b561937aa74483bf96c042e701e6f98997150f1f1a6b165cddd40d8d1 +a7dd196d99ee7c75b92a03915f2b370e3f4c598eb8521b90af1cb5dd7f9ee49c diff --git a/tool/tclConfigShToTcl.sh b/tool/tclConfigShToAutoDef.sh similarity index 100% rename from tool/tclConfigShToTcl.sh rename to tool/tclConfigShToAutoDef.sh From d8f6222bee4860682a4ae3ee1c122e74adb1abcb Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 16 Nov 2024 14:29:51 +0000 Subject: [PATCH 355/522] Add --destdir flag support to buildtclext.tcl, but do not yet add that to the makefile (so that this change can be cherrypicked to the 3.47 build). FossilOrigin-Name: 67a3ca0c013b6a9da3b2c50ffc86b96b14454d1e45fa90d3b0a238488a783e79 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/buildtclext.tcl | 7 ++++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f203e781dd..1dff36b3fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\stool/tclConfigShToTcl.sh\sto\stool/tclConfigShToAutoDef.sh\sin\sthe\sname\sof\spedantic\scorrectness. -D 2024-11-16T10:42:33.822 +C Add\s--destdir\sflag\ssupport\sto\sbuildtclext.tcl,\sbut\sdo\snot\syet\sadd\sthat\sto\sthe\smakefile\s(so\sthat\sthis\schange\scan\sbe\scherrypicked\sto\sthe\s3.47\sbuild). +D 2024-11-16T14:29:51.660 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2105,7 +2105,7 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e045 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x F tool/build-shell.sh 369c4b171cc877ad974fef691e4da782b4c1e99fe8f4361316c735f64d49280f -F tool/buildtclext.tcl f046701e0bfa7c70116555dd4c3fbd7a8b61779c10a9e7586936c77a118c4b09 +F tool/buildtclext.tcl 74b5a09d6f1890370b4bbeeb23c70659b5e90c4b0182451871832b13aeaeb61e F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca @@ -2189,7 +2189,7 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9 -F tool/tclConfigShToAutoDef.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x tool/tclConfigShToTcl.sh +F tool/tclConfigShToAutoDef.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x F tool/tclConfigShToMake.sh 7c065d81c2d178e15e45a77372c6e5a38b5a1b08755301cd6f20a3a862db7312 x F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl fa2f37ab39b2a0087fafb6a7f3ce19503e25e624ffa8ed9951717ab72920c088 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bfdc416b561937aa74483bf96c042e701e6f98997150f1f1a6b165cddd40d8d1 -R ad6c57c80354771f347efbb55126765b +P a7dd196d99ee7c75b92a03915f2b370e3f4c598eb8521b90af1cb5dd7f9ee49c +R a41a04f6172c3334020ea9fa150275a0 U stephan -Z ff27965bc7c5248a616703d2fb15edca +Z ebf5f234ba63bec0c8691ad659e50c5b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2201200f83..d2efa2502f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7dd196d99ee7c75b92a03915f2b370e3f4c598eb8521b90af1cb5dd7f9ee49c +67a3ca0c013b6a9da3b2c50ffc86b96b14454d1e45fa90d3b0a238488a783e79 diff --git a/tool/buildtclext.tcl b/tool/buildtclext.tcl index ba16fc3cde..4dd2cf05fe 100644 --- a/tool/buildtclext.tcl +++ b/tool/buildtclext.tcl @@ -15,6 +15,7 @@ Options: --info Show info on existing SQLite TCL extension installs --install-only Install an extension previously build --uninstall Uninstall the extension + --destdir DIR Installation root (used by "make install DESTDIR=...") Other options are retained and passed through into the compiler.} @@ -25,6 +26,7 @@ set uninstall 0 set infoonly 0 set CC {} set OPTS {} +set DESTDIR ""; # --destdir "$(DESTDIR)" for {set ii 0} {$ii<[llength $argv]} {incr ii} { set a0 [lindex $argv $ii] if {$a0=="--install-only"} { @@ -42,6 +44,9 @@ for {set ii 0} {$ii<[llength $argv]} {incr ii} { } elseif {$a0=="--cc" && $ii+1<[llength $argv]} { incr ii set CC [lindex $argv $ii] + } elseif {$a0=="--destdir" && $ii+1<[llength $argv]} { + incr ii + set DESTDIR [lindex $argv $ii] } elseif {[string match -* $a0]} { append OPTS " $a0" } else { @@ -248,7 +253,7 @@ package ifneeded sqlite3 $VERSION \\ if {$install} { # Install the extension - set DEST2 $DEST/sqlite$VERSION + set DEST2 ${DESTDIR}$DEST/sqlite$VERSION file mkdir $DEST2 puts "installing $DEST2/pkgIndex.tcl" file copy -force pkgIndex.tcl $DEST2 From f6c7cc606ea0a11b4dcc41cf2fb58eff3e70df93 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 16 Nov 2024 14:30:43 +0000 Subject: [PATCH 356/522] Add the --destdir flag to the tclextension-install makefile target. FossilOrigin-Name: d1663cf05f7dcaafd479bacf083b6b774f34fd3db89012b49599d30817eb174f --- main.mk | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/main.mk b/main.mk index 8fa0dee92e..83efa78249 100644 --- a/main.mk +++ b/main.mk @@ -1536,7 +1536,7 @@ tclextension: tclsqlite3.c # to find it. # tclextension-install: tclsqlite3.c - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(T.cc)" $(CFLAGS.tclextension) + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --destdir "$(DESTDIR)" --cc "$(T.cc)" $(CFLAGS.tclextension) # # Uninstall the SQLite TCL extension that is used by $TCLSH_CMD. diff --git a/manifest b/manifest index 1dff36b3fc..c97aecfe3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s--destdir\sflag\ssupport\sto\sbuildtclext.tcl,\sbut\sdo\snot\syet\sadd\sthat\sto\sthe\smakefile\s(so\sthat\sthis\schange\scan\sbe\scherrypicked\sto\sthe\s3.47\sbuild). -D 2024-11-16T14:29:51.660 +C Add\sthe\s--destdir\sflag\sto\sthe\stclextension-install\smakefile\starget. +D 2024-11-16T14:30:43.559 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 579c3f70be718c97b82c12c14942305ed0c330619355aad26ed14a752f6daf57 +F main.mk e2287ed82f924c9d54493634dc7bb10797b8ef69ce7becef62d6a453337d5a45 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a7dd196d99ee7c75b92a03915f2b370e3f4c598eb8521b90af1cb5dd7f9ee49c -R a41a04f6172c3334020ea9fa150275a0 +P 67a3ca0c013b6a9da3b2c50ffc86b96b14454d1e45fa90d3b0a238488a783e79 +R 64cbfdd333d943accf4446692c9fa1aa U stephan -Z ebf5f234ba63bec0c8691ad659e50c5b +Z ab5f1908008ea743b14ee06e559bb041 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d2efa2502f..c25b310fc2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67a3ca0c013b6a9da3b2c50ffc86b96b14454d1e45fa90d3b0a238488a783e79 +d1663cf05f7dcaafd479bacf083b6b774f34fd3db89012b49599d30817eb174f From 50faa8d17edfda79686dd937da76b4ecbe948cf4 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 16 Nov 2024 17:09:55 +0000 Subject: [PATCH 357/522] Handle DESTDIR at an earlier phase in buildtclext.tcl to account for the is-writable-dir check and to filter out //zipfs: dirs as (im)possible installation targets. FossilOrigin-Name: d2e8c161a14fbbcc52c50dfd9274c9969e3c273e2cb7cbf2f865541af9f39ead --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/buildtclext.tcl | 14 +++++++++++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c97aecfe3f..9cfad2f284 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--destdir\sflag\sto\sthe\stclextension-install\smakefile\starget. -D 2024-11-16T14:30:43.559 +C Handle\sDESTDIR\sat\san\searlier\sphase\sin\sbuildtclext.tcl\sto\saccount\sfor\sthe\sis-writable-dir\scheck\sand\sto\sfilter\sout\s//zipfs:\sdirs\sas\s(im)possible\sinstallation\stargets. +D 2024-11-16T17:09:55.838 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2105,7 +2105,7 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e045 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x F tool/build-shell.sh 369c4b171cc877ad974fef691e4da782b4c1e99fe8f4361316c735f64d49280f -F tool/buildtclext.tcl 74b5a09d6f1890370b4bbeeb23c70659b5e90c4b0182451871832b13aeaeb61e +F tool/buildtclext.tcl 12b49ae392006251d110f051d22036f7807d7ea1602780f4c165154b12567397 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 67a3ca0c013b6a9da3b2c50ffc86b96b14454d1e45fa90d3b0a238488a783e79 -R 64cbfdd333d943accf4446692c9fa1aa +P d1663cf05f7dcaafd479bacf083b6b774f34fd3db89012b49599d30817eb174f +R 657a89bc255ed08e248d99748106e69f U stephan -Z ab5f1908008ea743b14ee06e559bb041 +Z b80d9fe06498e5fae8380933f57f5fcc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c25b310fc2..680fc19d82 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d1663cf05f7dcaafd479bacf083b6b774f34fd3db89012b49599d30817eb174f +d2e8c161a14fbbcc52c50dfd9274c9969e3c273e2cb7cbf2f865541af9f39ead diff --git a/tool/buildtclext.tcl b/tool/buildtclext.tcl index 4dd2cf05fe..cdcb4ca002 100644 --- a/tool/buildtclext.tcl +++ b/tool/buildtclext.tcl @@ -201,7 +201,15 @@ if {$install} { # set DEST {} foreach dir $auto_path { - if {[file writable $dir]} { + if {[string match //*:* $dir]} { + # We can't install to //zipfs: paths + continue + } elseif {"" ne $DESTDIR && ![file writable $DESTDIR]} { + continue + } + set dir ${DESTDIR}$dir + if {[file writable $dir] || "" ne $DESTDIR} { + # the dir will be created later ^^^^^^^^ set DEST $dir break } elseif {[glob -nocomplain $dir/sqlite3*/pkgIndex.tcl]!=""} { @@ -219,7 +227,7 @@ if {$install} { puts "to work around this problem.\n" puts "These are the (unwritable) \$auto_path directories:\n" foreach dir $auto_path { - puts " * $dir" + puts " * ${DESTDIR}$dir" } exit 1 } @@ -253,7 +261,7 @@ package ifneeded sqlite3 $VERSION \\ if {$install} { # Install the extension - set DEST2 ${DESTDIR}$DEST/sqlite$VERSION + set DEST2 $DEST/sqlite$VERSION file mkdir $DEST2 puts "installing $DEST2/pkgIndex.tcl" file copy -force pkgIndex.tcl $DEST2 From 18689b8fb28805cee499d913738a6822247c0c9c Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Nov 2024 17:39:34 +0000 Subject: [PATCH 358/522] Fix argument expansion in sqlite-tclsh on Windows such that if an argument does not match a filename even after glob expansion, it is appended to the argument list verbatim. FossilOrigin-Name: cd942dce148c9d8f5a94cee61923aad8d1b732b807e004005f78323be30c02e7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9cfad2f284..9301466f3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Handle\sDESTDIR\sat\san\searlier\sphase\sin\sbuildtclext.tcl\sto\saccount\sfor\sthe\sis-writable-dir\scheck\sand\sto\sfilter\sout\s//zipfs:\sdirs\sas\s(im)possible\sinstallation\stargets. -D 2024-11-16T17:09:55.838 +C Fix\sargument\sexpansion\sin\ssqlite-tclsh\son\sWindows\ssuch\sthat\sif\san\sargument\ndoes\snot\smatch\sa\sfilename\seven\safter\sglob\sexpansion,\sit\sis\sappended\sto\sthe\nargument\slist\sverbatim. +D 2024-11-16T17:39:34.746 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -783,7 +783,7 @@ F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2c F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153 +F src/tclsqlite.c c4b0b27b0ad34e4af085040a1ebe94a35ad5161663cd905d1b947f7884691bff F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d1663cf05f7dcaafd479bacf083b6b774f34fd3db89012b49599d30817eb174f -R 657a89bc255ed08e248d99748106e69f -U stephan -Z b80d9fe06498e5fae8380933f57f5fcc +P d2e8c161a14fbbcc52c50dfd9274c9969e3c273e2cb7cbf2f865541af9f39ead +R 3550a38f34f40ce6e4e244b9386d8410 +U drh +Z 0ad8b78a6ff21acc6a3ebcf1785c2111 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 680fc19d82..0322597271 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2e8c161a14fbbcc52c50dfd9274c9969e3c273e2cb7cbf2f865541af9f39ead +cd942dce148c9d8f5a94cee61923aad8d1b732b807e004005f78323be30c02e7 diff --git a/src/tclsqlite.c b/src/tclsqlite.c index af0d27b1fe..36459e4a94 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -4037,9 +4037,12 @@ static const char *tclsh_main_loop(void){ "if {[file exists $arg]} {\n" "lappend new $arg\n" "} else {\n" + "set once 0\n" "foreach match [lsort [glob -nocomplain $arg]] {\n" "lappend new $match\n" + "set once 1\n" "}\n" + "if {!$once} {lappend new $arg}\n" "}\n" "}\n" "set argv $new\n" From 70d390134cac808718e6d12df00172dec9fb290e Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Nov 2024 18:54:46 +0000 Subject: [PATCH 359/522] Call fflush() on ".echo" output from the shell, so that the output to stdout is aligned with output to stderr. FossilOrigin-Name: c38b9db3c4f71706a7d211424da64311e6e5daf64b224565a6d82d4b1a68e261 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9301466f3b..61d0831e96 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sargument\sexpansion\sin\ssqlite-tclsh\son\sWindows\ssuch\sthat\sif\san\sargument\ndoes\snot\smatch\sa\sfilename\seven\safter\sglob\sexpansion,\sit\sis\sappended\sto\sthe\nargument\slist\sverbatim. -D 2024-11-16T17:39:34.746 +C Call\sfflush()\son\s".echo"\soutput\sfrom\sthe\sshell,\sso\sthat\sthe\soutput\sto\nstdout\sis\saligned\swith\soutput\sto\sstderr. +D 2024-11-16T18:54:46.664 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -775,7 +775,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in c61d7af58e678d479f1450e4ea236d2d6ac3bb16a636030104f210303b30d563 +F src/shell.c.in 469039a2a09603bf32f47b5c4ddc61e8b980139919db1f46000241357f5f3588 F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d2e8c161a14fbbcc52c50dfd9274c9969e3c273e2cb7cbf2f865541af9f39ead -R 3550a38f34f40ce6e4e244b9386d8410 +P cd942dce148c9d8f5a94cee61923aad8d1b732b807e004005f78323be30c02e7 +R c6e3e7808022fc93197afc8ff5529a17 U drh -Z 0ad8b78a6ff21acc6a3ebcf1785c2111 +Z 8206467963ac0d5803b490ec391283d6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0322597271..db6cd4173c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd942dce148c9d8f5a94cee61923aad8d1b732b807e004005f78323be30c02e7 +c38b9db3c4f71706a7d211424da64311e6e5daf64b224565a6d82d4b1a68e261 diff --git a/src/shell.c.in b/src/shell.c.in index 55fba9d82d..26b6d73de6 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -12237,7 +12237,10 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ } static void echo_group_input(ShellState *p, const char *zDo){ - if( ShellHasFlag(p, SHFLG_Echo) ) sqlite3_fprintf(p->out, "%s\n", zDo); + if( ShellHasFlag(p, SHFLG_Echo) ){ + sqlite3_fprintf(p->out, "%s\n", zDo); + fflush(p->out); + } } #ifdef SQLITE_SHELL_FIDDLE From f6fdf32553a1be18cebcd9ec93bc21fc95c794f9 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 17 Nov 2024 09:49:53 +0000 Subject: [PATCH 360/522] buildtclext.tcl: add docs explaining the DESTDIR check and break out of the auto_path search loop early if the DESTDIR is not writable, rather than re-checking that repeatedly. FossilOrigin-Name: d07be336eaeb9a5d56ac6e1b63f4d8e50d3ac236f5953cc178ef34542a7cd8fa --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/buildtclext.tcl | 13 ++++++++++++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 61d0831e96..6b51760a5e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Call\sfflush()\son\s".echo"\soutput\sfrom\sthe\sshell,\sso\sthat\sthe\soutput\sto\nstdout\sis\saligned\swith\soutput\sto\sstderr. -D 2024-11-16T18:54:46.664 +C buildtclext.tcl:\sadd\sdocs\sexplaining\sthe\sDESTDIR\scheck\sand\sbreak\sout\sof\sthe\sauto_path\ssearch\sloop\searly\sif\sthe\sDESTDIR\sis\snot\swritable,\srather\sthan\sre-checking\sthat\srepeatedly. +D 2024-11-17T09:49:53.530 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2105,7 +2105,7 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e045 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x F tool/build-shell.sh 369c4b171cc877ad974fef691e4da782b4c1e99fe8f4361316c735f64d49280f -F tool/buildtclext.tcl 12b49ae392006251d110f051d22036f7807d7ea1602780f4c165154b12567397 +F tool/buildtclext.tcl 5e1f1aa843e635c8b7480c7d1ec1f149a5e52136ae2fca1226304053a1a60587 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cd942dce148c9d8f5a94cee61923aad8d1b732b807e004005f78323be30c02e7 -R c6e3e7808022fc93197afc8ff5529a17 -U drh -Z 8206467963ac0d5803b490ec391283d6 +P c38b9db3c4f71706a7d211424da64311e6e5daf64b224565a6d82d4b1a68e261 +R 6c99f9d2b2ea12c86b973c72b1e2d97d +U stephan +Z 8990c425a49b319cd7781e9a50d42f1e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index db6cd4173c..b192208620 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c38b9db3c4f71706a7d211424da64311e6e5daf64b224565a6d82d4b1a68e261 +d07be336eaeb9a5d56ac6e1b63f4d8e50d3ac236f5953cc178ef34542a7cd8fa diff --git a/tool/buildtclext.tcl b/tool/buildtclext.tcl index cdcb4ca002..c74540c9ea 100644 --- a/tool/buildtclext.tcl +++ b/tool/buildtclext.tcl @@ -205,7 +205,18 @@ if {$install} { # We can't install to //zipfs: paths continue } elseif {"" ne $DESTDIR && ![file writable $DESTDIR]} { - continue + # In the common case, ${DESTDIR}${dir} will not exist when we + # get to this point of the installation, and the "is writable?" + # check just below this will fail for that case. + # + # Assumption made for simplification's sake: if ${DESTDIR} is + # not writable, no part of the remaining path will + # be. ${DESTDIR} is typically used by OS package maintainers, + # not normal installations, and it "shouldn't" ever happen that + # the DESTDIR is read-only while the target ${DESTDIR}${prefix} + # is not, as it's typical for such installations to create + # ${prefix} on-demand under ${DESTDIR}. + break } set dir ${DESTDIR}$dir if {[file writable $dir] || "" ne $DESTDIR} { From bbc6e5c9b71d3f459557c182a3be34b25319a3bf Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 17 Nov 2024 11:42:43 +0000 Subject: [PATCH 361/522] Make the --vfstrace output from the CLI go to the same output channel as everything else. FossilOrigin-Name: f71d4900205ae6ee41f849c4026d0fe4d6cf281dfc3bac8105fc8e242d128b67 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6b51760a5e..209310638f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C buildtclext.tcl:\sadd\sdocs\sexplaining\sthe\sDESTDIR\scheck\sand\sbreak\sout\sof\sthe\sauto_path\ssearch\sloop\searly\sif\sthe\sDESTDIR\sis\snot\swritable,\srather\sthan\sre-checking\sthat\srepeatedly. -D 2024-11-17T09:49:53.530 +C Make\sthe\s--vfstrace\soutput\sfrom\sthe\sCLI\sgo\sto\sthe\ssame\soutput\schannel\sas\neverything\selse. +D 2024-11-17T11:42:43.363 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -775,7 +775,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 469039a2a09603bf32f47b5c4ddc61e8b980139919db1f46000241357f5f3588 +F src/shell.c.in 9a0011ee9650818782ee746e0e8747568a6f02fb3ae323dc6e27fa1a61457523 F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c38b9db3c4f71706a7d211424da64311e6e5daf64b224565a6d82d4b1a68e261 -R 6c99f9d2b2ea12c86b973c72b1e2d97d -U stephan -Z 8990c425a49b319cd7781e9a50d42f1e +P d07be336eaeb9a5d56ac6e1b63f4d8e50d3ac236f5953cc178ef34542a7cd8fa +R 173665514e770745563aa2982f85029a +U drh +Z d67df32afae4b3e2bba6c9bfe32d205b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b192208620..611653469b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d07be336eaeb9a5d56ac6e1b63f4d8e50d3ac236f5953cc178ef34542a7cd8fa +f71d4900205ae6ee41f849c4026d0fe4d6cf281dfc3bac8105fc8e242d128b67 diff --git a/src/shell.c.in b/src/shell.c.in index 26b6d73de6..a6700eb83a 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -12701,6 +12701,15 @@ static void sayAbnormalExit(void){ if( seenInterrupt ) eputz("Program interrupted.\n"); } +/* Routine to output from vfstrace +*/ +static int vfstraceOut(const char *z, void *pArg){ + ShellState *p = (ShellState*)pArg; + sqlite3_fputs(z, p->out); + fflush(p->out); + return 1; +} + #ifndef SQLITE_SHELL_IS_UTF8 # if (defined(_WIN32) || defined(WIN32)) \ && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__))) @@ -12937,8 +12946,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break; } }else if( cli_strcmp(z,"-vfstrace")==0 ){ - vfstrace_register("trace",0,(int(*)(const char*,void*))sqlite3_fputs, - stderr,1); bEnableVfstrace = 1; #ifdef SQLITE_ENABLE_MULTIPLEX }else if( cli_strcmp(z,"-multiplex")==0 ){ @@ -13035,6 +13042,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #endif } data.out = stdout; + if( bEnableVfstrace ){ + vfstrace_register("trace",0,vfstraceOut, &data, 1); + } #ifndef SQLITE_SHELL_FIDDLE sqlite3_appendvfs_init(0,0,0); #endif From 9c8235b1bd62faa9afbcf85523980be8b908f075 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Nov 2024 13:29:16 +0000 Subject: [PATCH 362/522] Fix minor problems in testrunner.tcl that pop up when the command-line arguments are such that no tests are run. FossilOrigin-Name: 321ded32f67550e964cd64d61aa0cbc0029ce2fdee4588a46b01dbb5aa87150b --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/testrunner.tcl | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 209310638f..187a7787d8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\s--vfstrace\soutput\sfrom\sthe\sCLI\sgo\sto\sthe\ssame\soutput\schannel\sas\neverything\selse. -D 2024-11-17T11:42:43.363 +C Fix\sminor\sproblems\sin\stestrunner.tcl\sthat\spop\sup\swhen\sthe\scommand-line\sarguments\nare\ssuch\sthat\sno\stests\sare\srun. +D 2024-11-18T13:29:16.826 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1719,7 +1719,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 -F test/testrunner.tcl c40d5700578f8c9d00e0e15f105f645c471bc2c48eb8b013bd2953400f2c6bf0 x +F test/testrunner.tcl 90ed8b6c2b26dc1f6af08aeb04670a5df86172f3d9828d8af000f972afa50061 x F test/testrunner_data.tcl ba4aeea28aa03cfa6fe7e57782ddecb7a7b91c3a0b3251583cb4f0ee002de6a6 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d07be336eaeb9a5d56ac6e1b63f4d8e50d3ac236f5953cc178ef34542a7cd8fa -R 173665514e770745563aa2982f85029a +P f71d4900205ae6ee41f849c4026d0fe4d6cf281dfc3bac8105fc8e242d128b67 +R c842f5cfce9a13599fcce2ed5a6b5bb2 U drh -Z d67df32afae4b3e2bba6c9bfe32d205b +Z c55681dc305689429003d496466dfaa7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 611653469b..527bf0148d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f71d4900205ae6ee41f849c4026d0fe4d6cf281dfc3bac8105fc8e242d128b67 +321ded32f67550e964cd64d61aa0cbc0029ce2fdee4588a46b01dbb5aa87150b diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 889bfeaffd..d365092e05 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -465,6 +465,7 @@ if {[string compare -nocase script [lindex $argv 0]]==0} { # number of milliseconds in the argument. # proc elapsetime {ms} { + if {$ms==""} {set ms 0} set s [expr {int(($ms+500.0)*0.001)}] set hr [expr {$s/3600}] set mn [expr {($s/60)%60}] @@ -1603,6 +1604,8 @@ proc run_testset {} { SELECT pltfm, count(*) FROM jobs WHERE pltfm IS NOT NULL ORDER BY 2 DESC LIMIT 1 } break + if {$totalerr==""} {set totalerr 0} + if {$totaltest==""} {set totaltest 0} puts "$totalerr errors out of $totaltest tests in $et $pltfm" trdb eval { SELECT DISTINCT substr(svers,1,79) as v1 FROM jobs WHERE svers IS NOT NULL From de8aa17eb51b420488235556f37300a31cfee673 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Nov 2024 14:08:42 +0000 Subject: [PATCH 363/522] Fix a "applying zero offset to null pointer" usan error in the fts5 trigram tokenizer. FossilOrigin-Name: 9b79b999d4192a3a250bf343825f61e9cb83203e4d94dcfa20c320d5f1386d69 --- ext/fts5/fts5_tokenize.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_tokenize.c b/ext/fts5/fts5_tokenize.c index f10c2379de..b8a1136465 100644 --- a/ext/fts5/fts5_tokenize.c +++ b/ext/fts5/fts5_tokenize.c @@ -1353,7 +1353,7 @@ static int fts5TriTokenize( char *zOut = aBuf; int ii; const unsigned char *zIn = (const unsigned char*)pText; - const unsigned char *zEof = &zIn[nText]; + const unsigned char *zEof = (zIn ? &zIn[nText] : 0); u32 iCode = 0; int aStart[3]; /* Input offset of each character in aBuf[] */ diff --git a/manifest b/manifest index 187a7787d8..63d697d849 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sminor\sproblems\sin\stestrunner.tcl\sthat\spop\sup\swhen\sthe\scommand-line\sarguments\nare\ssuch\sthat\sno\stests\sare\srun. -D 2024-11-18T13:29:16.826 +C Fix\sa\s"applying\szero\soffset\sto\snull\spointer"\susan\serror\sin\sthe\sfts5\strigram\stokenizer. +D 2024-11-18T14:08:42.960 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -116,7 +116,7 @@ F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b -F ext/fts5/fts5_tokenize.c 87ab719f0556172da3414f1741c11bb4d333ebecde157945a55478bfe6e46c44 +F ext/fts5/fts5_tokenize.c 49aea8cc400a690a6c4f83c4cedc67f4f8830c6789c4ee343404f62bcaebca7b F ext/fts5/fts5_unicode2.c 6f9b0fb79a8facaed76628ffd4eb9c16d7f2b84b52872784f617cf3422a9b043 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f71d4900205ae6ee41f849c4026d0fe4d6cf281dfc3bac8105fc8e242d128b67 -R c842f5cfce9a13599fcce2ed5a6b5bb2 -U drh -Z c55681dc305689429003d496466dfaa7 +P 321ded32f67550e964cd64d61aa0cbc0029ce2fdee4588a46b01dbb5aa87150b +R 9bcf58276e7ecc61be5b475731de0f25 +U dan +Z 37f8f1c1585e0f2f0b48eafeda549304 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 527bf0148d..9c97ee409c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -321ded32f67550e964cd64d61aa0cbc0029ce2fdee4588a46b01dbb5aa87150b +9b79b999d4192a3a250bf343825f61e9cb83203e4d94dcfa20c320d5f1386d69 From 0df847cc776131919935658230fe2e629906dabb Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 18 Nov 2024 14:15:08 +0000 Subject: [PATCH 364/522] Remove the .POSIX entries from the makefiles because they cause portability problems rather than solve them. FossilOrigin-Name: e1330ecf170436678c5c235557fb95b8acbf4fad62583edba4af03aff49afbc5 --- Makefile.in | 1 - main.mk | 1 - manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Makefile.in b/Makefile.in index 500b5eb0b7..b374bd4838 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,7 +9,6 @@ # The docs for many of its variables are in the primary static # makefile, main.mk (which this one includes at runtime). # -.POSIX: #maintenance reminder: X:=Y is not POSIX-portable all: ######################################################################## # diff --git a/main.mk b/main.mk index 83efa78249..a22c0fe775 100644 --- a/main.mk +++ b/main.mk @@ -18,7 +18,6 @@ # invoked. This file will use defaults, very possibly invalid, for any # which are not defined. ######################################################################## -.POSIX: #maintenance reminder: X:=Y is not POSIX-portable all: # # $(TOP) = diff --git a/manifest b/manifest index 63d697d849..6aeda5c46f 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sa\s"applying\szero\soffset\sto\snull\spointer"\susan\serror\sin\sthe\sfts5\strigram\stokenizer. -D 2024-11-18T14:08:42.960 +C Remove\sthe\s.POSIX\sentries\sfrom\sthe\smakefiles\sbecause\sthey\scause\sportability\sproblems\srather\sthan\ssolve\sthem. +D 2024-11-18T14:15:08.975 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in 2c90ab3183f810086878a784c323b7816238a5e6943d267c25a71edc623a05a3 +F Makefile.in c3a01e98bd2ae6a4631df02f11249ac07ffa3d540d3034e2675f66cc259f2ea7 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk e2287ed82f924c9d54493634dc7bb10797b8ef69ce7becef62d6a453337d5a45 +F main.mk c4e37e3015f9c2d8fd20fa3071ba86e7396959c8d5960e37e95aa85421e2b739 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 321ded32f67550e964cd64d61aa0cbc0029ce2fdee4588a46b01dbb5aa87150b -R 9bcf58276e7ecc61be5b475731de0f25 -U dan -Z 37f8f1c1585e0f2f0b48eafeda549304 +P 9b79b999d4192a3a250bf343825f61e9cb83203e4d94dcfa20c320d5f1386d69 +R 327f4f8a7444c4d4336a89e4ec576fd8 +U stephan +Z e12fcd84e46ac65f835dccb3914d7b22 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9c97ee409c..82e8bdd0a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b79b999d4192a3a250bf343825f61e9cb83203e4d94dcfa20c320d5f1386d69 +e1330ecf170436678c5c235557fb95b8acbf4fad62583edba4af03aff49afbc5 From 5cad859f61145644513cdf901afbb8d88dcc9b9b Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Nov 2024 16:44:26 +0000 Subject: [PATCH 365/522] Attempt to reduce divergence with begin-concurrent. FossilOrigin-Name: f783d90187fb326faa3d0244b30138b023c4a8483486f260b7a022a927c13f3a --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/parse.y | 11 +++++++++-- test/corruptN.test | 9 --------- test/wal_common.tcl | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 6aeda5c46f..4cb717bf18 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\s.POSIX\sentries\sfrom\sthe\smakefiles\sbecause\sthey\scause\sportability\sproblems\srather\sthan\ssolve\sthem. -D 2024-11-18T14:15:08.975 +C Attempt\sto\sreduce\sdivergence\swith\sbegin-concurrent. +D 2024-11-18T16:44:26.814 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -763,7 +763,7 @@ F src/os_win.c db4baa8f62bbfe3967c71b008cea31a8f2ff337c1667ff4d8a677e697315ff0d F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a -F src/parse.y 8ec56598aa0df92428627502267d0d1c9778cc27308f8ffd31dfb2d017a8755f +F src/parse.y dcf45a81b61223ac93e61fdfe9b22d635dd371c446e8222634d90aa37e25e5f6 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 @@ -1041,7 +1041,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test ac13504593d89d69690d45479547616ed12644d42b5cb7eeb2e759a76fc23dcb F test/corruptL.test 652fc8ac0763a6fd3eb28b951d481924167b2d9936083bcc68253b2274a0c8fe F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 -F test/corruptN.test 40bc47aee4af9aadff902be43f14d69dc17b3731448dad6c7cc722da913f1455 +F test/corruptN.test a034bb217bebd8d007625dfb078e76ec3d53515052dbceb68bd47b2c27674d5c F test/cost.test cc434a026b1e9d0d98137a147e24e5daf1b1ad09e9ff7da63b34c83ddd136d92 F test/count.test cd4bd531066e8d77ef8fe1e3fc8253d042072e117ccab214b290cf83f1602249 F test/countofview.test 4088e461a10ee33e69803c177a69aa1d7bba81a9ffc2df66d76465a22ca7fdfc @@ -1995,7 +1995,7 @@ F test/wal64k.test 2a525c0f45d709bae3765c71045ccec5df7d100ccbd3a7860fdba46c9addb F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8 F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750 -F test/wal_common.tcl 4589f701d5527ace2eba43823c96c2177e1f9dd2a6098256ee2203a0a313c13a +F test/wal_common.tcl 204d1721ac13c5e0c7fae6380315b5ab7f4e8423f580d826c5e9df1995cb018d F test/walbak.test 018d4e5a3d45c6298d11b99f09a8ef6876527946 F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434 F test/walblock.test be48f3a75eff0b4456209f26b3ce186c2015497d @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9b79b999d4192a3a250bf343825f61e9cb83203e4d94dcfa20c320d5f1386d69 -R 327f4f8a7444c4d4336a89e4ec576fd8 -U stephan -Z e12fcd84e46ac65f835dccb3914d7b22 +P e1330ecf170436678c5c235557fb95b8acbf4fad62583edba4af03aff49afbc5 +R f888b7564d00e145c0007eac37a11cdd +U drh +Z 42957bc99f867ff6f91e562cbfd36cd8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 82e8bdd0a3..a9ea9de121 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1330ecf170436678c5c235557fb95b8acbf4fad62583edba4af03aff49afbc5 +f783d90187fb326faa3d0244b30138b023c4a8483486f260b7a022a927c13f3a diff --git a/src/parse.y b/src/parse.y index 8fdea9bfa3..b8d904d12c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -43,7 +43,7 @@ %syntax_error { UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ if( TOKEN.z[0] ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + parserSyntaxError(pParse, &TOKEN); }else{ sqlite3ErrorMsg(pParse, "incomplete input"); } @@ -111,6 +111,13 @@ struct TrigEvent { int a; IdList * b; }; struct FrameBound { int eType; Expr *pExpr; }; +/* +** Generate a syntax error +*/ +static void parserSyntaxError(Parse *pParse, Token *p){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", p); +} + /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. @@ -1156,7 +1163,7 @@ expr(A) ::= VARIABLE(X). { Token t = X; /*A-overwrites-X*/ assert( t.n>=2 ); if( pParse->nested==0 ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); + parserSyntaxError(pParse, &t); A = 0; }else{ A = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); diff --git a/test/corruptN.test b/test/corruptN.test index 8108609c09..2297991aba 100644 --- a/test/corruptN.test +++ b/test/corruptN.test @@ -141,15 +141,6 @@ do_test 2.0 { | end c-b92b.txt.db }]} {} -# This test only works with the legacy RC4 PRNG -if 0 { - prng_seed 0 db - do_catchsql_test 2.1 { - SELECT count(*) FROM sqlite_schema; - WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000) - INSERT INTO t1(a) SELECT randomblob(null) FROM c; - } {1 {database disk image is malformed}} -} reset_db if {![info exists ::G(perm:presql)]} { diff --git a/test/wal_common.tcl b/test/wal_common.tcl index cdba53b5b2..d31131aa02 100644 --- a/test/wal_common.tcl +++ b/test/wal_common.tcl @@ -87,3 +87,43 @@ proc wal_fix_walindex_cksum {hdrvar} { lset hdr 10 $c1 lset hdr 11 $c2 } + +# This command assumes that $file is the name of a database file opened +# in wal mode using a [testvfs] VFS. It returns a list of the 12 32-bit +# integers that make up the wal-index-header for the named file. +# +proc set_tvfs_hdr {file args} { + + # Set $nHdr to the number of bytes in the wal-index header: + set nHdr 48 + set nInt [expr {$nHdr/4}] + + if {[llength $args]>2} { + error {wrong # args: should be "set_tvfs_hdr fileName ?val1? ?val2?"} + } + + set blob [tvfs shm $file] + if {$::tcl_platform(byteOrder)=="bigEndian"} {set fmt I} {set fmt i} + + if {[llength $args]} { + set ia [lindex $args 0] + set ib $ia + if {[llength $args]==2} { + set ib [lindex $args 1] + } + binary scan $blob a[expr $nHdr*2]a* dummy tail + set blob [binary format ${fmt}${nInt}${fmt}${nInt}a* $ia $ib $tail] + tvfs shm $file $blob + } + + binary scan $blob ${fmt}${nInt} ints + return $ints +} + +proc incr_tvfs_hdr {file idx incrval} { + set ints [set_tvfs_hdr $file] + set v [lindex $ints $idx] + incr v $incrval + lset ints $idx $v + set_tvfs_hdr $file $ints +} From 12599d566bd3f905e70e991839d08638101e9e50 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Nov 2024 17:05:45 +0000 Subject: [PATCH 366/522] Attempt to reduce divergence with the wal2 branch. FossilOrigin-Name: e0d8f9916c2d899094b71af74f44e089a97db6d80f09eb80a5d8be733c1bf942 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_hexio.c | 22 +++++++++++++++++----- test/savepoint6.test | 17 ++++++++++++++--- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 4cb717bf18..8984444fe6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\sreduce\sdivergence\swith\sbegin-concurrent. -D 2024-11-18T16:44:26.814 +C Attempt\sto\sreduce\sdivergence\swith\sthe\swal2\sbranch. +D 2024-11-18T17:05:45.350 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -804,7 +804,7 @@ F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c9 F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86 F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5 F src/test_func.c 8c0e89192f70fac307822d1ac2911ee51751288780b3db0c5ab5ca75fa0fe851 -F src/test_hexio.c 0f777bf9fbb2684bb4978372bacc90ef7337d5d9e3cebe067a9409941e88bacf +F src/test_hexio.c 7449504e4bde876ba91b202617a9228c7c8c2e7bd8b957302f3803ac0e9e353c F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5 F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293 @@ -1583,7 +1583,7 @@ F test/savepoint.test 6e9804a17767f08432c7a5e738b9a8f4b891d243110b63d3a41d270d3d F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7 F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd -F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 +F test/savepoint6.test 48a645a7bb3a59a6fcf06a7364cfe5b655c336760de39068f7c241b0fc80d963 F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test b249328caf4d317e71058006872b8012598a5fa045b30bf24a81eeff650ab49e @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e1330ecf170436678c5c235557fb95b8acbf4fad62583edba4af03aff49afbc5 -R f888b7564d00e145c0007eac37a11cdd +P f783d90187fb326faa3d0244b30138b023c4a8483486f260b7a022a927c13f3a +R 6377acb59760f57785ee6902b4729fcf U drh -Z 42957bc99f867ff6f91e562cbfd36cd8 +Z a7e2057b268c20267be2a2d81b2bdc9a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a9ea9de121..d63c796f20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f783d90187fb326faa3d0244b30138b023c4a8483486f260b7a022a927c13f3a +e0d8f9916c2d899094b71af74f44e089a97db6d80f09eb80a5d8be733c1bf942 diff --git a/src/test_hexio.c b/src/test_hexio.c index 3c856b3306..1a21e89aa0 100644 --- a/src/test_hexio.c +++ b/src/test_hexio.c @@ -187,7 +187,7 @@ static int SQLITE_TCLAPI hexio_write( } /* -** USAGE: hexio_get_int HEXDATA +** USAGE: hexio_get_int [-littleendian] HEXDATA ** ** Interpret the HEXDATA argument as a big-endian integer. Return ** the value of that integer. HEXDATA can contain between 2 and 8 @@ -205,12 +205,20 @@ static int SQLITE_TCLAPI hexio_get_int( const unsigned char *zIn; unsigned char *aOut; unsigned char aNum[4]; + int bLittle = 0; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA"); + if( objc==3 ){ + Tcl_Size n; + char *z = Tcl_GetStringFromObj(objv[1], &n); + if( n>=2 && n<=13 && memcmp(z, "-littleendian", n)==0 ){ + bLittle = 1; + } + } + if( (objc-bLittle)!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "[-littleendian] HEXDATA"); return TCL_ERROR; } - zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn); + zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1+bLittle], &nIn); aOut = sqlite3_malloc64( 1 + nIn/2 ); if( aOut==0 ){ return TCL_ERROR; @@ -223,7 +231,11 @@ static int SQLITE_TCLAPI hexio_get_int( memcpy(&aNum[4-nOut], aOut, nOut); } sqlite3_free(aOut); - val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3]; + if( bLittle ){ + val = (int)((u32)aNum[3]<<24) | (aNum[2]<<16) | (aNum[1]<<8) | aNum[0]; + }else{ + val = (int)((u32)aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3]; + } Tcl_SetObjResult(interp, Tcl_NewIntObj(val)); return TCL_OK; } diff --git a/test/savepoint6.test b/test/savepoint6.test index b1d0d46f5c..6b41ef2da9 100644 --- a/test/savepoint6.test +++ b/test/savepoint6.test @@ -15,6 +15,10 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl proc sql {zSql} { + if {0 && $::debug_op} { + puts stderr "$zSql ;" + flush stderr + } uplevel db eval [list $zSql] #puts stderr "$zSql ;" } @@ -67,11 +71,13 @@ proc x_to_y {x} { # delete_rows XVALUES # proc savepoint {zName} { + if {$::debug_op} { puts stderr "savepoint $zName" ; flush stderr } catch { sql "SAVEPOINT $zName" } lappend ::lSavepoint [list $zName [array get ::aEntry]] } proc rollback {zName} { + if {$::debug_op} { puts stderr "rollback $zName" ; flush stderr } catch { sql "ROLLBACK TO $zName" } for {set i [expr {[llength $::lSavepoint]-1}]} {$i>=0} {incr i -1} { set zSavepoint [lindex $::lSavepoint $i 0] @@ -89,6 +95,7 @@ proc rollback {zName} { } proc release {zName} { + if {$::debug_op} { puts stderr "release $zName" ; flush stderr } catch { sql "RELEASE $zName" } for {set i [expr {[llength $::lSavepoint]-1}]} {$i>=0} {incr i -1} { set zSavepoint [lindex $::lSavepoint $i 0] @@ -104,6 +111,7 @@ proc release {zName} { } proc insert_rows {lX} { + if {$::debug_op} { puts stderr "insert_rows $lX" ; flush stderr } foreach x $lX { set y [x_to_y $x] @@ -116,6 +124,7 @@ proc insert_rows {lX} { } proc delete_rows {lX} { + if {$::debug_op} { puts stderr "delete_rows $lX" ; flush stderr } foreach x $lX { # Update database [db] sql "DELETE FROM t1 WHERE x = $x" @@ -164,6 +173,11 @@ proc random_integers {nRes nRange} { } #------------------------------------------------------------------------- +set ::debug_op 0 +proc debug_ops {} { + set ::debug_op 1 +} + proc database_op {} { set i [expr int(rand()*2)] if {$i==0} { @@ -185,9 +199,6 @@ proc savepoint_op {} { set C [lindex $cmds [expr int(rand()*6)]] set N [lindex $names [expr int(rand()*5)]] - #puts stderr " $C $N ; " - #flush stderr - $C $N return ok } From ea206ad17ba0b40ff69539ffc61067396a024ce2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Nov 2024 18:45:31 +0000 Subject: [PATCH 367/522] Reduce divergence from begin-concurrent. FossilOrigin-Name: 84d41e9d04c62601e84621e8edb3b81abbacc366a6b5e7059f8b6796fade7ffa --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/wal2.test | 37 ------------------------------------- 3 files changed, 7 insertions(+), 44 deletions(-) diff --git a/manifest b/manifest index 8984444fe6..42c69a71fa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\sreduce\sdivergence\swith\sthe\swal2\sbranch. -D 2024-11-18T17:05:45.350 +C Reduce\sdivergence\sfrom\sbegin-concurrent. +D 2024-11-18T18:45:31.904 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1986,7 +1986,7 @@ F test/vtabdistinct.test 7688f0889358f849fd60bbfde1ded38b014b18066076d4bfbb75395 F test/vtabdrop.test 65d4cf6722972e5499bdaf0c0d70ee3b8133944a4e4bc31862563f32a7edca12 F test/vtabrhs1.test 9b5ecbc74a689500c33a4b2b36761f9bcc22fcc4e3f9d21066ee0c9c74cf5f6c F test/wal.test 519c550255c78f55959e9159b93ebbfad2b4e9f36f5b76284da41f572f9d27da -F test/wal2.test 44fe1cb4935dbbddfa0a34c2c4fd90f0ba8654d59b83c4136eb90fb327fd264f +F test/wal2.test e89ca97593b5e92849039f6b68ce1719a853ef20fa22c669ec1ac452fbc31cab F test/wal3.test 5de023bb862fd1eb9d2ad26fa8d9c43abb5370582e5b08b2ae0d6f93661bc310 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f783d90187fb326faa3d0244b30138b023c4a8483486f260b7a022a927c13f3a -R 6377acb59760f57785ee6902b4729fcf +P e0d8f9916c2d899094b71af74f44e089a97db6d80f09eb80a5d8be733c1bf942 +R 15b624443bf22191f7b1a220224ff1ba U drh -Z a7e2057b268c20267be2a2d81b2bdc9a +Z e17d5ca17fa701911504cdcf5a540396 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d63c796f20..125d18f312 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0d8f9916c2d899094b71af74f44e089a97db6d80f09eb80a5d8be733c1bf942 +84d41e9d04c62601e84621e8edb3b81abbacc366a6b5e7059f8b6796fade7ffa diff --git a/test/wal2.test b/test/wal2.test index 5e4c4ebc27..5ef303edc6 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -35,43 +35,6 @@ proc cond_incr_sync_count {adj} { } } -proc set_tvfs_hdr {file args} { - - # Set $nHdr to the number of bytes in the wal-index header: - set nHdr 48 - set nInt [expr {$nHdr/4}] - - if {[llength $args]>2} { - error {wrong # args: should be "set_tvfs_hdr fileName ?val1? ?val2?"} - } - - set blob [tvfs shm $file] - if {$::tcl_platform(byteOrder)=="bigEndian"} {set fmt I} {set fmt i} - - if {[llength $args]} { - set ia [lindex $args 0] - set ib $ia - if {[llength $args]==2} { - set ib [lindex $args 1] - } - binary scan $blob a[expr $nHdr*2]a* dummy tail - set blob [binary format ${fmt}${nInt}${fmt}${nInt}a* $ia $ib $tail] - tvfs shm $file $blob - } - - binary scan $blob ${fmt}${nInt} ints - return $ints -} - -proc incr_tvfs_hdr {file idx incrval} { - set ints [set_tvfs_hdr $file] - set v [lindex $ints $idx] - incr v $incrval - lset ints $idx $v - set_tvfs_hdr $file $ints -} - - #------------------------------------------------------------------------- # Test case wal2-1.*: # From fefc7b1bf77b9dda26266205a93adf496b36f454 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 19 Nov 2024 11:58:32 +0000 Subject: [PATCH 368/522] Fix a problem handling OOM errors in fts3 that could occur when parsing multi-token strings. FossilOrigin-Name: 4c4d1db00bd2c522165876dcf1606116a72525d9ffc891b266213704e25cde55 --- ext/fts3/fts3_expr.c | 33 ++++++++++++++++----------------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/fts3fault.test | 8 ++++++++ 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/ext/fts3/fts3_expr.c b/ext/fts3/fts3_expr.c index ea8167c595..9e201b1684 100644 --- a/ext/fts3/fts3_expr.c +++ b/ext/fts3/fts3_expr.c @@ -319,10 +319,11 @@ static int getNextString( Fts3PhraseToken *pToken; p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); - if( !p ) goto no_mem; - zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); - if( !zTemp ) goto no_mem; + if( !zTemp || !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } assert( nToken==ii ); pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; @@ -337,9 +338,6 @@ static int getNextString( nToken = ii+1; } } - - pModule->xClose(pCursor); - pCursor = 0; } if( rc==SQLITE_DONE ){ @@ -347,7 +345,10 @@ static int getNextString( char *zBuf = 0; p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); - if( !p ) goto no_mem; + if( !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); p->eType = FTSQUERY_PHRASE; p->pPhrase = (Fts3Phrase *)&p[1]; @@ -355,11 +356,9 @@ static int getNextString( p->pPhrase->nToken = nToken; zBuf = (char *)&p->pPhrase->aToken[nToken]; + assert( nTemp==0 || zTemp ); if( zTemp ){ memcpy(zBuf, zTemp, nTemp); - sqlite3_free(zTemp); - }else{ - assert( nTemp==0 ); } for(jj=0; jjpPhrase->nToken; jj++){ @@ -369,17 +368,17 @@ static int getNextString( rc = SQLITE_OK; } - *ppExpr = p; - return rc; -no_mem: - + getnextstring_out: if( pCursor ){ pModule->xClose(pCursor); } sqlite3_free(zTemp); - sqlite3_free(p); - *ppExpr = 0; - return SQLITE_NOMEM; + if( rc!=SQLITE_OK ){ + sqlite3_free(p); + p = 0; + } + *ppExpr = p; + return rc; } /* diff --git a/manifest b/manifest index 42c69a71fa..0ed54a2c71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sdivergence\sfrom\sbegin-concurrent. -D 2024-11-18T18:45:31.904 +C Fix\sa\sproblem\shandling\sOOM\serrors\sin\sfts3\sthat\scould\soccur\swhen\sparsing\smulti-token\sstrings. +D 2024-11-19T11:58:32.252 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -80,7 +80,7 @@ F ext/fts3/fts3.c 9f8ce82bbf4ec0636e6170e58f17b04817fa4c39b2d5126ac06f005d485f6d F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682 F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 -F ext/fts3/fts3_expr.c 903bfb9433109fffb10e910d7066c49cbf8eeae316adc93f0499c4da7dfc932a +F ext/fts3/fts3_expr.c 365849a2a1185e19028a9db2d9f1ea63efe909a3a6aca7ec86fc26a13a60bd58 F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 @@ -1204,7 +1204,7 @@ F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8 F test/fts3expr4.test 6c7675bbdbffe6ffc95e9e861500b8ac3f739c4d004ffda812f138eeb1b45529 F test/fts3expr5.test a5b9a053becbdb8e973fbf4d6d3abaabeb42d511d1848bd57931f3e0a1cf983e F test/fts3f.test 8c438d5e1cab526b0021988fb1dc70cf3597b006a33ffd6c955ee89929077fe3 -F test/fts3fault.test f4e1342acfe6d216a001490e8cd52afac1f9ffe4a11bbcdcb296129a45c5df45 +F test/fts3fault.test 9228f00cd69e2a5d2ed0f06c181981f4f90bd36da9f86b73f3a58b4b23451fd4 F test/fts3fault2.test 7b2741e5095367238380b0fcdb837f36c24484c7a5f353659b387df63cf039ec F test/fts3fault3.test ccdd2292dd2d4e21e30fc5f4c8e064f79e516087eec5ff57ab6bc4f6a7714097 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e0d8f9916c2d899094b71af74f44e089a97db6d80f09eb80a5d8be733c1bf942 -R 15b624443bf22191f7b1a220224ff1ba -U drh -Z e17d5ca17fa701911504cdcf5a540396 +P 84d41e9d04c62601e84621e8edb3b81abbacc366a6b5e7059f8b6796fade7ffa +R 15d5c68f2ffe8e979f466eec5e117ba3 +U dan +Z 7f81f47d67e456b494dfb3b575661f30 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 125d18f312..dea58b2d92 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84d41e9d04c62601e84621e8edb3b81abbacc366a6b5e7059f8b6796fade7ffa +4c4d1db00bd2c522165876dcf1606116a72525d9ffc891b266213704e25cde55 diff --git a/test/fts3fault.test b/test/fts3fault.test index 21defd282f..20e5f25de5 100644 --- a/test/fts3fault.test +++ b/test/fts3fault.test @@ -216,6 +216,14 @@ do_faultsim_test 8.4 -prep { } -test { faultsim_test_result {0 3} } +do_faultsim_test 8.5 -prep { + faultsim_restore_and_reopen + db func mit mit +} -body { + execsql { SELECT mit(matchinfo(t8, 'l')) FROM t8 WHERE t8 MATCH '"a b c"' } +} -test { + faultsim_test_result {0 3} +} do_test 9.0 { faultsim_delete_and_reopen From fbd9de1830209ec810ef1bac614c2c57031728bf Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 19 Nov 2024 15:20:47 +0000 Subject: [PATCH 369/522] Initial configure support for linking certain binaries to libsqlite3.so instead of embedding it dynamically (which they typically do). This currently applies only to sqldiff, but support for adding the same for other tools is planned. This requires disabling the soname because setting it causes the build to link to whatever libsqlite3.so.0 is installed system-wide, so the soname now defaults to off. FossilOrigin-Name: 9192c146e2898456a6b8ea43a6f02c0227ddce5b584374fbeb2d63bd2ecd5d8c --- Makefile.in | 1 + auto.def | 8 ++++++-- main.mk | 15 +++++++++++++-- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Makefile.in b/Makefile.in index b374bd4838..219347c301 100644 --- a/Makefile.in +++ b/Makefile.in @@ -287,6 +287,7 @@ AS_AUTO_DEF = $(TOP)/auto.def AS_AUTORECONFIG = @SQLITE_AUTORECONFIG@ USE_AMALGAMATION ?= @USE_AMALGAMATION@ +LINK_TOOLS_DYNAMICALLY ?= @LINK_TOOLS_DYNAMICALLY@ AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@ # diff --git a/auto.def b/auto.def index 919df0101f..addaf408e3 100644 --- a/auto.def +++ b/auto.def @@ -198,7 +198,9 @@ set flags { linemacros => {Enable #line macros in the amalgamation} dev => {Enable dev-mode build: automatically enables certain other flags} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} - soname:=legacy => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} + link-tools-dynamically => {Dynamically link libsqlite3 to certain tools which normally statically embed it.} + soname:=none => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} + # --soname has a long story behind it, as well as no small amount of uncertainty. # } if {"" ne $DUMP_DEFINES_JSON} { @@ -327,6 +329,8 @@ proj-if-opt-truthy dev { define CFLAGS [get-env CFLAGS {-O0 -g}] } +define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided link-tools-dynamically] + ######################################################################## # Handle --with-wasi-sdk=DIR # @@ -468,7 +472,7 @@ apply {{} { if {[proj-opt-was-provided soname]} { set soname [opt-val soname] } else { - set soname legacy + set soname none; # enabling soname breaks linking for the --link-tools-dynamically feature } switch -exact -- $soname { none { return 0 } diff --git a/main.mk b/main.mk index a22c0fe775..20a54adfc3 100644 --- a/main.mk +++ b/main.mk @@ -205,6 +205,14 @@ ENABLE_STATIC ?= 1 # USE_AMALGAMATION ?= 1 # +# $(LINK_TOOLS_DYNAMICALLY) +# +# If true, certain binaries which typically statically link against +# libsqlite3 or its component object files will instead link against +# the DLL. +# +LINK_TOOLS_DYNAMICALLY ?= 0 +# # $(AMALGAMATION_GEN_FLAGS) = # # Optional flags for the amalgamation generator. @@ -1950,8 +1958,11 @@ install-shell-0: sqlite3$(T.exe) $(install-dir.bin) install-shell-1 install-shell-: install: install-shell-$(HAVE_WASI_SDK) -sqldiff$(T.exe): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h - $(T.link) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) +sqldiff$(T.exe): sqldiff.$(LINK_TOOLS_DYNAMICALLY) +sqldiff.0: $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h + $(T.link) -o sqldiff$(T.exe) $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) +sqldiff.1: $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h $(libsqlite3.SO) + $(T.link) -o sqldiff$(T.exe) $(TOP)/tool/sqldiff.c -L. -lsqlite3 $(LDFLAGS.configure) install-diff: sqldiff$(T.exe) $(install-dir.bin) $(INSTALL) -s sqldiff$(T.exe) "$(install-dir.bin)" diff --git a/manifest b/manifest index 0ed54a2c71..5d62160222 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sa\sproblem\shandling\sOOM\serrors\sin\sfts3\sthat\scould\soccur\swhen\sparsing\smulti-token\sstrings. -D 2024-11-19T11:58:32.252 +C Initial\sconfigure\ssupport\sfor\slinking\scertain\sbinaries\sto\slibsqlite3.so\sinstead\sof\sembedding\sit\sdynamically\s(which\sthey\stypically\sdo).\sThis\scurrently\sapplies\sonly\sto\ssqldiff,\sbut\ssupport\sfor\sadding\sthe\ssame\sfor\sother\stools\sis\splanned.\sThis\srequires\sdisabling\sthe\ssoname\sbecause\ssetting\sit\scauses\sthe\sbuild\sto\slink\sto\swhatever\slibsqlite3.so.0\sis\sinstalled\ssystem-wide,\sso\sthe\ssoname\snow\sdefaults\sto\soff. +D 2024-11-19T15:20:47.506 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in c3a01e98bd2ae6a4631df02f11249ac07ffa3d540d3034e2675f66cc259f2ea7 +F Makefile.in 5461b1125a3039fef49f4896519d164ebe22ee394d20d69913ab0fdc8c464b63 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 94f0f4a697e8221d5c7ca561771a3afabb0e707922daad89b60908b87a8e399b +F auto.def 6aa362ceeeaaf2521b0c781a44489d6f5bd6c7a147e9a6e8e6ae68a928158357 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk c4e37e3015f9c2d8fd20fa3071ba86e7396959c8d5960e37e95aa85421e2b739 +F main.mk d82de0fbdb6b7521c55e47feced1e76204058a19d860266a7c77b194cb298321 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 84d41e9d04c62601e84621e8edb3b81abbacc366a6b5e7059f8b6796fade7ffa -R 15d5c68f2ffe8e979f466eec5e117ba3 -U dan -Z 7f81f47d67e456b494dfb3b575661f30 +P 4c4d1db00bd2c522165876dcf1606116a72525d9ffc891b266213704e25cde55 +R 4e525e0050af78dd77407fe8fd687f7e +T *branch * link-tools-dynamically +T *sym-link-tools-dynamically * +T -sym-trunk * Cancelled\sby\sbranch. +U stephan +Z 39424480882931664661450c95279514 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dea58b2d92..d1e075f2be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c4d1db00bd2c522165876dcf1606116a72525d9ffc891b266213704e25cde55 +9192c146e2898456a6b8ea43a6f02c0227ddce5b584374fbeb2d63bd2ecd5d8c From 5ef61df185a26ea826aa79c94d6eee9329048f91 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 19 Nov 2024 16:40:49 +0000 Subject: [PATCH 370/522] Reformulate sqldiff deps and rules so that the target matches the resulting file name, to avoid rebuilding it on every make invocation. Apply the same treatment to the sqlite3 CLI shell. FossilOrigin-Name: 9a17b83f859ef14629cb78d8c9af1b3f2493b0c8756bc2ebcf92f0872fb507c3 --- auto.def | 2 +- main.mk | 48 +++++++++++++++++++++++++++++------------------- manifest | 17 +++++++---------- manifest.uuid | 2 +- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/auto.def b/auto.def index addaf408e3..1e388ac20e 100644 --- a/auto.def +++ b/auto.def @@ -199,7 +199,7 @@ set flags { dev => {Enable dev-mode build: automatically enables certain other flags} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} link-tools-dynamically => {Dynamically link libsqlite3 to certain tools which normally statically embed it.} - soname:=none => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} + soname:=legacy => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} # --soname has a long story behind it, as well as no small amount of uncertainty. # } diff --git a/main.mk b/main.mk index 20a54adfc3..af616086be 100644 --- a/main.mk +++ b/main.mk @@ -1930,11 +1930,26 @@ xbin: threadtest5 # special compile-time options that are interpreted by individual # source files within the amalgamation. # -sqlite3$(T.exe): shell.c sqlite3.c - $(T.link) -o $@ \ - shell.c sqlite3.c \ - $(CFLAGS.readline) $(SHELL_OPT) $(CFLAGS.icu) \ - $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) +# How/whether we build sqlite3$(T.exe) depends on both +# $(HAVE_WASI_SDK) and $(LINK_TOOLS_DYNAMICALLY), thus there are +# several targets here, only one of which the sqlite3$(T.exe) target +# indirectly resolves to. +# +sqlite3-shell.0.0.deps = shell.c sqlite3.c +sqlite3-shell.0.0.rules = \ + $(T.link) -o $@ \ + shell.c sqlite3.c \ + $(CFLAGS.readline) $(SHELL_OPT) $(CFLAGS.icu) \ + $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) +sqlite3-shell.0.1.deps = shell.c $(libsqlite3.SO) +sqlite3-shell.0.1.rules = \ + $(T.link) -o $@ \ + shell.c -L. -lsqlite3 \ + $(CFLAGS.readline) $(SHELL_OPT) $(CFLAGS.icu) \ + $(LDFLAGS.configure) $(LDFLAGS.readline) $(LDFLAGS.zlib) +sqlite3$(T.exe): $(sqlite3-shell.$(HAVE_WASI_SDK).$(LINK_TOOLS_DYNAMICALLY).deps) + $(sqlite3-shell.$(HAVE_WASI_SDK).$(LINK_TOOLS_DYNAMICALLY).rules) +all: sqlite3$(T.exe) # The "sqlite3d" CLI is build using separate source files. This # is useful during development and debugging. @@ -1945,24 +1960,19 @@ sqlite3d$(T.exe): shell.c $(LIBOBJS0) $(CFLAGS.readline) $(SHELL_OPT) \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) -# -# Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the -# semantics of 0 and 1 are confusingly swapped here. -# -sqlite3$(T.exe)-1: -sqlite3$(T.exe)-0 sqlite3$(T.exe)-: sqlite3$(T.exe) -all: sqlite3$(T.exe)-$(HAVE_WASI_SDK) - install-shell-0: sqlite3$(T.exe) $(install-dir.bin) $(INSTALL) -s sqlite3$(T.exe) "$(install-dir.bin)" -install-shell-1 install-shell-: +install-shell-1: install: install-shell-$(HAVE_WASI_SDK) -sqldiff$(T.exe): sqldiff.$(LINK_TOOLS_DYNAMICALLY) -sqldiff.0: $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h - $(T.link) -o sqldiff$(T.exe) $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) -sqldiff.1: $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h $(libsqlite3.SO) - $(T.link) -o sqldiff$(T.exe) $(TOP)/tool/sqldiff.c -L. -lsqlite3 $(LDFLAGS.configure) +# How to build sqldiff$(T.exe) depends on $(LINK_TOOLS_DYNAMICALLY) +# +sqldiff.0.deps = $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h +sqldiff.0.rules = $(T.link) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) +sqldiff.1.deps = $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h $(libsqlite3.SO) +sqldiff.1.rules = $(T.link) -o $@ $(TOP)/tool/sqldiff.c -L. -lsqlite3 $(LDFLAGS.configure) +sqldiff$(T.exe): $(sqldiff.$(LINK_TOOLS_DYNAMICALLY).deps) + $(sqldiff.$(LINK_TOOLS_DYNAMICALLY).rules) install-diff: sqldiff$(T.exe) $(install-dir.bin) $(INSTALL) -s sqldiff$(T.exe) "$(install-dir.bin)" diff --git a/manifest b/manifest index 5d62160222..3cfb99819a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\sconfigure\ssupport\sfor\slinking\scertain\sbinaries\sto\slibsqlite3.so\sinstead\sof\sembedding\sit\sdynamically\s(which\sthey\stypically\sdo).\sThis\scurrently\sapplies\sonly\sto\ssqldiff,\sbut\ssupport\sfor\sadding\sthe\ssame\sfor\sother\stools\sis\splanned.\sThis\srequires\sdisabling\sthe\ssoname\sbecause\ssetting\sit\scauses\sthe\sbuild\sto\slink\sto\swhatever\slibsqlite3.so.0\sis\sinstalled\ssystem-wide,\sso\sthe\ssoname\snow\sdefaults\sto\soff. -D 2024-11-19T15:20:47.506 +C Reformulate\ssqldiff\sdeps\sand\srules\sso\sthat\sthe\starget\smatches\sthe\sresulting\sfile\sname,\sto\savoid\srebuilding\sit\son\severy\smake\sinvocation.\sApply\sthe\ssame\streatment\sto\sthe\ssqlite3\sCLI\sshell. +D 2024-11-19T16:40:49.154 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 6aa362ceeeaaf2521b0c781a44489d6f5bd6c7a147e9a6e8e6ae68a928158357 +F auto.def b6fc55bf238320b58d06d6e5364374722aae3b8320c4f928e0e6c208405f2cfd F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk d82de0fbdb6b7521c55e47feced1e76204058a19d860266a7c77b194cb298321 +F main.mk 8ef1c08eb0e644df88978d2b1db4e2af9efc430a0fe3dd152d00fa21593fee41 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,11 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4c4d1db00bd2c522165876dcf1606116a72525d9ffc891b266213704e25cde55 -R 4e525e0050af78dd77407fe8fd687f7e -T *branch * link-tools-dynamically -T *sym-link-tools-dynamically * -T -sym-trunk * Cancelled\sby\sbranch. +P 9192c146e2898456a6b8ea43a6f02c0227ddce5b584374fbeb2d63bd2ecd5d8c +R 9e3125f578c182d0fd3f116bcadb353b U stephan -Z 39424480882931664661450c95279514 +Z c9c941efe50c477f477a1622a4a0493c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d1e075f2be..5cd2262fb1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9192c146e2898456a6b8ea43a6f02c0227ddce5b584374fbeb2d63bd2ecd5d8c +9a17b83f859ef14629cb78d8c9af1b3f2493b0c8756bc2ebcf92f0872fb507c3 From 3cd93a0b67ccd688864782c2a2148d987f1c3001 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 19 Nov 2024 17:41:13 +0000 Subject: [PATCH 371/522] Revert linking the shell to the dll for reasons explained in new makefile comments. Move the --with-debug configure flag into the developer options set and add commentary about why it should never be used for production builds. FossilOrigin-Name: 7b14309be42be4204c4d30e9741d56d75ab8ec34686791d032612337fe1c4dcf --- auto.def | 9 +++++++-- autosetup/proj.tcl | 10 +++++----- main.mk | 48 +++++++++++++++++++++++----------------------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 45 insertions(+), 40 deletions(-) diff --git a/auto.def b/auto.def index 1e388ac20e..eee8c5aeff 100644 --- a/auto.def +++ b/auto.def @@ -123,7 +123,6 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json ######################################################################## set flags { # - with-debug:=1 => {Enable debug build flags} shared=1 => {Disable build of shared libary} static=1 => {Disable build of static library (mostly)} amalgamation=1 => {Disable the amalgamation and instead build all files separately.} @@ -193,10 +192,16 @@ set flags { with-emsdk:=auto => {Top-most dir of the Emscripten SDK installation. Default = EMSDK env var.} # # + + # --with-debug does more than simply builds with a -g compilation + # flag and will impact performance by as much as 4x, as it includes + # large numbers of assert()s in performance-critical loops. Never + # use --with-debug for production builds. + with-debug:=1 => {Enable debug build flags} + dev => {Enable dev-mode build: automatically enables certain other flags} test-status => {Enable status of tests} gcov=0 => {Enable coverage testing using gcov} linemacros => {Enable #line macros in the amalgamation} - dev => {Enable dev-mode build: automatically enables certain other flags} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} link-tools-dynamically => {Dynamically link libsqlite3 to certain tools which normally statically embed it.} soname:=legacy => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 863962c2f8..7da0b0fa35 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -311,11 +311,11 @@ proc proj-first-bin-of {args} { ######################################################################## # @proj-opt-was-provided key # -# Returns 1 if the user specifically provided the given configure -# flag, else 0. This can be used to distinguish between options which -# have a default value and those which were explicitly provided by the -# user, even if the latter is done in a way which uses the default -# value. +# Returns 1 if the user specifically provided the given configure flag +# or if it was specifically set using proj-opt-set, else 0. This can +# be used to distinguish between options which have a default value +# and those which were explicitly provided by the user, even if the +# latter is done in a way which uses the default value. # # For example, with a configure flag defined like: # diff --git a/main.mk b/main.mk index af616086be..3193e531d1 100644 --- a/main.mk +++ b/main.mk @@ -901,6 +901,9 @@ TESTOPTS = --verbose=file --output=test-out.txt # # Extra compiler options for various shell tools # +# Note that some of these will only apply when embedding sqlite3.c +# into the shell, as these flags are not otherwise passed on to the +# library. SHELL_OPT += -DSQLITE_DQS=0 SHELL_OPT += -DSQLITE_ENABLE_FTS4 #SHELL_OPT += -DSQLITE_ENABLE_FTS5 @@ -1926,30 +1929,27 @@ threadtest5: sqlite3.c $(TOP)/test/threadtest5.c $(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3) xbin: threadtest5 -# The standard CLI is built using the amalgamation since it uses -# special compile-time options that are interpreted by individual -# source files within the amalgamation. -# -# How/whether we build sqlite3$(T.exe) depends on both -# $(HAVE_WASI_SDK) and $(LINK_TOOLS_DYNAMICALLY), thus there are -# several targets here, only one of which the sqlite3$(T.exe) target -# indirectly resolves to. -# -sqlite3-shell.0.0.deps = shell.c sqlite3.c -sqlite3-shell.0.0.rules = \ - $(T.link) -o $@ \ - shell.c sqlite3.c \ - $(CFLAGS.readline) $(SHELL_OPT) $(CFLAGS.icu) \ - $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) -sqlite3-shell.0.1.deps = shell.c $(libsqlite3.SO) -sqlite3-shell.0.1.rules = \ - $(T.link) -o $@ \ - shell.c -L. -lsqlite3 \ - $(CFLAGS.readline) $(SHELL_OPT) $(CFLAGS.icu) \ - $(LDFLAGS.configure) $(LDFLAGS.readline) $(LDFLAGS.zlib) -sqlite3$(T.exe): $(sqlite3-shell.$(HAVE_WASI_SDK).$(LINK_TOOLS_DYNAMICALLY).deps) - $(sqlite3-shell.$(HAVE_WASI_SDK).$(LINK_TOOLS_DYNAMICALLY).rules) -all: sqlite3$(T.exe) +# +# When building sqlite3$(T.exe) we specifically embed a copy of +# sqlite3.c, and not link to libsqlite3.so or libsqlite3.a, because +# the shell needs to be able to enable arbitrary library features, +# some of which have significant performance impacts. For example,, +# SQLITE_ENABLE_EXPLAIN_COMMENTS has been measured as having a 5.2% +# runtime performance hit, which is fine for use in the shell but is +# not appropriate for the canonical library build. +# +sqlite3$(T.exe): shell.c sqlite3.c + $(T.link) -o $@ \ + shell.c sqlite3.c \ + $(CFLAGS.readline) $(SHELL_OPT) $(CFLAGS.icu) \ + $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) +# +# Build sqlite3$(T.exe) by default except in wasi-sdk builds. Yes, the +# semantics of 0 and 1 are confusingly swapped here. +# +sqlite3$(T.exe)-1: +sqlite3$(T.exe)-0: sqlite3$(T.exe) +all: sqlite3$(T.exe)-$(HAVE_WASI_SDK) # The "sqlite3d" CLI is build using separate source files. This # is useful during development and debugging. diff --git a/manifest b/manifest index 3cfb99819a..e7c415ad2b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reformulate\ssqldiff\sdeps\sand\srules\sso\sthat\sthe\starget\smatches\sthe\sresulting\sfile\sname,\sto\savoid\srebuilding\sit\son\severy\smake\sinvocation.\sApply\sthe\ssame\streatment\sto\sthe\ssqlite3\sCLI\sshell. -D 2024-11-19T16:40:49.154 +C Revert\slinking\sthe\sshell\sto\sthe\sdll\sfor\sreasons\sexplained\sin\snew\smakefile\scomments.\sMove\sthe\s--with-debug\sconfigure\sflag\sinto\sthe\sdeveloper\soptions\sset\sand\sadd\scommentary\sabout\swhy\sit\sshould\snever\sbe\sused\sfor\sproduction\sbuilds. +D 2024-11-19T17:41:13.115 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def b6fc55bf238320b58d06d6e5364374722aae3b8320c4f928e0e6c208405f2cfd +F auto.def 4f5ae3ed11bb110b1eda2a6b7ee46489b7371bc8f7c19f0ed944613c170e4951 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 96fe16b87c9feb9c1cf2682280f678c659bc52c09fca5de02afc2f7ec5bfb154 +F autosetup/proj.tcl 22556a325c964aa5377d4d881722385f41fcd7c1b60102ba8965f7814c83e9ce F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 8ef1c08eb0e644df88978d2b1db4e2af9efc430a0fe3dd152d00fa21593fee41 +F main.mk 7cb02ba61e74ccab3ad6775b9207b12c6a26bbe3b2dd280039bc0cd532a52ceb F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9192c146e2898456a6b8ea43a6f02c0227ddce5b584374fbeb2d63bd2ecd5d8c -R 9e3125f578c182d0fd3f116bcadb353b +P 9a17b83f859ef14629cb78d8c9af1b3f2493b0c8756bc2ebcf92f0872fb507c3 +R 0effbfea81177717d860b06a74ce79d8 U stephan -Z c9c941efe50c477f477a1622a4a0493c +Z aa386346708361b0b61a6d6560bd2986 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5cd2262fb1..2cf57950de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a17b83f859ef14629cb78d8c9af1b3f2493b0c8756bc2ebcf92f0872fb507c3 +7b14309be42be4204c4d30e9741d56d75ab8ec34686791d032612337fe1c4dcf From 5608fb36ec84f1378cbfcc32e004b0343fd26070 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Nov 2024 18:26:47 +0000 Subject: [PATCH 372/522] Enhancements to tool/mkccode.tcl such that it recognizes -D command line arguments and can use them in internal IFDEF and IFNDEF macros. Update the tool/sqlite3_analyzer.c.in script such that it omits the SQLite amalgamation if -DSQLITE_ENABLE_DBSTAT_VTAB is defined. FossilOrigin-Name: 7fec209290aa1a6dbbca8de154edaac5d8d0ce042bc0617d27fb2095c8d580f1 --- manifest | 16 ++++---- manifest.uuid | 2 +- tool/mkccode.tcl | 79 +++++++++++++++++++++++++++++++++++--- tool/sqlite3_analyzer.c.in | 6 ++- 4 files changed, 86 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 0ed54a2c71..87bdfbdd5f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\shandling\sOOM\serrors\sin\sfts3\sthat\scould\soccur\swhen\sparsing\smulti-token\sstrings. -D 2024-11-19T11:58:32.252 +C Enhancements\sto\stool/mkccode.tcl\ssuch\sthat\sit\srecognizes\s-D\scommand\sline\narguments\sand\scan\suse\sthem\sin\sinternal\sIFDEF\sand\sIFNDEF\smacros.\s\sUpdate\nthe\stool/sqlite3_analyzer.c.in\sscript\ssuch\sthat\sit\somits\sthe\sSQLite\samalgamation\nif\s-DSQLITE_ENABLE_DBSTAT_VTAB\sis\sdefined. +D 2024-11-19T18:26:47.422 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2135,7 +2135,7 @@ F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a -F tool/mkccode.tcl 4cb8ad7e7330aaed052b0657a1bfacbc67103c400e41860aff643a482cfc2d3e x +F tool/mkccode.tcl b0ddad168362ba6225c9372856ba0db90145734e882a9a5bb8951ef0d5bc6331 x F tool/mkctimec.tcl ef6a67ec82e5b6fc19152a4c79f237227b18bf67ff16d155bac7adb94355d9cf x F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559 F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a @@ -2178,7 +2178,7 @@ F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b -F tool/sqlite3_analyzer.c.in 348ba349bbdc93c9866439f9f935d7284866a2a4e6898bc906ae1204ade56918 +F tool/sqlite3_analyzer.c.in 39690af454d2866e87e2b475ec5eabee366f211f2307e90b918345f35bb1a643 F tool/sqlite3_rsync.c 9a1cca2ab1271c59b37a6493c15dc1bcd0ab9149197a9125926bc08dd26b83fb F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 84d41e9d04c62601e84621e8edb3b81abbacc366a6b5e7059f8b6796fade7ffa -R 15d5c68f2ffe8e979f466eec5e117ba3 -U dan -Z 7f81f47d67e456b494dfb3b575661f30 +P 4c4d1db00bd2c522165876dcf1606116a72525d9ffc891b266213704e25cde55 +R cdb63603c9c3a16b29feb4bae93e8b25 +U drh +Z 2a605008d2464811e071ed45a95c8ad5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dea58b2d92..643a526325 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c4d1db00bd2c522165876dcf1606116a72525d9ffc891b266213704e25cde55 +7fec209290aa1a6dbbca8de154edaac5d8d0ce042bc0617d27fb2095c8d580f1 diff --git a/tool/mkccode.tcl b/tool/mkccode.tcl index e847c8d3b8..457865b66f 100755 --- a/tool/mkccode.tcl +++ b/tool/mkccode.tcl @@ -6,7 +6,7 @@ # # Usage example: # -# tclsh mkccode.tcl demoapp.c.in >demoapp.c +# tclsh mkccode.tcl -DENABLE_FEATURE_XYZ demoapp.c.in >demoapp.c # # The demoapp.c.in file contains a mixture of C code, TCL script, and # processing directives used by mktclsqliteprog.tcl to build the final C-code @@ -33,29 +33,63 @@ # then all of the text in the input file is converted into C-language # string literals. # +# IFDEF macro +# IFNDEF macro +# ELSE +# ENDIF +# +# The text from "IFDEF macro" down to the next ELSE or ENDIF is +# included only if -Dmacro appears as a command-line argument. +# The "IFNDEF macro" simply inverts the initial test. +# # None of the control directives described above will nest. Only the # top-level input file ("demoapp.c.in" in the example) is interpreted. # referenced files are copied verbatim. # -if {[llength $argv]!=1} { - puts stderr "Usage: $argv0 TEMPLATE >OUTPUT" +proc usage {} { + puts stderr "Usage: $::argv0 \[OPTIONS\] TEMPLATE >OUTPUT" exit 1 } -set infile [lindex $argv 0] +set infile {} +foreach ax $argv { + if {[string match -D* $ax]} { + if {[string match *=* $ax]} { + regexp {-D([^=]+)=(.*)} ax all name value + set DEF($name) $value + } else { + set DEF([string range $ax 2 end]) 1 + } + continue + } + if {[string match -* $ax]} { + puts stderr "$::argv0: Unknown option \"$ax\"" + usage + } + if {$infile!=""} { + puts stderr "$::argv0: Surplus argument: \"$ax\"" + usage + } + set infile $ax +} set ROOT [file normalize [file dir $argv0]/..] set HOME [file normalize [file dir $infile]] set in [open $infile rb] puts [subst {/* DO NOT EDIT ** -** This file was generated by \"$argv0 $infile\". +** This file was generated by \"$argv0 $argv\". ** To make changes, edit $infile then rerun the generator ** command. */}] set instr 0 +set omit {} +set nomit 0 +set ln 0 while {1} { set line [gets $in] + incr ln if {[eof $in]} break if {[regexp {^INCLUDE (.*)} $line all path]} { + if {$nomit>0 && [string match *1* $omit]} continue if {0} { # https://github.com/msteveb/jimtcl/issues/320 regsub {^\$ROOT\y} $path $ROOT path @@ -91,10 +125,43 @@ while {1} { puts "/* END_STRING */" continue } - if {$instr} { + if {[regexp {^IFNDEF +([A-Za-z_]+)} $line all name]} { + set omit $omit[info exists DEF($name)] + incr nomit + continue + } + if {[regexp {^IFDEF +([A-Za-z_]+)} $line all name]} { + set omit $omit[expr {![info exists DEF($name)]}] + incr nomit + continue + } + if {[regexp {^ELSE} $line]} { + if {!$nomit} { + puts stderr "$infile:$ln: ELSE without a prior IFDEF" + exit 1 + } + set omit [string range $omit 0 end-1][expr {![string index $omit end]}] + continue + } + if {[regexp {^ENDIF} $line]} { + if {!$nomit} { + puts stderr "$infile:$ln: ENDIF without a prior IFDEF" + exit 1 + } + incr nomit -1 + set omit [string range $omit 0 [expr {$nomit-1}]] + continue + } + if {$nomit>0 && [string match *1* $omit]} { + # noop + } elseif {$instr} { set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line] puts "\"$x\\n\"" } else { puts $line } } +if {$nomit} { + puts stderr "$infile:$ln: One or more unterminated IFDEFs" + exit 1 +} diff --git a/tool/sqlite3_analyzer.c.in b/tool/sqlite3_analyzer.c.in index 1c9fc836a1..a934f05700 100644 --- a/tool/sqlite3_analyzer.c.in +++ b/tool/sqlite3_analyzer.c.in @@ -3,6 +3,7 @@ ** text on standard output. */ #define TCLSH_INIT_PROC sqlite3_analyzer_init_proc +IFNDEF SQLITE_ENABLE_DBSTAT_VTAB #define SQLITE_ENABLE_DBSTAT_VTAB 1 #undef SQLITE_THREADSAFE #define SQLITE_THREADSAFE 0 @@ -14,9 +15,10 @@ #define SQLITE_DEFAULT_MEMSTATUS 0 #define SQLITE_MAX_EXPR_DEPTH 0 #define SQLITE_OMIT_LOAD_EXTENSION 1 -#if !defined(SQLITE_AMALGAMATION) && !defined(USE_EXTERNAL_SQLITE) INCLUDE sqlite3.c -#endif +ELSE +#include "sqlite3.h" +ENDIF INCLUDE $ROOT/src/tclsqlite.c #if defined(_WIN32) From c73b85c156b93911ceb62a435b1566b0b6f41bcb Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 19 Nov 2024 19:47:51 +0000 Subject: [PATCH 373/522] Get sqlite3_analyzer optionally linking against libsqlite3.so instead of embedding sqlite3.c. Patch mkccode.tcl to accept digits in its IFDEF/IFNDEF checks and sqlite3_analyzer.c.in to only include sqlite3.c if -DINCLUDE_SQLITE3_C is passed to mkccode.tcl. FossilOrigin-Name: 80f3bf8c2ee31ba1ab9187d64d5dcbbf97a61845a21b036f89ea9133153575c0 --- main.mk | 33 +++++++++++++++++++++++++++------ manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/mkccode.tcl | 4 ++-- tool/sqlite3_analyzer.c.in | 3 ++- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/main.mk b/main.mk index 3193e531d1..878be92ae6 100644 --- a/main.mk +++ b/main.mk @@ -1741,13 +1741,34 @@ smoketest: $(TESTPROGS) fuzzcheck$(T.exe) shelltest: $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell +# +# sqlite3_analyzer.c build depends on $(LINK_TOOLS_DYNAMICALLY). +# +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 \ - $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 - $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c - -sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c - $(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC \ - $(LDFLAGS.libsqlite3) + $(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)) \ + $(OPT_FEATURE_FLAGS) \ + > $@ + +# +# sqlite3_analyzer's build mode depends on $(LINK_TOOLS_DYNAMICALLY). +# +sqlite3_analyzer.flags.1 = -L. -lsqlite3 $(LDFLAGS.math) +sqlite3_analyzer.flags.0 = $(LDFLAGS.libsqlite3) +sqlite3_analyzer.deps.1 = $(libsqlite3.SO) +sqlite3_analyzer.deps.0 = +sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c \ + $(sqlite3_analyzer.deps.$(LINK_TOOLS_DYNAMICALLY)) + $(T.link.tcl) sqlite3_analyzer.c -o $@ \ + $(sqlite3_analyzer.flags.$(LINK_TOOLS_DYNAMICALLY)) \ + $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC +# ^^^^ the order of those flags is relevant for +# $(sqlite3_analyzer.flags.1): if the $$TCL_... flags come first they +# 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 \ $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl \ diff --git a/manifest b/manifest index efd82a70ad..8c13ab27c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\sinto\sthis\sbranch.\sFix\sa\ssmall\sjimtcl/tclsh\sregex\sincompatibility\sin\smkccode.tcl. -D 2024-11-19T19:16:58.734 +C Get\ssqlite3_analyzer\soptionally\slinking\sagainst\slibsqlite3.so\sinstead\sof\sembedding\ssqlite3.c.\sPatch\smkccode.tcl\sto\saccept\sdigits\sin\sits\sIFDEF/IFNDEF\schecks\sand\ssqlite3_analyzer.c.in\sto\sonly\sinclude\ssqlite3.c\sif\s-DINCLUDE_SQLITE3_C\sis\spassed\sto\smkccode.tcl. +D 2024-11-19T19:47:51.323 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 7cb02ba61e74ccab3ad6775b9207b12c6a26bbe3b2dd280039bc0cd532a52ceb +F main.mk b1f78ccd8b6db3fbc6a7e9952fc3e60433ad8d25798eb0b55632b1eb502ab30a F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2135,7 +2135,7 @@ F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a -F tool/mkccode.tcl 0e7488b7218128271b93a4b16e60a169097b6cb555446ce4d6a131be039bb536 x +F tool/mkccode.tcl 210159febe0ef0ecbc53c79833500663ceaba0115b2b374405818dc835b5f84b x F tool/mkctimec.tcl ef6a67ec82e5b6fc19152a4c79f237227b18bf67ff16d155bac7adb94355d9cf x F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559 F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a @@ -2178,7 +2178,7 @@ F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/sqldiff.c 2a0987d183027c795ced13d6749061c1d2f38e24eddb428f56fa64c3a8f51e4b -F tool/sqlite3_analyzer.c.in 39690af454d2866e87e2b475ec5eabee366f211f2307e90b918345f35bb1a643 +F tool/sqlite3_analyzer.c.in fc7735c499d226a49d843d8209b2543e4e5229eeb71a674c331323a2217b65b4 F tool/sqlite3_rsync.c 9a1cca2ab1271c59b37a6493c15dc1bcd0ab9149197a9125926bc08dd26b83fb F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7b14309be42be4204c4d30e9741d56d75ab8ec34686791d032612337fe1c4dcf 7fec209290aa1a6dbbca8de154edaac5d8d0ce042bc0617d27fb2095c8d580f1 -R 0da2647f2e208e5fa5304d40f71239b4 +P 7fb3ebfec634e0508267049fddb2b513201dbefce4d378ca3ec261c5d8336d7f +R 631735400a3a45c7eca237a47c49e579 U stephan -Z bed720f65fe4f336de4e69b585a4a039 +Z b91791961d3936264eb9b5de6178a0fb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d9f567ad70..22db0ea473 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7fb3ebfec634e0508267049fddb2b513201dbefce4d378ca3ec261c5d8336d7f +80f3bf8c2ee31ba1ab9187d64d5dcbbf97a61845a21b036f89ea9133153575c0 diff --git a/tool/mkccode.tcl b/tool/mkccode.tcl index b95f0c679d..ecafbdadb9 100755 --- a/tool/mkccode.tcl +++ b/tool/mkccode.tcl @@ -125,12 +125,12 @@ while {1} { puts "/* END_STRING */" continue } - if {[regexp {^IFNDEF +([A-Za-z_]+)} $line all name]} { + if {[regexp {^IFNDEF +([A-Za-z_0-9]+)} $line all name]} { set omit $omit[info exists DEF($name)] incr nomit continue } - if {[regexp {^IFDEF +([A-Za-z_]+)} $line all name]} { + if {[regexp {^IFDEF +([A-Za-z_0-9]+)} $line all name]} { set omit $omit[expr {![info exists DEF($name)]}] incr nomit continue diff --git a/tool/sqlite3_analyzer.c.in b/tool/sqlite3_analyzer.c.in index a934f05700..9c11752b81 100644 --- a/tool/sqlite3_analyzer.c.in +++ b/tool/sqlite3_analyzer.c.in @@ -3,7 +3,8 @@ ** text on standard output. */ #define TCLSH_INIT_PROC sqlite3_analyzer_init_proc -IFNDEF SQLITE_ENABLE_DBSTAT_VTAB +IFDEF INCLUDE_SQLITE3_C +#undef SQLITE_ENABLE_DBSTAT_VTAB #define SQLITE_ENABLE_DBSTAT_VTAB 1 #undef SQLITE_THREADSAFE #define SQLITE_THREADSAFE 0 From b81e11b25ba63403b26f5ed54d221861af730d8c Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 19 Nov 2024 20:14:31 +0000 Subject: [PATCH 374/522] Move the in-comment-code commentary about --with-debug, from [7b14309be4], into the --help text for that flag, where it's readily visible. FossilOrigin-Name: c938e5d783b3f015b2a1b9f3711664b13497c4b71e4a890c65d6665539522ff8 --- auto.def | 11 +++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/auto.def b/auto.def index eee8c5aeff..d5f1b694f9 100644 --- a/auto.def +++ b/auto.def @@ -192,12 +192,11 @@ set flags { with-emsdk:=auto => {Top-most dir of the Emscripten SDK installation. Default = EMSDK env var.} # # - - # --with-debug does more than simply builds with a -g compilation - # flag and will impact performance by as much as 4x, as it includes - # large numbers of assert()s in performance-critical loops. Never - # use --with-debug for production builds. - with-debug:=1 => {Enable debug build flags} + with-debug:=1 => {Enable debug build flags. --with-debug does more + than simply builds with a -g compilation flag and will impact + performance by as much as 4x, as it includes large numbers of + assert()s in performance-critical loops. Never use --with-debug + for production builds.} dev => {Enable dev-mode build: automatically enables certain other flags} test-status => {Enable status of tests} gcov=0 => {Enable coverage testing using gcov} diff --git a/manifest b/manifest index 8c13ab27c3..4cb68a5e80 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\ssqlite3_analyzer\soptionally\slinking\sagainst\slibsqlite3.so\sinstead\sof\sembedding\ssqlite3.c.\sPatch\smkccode.tcl\sto\saccept\sdigits\sin\sits\sIFDEF/IFNDEF\schecks\sand\ssqlite3_analyzer.c.in\sto\sonly\sinclude\ssqlite3.c\sif\s-DINCLUDE_SQLITE3_C\sis\spassed\sto\smkccode.tcl. -D 2024-11-19T19:47:51.323 +C Move\sthe\sin-comment-code\scommentary\sabout\s--with-debug,\sfrom\s[7b14309be4],\sinto\sthe\s--help\stext\sfor\sthat\sflag,\swhere\sit's\sreadily\svisible. +D 2024-11-19T20:14:31.784 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 4f5ae3ed11bb110b1eda2a6b7ee46489b7371bc8f7c19f0ed944613c170e4951 +F auto.def 87c3d42428225c89dba75d399ea83c756f4a21b5c6ed591436d6c930c8d6c73a F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7fb3ebfec634e0508267049fddb2b513201dbefce4d378ca3ec261c5d8336d7f -R 631735400a3a45c7eca237a47c49e579 +P 80f3bf8c2ee31ba1ab9187d64d5dcbbf97a61845a21b036f89ea9133153575c0 +R 07c8458360fbc34333a873b33b8ca43f U stephan -Z b91791961d3936264eb9b5de6178a0fb +Z 3761f0fd6432507d765cfeef5912a493 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 22db0ea473..53fbd282cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80f3bf8c2ee31ba1ab9187d64d5dcbbf97a61845a21b036f89ea9133153575c0 +c938e5d783b3f015b2a1b9f3711664b13497c4b71e4a890c65d6665539522ff8 From 457d9384a22d943abb9239a4043466feb2f88005 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 19 Nov 2024 20:21:40 +0000 Subject: [PATCH 375/522] Rename --link-tools-dynamically to --dynlink-tools, per discussion. FossilOrigin-Name: 50b9f6fde44f9afda27e47badde6115ab6d9ccd5e22b446a8d8127499848815f --- auto.def | 6 +++--- main.mk | 5 ++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/auto.def b/auto.def index d5f1b694f9..e6c6dfc00a 100644 --- a/auto.def +++ b/auto.def @@ -202,7 +202,7 @@ set flags { gcov=0 => {Enable coverage testing using gcov} linemacros => {Enable #line macros in the amalgamation} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} - link-tools-dynamically => {Dynamically link libsqlite3 to certain tools which normally statically embed it.} + dynlink-tools => {Dynamically link libsqlite3 to certain tools which normally statically embed it.} soname:=legacy => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} # --soname has a long story behind it, as well as no small amount of uncertainty. # @@ -333,7 +333,7 @@ proj-if-opt-truthy dev { define CFLAGS [get-env CFLAGS {-O0 -g}] } -define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided link-tools-dynamically] +define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided dynlink-tools] ######################################################################## # Handle --with-wasi-sdk=DIR @@ -476,7 +476,7 @@ apply {{} { if {[proj-opt-was-provided soname]} { set soname [opt-val soname] } else { - set soname none; # enabling soname breaks linking for the --link-tools-dynamically feature + set soname none; # enabling soname breaks linking for the --dynlink-tools feature } switch -exact -- $soname { none { return 0 } diff --git a/main.mk b/main.mk index 878be92ae6..f1c36b3575 100644 --- a/main.mk +++ b/main.mk @@ -209,7 +209,10 @@ USE_AMALGAMATION ?= 1 # # If true, certain binaries which typically statically link against # libsqlite3 or its component object files will instead link against -# the DLL. +# the DLL. The caveat is that running such builds from the source tree +# may require that the user specifically prepend "." to their +# $LD_LIBRARY_PATH so that the dynamic linker does not pick up a +# libsqlite3.so from outside the source tree. # LINK_TOOLS_DYNAMICALLY ?= 0 # diff --git a/manifest b/manifest index 4cb68a5e80..52a4d101ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sthe\sin-comment-code\scommentary\sabout\s--with-debug,\sfrom\s[7b14309be4],\sinto\sthe\s--help\stext\sfor\sthat\sflag,\swhere\sit's\sreadily\svisible. -D 2024-11-19T20:14:31.784 +C Rename\s--link-tools-dynamically\sto\s--dynlink-tools,\sper\sdiscussion. +D 2024-11-19T20:21:40.498 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 87c3d42428225c89dba75d399ea83c756f4a21b5c6ed591436d6c930c8d6c73a +F auto.def b81388775c7596c22d19ce7c5e0692d8cb6beb89ae591e2684a238084acabf61 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk b1f78ccd8b6db3fbc6a7e9952fc3e60433ad8d25798eb0b55632b1eb502ab30a +F main.mk de4824958a997377f0b661329699eb0b58e81c3076d68bf45898305d074fd3ee F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 80f3bf8c2ee31ba1ab9187d64d5dcbbf97a61845a21b036f89ea9133153575c0 -R 07c8458360fbc34333a873b33b8ca43f +P c938e5d783b3f015b2a1b9f3711664b13497c4b71e4a890c65d6665539522ff8 +R 2438fd2896d39f35fc299b3fd744f13f U stephan -Z 3761f0fd6432507d765cfeef5912a493 +Z e384122113bfcbb2fa4bae830787db35 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 53fbd282cc..ae727ec259 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c938e5d783b3f015b2a1b9f3711664b13497c4b71e4a890c65d6665539522ff8 +50b9f6fde44f9afda27e47badde6115ab6d9ccd5e22b446a8d8127499848815f From 18c9e2638eed17bb3ed35581d0054c7404e56f33 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Nov 2024 21:14:48 +0000 Subject: [PATCH 376/522] Add missing $TCL_LIBS to the link for sqlite3_analyzer. FossilOrigin-Name: bfab759611b0562837d8733ce56591854db08c122956524799dc1d5b3e2d0279 --- main.mk | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index f1c36b3575..144c1e2b58 100644 --- a/main.mk +++ b/main.mk @@ -1767,7 +1767,7 @@ sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c \ $(sqlite3_analyzer.deps.$(LINK_TOOLS_DYNAMICALLY)) $(T.link.tcl) sqlite3_analyzer.c -o $@ \ $(sqlite3_analyzer.flags.$(LINK_TOOLS_DYNAMICALLY)) \ - $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC + $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC $$TCL_LIBS # ^^^^ the order of those flags is relevant for # $(sqlite3_analyzer.flags.1): if the $$TCL_... flags come first they # can cause the $@ to link to an out-of-tree libsqlite3.so, which may diff --git a/manifest b/manifest index 52a4d101ec..fa0500c459 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\s--link-tools-dynamically\sto\s--dynlink-tools,\sper\sdiscussion. -D 2024-11-19T20:21:40.498 +C Add\smissing\s$TCL_LIBS\sto\sthe\slink\sfor\ssqlite3_analyzer. +D 2024-11-19T21:14:48.228 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk de4824958a997377f0b661329699eb0b58e81c3076d68bf45898305d074fd3ee +F main.mk 4e437d2c9cd67db9c1a0715b70e3c9f6b20f54cd97bd21b1b1a40a6181dfe874 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c938e5d783b3f015b2a1b9f3711664b13497c4b71e4a890c65d6665539522ff8 -R 2438fd2896d39f35fc299b3fd744f13f -U stephan -Z e384122113bfcbb2fa4bae830787db35 +P 50b9f6fde44f9afda27e47badde6115ab6d9ccd5e22b446a8d8127499848815f +R 550a68b5ea9d3db22b4d7e049a260626 +U drh +Z 02a349b181e8372ee68443f7fc5c2aa7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ae727ec259..a1aef6a738 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50b9f6fde44f9afda27e47badde6115ab6d9ccd5e22b446a8d8127499848815f +bfab759611b0562837d8733ce56591854db08c122956524799dc1d5b3e2d0279 From a34fbd1b9b1817a9fc26b6231c1d5f8b9cb5601b Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 19 Nov 2024 21:19:12 +0000 Subject: [PATCH 377/522] Add fix from [bfab759611b0] to sqltclsh. Remove some now-unneeded has_tclsh84/5 checks in cases where jimsh can be used. FossilOrigin-Name: 9d389b998317c5006876f2f40d56cd763d1555bbeaf48b2bca9bd46dcd02b80e --- main.mk | 30 +++++++++++++++--------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/main.mk b/main.mk index 144c1e2b58..e2458c5481 100644 --- a/main.mk +++ b/main.mk @@ -1031,7 +1031,7 @@ T.link.tcl = $(T.tcl.env.source); $(T.link) # all that automatic generation. # .target_source: $(MAKE_SANITY_CHECK) $(SRC) $(TOP)/tool/vdbe-compress.tcl \ - fts5.c $(B.tclsh) # has_tclsh84 + fts5.c $(B.tclsh) rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc @@ -1057,19 +1057,19 @@ mksourceid$(B.exe): $(MAKE_SANITY_CHECK) $(TOP)/tool/mksourceid.c sqlite3.h: $(MAKE_SANITY_CHECK) $(TOP)/src/sqlite.h.in \ $(TOP)/manifest mksourceid$(B.exe) \ - $(TOP)/VERSION $(B.tclsh) # has_tclsh84 + $(TOP)/VERSION $(B.tclsh) $(B.tclsh) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify$(B.exe) \ - $(B.tclsh) # has_tclsh84 + $(B.tclsh) $(B.tclsh) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . -sqlite3r.h: sqlite3.h $(B.tclsh) # has_tclsh84 +sqlite3r.h: sqlite3.h $(B.tclsh) $(B.tclsh) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -sqlite3r.c: sqlite3.c sqlite3r.h $(B.tclsh) # has_tclsh84 +sqlite3r.c: sqlite3.c sqlite3r.h $(B.tclsh) cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ @@ -1356,11 +1356,11 @@ tcl: tclsqlite3$(T.exe)-$(HAVE_TCL) # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(B.tclsh) # has_tclsh84 +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl $(B.tclsh) $(B.tclsh) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c opcodes.h: parse.h $(TOP)/src/vdbe.c \ - $(TOP)/tool/mkopcodeh.tcl $(B.tclsh) # has_tclsh84 + $(TOP)/tool/mkopcodeh.tcl $(B.tclsh) cat parse.h $(TOP)/src/vdbe.c | $(B.tclsh) $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. @@ -1371,7 +1371,7 @@ parse.c: $(TOP)/src/parse.y lemon$(B.exe) cp $(TOP)/src/parse.y . ./lemon$(B.exe) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y -sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(B.tclsh) # has_tclsh84 +sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION $(B.tclsh) echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ cat $(TOP)/VERSION | $(B.tclsh) $(TOP)/tool/replace.tcl exact . , >>$@ @@ -1385,7 +1385,7 @@ keywordhash.h: mkkeywordhash$(B.exe) # # sqlite3.c split into many smaller files. # -sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(B.tclsh) # has_tclsh84 +sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl $(B.tclsh) $(B.tclsh) $(TOP)/tool/split-sqlite3c.tcl # @@ -1591,7 +1591,7 @@ fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(B.exe) fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) $(B.tclsh) # has_tclsh84 +fts5.c: $(FTS5_SRC) $(B.tclsh) $(B.tclsh) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . @@ -1759,7 +1759,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \ # # sqlite3_analyzer's build mode depends on $(LINK_TOOLS_DYNAMICALLY). # -sqlite3_analyzer.flags.1 = -L. -lsqlite3 $(LDFLAGS.math) +sqlite3_analyzer.flags.1 = -L. -lsqlite3 sqlite3_analyzer.flags.0 = $(LDFLAGS.libsqlite3) sqlite3_analyzer.deps.1 = $(libsqlite3.SO) sqlite3_analyzer.deps.0 = @@ -1775,12 +1775,12 @@ sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c \ 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 has_tclsh85 + $(TOP)/tool/sqltclsh.c.in $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(T.exe): $(T.tcl.env.sh) sqltclsh.c $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) \ - $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) + $(LDFLAGS.libsqlite3) $$TCL_LIB_SPEC $$TCL_LIBS # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. xbin: sqltclsh$(T.exe) sqlite3_analyzer$(T.exe) @@ -1801,7 +1801,7 @@ CHECKER_DEPS =\ $(TOP)/ext/misc/btreeinfo.c \ $(TOP)/ext/repair/sqlite3_checker.c.in -sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 +sqlite3_checker.c: $(CHECKER_DEPS) $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ sqlite3_checker$(T.exe): $(T.tcl.env.sh) sqlite3_checker.c @@ -2177,7 +2177,7 @@ SHELL_DEP = \ $(TOP)/src/test_windirent.c \ $(TOP)/src/test_windirent.h -shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(B.tclsh) # has_tclsh84 +shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(B.tclsh) $(B.tclsh) $(TOP)/tool/mkshellc.tcl >shell.c # diff --git a/manifest b/manifest index fa0500c459..3c0334288c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\s$TCL_LIBS\sto\sthe\slink\sfor\ssqlite3_analyzer. -D 2024-11-19T21:14:48.228 +C Add\sfix\sfrom\s[bfab759611b0]\sto\ssqltclsh.\sRemove\ssome\snow-unneeded\shas_tclsh84/5\schecks\sin\scases\swhere\sjimsh\scan\sbe\sused. +D 2024-11-19T21:19:12.706 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 4e437d2c9cd67db9c1a0715b70e3c9f6b20f54cd97bd21b1b1a40a6181dfe874 +F main.mk 87ce967497ff2fc81406fc91c290b1faf3dfa8bb7724e3980be297381369b4f8 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 50b9f6fde44f9afda27e47badde6115ab6d9ccd5e22b446a8d8127499848815f -R 550a68b5ea9d3db22b4d7e049a260626 -U drh -Z 02a349b181e8372ee68443f7fc5c2aa7 +P bfab759611b0562837d8733ce56591854db08c122956524799dc1d5b3e2d0279 +R 0f52e38972daef31ec132c6a8f286547 +U stephan +Z 58d6b35becabf99bb64f154abaacc201 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a1aef6a738..b0f59a8497 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfab759611b0562837d8733ce56591854db08c122956524799dc1d5b3e2d0279 +9d389b998317c5006876f2f40d56cd763d1555bbeaf48b2bca9bd46dcd02b80e From 95669823282326526772ae51289f26aa1753e57c Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Nov 2024 11:34:16 +0000 Subject: [PATCH 378/522] Do not report an sqlite3_error_offset() for errors that occur inside of views or triggers, since the text of those elements is not part of the original query. FossilOrigin-Name: bf66c6dfc25c2562a4e6a5b24dd1660213a8fefbb5763e7583b87fb06dbaaf43 --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/printf.c | 1 + test/errofst1.test | 31 +++++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 test/errofst1.test diff --git a/manifest b/manifest index 87bdfbdd5f..09bf32dd9b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\stool/mkccode.tcl\ssuch\sthat\sit\srecognizes\s-D\scommand\sline\narguments\sand\scan\suse\sthem\sin\sinternal\sIFDEF\sand\sIFNDEF\smacros.\s\sUpdate\nthe\stool/sqlite3_analyzer.c.in\sscript\ssuch\sthat\sit\somits\sthe\sSQLite\samalgamation\nif\s-DSQLITE_ENABLE_DBSTAT_VTAB\sis\sdefined. -D 2024-11-19T18:26:47.422 +C Do\snot\sreport\san\ssqlite3_error_offset()\sfor\serrors\sthat\soccur\sinside\sof\nviews\sor\striggers,\ssince\sthe\stext\sof\sthose\selements\sis\snot\spart\sof\sthe\noriginal\squery. +D 2024-11-20T11:34:16.309 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -770,7 +770,7 @@ F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 F src/pragma.c a2ec3657a953fa7dea7c1e680e4358b6ce6ae570b6c5234e0f5ef219d308d223 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126 -F src/printf.c 6a87534ebfb9e5346011191b1f3a7ebc457f5938c7e4feeea478ecf53f6a41b2 +F src/printf.c 96f7f8baeedc7639da94e4e7a4a2c200e2537c4eec9e5e1c2ffc821f40eb3105 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 @@ -1124,6 +1124,7 @@ F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 F test/eqp.test 82f221e8cd588434d7f3bba9a0f4c78cbe7a541615a41632e12f50608bfb4a99 F test/eqp2.test 6e8996148de88f0e7670491e92e712a2920a369b4406f21a27c3c9b6a46b68dd F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 +F test/errofst1.test 6da78363739ba8991f498396ab331b5d64e7ab5c4172c12b5884683ef523ac53 F test/eval.test 73969a2d43a511bf44080c44485a8c4d796b6a4f038d19e491867081155692c0 F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650bf0747 F test/exclusive2.test cd70b1d9c6fffd336f9795b711dcc5d9ceba133ad3f7001da3fda63615bdc91e @@ -2198,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4c4d1db00bd2c522165876dcf1606116a72525d9ffc891b266213704e25cde55 -R cdb63603c9c3a16b29feb4bae93e8b25 +P 7fec209290aa1a6dbbca8de154edaac5d8d0ce042bc0617d27fb2095c8d580f1 +R 9836fa6ecc3ea6cb30fb659606cd39d3 U drh -Z 2a605008d2464811e071ed45a95c8ad5 +Z 6d36dcf7e943a68e08518adf95cc789e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 643a526325..0e8a1efe30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7fec209290aa1a6dbbca8de154edaac5d8d0ce042bc0617d27fb2095c8d580f1 +bf66c6dfc25c2562a4e6a5b24dd1660213a8fefbb5763e7583b87fb06dbaaf43 diff --git a/src/printf.c b/src/printf.c index a140565146..71363f91b4 100644 --- a/src/printf.c +++ b/src/printf.c @@ -938,6 +938,7 @@ void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){ pExpr = pExpr->pLeft; } if( pExpr==0 ) return; + if( ExprHasProperty(pExpr, EP_FromDDL) ) return; db->errByteOffset = pExpr->w.iOfst; } diff --git a/test/errofst1.test b/test/errofst1.test new file mode 100644 index 0000000000..f8876316e5 --- /dev/null +++ b/test/errofst1.test @@ -0,0 +1,31 @@ +# 2024-11-20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test cases for sqlite3_error_offset() +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test errofst1-1.1 { + CREATE TABLE t1 as select 1 as aa; + CREATE VIEW t2 AS + WITH t3 AS (SELECT 1 FROM t1 AS bb, t1 AS cc WHERE cc.aa <= sts.aa) + SELECT 1 FROM t3 AS dd; +} +do_catchsql_test errofst1-1.2 { + SELECT * FROM t2; +} {1 {no such column: sts.aa}} +do_test errofst1-1.3 { + sqlite3_error_offset db +} {-1} + +finish_test From d4a65cfc51c5dffebc23d29a91cd369c36943f4c Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Nov 2024 14:19:44 +0000 Subject: [PATCH 379/522] Provide the sqlite3ShowWhereTerm() interface callable interactively from a debugger, when compiling with SQLITE_DEBUG. FossilOrigin-Name: c77a4a42f2e3d16427a69295436efe36335e56e97abd0efba814092498a8dea8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/treeview.c | 4 ++++ src/where.c | 5 ++++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 09bf32dd9b..624360ce4e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sreport\san\ssqlite3_error_offset()\sfor\serrors\sthat\soccur\sinside\sof\nviews\sor\striggers,\ssince\sthe\stext\sof\sthose\selements\sis\snot\spart\sof\sthe\noriginal\squery. -D 2024-11-20T11:34:16.309 +C Provide\sthe\ssqlite3ShowWhereTerm()\sinterface\scallable\sinteractively\sfrom\na\sdebugger,\swhen\scompiling\swith\sSQLITE_DEBUG. +D 2024-11-20T14:19:44.523 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -836,7 +836,7 @@ F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68 -F src/treeview.c 88aa39b754f5ef7214385c1bbbdd2f3dc20efafeed0cf590e8d1199b9c6e44aa +F src/treeview.c 4eeb155abefd88a60d0c37cc00bcfac38a8dd566970f019e4af7e02672ee2599 F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 @@ -858,7 +858,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 8b7e309a8012659ac9275ad8cdcc6acaf73fa04b1090e38a01335f230fd10681 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c 4de9e7ca5f49e4a21c1d733e2b2fbbc8b62b1a157a58a562c569da84cfcb005b +F src/where.c 504d72098437ab97dfd3a71cea85e554381650f9dffde277c66603f3e34daddc F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca F src/wherecode.c 81b9af89f4f85c8097d0da6a31499f015eabc4d3584963d30ba7b7b782e26514 F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7fec209290aa1a6dbbca8de154edaac5d8d0ce042bc0617d27fb2095c8d580f1 -R 9836fa6ecc3ea6cb30fb659606cd39d3 +P bf66c6dfc25c2562a4e6a5b24dd1660213a8fefbb5763e7583b87fb06dbaaf43 +R 0752d1ca03189356b3058d9f9278a405 U drh -Z 6d36dcf7e943a68e08518adf95cc789e +Z 314628466d5a8713bca43ea5e20a45da # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0e8a1efe30..b84bf19c0e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf66c6dfc25c2562a4e6a5b24dd1660213a8fefbb5763e7583b87fb06dbaaf43 +c77a4a42f2e3d16427a69295436efe36335e56e97abd0efba814092498a8dea8 diff --git a/src/treeview.c b/src/treeview.c index de67161229..865de9991c 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -1302,6 +1302,10 @@ void sqlite3TreeViewTrigger( ** accessible to the debugging, and to avoid warnings about unused ** functions. But these routines only exist in debugging builds, so they ** do not contaminate the interface. +** +** See Also: +** +** sqlite3ShowWhereTerm() in where.c */ void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} diff --git a/src/where.c b/src/where.c index f24cf7f769..1315a8cc37 100644 --- a/src/where.c +++ b/src/where.c @@ -2332,7 +2332,7 @@ static int whereInScanEst( #endif /* SQLITE_ENABLE_STAT4 */ -#ifdef WHERETRACE_ENABLED +#if defined(WHERETRACE_ENABLED) || defined(SQLITE_DEBUG) /* ** Print the content of a WhereTerm object */ @@ -2376,6 +2376,9 @@ void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } +void sqlite3ShowWhereTerm(WhereTerm *pTerm){ + sqlite3WhereTermPrint(pTerm, 0); +} #endif #ifdef WHERETRACE_ENABLED From 2722e2e822a26eb62cdf0e12683de1c5f61bf2b9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Nov 2024 14:59:32 +0000 Subject: [PATCH 380/522] Bug fix in the SubrtnSig logic from [c9a3498113074bbc], if a subquery is copied and then changes are made to the copy, be sure to give the copy a unique Select.selId value so that the original will not be substituted in place of the modified copy. [forum:/forumpost/0b9ded2f8428ac00|Forum post 0b9ded2f8428ac00]. FossilOrigin-Name: 19d1bede5654bcfa9f7a151b9b2616a3d10873b8e3f8cf54a3a7e810da08f844 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 1 + test/in7.test | 27 ++++++++++++++++++++++++++- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 624360ce4e..6e59cc7243 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Provide\sthe\ssqlite3ShowWhereTerm()\sinterface\scallable\sinteractively\sfrom\na\sdebugger,\swhen\scompiling\swith\sSQLITE_DEBUG. -D 2024-11-20T14:19:44.523 +C Bug\sfix\sin\sthe\sSubrtnSig\slogic\sfrom\s[c9a3498113074bbc],\sif\sa\ssubquery\sis\ncopied\sand\sthen\schanges\sare\smade\sto\sthe\scopy,\sbe\ssure\sto\sgive\sthe\scopy\na\sunique\sSelect.selId\svalue\sso\sthat\sthe\soriginal\swill\snot\sbe\ssubstituted\nin\splace\sof\sthe\smodified\scopy.\n[forum:/forumpost/0b9ded2f8428ac00|Forum\spost\s0b9ded2f8428ac00]. +D 2024-11-20T14:59:32.102 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -860,7 +860,7 @@ F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 504d72098437ab97dfd3a71cea85e554381650f9dffde277c66603f3e34daddc F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca -F src/wherecode.c 81b9af89f4f85c8097d0da6a31499f015eabc4d3584963d30ba7b7b782e26514 +F src/wherecode.c 0c3d3199a2b769a5e2bb70feb5003dc85b3d86842ecaf903a47f2b4205ca5dab F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f F src/window.c 6c386af5972a58f9a9847bba9d7ca70c4c682391ab8478d94a6e046b22a0dbb3 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1301,7 +1301,7 @@ F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test bb767ec1cfd1730256f0a83219f0acda36bc251b63f8b8bb7d8c7cff17875a4f F test/in5.test 4fd79c70dfa0681313e8cdca07f5ff0400bdc0e20f808a5c59eaef1e4b48082a F test/in6.test f5f40d6816a8bb7c784424b58a10ac38efb76ab29127a2c17399e0cbeeda0e4b -F test/in7.test 9256cdb30dc487f2078bb4bb30f43f2c1ff4d277a9c7c9a14bd1c9510c9c8cae +F test/in7.test 5050b648510d88bd27ff6b40991a45e1cc277c20e258162e81650e01069a56bb F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f F test/incrblob3.test 67621a04b3084113bf38ce03797d70eca012d9d8f948193b8f655df577b0da6f @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bf66c6dfc25c2562a4e6a5b24dd1660213a8fefbb5763e7583b87fb06dbaaf43 -R 0752d1ca03189356b3058d9f9278a405 +P c77a4a42f2e3d16427a69295436efe36335e56e97abd0efba814092498a8dea8 +R 334ca864785a19dfa280dbef32e35002 U drh -Z 314628466d5a8713bca43ea5e20a45da +Z af9f774053d8dc7c5fd09306a426c7d8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b84bf19c0e..507330bbf4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c77a4a42f2e3d16427a69295436efe36335e56e97abd0efba814092498a8dea8 +19d1bede5654bcfa9f7a151b9b2616a3d10873b8e3f8cf54a3a7e810da08f844 diff --git a/src/wherecode.c b/src/wherecode.c index 0bd1733b76..045653aac8 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -615,6 +615,7 @@ static Expr *removeUnindexableInClauseTerms( pNew->pLeft->x.pList = pLhs; } pSelect->pEList = pRhs; + pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */ if( pLhs && pLhs->nExpr==1 ){ /* Take care here not to generate a TK_VECTOR containing only a ** single value. Since the parser never creates such a vector, some diff --git a/test/in7.test b/test/in7.test index 29013ff593..4dc0821d18 100644 --- a/test/in7.test +++ b/test/in7.test @@ -192,6 +192,31 @@ do_execsql_test 3.4 { 1 2 3 4 5 6 } - +# 2024-11-20 https://sqlite.org/forum/forumpost/0b9ded2f8428ac00 +# +# Bug in SubrtnSig logic. If a SELECT statement is copied and the copy +# is subsequently modified, we need to change the Select.selId on the +# copy so that when the copy is used to generate code, the SubrtnSig +# logic won't try to substitute the original SELECT in place of the +# copy which is now different. +# +do_execsql_test 3.5 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1 (a int UNIQUE); + CREATE TABLE t2 (b int UNIQUE); + INSERT INTO t1 VALUES (1); + INSERT INTO t2 VALUES (1), (2); + SELECT t1.a, t2.b FROM t1, t2 WHERE (t1.a, t2.b) = (1, 1); +} {1 1} +do_execsql_test 3.6 { + SELECT t1.a, t2.b FROM t1, t2 WHERE (t1.a, t2.b) IN ((1, 1)); +} {1 1} +do_execsql_test 3.7 { + SELECT t1.a, t2.b FROM t1, t2 WHERE (t1.a, t2.b) = (1, 2); +} {1 2} +do_execsql_test 3.8 { + SELECT t1.a, t2.b FROM t1, t2 WHERE (t1.a, t2.b) IN ((1, 2)); +} {1 2} finish_test From 914e32f24a4304c3d37766624f39912af10e898e Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Nov 2024 16:17:01 +0000 Subject: [PATCH 381/522] Use shared-library flags, not shared-object flags, to create shared libraries. This makes no difference on Linux, but is required for Mac. FossilOrigin-Name: bfaa3ee7588b6f6be9799882c6ed6472357d988fac31512d5e92fe28f57029c6 --- Makefile.in | 2 +- main.mk | 6 +++--- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 219347c301..3d2e736fd1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -143,7 +143,7 @@ LDFLAGS.configure = @LDFLAGS@ # CFLAGS.core is documented in main.mk. # CFLAGS.core = @SH_CFLAGS@ -LDFLAGS.shobj = @SHOBJ_LDFLAGS@ +LDFLAGS.shlib = @SH_LDFLAGS@ LDFLAGS.zlib = @LDFLAGS_ZLIB@ LDFLAGS.math = @LDFLAGS_MATH@ LDFLAGS.rpath = @LDFLAGS_RPATH@ diff --git a/main.mk b/main.mk index e2458c5481..b1f1635980 100644 --- a/main.mk +++ b/main.mk @@ -159,7 +159,7 @@ LDFLAGS.math ?= -lm LDFLAGS.rpath ?= -Wl,-rpath -Wl,$(prefix)/lib LDFLAGS.pthread ?= -lpthread LDFLAGS.dlopen ?= -ldl -LDFLAGS.shobj ?= -shared +LDFLAGS.shlib ?= -shared LDFLAGS.icu ?= # -licui18n -licuuc -licudata CFLAGS.icu ?= LDFLAGS.soname.libsqlite3 ?= @@ -385,7 +385,7 @@ T.link = $(T.cc.sqlite) $(T.link.extras) # # $(T.link.shared) = $(T.link) invocation specifically for shared libraries # -T.link.shared = $(T.link) $(LDFLAGS.shobj) +T.link.shared = $(T.link) $(LDFLAGS.shlib) # # $(LDFLAGS.libsqlite3) should be used with any deliverable for which @@ -2245,7 +2245,7 @@ sqlite3.def: $(LIBOBJ) | sed 's/^.* _//' >>sqlite3.def sqlite3.dll: $(LIBOBJ) sqlite3.def - $(T.cc.sqlite) $(LDFLAGS.shobj) -o $@ sqlite3.def \ + $(T.cc.sqlite) $(LDFLAGS.shlib) -o $@ sqlite3.def \ -Wl,"--strip-all" $(LIBOBJ) $(LDFLAGS.configure) # diff --git a/manifest b/manifest index 3c0334288c..f1118f4bfd 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\sfix\sfrom\s[bfab759611b0]\sto\ssqltclsh.\sRemove\ssome\snow-unneeded\shas_tclsh84/5\schecks\sin\scases\swhere\sjimsh\scan\sbe\sused. -D 2024-11-19T21:19:12.706 +C Use\sshared-library\sflags,\snot\sshared-object\sflags,\sto\screate\sshared\slibraries.\nThis\smakes\sno\sdifference\son\sLinux,\sbut\sis\srequired\sfor\sMac. +D 2024-11-20T16:17:01.857 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in 5461b1125a3039fef49f4896519d164ebe22ee394d20d69913ab0fdc8c464b63 +F Makefile.in b22a52dc08b8a727c298af4f93171b2862df1d6fce4c255b15f6ce1011a9ee7d F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 87ce967497ff2fc81406fc91c290b1faf3dfa8bb7724e3980be297381369b4f8 +F main.mk e3873a2363bef0fb8e3a65a21e548ce1aa9aeeb3795362c3e78346e655d501a4 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bfab759611b0562837d8733ce56591854db08c122956524799dc1d5b3e2d0279 -R 0f52e38972daef31ec132c6a8f286547 -U stephan -Z 58d6b35becabf99bb64f154abaacc201 +P 9d389b998317c5006876f2f40d56cd763d1555bbeaf48b2bca9bd46dcd02b80e +R 8bdca5a71a238d4249a2b123157a4e29 +U drh +Z 1e9ca84e1d99022a8171dd65daab42e8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b0f59a8497..a58ebcec98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d389b998317c5006876f2f40d56cd763d1555bbeaf48b2bca9bd46dcd02b80e +bfaa3ee7588b6f6be9799882c6ed6472357d988fac31512d5e92fe28f57029c6 From 032bcf72fb8768a4bd995c4bb874e5c2e25165bb Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 20 Nov 2024 20:39:18 +0000 Subject: [PATCH 382/522] Fix compiler warnings caused by variable shadowing. FossilOrigin-Name: 211b305791980b24c4192ffc57a0471473de3fca32bfc146c0eeacedef7a88aa --- ext/fts5/fts5_index.c | 5 ++--- main.mk | 1 - manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index e7028e411c..8730b69509 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6389,10 +6389,10 @@ static void fts5TokendataIterAppendMap( if( p->rc==SQLITE_OK ){ if( pT->nMap==pT->nMapAlloc ){ int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; - int nByte = nNew * sizeof(Fts5TokenDataMap); + int nAlloc = nNew * sizeof(Fts5TokenDataMap); Fts5TokenDataMap *aNew; - aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte); + aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc); if( aNew==0 ){ p->rc = SQLITE_NOMEM; return; @@ -7580,7 +7580,6 @@ int sqlite3Fts5IndexIterWriteTokendata( assert( pIter->pTokenDataIter || pIter->nSeg>0 ); if( pIter->nSeg>0 ){ /* This is a prefix term iterator. */ - Fts5TokenDataIter *pT = pIter->pTokenDataIter; if( pT==0 ){ pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); pIter->pTokenDataIter = pT; diff --git a/main.mk b/main.mk index d4cfb3b5e7..71b730c0bf 100644 --- a/main.mk +++ b/main.mk @@ -778,7 +778,6 @@ TESTSRC2 = \ $(TOP)/ext/fts3/fts3.c \ $(TOP)/ext/fts3/fts3_aux.c \ $(TOP)/ext/fts3/fts3_expr.c \ - $(TOP)/ext/fts3/fts3_term.c \ $(TOP)/ext/fts3/fts3_tokenizer.c \ $(TOP)/ext/fts3/fts3_write.c \ $(TOP)/ext/session/sqlite3session.c \ diff --git a/manifest b/manifest index 69261eb226..75828653be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\sinto\sthis\sbranch. -D 2024-11-06T17:31:48.766 +C Fix\scompiler\swarnings\scaused\sby\svariable\sshadowing. +D 2024-11-20T20:39:18.431 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -113,7 +113,7 @@ F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70 F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c 2cef40d6fdd761229dd4127e0b1ddcb61dfd6a4ac7e73653b7fddbe0075e50be +F ext/fts5/fts5_index.c cef6791bd9f9db4305494292d6dd5d24a7379aabf370a4d6b559e16b740fa88e F ext/fts5/fts5_main.c b2ec6bf97fc378906c0e78c61f10ca8e64f15e03237f2521f7d81736983be378 F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c F ext/fts5/fts5_tcl.c aee6ae6d0c6968564c392bf0d09aaabb4d8bea9ca69fd224dc9b44243324acbf @@ -701,7 +701,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk c1a91dc50ffc1cb828b85d767d02d80d9eabeb0ef47e77e57bd72617749c5dbf +F main.mk 3dbee6d7e7678b79531b78048fea187146cb7e0352047ed774003ba4df1fb93a F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9cc04331a01760189d88697233009dbe8a60eda589792ad01b56300499e9f54d 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9 -R 43b03038eb634e877d13ab18dcd80180 +P edb842349320eda9550bdfcd5a327949c5512e02f4b993782587b2131a425746 +R 87e3d58f4f7440e00e0a55bcb770c2ab U dan -Z 70a74ef30cc348badfc60dd108f53b23 +Z e1bc2b76da9d8c387af12aec8bd8d459 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b5f3f21ebe..259f7f2dfa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -edb842349320eda9550bdfcd5a327949c5512e02f4b993782587b2131a425746 +211b305791980b24c4192ffc57a0471473de3fca32bfc146c0eeacedef7a88aa From 9bf5bea60709d4afa37a085b86de3651b0ddd5c9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Nov 2024 01:50:01 +0000 Subject: [PATCH 383/522] Document that -nofollow does not work on Windows. Fix Windows symlink test cases for when the test suite is run as administrator. FossilOrigin-Name: 4de8a75ec5a2e3655a2d0c5a9333b58f8b48b681255f0a01866b610ae6249bc2 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/os_win.c | 2 +- test/symlink2.test | 4 +++- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index fc192ad2f9..2e1cc07290 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sconfiguration\soption\s--dynlink-tools\scauses\ssome\scommand-line\stools\slike\nsqldiff\sand\ssqlite3_analyzer\sto\slink\sagainst\sthe\slibsqlite3.so\ssystem\slibrary\nrather\sthan\sbeing\sbuilt-in.\s\sCaution:\s\ssqlite3_analyzer\srequires\sthe\nSQLITE_ENABLE_DBSTAT_VTAB\scompile-time\soption\son\sits\sSQLite\slibrary\sin\sorder\nto\swork,\sso\sdo\snot\suse\s--dynlink-tools\sto\sbuild\ssqlite3_analyzer\swithout\sit. -D 2024-11-20T16:21:34.531 +C Document\sthat\s-nofollow\sdoes\snot\swork\son\sWindows.\s\sFix\sWindows\ssymlink\ntest\scases\sfor\swhen\sthe\stest\ssuite\sis\srun\sas\sadministrator. +D 2024-11-21T01:50:01.790 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -759,7 +759,7 @@ F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6 -F src/os_win.c db4baa8f62bbfe3967c71b008cea31a8f2ff337c1667ff4d8a677e697315ff0d +F src/os_win.c 49c7725b500f5867e8360e75eeb30f9d70b62fa1f05c8a101da627210578df32 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a @@ -1702,7 +1702,7 @@ F test/swarmvtab2.test c948cb2fdfc5b01d85e8f6d6504854202dc1a0782ab2a0ed61538f27c F test/swarmvtab3.test 41a3ab47cb7a834d4e5336425103b617410a67bb95d335ef536f887587ece073 F test/swarmvtabfault.test 8a67a9f27c61073a47990829e92bc0c64420a807cb642b15a25f6c788210ed95 F test/symlink.test 4368af0e213dd6e726a6240a16f2bb96a5a58f83f2d5d60652f27547b28cbf06 -F test/symlink2.test 9531f475a53d8781c4f81373f87faf2e2aff4f5fb2102ec6386e0c827916a670 +F test/symlink2.test bf932ff7fe95c9dbb39d2a990df9098b0ea943233c97e40098e0a8d6b559a96f F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d4333092 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a067468b43b8cb2305e9f9fe414e5f40c875bb5d2cba5f00b8154396e95fcf37 @@ -2199,9 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 19d1bede5654bcfa9f7a151b9b2616a3d10873b8e3f8cf54a3a7e810da08f844 bfaa3ee7588b6f6be9799882c6ed6472357d988fac31512d5e92fe28f57029c6 -R 4149ca832938d8cc469625636a536cf9 -T +closed bfaa3ee7588b6f6be9799882c6ed6472357d988fac31512d5e92fe28f57029c6 +P 314c606dd36e03d2ded899c536585ea21250af56b553fa4c96dc714cb5099522 +R a9c1137cb0a1880ef7ace69df297b1fe U drh -Z 353d2b1e26c72a6c71622b8679ecfa79 +Z f9b2b2148aa55df305d649103f2dcab2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8022a04f68..fa803e8c76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -314c606dd36e03d2ded899c536585ea21250af56b553fa4c96dc714cb5099522 +4de8a75ec5a2e3655a2d0c5a9333b58f8b48b681255f0a01866b610ae6249bc2 diff --git a/src/os_win.c b/src/os_win.c index 4d245263fe..8ce1647f60 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -5053,7 +5053,7 @@ static int winOpen( int rc = SQLITE_OK; /* Function Return Code */ #if !defined(NDEBUG) || SQLITE_OS_WINCE - int eType = flags&0xFFFFFF00; /* Type of file to open */ + int eType = flags&0x0FFF00; /* Type of file to open */ #endif int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); diff --git a/test/symlink2.test b/test/symlink2.test index 4123092deb..9a2237e4c0 100644 --- a/test/symlink2.test +++ b/test/symlink2.test @@ -57,6 +57,7 @@ do_execsql_test 1.0 { INSERT INTO t1 VALUES(1,9999); } +forcedelete link.db do_test 2.0 { createWin32Symlink link.db test.db } {} @@ -87,12 +88,13 @@ do_test 3.4 { db3 close } {} +# The -nofollow option does not work on Windows do_test 3.5 { list [catch { sqlite3 db4 link.db -nofollow true execsql { SELECT x, y FROM t1; } db4 } res] $res -} {1 {unable to open database file}} +} {0 {1 9999}} catch {db4 close} From 2f70d5838ac764f2ece98d0231f46459cf533ce6 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 21 Nov 2024 15:53:31 +0000 Subject: [PATCH 384/522] Fix a JS test which was broken when OMIT_PROGRESS_CALLBACK was _not_ used. FossilOrigin-Name: fba23150b5b57980f8ed2656a2325f95215ca1e13fc3449b5eec804831dd65c8 --- ext/wasm/tester1.c-pp.js | 7 +++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 4347c8fd79..7ed2780201 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1248,8 +1248,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule; let st = this.db.prepare( new TextEncoder('utf-8').encode("select 3 as a") ); - //debug("statement =",st); - T.assert( !this.progressHandlerCount ); + if( wasm.compileOptionUsed('OMIT_PROGRESS_CALLBACK') ) { + T.assert( !this.progressHandlerCount ); + }else{ + T.assert( 1===this.progressHandlerCount, "Checking this.progressHandlerCount" ); + } let rc; try { T.assert(wasm.isPtr(st.pointer)) diff --git a/manifest b/manifest index 2e1cc07290..6e481129f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Document\sthat\s-nofollow\sdoes\snot\swork\son\sWindows.\s\sFix\sWindows\ssymlink\ntest\scases\sfor\swhen\sthe\stest\ssuite\sis\srun\sas\sadministrator. -D 2024-11-21T01:50:01.790 +C Fix\sa\sJS\stest\swhich\swas\sbroken\swhen\sOMIT_PROGRESS_CALLBACK\swas\s_not_\sused. +D 2024-11-21T15:53:31.229 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -690,7 +690,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js b683e64f776e03dc7cb81cf4737b991c644b0a59e3ca52dcdc606d851a95475e +F ext/wasm/tester1.c-pp.js f255a7c6730b341e2633d54b7edb27b91cd35744c011ddd321418a0735b0e44b F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 314c606dd36e03d2ded899c536585ea21250af56b553fa4c96dc714cb5099522 -R a9c1137cb0a1880ef7ace69df297b1fe -U drh -Z f9b2b2148aa55df305d649103f2dcab2 +P 4de8a75ec5a2e3655a2d0c5a9333b58f8b48b681255f0a01866b610ae6249bc2 +R 203ec458b356478f1ca21979ec7c6063 +U stephan +Z 17a966985bd13abb0d145bb10bf4f3d0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fa803e8c76..06b7f898c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4de8a75ec5a2e3655a2d0c5a9333b58f8b48b681255f0a01866b610ae6249bc2 +fba23150b5b57980f8ed2656a2325f95215ca1e13fc3449b5eec804831dd65c8 From d204a83c9b5d3db971263a2922e80daf1d1539fa Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 21 Nov 2024 20:07:01 +0000 Subject: [PATCH 385/522] Add the --scanstatus configure flag to set -DSQLITE_ENABLE_STMT_SCANSTATUS. FossilOrigin-Name: b6bd25bd769e4286ad0b8ca5059bc9da52188cefe92525d8994aa921768aa750 --- auto.def | 2 ++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/auto.def b/auto.def index e6c6dfc00a..33c7a99c24 100644 --- a/auto.def +++ b/auto.def @@ -197,6 +197,7 @@ set flags { performance by as much as 4x, as it includes large numbers of assert()s in performance-critical loops. Never use --with-debug for production builds.} + scanstatus => {Enable the SQLITE_ENABLE_STMT_SCANSTATUS feature flag} dev => {Enable dev-mode build: automatically enables certain other flags} test-status => {Enable status of tests} gcov=0 => {Enable coverage testing using gcov} @@ -1290,6 +1291,7 @@ foreach {boolFlag featureFlag ifSetEvalThis} { sqlite-add-feature-flag -DSQLITE_ENABLE_MEMSYS3 } } + scanstatus -DSQLITE_ENABLE_STMT_SCANSTATUS } { proj-if-opt-truthy $boolFlag { sqlite-add-feature-flag $featureFlag diff --git a/manifest b/manifest index 6e481129f4..a4a2d9b680 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sJS\stest\swhich\swas\sbroken\swhen\sOMIT_PROGRESS_CALLBACK\swas\s_not_\sused. -D 2024-11-21T15:53:31.229 +C Add\sthe\s--scanstatus\sconfigure\sflag\sto\sset\s-DSQLITE_ENABLE_STMT_SCANSTATUS. +D 2024-11-21T20:07:01.993 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def b81388775c7596c22d19ce7c5e0692d8cb6beb89ae591e2684a238084acabf61 +F auto.def 56e4bfbbcfabb3517cb451585f7532c7f680bed2a73e1b44731ac467e24d479f F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4de8a75ec5a2e3655a2d0c5a9333b58f8b48b681255f0a01866b610ae6249bc2 -R 203ec458b356478f1ca21979ec7c6063 +P fba23150b5b57980f8ed2656a2325f95215ca1e13fc3449b5eec804831dd65c8 +R 192be6085076aabb2381038d83a37d79 U stephan -Z 17a966985bd13abb0d145bb10bf4f3d0 +Z 4588e899db9b63f72b64cfa46e88a4c7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 06b7f898c1..425a609497 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fba23150b5b57980f8ed2656a2325f95215ca1e13fc3449b5eec804831dd65c8 +b6bd25bd769e4286ad0b8ca5059bc9da52188cefe92525d8994aa921768aa750 From a8c68e551d4b93b8ff52b6fb907405b0ea95eed2 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 21 Nov 2024 20:10:38 +0000 Subject: [PATCH 386/522] Fix a bug-in-waiting (one too few list elements) in [b6bd25bd769e]. FossilOrigin-Name: e527dcd016fbeb55b0e613a0b3b95350bbc8b3ee601bbadfedaf6bd5458b3570 --- auto.def | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index 33c7a99c24..9c214ec39c 100644 --- a/auto.def +++ b/auto.def @@ -1291,7 +1291,7 @@ foreach {boolFlag featureFlag ifSetEvalThis} { sqlite-add-feature-flag -DSQLITE_ENABLE_MEMSYS3 } } - scanstatus -DSQLITE_ENABLE_STMT_SCANSTATUS + scanstatus -DSQLITE_ENABLE_STMT_SCANSTATUS {} } { proj-if-opt-truthy $boolFlag { sqlite-add-feature-flag $featureFlag diff --git a/manifest b/manifest index a4a2d9b680..59cebdd625 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--scanstatus\sconfigure\sflag\sto\sset\s-DSQLITE_ENABLE_STMT_SCANSTATUS. -D 2024-11-21T20:07:01.993 +C Fix\sa\sbug-in-waiting\s(one\stoo\sfew\slist\selements)\sin\s[b6bd25bd769e]. +D 2024-11-21T20:10:38.627 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 56e4bfbbcfabb3517cb451585f7532c7f680bed2a73e1b44731ac467e24d479f +F auto.def c71f141cbeca906b157827959ca556eb19f762428fa7f5001161e5d21093178f F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fba23150b5b57980f8ed2656a2325f95215ca1e13fc3449b5eec804831dd65c8 -R 192be6085076aabb2381038d83a37d79 +P b6bd25bd769e4286ad0b8ca5059bc9da52188cefe92525d8994aa921768aa750 +R c656a51c47db56b0a493f0f6df484148 U stephan -Z 4588e899db9b63f72b64cfa46e88a4c7 +Z 67a0f0d45e736ce179484669cd424a17 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 425a609497..b5bdb2b91a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6bd25bd769e4286ad0b8ca5059bc9da52188cefe92525d8994aa921768aa750 +e527dcd016fbeb55b0e613a0b3b95350bbc8b3ee601bbadfedaf6bd5458b3570 From 9edb535bddec61d9cdf7cf72457e57a991b18fca Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Nov 2024 20:57:11 +0000 Subject: [PATCH 387/522] Make ".scanstatus" an undocumented alternative name for ".scanstats" in the CLI. FossilOrigin-Name: f20688efc2bc54648618b0aa2593a771f455ee8cc703b52273452d15e680b67c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 59cebdd625..2a42e16fea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug-in-waiting\s(one\stoo\sfew\slist\selements)\sin\s[b6bd25bd769e]. -D 2024-11-21T20:10:38.627 +C Make\s".scanstatus"\san\sundocumented\salternative\sname\sfor\s".scanstats"\sin\sthe\sCLI. +D 2024-11-21T20:57:11.560 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -775,7 +775,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 9a0011ee9650818782ee746e0e8747568a6f02fb3ae323dc6e27fa1a61457523 +F src/shell.c.in d8719347d467bc026ac43efdf5213cd9bab56503450a4b970fd09e4d4dab5409 F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b6bd25bd769e4286ad0b8ca5059bc9da52188cefe92525d8994aa921768aa750 -R c656a51c47db56b0a493f0f6df484148 -U stephan -Z 67a0f0d45e736ce179484669cd424a17 +P e527dcd016fbeb55b0e613a0b3b95350bbc8b3ee601bbadfedaf6bd5458b3570 +R de7a1058dc7d9edb28df5fa9d0ef82bc +U drh +Z d8274e63f396ef1ba4c0c2282830a6d5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b5bdb2b91a..86d326f1e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e527dcd016fbeb55b0e613a0b3b95350bbc8b3ee601bbadfedaf6bd5458b3570 +f20688efc2bc54648618b0aa2593a771f455ee8cc703b52273452d15e680b67c diff --git a/src/shell.c.in b/src/shell.c.in index a6700eb83a..22a5976d3f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -10411,7 +10411,10 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif /* !defined(SQLITE_SHELL_FIDDLE) */ - if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){ + if( c=='s' && + (cli_strncmp(azArg[0], "scanstats", n)==0 || + cli_strncmp(azArg[0], "scanstatus", n)==0) + ){ if( nArg==2 ){ if( cli_strcmp(azArg[1], "vm")==0 ){ p->scanstatsOn = 3; From f0a9af433a0a6dcae7e7a0159c92e8c9b85b2462 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Nov 2024 12:00:31 +0000 Subject: [PATCH 388/522] Fix harmless compiler warning caused by [c77a4a42f2e3d164]. FossilOrigin-Name: 063690d2c5cc2a887055b9141d3fcdb4fd2fa35d069c9a39b81903c531c73fcf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 2a42e16fea..46a6cbe7da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\s".scanstatus"\san\sundocumented\salternative\sname\sfor\s".scanstats"\sin\sthe\sCLI. -D 2024-11-21T20:57:11.560 +C Fix\sharmless\scompiler\swarning\scaused\sby\s[c77a4a42f2e3d164]. +D 2024-11-22T12:00:31.024 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -737,7 +737,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70 F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 -F src/main.c 9f4286302727f58fddc03a820d24cb7618a1e27473501792fbe979726f846d1f +F src/main.c efacea3a809ba236233c4bc7648e623c28cb5fd1e1a343e74fe772005f142d8c F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e527dcd016fbeb55b0e613a0b3b95350bbc8b3ee601bbadfedaf6bd5458b3570 -R de7a1058dc7d9edb28df5fa9d0ef82bc +P f20688efc2bc54648618b0aa2593a771f455ee8cc703b52273452d15e680b67c +R 2bcc1bc731850fcd4834b7042e1e5235 U drh -Z d8274e63f396ef1ba4c0c2282830a6d5 +Z 694866e50c564ff1bf4fd8cdd52185ff # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 86d326f1e5..f2455a0a70 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f20688efc2bc54648618b0aa2593a771f455ee8cc703b52273452d15e680b67c +063690d2c5cc2a887055b9141d3fcdb4fd2fa35d069c9a39b81903c531c73fcf diff --git a/src/main.c b/src/main.c index ff2a408d77..3a535e3cde 100644 --- a/src/main.c +++ b/src/main.c @@ -4288,6 +4288,7 @@ int sqlite3_test_control(int op, ...){ sqlite3ShowWinFunc(0); #endif sqlite3ShowSelect(0); + sqlite3ShowWhereTerm(0); } #endif break; From 38fdb2a857a476a862811d5e40952cab5d25f96f Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Nov 2024 12:07:21 +0000 Subject: [PATCH 389/522] Fix some harmless scanbuild warnings in the shell. FossilOrigin-Name: 9ba1c9b505d459366274043c1c5327f1a9d4e15d3564d99f8a15926af1d6d247 --- ext/expert/sqlite3expert.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 3 --- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/ext/expert/sqlite3expert.c b/ext/expert/sqlite3expert.c index 84b4793ddd..93693cfae9 100644 --- a/ext/expert/sqlite3expert.c +++ b/ext/expert/sqlite3expert.c @@ -1491,7 +1491,7 @@ static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ }else{ IdxTable *pTab; rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg); - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && ALWAYS(pTab!=0) ){ int i; char *zInner = 0; char *zOuter = 0; diff --git a/manifest b/manifest index 46a6cbe7da..fceac6cb5c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\scaused\sby\s[c77a4a42f2e3d164]. -D 2024-11-22T12:00:31.024 +C Fix\ssome\sharmless\sscanbuild\swarnings\sin\sthe\sshell. +D 2024-11-22T12:07:21.302 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -69,7 +69,7 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 F ext/expert/expert1.test 1d2da6606623b57bb47064e02140823ce1daecd4cacbf402c73ad3473d7f000c -F ext/expert/sqlite3expert.c 9d87c5eeb86707e4dbf140ca20a32935f88cfb5d8da94a406b7e0f0cdb815af6 +F ext/expert/sqlite3expert.c 494a6b7d4e0ead6dec6a50109dd78fcc054bb1a3fcc29c6f25e06a3685ed557e F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c b767b2039a0df707eb3147e86bcf68b252d8455d9a41774b1a836cd052ceca70 F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee @@ -775,7 +775,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in d8719347d467bc026ac43efdf5213cd9bab56503450a4b970fd09e4d4dab5409 +F src/shell.c.in f75bc23ace1ab3ee7ab05a1c09f8733deb6b3885f6c0c83b506e021c03be95ce F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f20688efc2bc54648618b0aa2593a771f455ee8cc703b52273452d15e680b67c -R 2bcc1bc731850fcd4834b7042e1e5235 +P 063690d2c5cc2a887055b9141d3fcdb4fd2fa35d069c9a39b81903c531c73fcf +R 13b3d4e078b262611ab19f5afe7794a7 U drh -Z 694866e50c564ff1bf4fd8cdd52185ff +Z dd389eddd9f1b1e329be94b3f99fecab # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f2455a0a70..5209cb273a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -063690d2c5cc2a887055b9141d3fcdb4fd2fa35d069c9a39b81903c531c73fcf +9ba1c9b505d459366274043c1c5327f1a9d4e15d3564d99f8a15926af1d6d247 diff --git a/src/shell.c.in b/src/shell.c.in index 22a5976d3f..730957bc25 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -11988,7 +11988,6 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, char cWait = (char)qss; /* intentional narrowing loss */ if( cWait==0 ){ PlainScan: - assert( cWait==0 ); while( (cin = *zLine++)!=0 ){ if( IsSpace(cin) ) continue; @@ -12040,7 +12039,6 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, if( *zLine != '/' ) continue; ++zLine; - cWait = 0; CONTINUE_PROMPT_AWAITC(pst, 0); qss = QSS_SETV(qss, 0); goto PlainScan; @@ -12052,7 +12050,6 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, } deliberate_fall_through; case ']': - cWait = 0; CONTINUE_PROMPT_AWAITC(pst, 0); qss = QSS_SETV(qss, 0); goto PlainScan; From ed271dc7ea87ae7e7950b917c00fb02f1afaf141 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Nov 2024 12:29:35 +0000 Subject: [PATCH 390/522] Fix harmless scanbuild warnings caused by the introduction of the ".dbtotxt" command into the CLI by check-in [b43acf5a8cd4a5ef]. FossilOrigin-Name: 554d8fbd865436ace900859874b6c8c7e1b782184158a86b7788644e27bd1997 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 8 ++------ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index fceac6cb5c..0120709f77 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sharmless\sscanbuild\swarnings\sin\sthe\sshell. -D 2024-11-22T12:07:21.302 +C Fix\sharmless\sscanbuild\swarnings\scaused\sby\sthe\sintroduction\sof\sthe\n".dbtotxt"\scommand\sinto\sthe\sCLI\sby\scheck-in\s[b43acf5a8cd4a5ef]. +D 2024-11-22T12:29:35.356 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -775,7 +775,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in f75bc23ace1ab3ee7ab05a1c09f8733deb6b3885f6c0c83b506e021c03be95ce +F src/shell.c.in 7aa68b305246391984c48f10725416079394a64bf0349fa4087d835c41ef733d F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 063690d2c5cc2a887055b9141d3fcdb4fd2fa35d069c9a39b81903c531c73fcf -R 13b3d4e078b262611ab19f5afe7794a7 +P 9ba1c9b505d459366274043c1c5327f1a9d4e15d3564d99f8a15926af1d6d247 +R 0f0539622ac4b0da7137e3fd709352f4 U drh -Z dd389eddd9f1b1e329be94b3f99fecab +Z 816c51d5e78086444b5f5aa51a7c35b5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5209cb273a..53dbfc820e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ba1c9b505d459366274043c1c5327f1a9d4e15d3564d99f8a15926af1d6d247 +554d8fbd865436ace900859874b6c8c7e1b782184158a86b7788644e27bd1997 diff --git a/src/shell.c.in b/src/shell.c.in index 730957bc25..b4d7fc287f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6632,7 +6632,6 @@ static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){ sqlite3_stmt *pStmt = 0; sqlite3_int64 nPage = 0; int pgSz = 0; - const char *zFilename; const char *zTail; char *zName = 0; int rc, i, j; @@ -6660,17 +6659,15 @@ static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){ if( nPage<1 ) goto dbtotxt_error; rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0); if( rc ) goto dbtotxt_error; - rc = 0; if( sqlite3_step(pStmt)!=SQLITE_ROW ){ - zTail = zFilename = "unk.db"; + zTail = "unk.db"; }else{ - zFilename = (const char*)sqlite3_column_text(pStmt, 2); + const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2); if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; zTail = strrchr(zFilename, '/'); #if defined(_WIN32) if( zTail==0 ) zTail = strrchr(zFilename, '\\'); #endif - if( zTail ) zFilename = zTail; } zName = strdup(zTail); shell_check_oom(zName); @@ -6681,7 +6678,6 @@ static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){ rc = sqlite3_prepare_v2(p->db, "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0); if( rc ) goto dbtotxt_error; - rc = 0; while( sqlite3_step(pStmt)==SQLITE_ROW ){ sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0); const u8 *aData = sqlite3_column_blob(pStmt, 1); From 0cf7131555377eb53087484bf12cb4cb44cfce0f Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 22 Nov 2024 13:22:25 +0000 Subject: [PATCH 391/522] Add links to [/forumpost/5a3b44f510df8ded|the SONAME discussion] at relevant places in auto.def and the makefiles. No functional changes. FossilOrigin-Name: c78dcc318a36af123676e54d85fc7f980c21b0ea366d164a96e2d998286d3813 --- Makefile.in | 1 + auto.def | 2 +- main.mk | 2 +- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3d2e736fd1..483ca35d94 100644 --- a/Makefile.in +++ b/Makefile.in @@ -154,6 +154,7 @@ CFLAGS.readline = @CFLAGS_READLINE@ LDFLAGS.icu = @LDFLAGS_ICU@ CFLAGS.icu = @CFLAGS_ICU@ LDFLAGS.libsqlite3.soname = @LDFLAGS_LIBSQLITE3_SONAME@ +# soname: see https://sqlite.org/src/forumpost/5a3b44f510df8ded ENABLE_SHARED = @ENABLE_SHARED@ ENABLE_STATIC = @ENABLE_STATIC@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ diff --git a/auto.def b/auto.def index 9c214ec39c..086d8e1e3c 100644 --- a/auto.def +++ b/auto.def @@ -205,7 +205,7 @@ set flags { dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} dynlink-tools => {Dynamically link libsqlite3 to certain tools which normally statically embed it.} soname:=legacy => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} - # --soname has a long story behind it, as well as no small amount of uncertainty. + # --soname has a long story behind it: https://sqlite.org/src/forumpost/5a3b44f510df8ded # } if {"" ne $DUMP_DEFINES_JSON} { diff --git a/main.mk b/main.mk index b1f1635980..9c1ecd2800 100644 --- a/main.mk +++ b/main.mk @@ -162,7 +162,7 @@ LDFLAGS.dlopen ?= -ldl LDFLAGS.shlib ?= -shared LDFLAGS.icu ?= # -licui18n -licuuc -licudata CFLAGS.icu ?= -LDFLAGS.soname.libsqlite3 ?= +LDFLAGS.soname.libsqlite3 ?= # see https://sqlite.org/src/forumpost/5a3b44f510df8ded # libreadline (or a workalike): # To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE=1 LDFLAGS.readline ?= -lreadline # these vary across platforms diff --git a/manifest b/manifest index 0120709f77..0aff53498b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sharmless\sscanbuild\swarnings\scaused\sby\sthe\sintroduction\sof\sthe\n".dbtotxt"\scommand\sinto\sthe\sCLI\sby\scheck-in\s[b43acf5a8cd4a5ef]. -D 2024-11-22T12:29:35.356 +C Add\slinks\sto\s[/forumpost/5a3b44f510df8ded|the\sSONAME\sdiscussion]\sat\srelevant\splaces\sin\sauto.def\sand\sthe\smakefiles.\sNo\sfunctional\schanges. +D 2024-11-22T13:22:25.012 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in b22a52dc08b8a727c298af4f93171b2862df1d6fce4c255b15f6ce1011a9ee7d +F Makefile.in d0ad8cdcb5a0492eee78b7ae74ace1213294649a547ba90d15e9c39cc08fdbb4 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def c71f141cbeca906b157827959ca556eb19f762428fa7f5001161e5d21093178f +F auto.def 7cc8f9f228a234db7955ce9061bef85b74162cd890afaaf6338ebc49fa04b2de F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk e3873a2363bef0fb8e3a65a21e548ce1aa9aeeb3795362c3e78346e655d501a4 +F main.mk b917f0d5e6aecc035a91132dd476a7a377af493a8e57e44b852a8b9581566800 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9ba1c9b505d459366274043c1c5327f1a9d4e15d3564d99f8a15926af1d6d247 -R 0f0539622ac4b0da7137e3fd709352f4 -U drh -Z 816c51d5e78086444b5f5aa51a7c35b5 +P 554d8fbd865436ace900859874b6c8c7e1b782184158a86b7788644e27bd1997 +R 98e9659ab220b4d9f62564eeb9669425 +U stephan +Z 498e6bdf598b32247f18c53c3d6f4d47 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 53dbfc820e..fa5a606748 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -554d8fbd865436ace900859874b6c8c7e1b782184158a86b7788644e27bd1997 +c78dcc318a36af123676e54d85fc7f980c21b0ea366d164a96e2d998286d3813 From 7a13effa20aff6864926c849669ff92e4a90383c Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 22 Nov 2024 13:47:12 +0000 Subject: [PATCH 392/522] Remove the libsqlite3.so.3 link from the installation process, as it now serves no functional purpose. We retain libsqlite3.so.0 (A) for compatibility with clients linked against legacy builds and (B) 0 is still valid as the library's ABI version. FossilOrigin-Name: 91bd9813e04e34e088d5e73bfe2a4f338513363d9a99095a232b811c6b616354 --- main.mk | 18 ++++++++++-------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/main.mk b/main.mk index 9c1ecd2800..1f7c9bafd3 100644 --- a/main.mk +++ b/main.mk @@ -1414,9 +1414,12 @@ all: so # and create symlinks which point to it: # # - libsqlite3.so.$(PACKAGE_VERSION) -# - libsqlite3.so.3 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) -# - libsqlite3.so.0 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) (see below) -# - libsqlite3.so =symlink-> libsqlite3.so.3 +# - libsqlite3.so.0 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) (see below) +# - libsqlite3.so =symlink-> libsqlite3.so.3 +# +# N.B. we initially had a link named libsqlite3.so.3 but it's +# unnecessary unless we want to set SONAME to libsqlite3.so.3, which +# is also unnecessary. # # The link named libsqlite3.so.0 is provided in an attempt to reduce # downstream disruption when performing upgrades from pre-3.48 to a @@ -1442,7 +1445,7 @@ all: so # down-side of this is that it may upset packaging tools when we # replace libsqlite3.so (from a legacy package) with a new symlink. # -# 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links +# 2) If INSTALL_SO_086_LINK=1 and point (1) does not apply then links # to the legacy-style names are created. The primary intent of this # is to enable chains of operations such as the hypothetical (apt # remove sqlite3-3.47.0 && apt install sqlite3-3.48.0). In such @@ -1456,10 +1459,9 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) "$(install-dir.lib)" @echo "Setting up $(libsqlite3.SO) symlinks..."; \ cd "$(install-dir.lib)" || exit $$?; \ - rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).0 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ + rm -f $(libsqlite3.SO).0 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO) || exit $$?; \ - ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).3 || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \ ls -la $(libsqlite3.SO) $(libsqlite3.SO).[03]*; \ if [ -e $(libsqlite3.SO).0.8.6 ]; then \ @@ -1467,8 +1469,8 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) rm -f libsqlite3.la $(libsqlite3.SO).0.8.6 || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ ls -la $(libsqlite3.SO).0.8.6; \ - elif [ x1 = "x$(INSTALL_SO_086_LINKS)" ]; then \ - echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINKS=1"; \ + elif [ x1 = "x$(INSTALL_SO_086_LINK)" ]; then \ + echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINK=1"; \ rm -f libsqlite3.la $(libsqlite3.SO).0.8.6 || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ ls -la $(libsqlite3.SO).0.8.6; \ diff --git a/manifest b/manifest index 0aff53498b..325c9fd9cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\slinks\sto\s[/forumpost/5a3b44f510df8ded|the\sSONAME\sdiscussion]\sat\srelevant\splaces\sin\sauto.def\sand\sthe\smakefiles.\sNo\sfunctional\schanges. -D 2024-11-22T13:22:25.012 +C Remove\sthe\slibsqlite3.so.3\slink\sfrom\sthe\sinstallation\sprocess,\sas\sit\snow\sserves\sno\sfunctional\spurpose.\sWe\sretain\slibsqlite3.so.0\s(A)\sfor\scompatibility\swith\sclients\slinked\sagainst\slegacy\sbuilds\sand\s(B)\s0\sis\sstill\svalid\sas\sthe\slibrary's\sABI\sversion. +D 2024-11-22T13:47:12.667 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk b917f0d5e6aecc035a91132dd476a7a377af493a8e57e44b852a8b9581566800 +F main.mk 9c6c9473eb83a72a4cd80aab95c7dd64bb59286c151d5745091a5a178d111c84 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 554d8fbd865436ace900859874b6c8c7e1b782184158a86b7788644e27bd1997 -R 98e9659ab220b4d9f62564eeb9669425 +P c78dcc318a36af123676e54d85fc7f980c21b0ea366d164a96e2d998286d3813 +R c696fe78d3d189a1b874e36c608737fb U stephan -Z 498e6bdf598b32247f18c53c3d6f4d47 +Z 044fe3be3927265c623f70a401222db0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fa5a606748..66959ba790 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c78dcc318a36af123676e54d85fc7f980c21b0ea366d164a96e2d998286d3813 +91bd9813e04e34e088d5e73bfe2a4f338513363d9a99095a232b811c6b616354 From dcaf03fccf9beecce47c405647cb3febc716d38d Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 22 Nov 2024 14:12:18 +0000 Subject: [PATCH 393/522] Makefile doc cleanups. No functional changes. FossilOrigin-Name: 64add0ac706101c53e2d2877fdc0d1ccd071814cae969768d2741cee05f23c01 --- main.mk | 62 +++++++++++++++++++++++++++++++-------------------- manifest | 12 +++++----- manifest.uuid | 2 +- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/main.mk b/main.mk index 1f7c9bafd3..9a706d1078 100644 --- a/main.mk +++ b/main.mk @@ -105,6 +105,9 @@ TCLSH_CMD ?= tclsh # JIMSH requires a leading path component, even if it's ./, so that it # can be used as a shell command. # +# On Windows platforms, if -DHAVE_REALPATH does not work then try +# -DHAVE__FULLPATH (note the double-underscore). +# CFLAGS.jimsh ?= -DHAVE_REALPATH JIMSH ?= ./jimsh$(T.exe) # @@ -119,12 +122,12 @@ B.tclsh ?= $(JIMSH) # # Autotools-conventional vars which are (in this tree) used only by -# package installation rules. +# package installation rules and for generating sqlite3.pc (pkg-config +# data file). # # The following ${XYZdir} vars are provided for the sake of clients # who expect to be able to override these using autotools-conventional -# dir name vars. In this build they apply only to installation-related -# rules. +# dir name vars. # prefix ?= /usr/local datadir ?= $(prefix)/share @@ -202,17 +205,22 @@ ENABLE_STATIC ?= 1 # # 1 if the amalgamation (sqlite3.c/h) should be built/used, otherwise # the library is built from all of its original source files. +# Certaint tools, like sqlite3$(T.exe), require the amalgamation and +# will ignore this preference. # USE_AMALGAMATION ?= 1 # # $(LINK_TOOLS_DYNAMICALLY) # -# If true, certain binaries which typically statically link against +# If 1, certain binaries which typically statically link against # libsqlite3 or its component object files will instead link against # the DLL. The caveat is that running such builds from the source tree # may require that the user specifically prepend "." to their # $LD_LIBRARY_PATH so that the dynamic linker does not pick up a -# libsqlite3.so from outside the source tree. +# libsqlite3.so from outside the source tree. Alternately, symlinking +# the in-build-tree $(libsqlite3.SO) to some dir in the system's +# library path will work for giving the apps access to the in-tree +# DLL. # LINK_TOOLS_DYNAMICALLY ?= 0 # @@ -227,16 +235,21 @@ AMALGAMATION_GEN_FLAGS ?= --linemacros=0 # Preprocessor flags for enabling and disabling specific libsqlite3 # features (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). The same set of OMIT # and ENABLE flags must be passed to the LEMON parser generator and -# the mkkeywordhash tool as well. -# -# Add OPTIONS=... on the make command line to append additional options -# to the OPT_FEATURE_FLAGS. Note that some flags only work if the -# build is specifically configured to account for them. Adding them -# later, when compiling the amalgamation, may or may not work. -# -# TO CLARIFY: OPTS=... has historically been expected in some -# contexts, and is distinctly different from OPTIONS and -# OPT_FEATURE_FLAGS, but its name is confusingly close to $(OPTIONS). +# the mkkeywordhash tool as well. This is normally set by the +# configure process, and passing a custom value to a +# coonfigure-filtered Makefile may not work. +# +# When using the canonical makefile, add $(OPTIONS)=... on the make +# command line to append additional options to the +# $(OPT_FEATURE_FLAGS). Note that some flags, because they influence +# generation of the SQL parser, only work if the build is specifically +# configured to account for them. Adding them later, when compiling +# the amalgamation separately, may or may not work. +# +# $(OPTS)=... is another way of influencing C compilation. It is +# distinctly separate from $(OPTIONS) and $(OPT_FEATURE_FLAGS) but, +# like those, $(OPTS) applies to all invocations of $(T.cc). The +# configure process does not set either of $(OPTIONS) or $(OPTS). # OPT_FEATURE_FLAGS ?= # @@ -248,15 +261,17 @@ SHELL_OPT ?= # # TCL_CONFIG_SH must, for some of the build targets, refer to a valid # tclConfig.sh. That script will be used to populate most of the other -# TCL-related vars the build needs. +# TCL-related vars the build needs. The core library does not require +# TCL, but TCL is needed for running tests and certain tools, e.g. +# sqlite3_analyzer. # TCL_CONFIG_SH ?= # # $(HAVE_WASI_SDK) = # -# 1 when building with the WASI SDK. This disables certain build -# targets. It is expected that the invoker assigns CC to the wasi-sdk -# CC. +# Set to 1 when building with the WASI SDK. This disables certain +# build targets. It is expected that the invoker sets $(CC), $(LD), +# and $(AR) to their counterparts from the wasi-sdk. # HAVE_WASI_SDK ?= 0 # @@ -312,22 +327,21 @@ T.cc += $(CFLAGS.core) $(CFLAGS.env) # The legacy build applied such LDFLAGS to all link operations for all # deliverables. The 3.48+ build applies them (as of this writing) more # selectively: search this file LDFLAGS.configure to see where they're -# set. As of this writing, they only affect targets which use -# $(LDFLAGS.libsqlite3) - see that var's docs for details. +# set. # LDFLAGS.configure ?= # # The difference between $(OPT_FEATURE_FLAGS) and $(OPTS) is that the -# former is historically provided by the configure script, whereas the -# latter is intended to be provided as arguments to the make +# former is historically provided by the configure script, whereas +# $(OPTS) is intended to be provided as arguments to the make # invocation. # T.cc += $(OPT_FEATURE_FLAGS) # # Add in any optional global compilation flags on the make command -# line ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". +# line i.e. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1". # T.cc += $(OPTS) diff --git a/manifest b/manifest index 325c9fd9cc..a2a0993d19 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\slibsqlite3.so.3\slink\sfrom\sthe\sinstallation\sprocess,\sas\sit\snow\sserves\sno\sfunctional\spurpose.\sWe\sretain\slibsqlite3.so.0\s(A)\sfor\scompatibility\swith\sclients\slinked\sagainst\slegacy\sbuilds\sand\s(B)\s0\sis\sstill\svalid\sas\sthe\slibrary's\sABI\sversion. -D 2024-11-22T13:47:12.667 +C Makefile\sdoc\scleanups.\sNo\sfunctional\schanges. +D 2024-11-22T14:12:18.841 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 9c6c9473eb83a72a4cd80aab95c7dd64bb59286c151d5745091a5a178d111c84 +F main.mk b19ce37b58d9378b89e868d9ef9546c0068e5e6b49b02e44e600b752519e888f F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c78dcc318a36af123676e54d85fc7f980c21b0ea366d164a96e2d998286d3813 -R c696fe78d3d189a1b874e36c608737fb +P 91bd9813e04e34e088d5e73bfe2a4f338513363d9a99095a232b811c6b616354 +R 0e0e7948374fb4ea8d89262652e0cc24 U stephan -Z 044fe3be3927265c623f70a401222db0 +Z c67cb4da7f21bbdaef588069bb0cb4d5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 66959ba790..da30cd0938 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91bd9813e04e34e088d5e73bfe2a4f338513363d9a99095a232b811c6b616354 +64add0ac706101c53e2d2877fdc0d1ccd071814cae969768d2741cee05f23c01 From 5c945264b0dd500f2d301b2fb82394d20af5bb85 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 22 Nov 2024 14:18:23 +0000 Subject: [PATCH 394/522] Move handling of the tempstore feature flag into the OPT_FEATURE_FLAGS list and remove the CFLAGS.libsqlite3 makefile var which exists solely to account for the tempstore being tracked separately from the other feature flags. FossilOrigin-Name: 2df5065d118ca4abcb4f285d07819e73c5e32f7e470d30eabc7e3d999ec8d0f2 --- Makefile.in | 5 -- auto.def | 2 +- main.mk | 178 ++++++++++++++++++++++++-------------------------- manifest | 16 ++--- manifest.uuid | 2 +- 5 files changed, 96 insertions(+), 107 deletions(-) diff --git a/Makefile.in b/Makefile.in index 483ca35d94..59963f3ced 100644 --- a/Makefile.in +++ b/Makefile.in @@ -184,11 +184,6 @@ JIMSH = ./jimsh$(TEXE) B.tclsh = @BTCLSH@ $(B.tclsh): -# -# $(CFLAGS.libsqlite3) is documented in main.mk. -# -CFLAGS.libsqlite3 = -DSQLITE_TEMP_STORE=@TEMP_STORE@ - # # $(OPT_FEATURE_FLAGS) is documented in main.mk. # diff --git a/auto.def b/auto.def index 086d8e1e3c..c49e7b949b 100644 --- a/auto.def +++ b/auto.def @@ -866,7 +866,7 @@ apply {{} { } } msg-result $ts - define TEMP_STORE $tsn + sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn }} ######################################################################## diff --git a/main.mk b/main.mk index 9a706d1078..3e1169368a 100644 --- a/main.mk +++ b/main.mk @@ -358,12 +358,6 @@ INSTALL.noexec = $(INSTALL) -m 0644 # T.compile = $(T.cc) $(T.compile.extras) -# -# $(CFLAGS.libsqlite3) must contain any CFLAGS which are relevant for -# compiling the library's own sources, including (sometimes) when -# compiling sqlite3.c directly in to another app. -# -CFLAGS.libsqlite3 ?= # # $(T.cc.sqlite) is $(T.cc) plus any flags which are desired for the # library as a whole, but not necessarily needed for every binary. It @@ -1100,255 +1094,255 @@ sqlite3ext.h: .target_source # DEPS_OBJ_COMMON = $(MAKE_SANITY_CHECK) $(HDR) parse.o: parse.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c parse.c + $(T.cc.sqlite) -c parse.c opcodes.o: opcodes.c - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c opcodes.c + $(T.cc.sqlite) -c opcodes.c # Rules to build individual *.o files from files in the src directory. # alter.o: $(TOP)/src/alter.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/alter.c + $(T.cc.sqlite) -c $(TOP)/src/alter.c analyze.o: $(TOP)/src/analyze.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/analyze.c + $(T.cc.sqlite) -c $(TOP)/src/analyze.c attach.o: $(TOP)/src/attach.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/attach.c + $(T.cc.sqlite) -c $(TOP)/src/attach.c auth.o: $(TOP)/src/auth.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/auth.c + $(T.cc.sqlite) -c $(TOP)/src/auth.c backup.o: $(TOP)/src/backup.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/backup.c + $(T.cc.sqlite) -c $(TOP)/src/backup.c bitvec.o: $(TOP)/src/bitvec.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/bitvec.c + $(T.cc.sqlite) -c $(TOP)/src/bitvec.c btmutex.o: $(TOP)/src/btmutex.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/btmutex.c + $(T.cc.sqlite) -c $(TOP)/src/btmutex.c btree.o: $(TOP)/src/btree.c $(DEPS_OBJ_COMMON) $(TOP)/src/pager.h - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/btree.c + $(T.cc.sqlite) -c $(TOP)/src/btree.c build.o: $(TOP)/src/build.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/build.c + $(T.cc.sqlite) -c $(TOP)/src/build.c callback.o: $(TOP)/src/callback.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/callback.c + $(T.cc.sqlite) -c $(TOP)/src/callback.c complete.o: $(TOP)/src/complete.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/complete.c + $(T.cc.sqlite) -c $(TOP)/src/complete.c ctime.o: $(TOP)/src/ctime.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/ctime.c + $(T.cc.sqlite) -c $(TOP)/src/ctime.c date.o: $(TOP)/src/date.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/date.c + $(T.cc.sqlite) -c $(TOP)/src/date.c dbpage.o: $(TOP)/src/dbpage.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/dbpage.c + $(T.cc.sqlite) -c $(TOP)/src/dbpage.c dbstat.o: $(TOP)/src/dbstat.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/dbstat.c + $(T.cc.sqlite) -c $(TOP)/src/dbstat.c delete.o: $(TOP)/src/delete.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/delete.c + $(T.cc.sqlite) -c $(TOP)/src/delete.c expr.o: $(TOP)/src/expr.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/expr.c + $(T.cc.sqlite) -c $(TOP)/src/expr.c fault.o: $(TOP)/src/fault.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/fault.c + $(T.cc.sqlite) -c $(TOP)/src/fault.c fkey.o: $(TOP)/src/fkey.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/fkey.c + $(T.cc.sqlite) -c $(TOP)/src/fkey.c func.o: $(TOP)/src/func.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/func.c + $(T.cc.sqlite) -c $(TOP)/src/func.c global.o: $(TOP)/src/global.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/global.c + $(T.cc.sqlite) -c $(TOP)/src/global.c hash.o: $(TOP)/src/hash.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/hash.c + $(T.cc.sqlite) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/insert.c + $(T.cc.sqlite) -c $(TOP)/src/insert.c json.o: $(TOP)/src/json.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/json.c + $(T.cc.sqlite) -c $(TOP)/src/json.c legacy.o: $(TOP)/src/legacy.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/legacy.c + $(T.cc.sqlite) -c $(TOP)/src/legacy.c loadext.o: $(TOP)/src/loadext.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/loadext.c + $(T.cc.sqlite) -c $(TOP)/src/loadext.c main.o: $(TOP)/src/main.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/main.c + $(T.cc.sqlite) -c $(TOP)/src/main.c malloc.o: $(TOP)/src/malloc.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/malloc.c + $(T.cc.sqlite) -c $(TOP)/src/malloc.c mem0.o: $(TOP)/src/mem0.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem0.c + $(T.cc.sqlite) -c $(TOP)/src/mem0.c mem1.o: $(TOP)/src/mem1.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem1.c + $(T.cc.sqlite) -c $(TOP)/src/mem1.c mem2.o: $(TOP)/src/mem2.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem2.c + $(T.cc.sqlite) -c $(TOP)/src/mem2.c mem3.o: $(TOP)/src/mem3.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem3.c + $(T.cc.sqlite) -c $(TOP)/src/mem3.c mem5.o: $(TOP)/src/mem5.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mem5.c + $(T.cc.sqlite) -c $(TOP)/src/mem5.c memdb.o: $(TOP)/src/memdb.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/memdb.c + $(T.cc.sqlite) -c $(TOP)/src/memdb.c memjournal.o: $(TOP)/src/memjournal.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/memjournal.c + $(T.cc.sqlite) -c $(TOP)/src/memjournal.c mutex.o: $(TOP)/src/mutex.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex.c + $(T.cc.sqlite) -c $(TOP)/src/mutex.c mutex_noop.o: $(TOP)/src/mutex_noop.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_noop.c + $(T.cc.sqlite) -c $(TOP)/src/mutex_noop.c mutex_unix.o: $(TOP)/src/mutex_unix.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_unix.c + $(T.cc.sqlite) -c $(TOP)/src/mutex_unix.c mutex_w32.o: $(TOP)/src/mutex_w32.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/mutex_w32.c + $(T.cc.sqlite) -c $(TOP)/src/mutex_w32.c notify.o: $(TOP)/src/notify.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/notify.c + $(T.cc.sqlite) -c $(TOP)/src/notify.c pager.o: $(TOP)/src/pager.c $(DEPS_OBJ_COMMON) $(TOP)/src/pager.h - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pager.c + $(T.cc.sqlite) -c $(TOP)/src/pager.c pcache.o: $(TOP)/src/pcache.c $(DEPS_OBJ_COMMON) $(TOP)/src/pcache.h - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pcache.c + $(T.cc.sqlite) -c $(TOP)/src/pcache.c pcache1.o: $(TOP)/src/pcache1.c $(DEPS_OBJ_COMMON) $(TOP)/src/pcache.h - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pcache1.c + $(T.cc.sqlite) -c $(TOP)/src/pcache1.c os.o: $(TOP)/src/os.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os.c + $(T.cc.sqlite) -c $(TOP)/src/os.c os_kv.o: $(TOP)/src/os_kv.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_kv.c + $(T.cc.sqlite) -c $(TOP)/src/os_kv.c os_unix.o: $(TOP)/src/os_unix.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_unix.c + $(T.cc.sqlite) -c $(TOP)/src/os_unix.c os_win.o: $(TOP)/src/os_win.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/os_win.c + $(T.cc.sqlite) -c $(TOP)/src/os_win.c pragma.o: $(TOP)/src/pragma.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/pragma.c + $(T.cc.sqlite) -c $(TOP)/src/pragma.c prepare.o: $(TOP)/src/prepare.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/prepare.c + $(T.cc.sqlite) -c $(TOP)/src/prepare.c printf.o: $(TOP)/src/printf.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/printf.c + $(T.cc.sqlite) -c $(TOP)/src/printf.c random.o: $(TOP)/src/random.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/random.c + $(T.cc.sqlite) -c $(TOP)/src/random.c resolve.o: $(TOP)/src/resolve.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/resolve.c + $(T.cc.sqlite) -c $(TOP)/src/resolve.c rowset.o: $(TOP)/src/rowset.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/rowset.c + $(T.cc.sqlite) -c $(TOP)/src/rowset.c select.o: $(TOP)/src/select.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/select.c + $(T.cc.sqlite) -c $(TOP)/src/select.c status.o: $(TOP)/src/status.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/status.c + $(T.cc.sqlite) -c $(TOP)/src/status.c sqlite3.o: sqlite3.h sqlite3.c - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c sqlite3.c + $(T.cc.sqlite) -c sqlite3.c table.o: $(TOP)/src/table.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/table.c + $(T.cc.sqlite) -c $(TOP)/src/table.c threads.o: $(TOP)/src/threads.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/threads.c + $(T.cc.sqlite) -c $(TOP)/src/threads.c tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/tokenize.c + $(T.cc.sqlite) -c $(TOP)/src/tokenize.c treeview.o: $(TOP)/src/treeview.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/treeview.c + $(T.cc.sqlite) -c $(TOP)/src/treeview.c trigger.o: $(TOP)/src/trigger.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/trigger.c + $(T.cc.sqlite) -c $(TOP)/src/trigger.c update.o: $(TOP)/src/update.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/update.c + $(T.cc.sqlite) -c $(TOP)/src/update.c upsert.o: $(TOP)/src/upsert.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/upsert.c + $(T.cc.sqlite) -c $(TOP)/src/upsert.c utf.o: $(TOP)/src/utf.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/utf.c + $(T.cc.sqlite) -c $(TOP)/src/utf.c util.o: $(TOP)/src/util.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/util.c + $(T.cc.sqlite) -c $(TOP)/src/util.c vacuum.o: $(TOP)/src/vacuum.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vacuum.c + $(T.cc.sqlite) -c $(TOP)/src/vacuum.c vdbe.o: $(TOP)/src/vdbe.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbe.c + $(T.cc.sqlite) -c $(TOP)/src/vdbe.c vdbeapi.o: $(TOP)/src/vdbeapi.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeapi.c + $(T.cc.sqlite) -c $(TOP)/src/vdbeapi.c vdbeaux.o: $(TOP)/src/vdbeaux.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeaux.c + $(T.cc.sqlite) -c $(TOP)/src/vdbeaux.c vdbeblob.o: $(TOP)/src/vdbeblob.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbeblob.c + $(T.cc.sqlite) -c $(TOP)/src/vdbeblob.c vdbemem.o: $(TOP)/src/vdbemem.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbemem.c + $(T.cc.sqlite) -c $(TOP)/src/vdbemem.c vdbesort.o: $(TOP)/src/vdbesort.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbesort.c + $(T.cc.sqlite) -c $(TOP)/src/vdbesort.c vdbetrace.o: $(TOP)/src/vdbetrace.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbetrace.c + $(T.cc.sqlite) -c $(TOP)/src/vdbetrace.c vdbevtab.o: $(TOP)/src/vdbevtab.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vdbevtab.c + $(T.cc.sqlite) -c $(TOP)/src/vdbevtab.c vtab.o: $(TOP)/src/vtab.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/vtab.c + $(T.cc.sqlite) -c $(TOP)/src/vtab.c wal.o: $(TOP)/src/wal.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/wal.c + $(T.cc.sqlite) -c $(TOP)/src/wal.c walker.o: $(TOP)/src/walker.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/walker.c + $(T.cc.sqlite) -c $(TOP)/src/walker.c where.o: $(TOP)/src/where.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/where.c + $(T.cc.sqlite) -c $(TOP)/src/where.c wherecode.o: $(TOP)/src/wherecode.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/wherecode.c + $(T.cc.sqlite) -c $(TOP)/src/wherecode.c whereexpr.o: $(TOP)/src/whereexpr.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/whereexpr.c + $(T.cc.sqlite) -c $(TOP)/src/whereexpr.c window.o: $(TOP)/src/window.c $(DEPS_OBJ_COMMON) - $(T.cc.sqlite) $(CFLAGS.libsqlite3) -c $(TOP)/src/window.c + $(T.cc.sqlite) -c $(TOP)/src/window.c tclsqlite.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON) $(T.compile.tcl) -DUSE_TCL_STUBS=1 $$TCL_INCLUDE_SPEC \ @@ -1648,7 +1642,7 @@ testfixture$(T.exe): $(T.tcl.env.sh) has_tclsh85 $(TESTFIXTURE_SRC) $(T.link.tcl) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -o $@ $(TESTFIXTURE_SRC) \ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC \ - $(CFLAGS.libsqlite3) $(LDFLAGS.libsqlite3) + $(LDFLAGS.libsqlite3) coretestprogs: testfixture$(B.exe) sqlite3$(B.exe) @@ -1795,7 +1789,7 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \ $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(T.exe): $(T.tcl.env.sh) sqltclsh.c - $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) \ + $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC \ $(LDFLAGS.libsqlite3) $$TCL_LIB_SPEC $$TCL_LIBS # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. @@ -1822,7 +1816,7 @@ sqlite3_checker.c: $(CHECKER_DEPS) sqlite3_checker$(T.exe): $(T.tcl.env.sh) sqlite3_checker.c $(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC \ - $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) + $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) xbin: sqlite3_checker$(T.exe) dbdump$(T.exe): $(TOP)/ext/misc/dbdump.c sqlite3.o diff --git a/manifest b/manifest index a2a0993d19..83f3b6f2c0 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Makefile\sdoc\scleanups.\sNo\sfunctional\schanges. -D 2024-11-22T14:12:18.841 +C Move\shandling\sof\sthe\stempstore\sfeature\sflag\sinto\sthe\sOPT_FEATURE_FLAGS\slist\sand\sremove\sthe\sCFLAGS.libsqlite3\smakefile\svar\swhich\sexists\ssolely\sto\saccount\sfor\sthe\stempstore\sbeing\stracked\sseparately\sfrom\sthe\sother\sfeature\sflags. +D 2024-11-22T14:18:23.840 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in d0ad8cdcb5a0492eee78b7ae74ace1213294649a547ba90d15e9c39cc08fdbb4 +F Makefile.in 85f2c740cadf969abbd9a6210b8b76636dbf231b9d3efe977b060c3055fac5b9 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 7cc8f9f228a234db7955ce9061bef85b74162cd890afaaf6338ebc49fa04b2de +F auto.def 1674fbca9580feb23fe4ecc710e39b0fbfadf6190231490424ac2b2bbde5de67 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk b19ce37b58d9378b89e868d9ef9546c0068e5e6b49b02e44e600b752519e888f +F main.mk 01e9b77600f8551df7f970075c09ad9e1898bf2adf512cb861d24b30fb1e6f52 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 91bd9813e04e34e088d5e73bfe2a4f338513363d9a99095a232b811c6b616354 -R 0e0e7948374fb4ea8d89262652e0cc24 +P 64add0ac706101c53e2d2877fdc0d1ccd071814cae969768d2741cee05f23c01 +R 9816c1b559fff5885cdaa7805e52b14e U stephan -Z c67cb4da7f21bbdaef588069bb0cb4d5 +Z 4bea40264480222fb7de358654df9b7c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index da30cd0938..a332296066 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64add0ac706101c53e2d2877fdc0d1ccd071814cae969768d2741cee05f23c01 +2df5065d118ca4abcb4f285d07819e73c5e32f7e470d30eabc7e3d999ec8d0f2 From de7e2b178d97363ef8e46901c465ace38f117281 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 22 Nov 2024 16:24:55 +0000 Subject: [PATCH 395/522] In order to support package builds, like OpenBSD's, which set a custom soname on libsqlite3.so, extend the --soname configure flag to allow arbitrary soname values. FossilOrigin-Name: 9c1c1b99837efe3704778c594a65e0cd4cd0a8ec492044d3bb07f1b37a692c6a --- auto.def | 26 +++++++++++++++++++------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/auto.def b/auto.def index c49e7b949b..8fa2584611 100644 --- a/auto.def +++ b/auto.def @@ -204,7 +204,14 @@ set flags { linemacros => {Enable #line macros in the amalgamation} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} dynlink-tools => {Dynamically link libsqlite3 to certain tools which normally statically embed it.} - soname:=legacy => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy} + soname:=legacy => + {SONAME for libsqlite3.so. "none", or not using this flag, sets no + soname. "legacy" sets it to its historical value of + libsqlite3.so.0. A value matching the glob "libsqlite3.*" sets + it to that literal value. Any other value is assumed to be a + suffix which gets applied to "libsqlite3.so.", + e.g. --soname=9.10 equates to "libsqlite3.so.9.10". + } # --soname has a long story behind it: https://sqlite.org/src/forumpost/5a3b44f510df8ded # } @@ -475,22 +482,27 @@ proj-check-rpath ; # Determine proper rpath-handling flag apply {{} { define LDFLAGS_LIBSQLITE3_SONAME "" if {[proj-opt-was-provided soname]} { - set soname [opt-val soname] + set soname [join [opt-val soname] ""] } else { set soname none; # enabling soname breaks linking for the --dynlink-tools feature } switch -exact -- $soname { - none { return 0 } - auto { set soname libsqlite3.so.3 } - legacy { set soname libsqlite3.so.0 } + none - "" { return 0 } + auto { set soname libsqlite3.so.3 } + legacy { set soname libsqlite3.so.0 } default { - proj-fatal "Invalid value for --soname. Use one of (none, auto, legacy)." + if {[string match libsqlite3.* $soname]} { + # use it as-is + } else { + # Assume it's a suffix + set soname "libsqlite3.so.${soname}" + } } } msg-debug "soname=$soname" if {[proj-check-soname $soname]} { define LDFLAGS_LIBSQLITE3_SONAME [get-define LDFLAGS_SONAME_PREFIX]$soname - msg-result "Setting SONAME: [get-define LDFLAGS_LIBSQLITE3_SONAME]" + msg-result "Setting SONAME using: [get-define LDFLAGS_LIBSQLITE3_SONAME]" } elseif {[proj-opt-was-provided soname]} { # --soname was explicitly requested but not available, so fail fatally proj-fatal "This environment does not support SONAME." diff --git a/manifest b/manifest index 83f3b6f2c0..927edd7b24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\shandling\sof\sthe\stempstore\sfeature\sflag\sinto\sthe\sOPT_FEATURE_FLAGS\slist\sand\sremove\sthe\sCFLAGS.libsqlite3\smakefile\svar\swhich\sexists\ssolely\sto\saccount\sfor\sthe\stempstore\sbeing\stracked\sseparately\sfrom\sthe\sother\sfeature\sflags. -D 2024-11-22T14:18:23.840 +C In\sorder\sto\ssupport\spackage\sbuilds,\slike\sOpenBSD's,\swhich\sset\sa\scustom\ssoname\son\slibsqlite3.so,\sextend\sthe\s--soname\sconfigure\sflag\sto\sallow\sarbitrary\ssoname\svalues. +D 2024-11-22T16:24:55.926 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 1674fbca9580feb23fe4ecc710e39b0fbfadf6190231490424ac2b2bbde5de67 +F auto.def 62eaab1eb8bad47950bcb604f2861a498e31e7d536656de67555d83b33bc9b6e F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 64add0ac706101c53e2d2877fdc0d1ccd071814cae969768d2741cee05f23c01 -R 9816c1b559fff5885cdaa7805e52b14e +P 2df5065d118ca4abcb4f285d07819e73c5e32f7e470d30eabc7e3d999ec8d0f2 +R c80d0be5b601602377ee64fea6d1d93b U stephan -Z 4bea40264480222fb7de358654df9b7c +Z 7d4e6781a8e821513a5e1b50822d0be1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a332296066..b7b4e236d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2df5065d118ca4abcb4f285d07819e73c5e32f7e470d30eabc7e3d999ec8d0f2 +9c1c1b99837efe3704778c594a65e0cd4cd0a8ec492044d3bb07f1b37a692c6a From 7398e279a711a1fea3ca4db08a02e8b421304f7c Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 22 Nov 2024 16:45:43 +0000 Subject: [PATCH 396/522] Remove a flaky JS test which has a result depending on unrepredictable context. That same feature is more reliably tested at a later point in the same script. FossilOrigin-Name: 3d6ae13805bdba4c73b7443f20073264cdd157299cb911228600e1528a136bb1 --- ext/wasm/tester1.c-pp.js | 5 ----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 7ed2780201..a21a1c330e 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -1248,11 +1248,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule; let st = this.db.prepare( new TextEncoder('utf-8').encode("select 3 as a") ); - if( wasm.compileOptionUsed('OMIT_PROGRESS_CALLBACK') ) { - T.assert( !this.progressHandlerCount ); - }else{ - T.assert( 1===this.progressHandlerCount, "Checking this.progressHandlerCount" ); - } let rc; try { T.assert(wasm.isPtr(st.pointer)) diff --git a/manifest b/manifest index 927edd7b24..5be12c1b31 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sorder\sto\ssupport\spackage\sbuilds,\slike\sOpenBSD's,\swhich\sset\sa\scustom\ssoname\son\slibsqlite3.so,\sextend\sthe\s--soname\sconfigure\sflag\sto\sallow\sarbitrary\ssoname\svalues. -D 2024-11-22T16:24:55.926 +C Remove\sa\sflaky\sJS\stest\swhich\shas\sa\sresult\sdepending\son\sunrepredictable\scontext.\sThat\ssame\sfeature\sis\smore\sreliably\stested\sat\sa\slater\spoint\sin\sthe\ssame\sscript. +D 2024-11-22T16:45:43.035 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -690,7 +690,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js f255a7c6730b341e2633d54b7edb27b91cd35744c011ddd321418a0735b0e44b +F ext/wasm/tester1.c-pp.js 228101c290003423f0bfb66a6ebbfc6904fa7b1b69466e700c135f74ee83d62a F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2df5065d118ca4abcb4f285d07819e73c5e32f7e470d30eabc7e3d999ec8d0f2 -R c80d0be5b601602377ee64fea6d1d93b +P 9c1c1b99837efe3704778c594a65e0cd4cd0a8ec492044d3bb07f1b37a692c6a +R 4aa6d28b53812054d01714f0a5a04f4b U stephan -Z 7d4e6781a8e821513a5e1b50822d0be1 +Z 6393d24f8f80b84fe0e1080e07e0ef37 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b7b4e236d4..7f5c9109b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c1c1b99837efe3704778c594a65e0cd4cd0a8ec492044d3bb07f1b37a692c6a +3d6ae13805bdba4c73b7443f20073264cdd157299cb911228600e1528a136bb1 From 8ff67df7ac451fe0e8e42b5088aa866fc20f5ebf Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Nov 2024 17:41:00 +0000 Subject: [PATCH 397/522] Fix another issue in argument expansion on Windows for tclsqlite3.c in interpreter mode. Problem introduced by check-in [9b87ea219bce5689] and unfixed by [cd942dce148c9d8f]. FossilOrigin-Name: 0fe1622cec95b7ebecc127ee57a08113d3da1dadbe72c03a13d6751b3043e50f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5be12c1b31..a1f3f97ae3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sflaky\sJS\stest\swhich\shas\sa\sresult\sdepending\son\sunrepredictable\scontext.\sThat\ssame\sfeature\sis\smore\sreliably\stested\sat\sa\slater\spoint\sin\sthe\ssame\sscript. -D 2024-11-22T16:45:43.035 +C Fix\sanother\sissue\sin\sargument\sexpansion\son\sWindows\sfor\stclsqlite3.c\sin\ninterpreter\smode.\s\sProblem\sintroduced\sby\scheck-in\s[9b87ea219bce5689]\sand\nunfixed\sby\s[cd942dce148c9d8f]. +D 2024-11-22T17:41:00.227 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -783,7 +783,7 @@ F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2c F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c c4b0b27b0ad34e4af085040a1ebe94a35ad5161663cd905d1b947f7884691bff +F src/tclsqlite.c 1c2f697cb12a1d49f5e0b448327f7cf614809423bb43753b2d97f87354298113 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9c1c1b99837efe3704778c594a65e0cd4cd0a8ec492044d3bb07f1b37a692c6a -R 4aa6d28b53812054d01714f0a5a04f4b -U stephan -Z 6393d24f8f80b84fe0e1080e07e0ef37 +P 3d6ae13805bdba4c73b7443f20073264cdd157299cb911228600e1528a136bb1 +R f112fd2beffd3eb814301c3676676b3e +U drh +Z 113c5b5aab1719624bc6c7ebe0ae9b2d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7f5c9109b5..8cd2bbe8d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d6ae13805bdba4c73b7443f20073264cdd157299cb911228600e1528a136bb1 +0fe1622cec95b7ebecc127ee57a08113d3da1dadbe72c03a13d6751b3043e50f diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 36459e4a94..4406ceef67 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -4034,7 +4034,7 @@ static const char *tclsh_main_loop(void){ #ifdef WIN32 "set new [list]\n" "foreach arg $argv {\n" - "if {[file exists $arg]} {\n" + "if {[string match -* $arg] || [file exists $arg]} {\n" "lappend new $arg\n" "} else {\n" "set once 0\n" From b56f179e45293735513a28b61f71068104adb6a0 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 25 Nov 2024 17:07:58 +0000 Subject: [PATCH 398/522] Correct duplicated soname linker flags, one of them mis-named. FossilOrigin-Name: 87dfd92d3a5a6a09c32c70e724a3f341bc63b9c6dfa0aa94fbbbdd45cc9c29f3 --- main.mk | 6 +++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/main.mk b/main.mk index 3e1169368a..f98850731e 100644 --- a/main.mk +++ b/main.mk @@ -165,7 +165,7 @@ LDFLAGS.dlopen ?= -ldl LDFLAGS.shlib ?= -shared LDFLAGS.icu ?= # -licui18n -licuuc -licudata CFLAGS.icu ?= -LDFLAGS.soname.libsqlite3 ?= # see https://sqlite.org/src/forumpost/5a3b44f510df8ded +LDFLAGS.libsqlite3.soname ?= # see https://sqlite.org/src/forumpost/5a3b44f510df8ded # libreadline (or a workalike): # To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE=1 LDFLAGS.readline ?= -lreadline # these vary across platforms @@ -1410,8 +1410,8 @@ all: lib # Dynamic libsqlite3 # $(libsqlite3.SO): $(LIBOBJ) - $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.soname.libsqlite3) \ - $(LDFLAGS.libsqlite3) $(LDFLAGS.libsqlite3.soname) + $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.libsqlite3) \ + $(LDFLAGS.libsqlite3.soname) $(libsqlite3.SO)-1: $(libsqlite3.SO) $(libsqlite3.SO)-0 $(libsqlite3.SO)-: so: $(libsqlite3.SO)-$(ENABLE_SHARED) diff --git a/manifest b/manifest index a1f3f97ae3..2232f78938 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sissue\sin\sargument\sexpansion\son\sWindows\sfor\stclsqlite3.c\sin\ninterpreter\smode.\s\sProblem\sintroduced\sby\scheck-in\s[9b87ea219bce5689]\sand\nunfixed\sby\s[cd942dce148c9d8f]. -D 2024-11-22T17:41:00.227 +C Correct\sduplicated\ssoname\slinker\sflags,\sone\sof\sthem\smis-named. +D 2024-11-25T17:07:58.248 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 01e9b77600f8551df7f970075c09ad9e1898bf2adf512cb861d24b30fb1e6f52 +F main.mk 1ec3c7a81198397b14bf75c9304f01e891a5d464797cd402d4f3781feadd3331 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3d6ae13805bdba4c73b7443f20073264cdd157299cb911228600e1528a136bb1 -R f112fd2beffd3eb814301c3676676b3e -U drh -Z 113c5b5aab1719624bc6c7ebe0ae9b2d +P 0fe1622cec95b7ebecc127ee57a08113d3da1dadbe72c03a13d6751b3043e50f +R 24cbca38f84059cbe901864cddc225cb +U stephan +Z 31635988b0bdb23e0fcab35446e8136f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8cd2bbe8d4..7f2309db58 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0fe1622cec95b7ebecc127ee57a08113d3da1dadbe72c03a13d6751b3043e50f +87dfd92d3a5a6a09c32c70e724a3f341bc63b9c6dfa0aa94fbbbdd45cc9c29f3 From f2d56bc57867ea8135e51d847b27e3221d99fd62 Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 26 Nov 2024 03:15:34 +0000 Subject: [PATCH 399/522] Replace some outdated docs re. soname with a link to the soname forum post. FossilOrigin-Name: 9225701cb88cb4629a12b45de5743378448b1d2ddb351916b77cfde638698070 --- auto.def | 22 ++-------------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/auto.def b/auto.def index 8fa2584611..b37bcb7f95 100644 --- a/auto.def +++ b/auto.def @@ -460,25 +460,8 @@ if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { proj-check-rpath ; # Determine proper rpath-handling flag ######################################################################## -# It's not yet clear whether we gain anything from setting -soname, -# but not having it has been a source of anxiety for some users. -# Setting it to any value other than its historical value of -# libsqlite3.so.0 may break dynamic linking of clients which initially -# linked against a legacy build (with its SONAME of libsqlite3.so.0). -# -# To be clear: the ABI has not changed between pre-3.48 and post-3.47 -# builds, but version number 0 (pre-3.48) was a historical remnant -# from libtool which "should" have always been version number 3 but -# was not, for reasons lost to history. -# -# If the goal is to reduce downstream disruption then we need to -# retain the SONAME libsqlite3.so.0. If the goal is to "pull the -# bandaid off" then switching libsqlite3.so.3 is arguably the right -# thing to do (at the very real risk of causing a fair amount of -# downstream disruption for package maintainers). -# -# See discussion in/around: -# https://sqlite.org/forum/forumpost/0c6fc6f46b2cb3 +# "soname" for libsqlite3.so. See discussion at: +# https://sqlite.org/src/forumpost/5a3b44f510df8ded apply {{} { define LDFLAGS_LIBSQLITE3_SONAME "" if {[proj-opt-was-provided soname]} { @@ -511,7 +494,6 @@ apply {{} { } }} - proj-define-for-opt shared ENABLE_SHARED "Build shared library?" if {![proj-define-for-opt static ENABLE_STATIC \ diff --git a/manifest b/manifest index 2232f78938..5b41e95747 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sduplicated\ssoname\slinker\sflags,\sone\sof\sthem\smis-named. -D 2024-11-25T17:07:58.248 +C Replace\ssome\soutdated\sdocs\sre.\ssoname\swith\sa\slink\sto\sthe\ssoname\sforum\spost. +D 2024-11-26T03:15:34.735 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 62eaab1eb8bad47950bcb604f2861a498e31e7d536656de67555d83b33bc9b6e +F auto.def 80085dd211b6a71b7d1cc23d182e8a0cce1c5219240b4b1433f86218ca1735ed F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0fe1622cec95b7ebecc127ee57a08113d3da1dadbe72c03a13d6751b3043e50f -R 24cbca38f84059cbe901864cddc225cb +P 87dfd92d3a5a6a09c32c70e724a3f341bc63b9c6dfa0aa94fbbbdd45cc9c29f3 +R f92d2e5c227f7cb85aa09c937d9a97c7 U stephan -Z 31635988b0bdb23e0fcab35446e8136f +Z 7ab9f4332ba4301187d6dc14d812546d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7f2309db58..7cbd49f00c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87dfd92d3a5a6a09c32c70e724a3f341bc63b9c6dfa0aa94fbbbdd45cc9c29f3 +9225701cb88cb4629a12b45de5743378448b1d2ddb351916b77cfde638698070 From 0dd542f79e7452689312f4e69a1d88befba38a90 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 26 Nov 2024 16:04:02 +0000 Subject: [PATCH 400/522] Minor tweak to ./configure --help output. FossilOrigin-Name: 7e634d0569667ce1e17f4a611039cbb726078dc2e6be1f1b19655dc569170ce5 --- auto.def | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index b37bcb7f95..efdac7036a 100644 --- a/auto.def +++ b/auto.def @@ -149,7 +149,7 @@ set flags { # --with-tcl=DIR may be either a dir containing tclConfig.sh or a # dir one level up from that from which we can derive a dir # containing tclConfig.sh. - with-tcl: => {Root of path containing tclConfig.sh} + with-tcl:DIR => {Directory containing tclConfig.sh} # If --with-tclsh=X given, it is used for (A) trying to find # tclConfig.sh and (B) all TCL-based code generation. Warning: if # its containing dir has multiple tclsh versions, it may select the diff --git a/manifest b/manifest index 5b41e95747..0bfa840b55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\ssome\soutdated\sdocs\sre.\ssoname\swith\sa\slink\sto\sthe\ssoname\sforum\spost. -D 2024-11-26T03:15:34.735 +C Minor\stweak\sto\s./configure\s--help\soutput. +D 2024-11-26T16:04:02.500 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 80085dd211b6a71b7d1cc23d182e8a0cce1c5219240b4b1433f86218ca1735ed +F auto.def 4fa9375aac42aa422e1852ccd8218a275212db6ef3182bb666eb2874d8af3898 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 87dfd92d3a5a6a09c32c70e724a3f341bc63b9c6dfa0aa94fbbbdd45cc9c29f3 -R f92d2e5c227f7cb85aa09c937d9a97c7 -U stephan -Z 7ab9f4332ba4301187d6dc14d812546d +P 9225701cb88cb4629a12b45de5743378448b1d2ddb351916b77cfde638698070 +R 1fd1cba45dac3cc717428822f5c6efda +U drh +Z a193b2ce84a7cd5ee03073da19cb5fbf # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7cbd49f00c..3d8eca1a44 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9225701cb88cb4629a12b45de5743378448b1d2ddb351916b77cfde638698070 +7e634d0569667ce1e17f4a611039cbb726078dc2e6be1f1b19655dc569170ce5 From 04a556acf2807ed97c93a3bccc6eb71f2c7a7d5e Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 26 Nov 2024 16:12:05 +0000 Subject: [PATCH 401/522] Move some of the in-comment configure script help text into the --help text. No functional changes. FossilOrigin-Name: ee8449c482b6f9cfb82fa2417da194fc9aa56f54ef3ac83d368537181634ab1c --- auto.def | 41 ++++++++++++++++++++++------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/auto.def b/auto.def index efdac7036a..6b315f27f2 100644 --- a/auto.def +++ b/auto.def @@ -122,6 +122,10 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # ######################################################################## set flags { + # When writing {help text blocks}, be aware that autosetup formats + # them differently (left-aligned, under the --flag, if the block + # starts with a newline. + # shared=1 => {Disable build of shared libary} static=1 => {Disable build of static library (mostly)} @@ -146,20 +150,19 @@ set flags { all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions} # # - # --with-tcl=DIR may be either a dir containing tclConfig.sh or a - # dir one level up from that from which we can derive a dir - # containing tclConfig.sh. - with-tcl:DIR => {Directory containing tclConfig.sh} - # If --with-tclsh=X given, it is used for (A) trying to find - # tclConfig.sh and (B) all TCL-based code generation. Warning: if - # its containing dir has multiple tclsh versions, it may select the - # wrong tclConfig.sh! - with-tclsh:PATH => {Full pathname of tclsh to use} - # --disable-tcl disables building of components which require TCL, - # including tests. This tree requires TCL for code generation but - # can use the in-tree copy of autosetup/jimsh0.c for that. The - # SQLite TCL extension and the test code require a canonical tclsh. - tcl=1 => {Disable components which require TCL} + with-tcl:DIR => + {Directory containing tclConfig.sh or a directory one level up from + that, from which we can derive a directory containing tclConfig.sh.} + with-tclsh:PATH => + {Full pathname of tclsh to use. It is used for (A) trying to find + tclConfig.sh and (B) all TCL-based code generation. Warning: if + its containing dir has multiple tclsh versions, it may select the + wrong tclConfig.sh!} + tcl=1 => + {Disable components which require TCL, including all tests. + This tree requires TCL for code generation but can use the in-tree + copy of autosetup/jimsh0.c for that. The SQLite TCL extension and the + test code require a canonical tclsh.} # # readline=1 => {Disable readline support} @@ -192,11 +195,11 @@ set flags { with-emsdk:=auto => {Top-most dir of the Emscripten SDK installation. Default = EMSDK env var.} # # - with-debug:=1 => {Enable debug build flags. --with-debug does more - than simply builds with a -g compilation flag and will impact - performance by as much as 4x, as it includes large numbers of - assert()s in performance-critical loops. Never use --with-debug - for production builds.} + with-debug:=1 => + {Enable debug build flags. This option will impact performance by + as much as 4x, as it includes large numbers of assert()s in + performance-critical loops. Never use --with-debug for production + builds.} scanstatus => {Enable the SQLITE_ENABLE_STMT_SCANSTATUS feature flag} dev => {Enable dev-mode build: automatically enables certain other flags} test-status => {Enable status of tests} diff --git a/manifest b/manifest index 0bfa840b55..3f8f3a7d8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\stweak\sto\s./configure\s--help\soutput. -D 2024-11-26T16:04:02.500 +C Move\ssome\sof\sthe\sin-comment\sconfigure\sscript\shelp\stext\sinto\sthe\s--help\stext.\sNo\sfunctional\schanges. +D 2024-11-26T16:12:05.631 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 4fa9375aac42aa422e1852ccd8218a275212db6ef3182bb666eb2874d8af3898 +F auto.def cb4d2a6a3809c3c015ad1d1e5a06836697f78e31b38f154cc20a7b0cb350e0d1 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2199,8 +2199,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9225701cb88cb4629a12b45de5743378448b1d2ddb351916b77cfde638698070 -R 1fd1cba45dac3cc717428822f5c6efda -U drh -Z a193b2ce84a7cd5ee03073da19cb5fbf +P 7e634d0569667ce1e17f4a611039cbb726078dc2e6be1f1b19655dc569170ce5 +R b03ff8f40892202b2bfdeabe2bfe4328 +U stephan +Z e952930a3cd549b7813b14b13b6d132c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3d8eca1a44..baa37c3050 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e634d0569667ce1e17f4a611039cbb726078dc2e6be1f1b19655dc569170ce5 +ee8449c482b6f9cfb82fa2417da194fc9aa56f54ef3ac83d368537181634ab1c From 58cb5644bc0ee5a705085328db29416010634cad Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 26 Nov 2024 19:02:16 +0000 Subject: [PATCH 402/522] Patch autosetup to rename --debug to --autosetup-debug so we can use --debug/--enable-debug for its historical purpose. --with-debug is now an alias for --enable-debug but can be removed entirely if all scripts which have been adjusted for the autosetup build are edited to (re)use the older flag name. FossilOrigin-Name: 3296c8d30559eafa20f4748339177149172ecf79b019c42ed0d5ee9cf62a666a --- auto.def | 15 ++++++++++----- autosetup/autosetup | 8 ++++---- manifest | 17 ++++++++++------- manifest.uuid | 2 +- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/auto.def b/auto.def index 6b315f27f2..fc86c58bed 100644 --- a/auto.def +++ b/auto.def @@ -36,7 +36,8 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # # 1) --debug is used by autosetup itself, so we have to rename it to # --with-debug. We cannot use --enable-debug because that is, for -# autosetup, and alias for --debug=1. +# autosetup, and alias for --debug=1. Alternately, we can patch +# autosetup to use --autosetup-debug for its own purposes instead. # # 2) In autosetup, all flags starting with (--enable, --disable) are # forced to be booleans and receive special handling in how they're @@ -195,10 +196,13 @@ set flags { with-emsdk:=auto => {Top-most dir of the Emscripten SDK installation. Default = EMSDK env var.} # # - with-debug:=1 => + # Note that using the --debug/--enable-debug flag here requires patching + # autosetup/autosetup to rename the --debug to --autosetup-debug. + with-debug=0 + debug=0 => {Enable debug build flags. This option will impact performance by as much as 4x, as it includes large numbers of assert()s in - performance-critical loops. Never use --with-debug for production + performance-critical loops. Never use --debug for production builds.} scanstatus => {Enable the SQLITE_ENABLE_STMT_SCANSTATUS feature flag} dev => {Enable dev-mode build: automatically enables certain other flags} @@ -234,6 +238,7 @@ unset flags proj-xfer-options-aliases { with-readline-inc => with-readline-cflags with-readline-lib => with-readline-ldflags + with-debug => debug } set srcdir $::autosetup(srcdir) @@ -339,7 +344,7 @@ proj-if-opt-truthy dev { # which check for these flags will show the user their updated # state. proj-opt-set all 1 - proj-opt-set with-debug 1 + proj-opt-set debug 1 proj-opt-set amalgamation 0 define CFLAGS [get-env CFLAGS {-O0 -g}] } @@ -515,7 +520,7 @@ proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \ "Use #line macros in the amalgamation:" msg-checking "SQLITE_DEBUG build? " -proj-if-opt-truthy with-debug { +proj-if-opt-truthy debug { define SQLITE_DEBUG 1 define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} msg-result yes diff --git a/autosetup/autosetup b/autosetup/autosetup index 90f5454b5f..1479fca407 100755 --- a/autosetup/autosetup +++ b/autosetup/autosetup @@ -9,7 +9,7 @@ dir=`dirname "$0"`; exec "`$dir/autosetup-find-tclsh`" "$0" "$@" set autosetup(version) 0.7.2 # Can be set to 1 to debug early-init problems -set autosetup(debug) [expr {"--debug" in $argv}] +set autosetup(debug) [expr {"--autosetup-debug" in $argv}] ################################################################## # @@ -98,7 +98,7 @@ proc main {argv} { version => "display the version of autosetup" ref:=text manual:=text reference:=text => "display the autosetup command reference. 'text', 'wiki', 'asciidoc' or 'markdown'" - debug => "display debugging output as autosetup runs" + autosetup-debug => "display debugging output as autosetup runs" install:=. => "install autosetup to the current or given directory" } if {$autosetup(installed)} { @@ -132,7 +132,7 @@ proc main {argv} { } # Debugging output (set this early) - incr autosetup(debug) [opt-bool debug] + incr autosetup(debug) [opt-bool autosetup-debug] incr autosetup(force) [opt-bool force] incr autosetup(msg-quiet) [opt-bool quiet] incr autosetup(msg-timing) [opt-bool timing] @@ -2530,7 +2530,7 @@ if {[catch {main $argv} msg opts] == 1} { show-notices autosetup-full-error [error-dump $msg $opts $autosetup(debug)] if {!$autosetup(debug)} { - puts stderr "Try: '[file tail $autosetup(exe)] --debug' for a full stack trace" + puts stderr "Try: '[file tail $autosetup(exe)] --autosetup-debug' for a full stack trace" } exit 1 } diff --git a/manifest b/manifest index 3f8f3a7d8d..c94527c6e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\ssome\sof\sthe\sin-comment\sconfigure\sscript\shelp\stext\sinto\sthe\s--help\stext.\sNo\sfunctional\schanges. -D 2024-11-26T16:12:05.631 +C Patch\sautosetup\sto\srename\s--debug\sto\s--autosetup-debug\sso\swe\scan\suse\s--debug/--enable-debug\sfor\sits\shistorical\spurpose.\s--with-debug\sis\snow\san\salias\sfor\s--enable-debug\sbut\scan\sbe\sremoved\sentirely\sif\sall\sscripts\swhich\shave\sbeen\sadjusted\sfor\sthe\sautosetup\sbuild\sare\sedited\sto\s(re)use\sthe\solder\sflag\sname. +D 2024-11-26T19:02:16.005 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def cb4d2a6a3809c3c015ad1d1e5a06836697f78e31b38f154cc20a7b0cb350e0d1 +F auto.def 961d2cf22b65d31f9eb97470b50cbbdca34b999cf86f438811c1ec214b296b8b F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -38,7 +38,7 @@ F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f041 F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e F autosetup/README.md f12fd1556b50ff33ebf5c1476f4640c6010b3093ba8d75ba12b5417884011d5e -F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x +F autosetup/autosetup df8b53928b1fe3c67db5bc77c8e1eb8160c1b6a26c370e9a06c68748f803b7e4 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x F autosetup/autosetup-find-tclsh 25905f6c302959db80c2951aa267b4411c5645b598ce761cfc24a166141e2c4c x @@ -2199,8 +2199,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7e634d0569667ce1e17f4a611039cbb726078dc2e6be1f1b19655dc569170ce5 -R b03ff8f40892202b2bfdeabe2bfe4328 +P ee8449c482b6f9cfb82fa2417da194fc9aa56f54ef3ac83d368537181634ab1c +R c2ee4fc9d127d16a71ba8ab0982dbb79 +T *branch * autosetup-debug-flag +T *sym-autosetup-debug-flag * +T -sym-trunk * Cancelled\sby\sbranch. U stephan -Z e952930a3cd549b7813b14b13b6d132c +Z 4f1cf71b215a7b4b77a2398c83036d85 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index baa37c3050..9aee3d801f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee8449c482b6f9cfb82fa2417da194fc9aa56f54ef3ac83d368537181634ab1c +3296c8d30559eafa20f4748339177149172ecf79b019c42ed0d5ee9cf62a666a From e2a3c7232b061e03b05ac4d891737d57a77dd030 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Nov 2024 20:16:34 +0000 Subject: [PATCH 403/522] Update documentation in fts5.h. FossilOrigin-Name: f1e44f703acb415e2ff7d7f87fa05fc874ef1c432095bb3ccb45c6ad2fd085a9 --- ext/fts5/fts5.h | 19 ++++++++++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index 5305a6915d..6c4d238959 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -306,8 +306,25 @@ struct Fts5PhraseIter { ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** ** This API can be quite slow if used with an FTS5 table created with the -** "detail=none" or "detail=column" option. +** "detail=none" or "detail=column" option. ** ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) ** If parameter iCol is less than zero, or greater than or equal to the diff --git a/manifest b/manifest index 75828653be..8dfeec1334 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\swarnings\scaused\sby\svariable\sshadowing. -D 2024-11-20T20:39:18.431 +C Update\sdocumentation\sin\sfts5.h. +D 2024-11-26T20:16:34.989 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -106,7 +106,7 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl 63db9624ccf70d4887836c320eda93ab552f21008f3be7ede551eac3ead62baa F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15 -F ext/fts5/fts5.h 6b4b92df890965567360db5f1ead24fd13a72cb23b95e4ed2ff58d1d89f7aa42 +F ext/fts5/fts5.h df1741b4dbf8446f663ba30ce6eca51ef1cef0dbc481806273fc8a0cc159f4b8 F ext/fts5/fts5Int.h 6abff7dd770dc5969c994c281e6e77fc277ce414d56cc4a62c145cc7036b0b67 F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P edb842349320eda9550bdfcd5a327949c5512e02f4b993782587b2131a425746 -R 87e3d58f4f7440e00e0a55bcb770c2ab +P 211b305791980b24c4192ffc57a0471473de3fca32bfc146c0eeacedef7a88aa +R ce521c664e19e9b02f777e0b20a87e4f U dan -Z e1bc2b76da9d8c387af12aec8bd8d459 +Z 1b49bcb3c99dc54eba71f1872e2bcc4a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 259f7f2dfa..5bd79817a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -211b305791980b24c4192ffc57a0471473de3fca32bfc146c0eeacedef7a88aa +f1e44f703acb415e2ff7d7f87fa05fc874ef1c432095bb3ccb45c6ad2fd085a9 From f12e5d1a0f8376289a2e6447b91a07bd7a4850da Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 26 Nov 2024 20:56:03 +0000 Subject: [PATCH 404/522] Provide a two-argument version of the iif() function, plus an alternative spelling that only requires a single "i". FossilOrigin-Name: a251ee645e11e24b67473d8a5bd3f8b72fde1ac9d5fda074f5da2297deb2faa8 --- manifest | 20 +++++++++++--------- manifest.uuid | 2 +- src/func.c | 3 +++ test/e_expr.test | 15 ++++++++++++--- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 229dfdc3aa..5b9a043667 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sfts5\sso\sthat\sthe\sxInstToken()\sextension\sAPI\sworks\swith\sprefix\squeries. -D 2024-11-26T20:46:18.270 +C Provide\sa\stwo-argument\sversion\sof\sthe\siif()\sfunction,\splus\san\salternative\nspelling\sthat\sonly\srequires\sa\ssingle\s"i". +D 2024-11-26T20:56:03.273 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -729,7 +729,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c a9d9f5fdfbdd3b2c94d7af1b11f181464b8a641736cf32cb92fa3c5e7ecb30df F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f -F src/func.c fa138d44348e189817542f6efa6232420b3e0081c835ced65883adc7fd777d65 +F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 @@ -1102,7 +1102,7 @@ F test/e_createtable.test 31b9bcb6ac8876bc7ec342d86d9c231a84c62b442093a6651dfd0f F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7 -F test/e_expr.test b950818a48269506d75a41c819003bd77a0893bc4a4f2fdee191bc74109c1a87 +F test/e_expr.test 4faef475076f676e2a009270dbd3a7658db30d12dc3d21e4b85cab5f50be18c5 F test/e_fkey.test feeba6238aeff9d809fb6236b351da8df4ae9bda89e088e54526b31a0cbfeec5 F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e @@ -2201,9 +2201,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 00dffd10f0c77fed53bdbf1536f6ef9b6076775f1b9a10794b87e3ace33ca1d9 f1e44f703acb415e2ff7d7f87fa05fc874ef1c432095bb3ccb45c6ad2fd085a9 -R 602e6f17d656c7098c104c9738f971e9 -T +closed f1e44f703acb415e2ff7d7f87fa05fc874ef1c432095bb3ccb45c6ad2fd085a9 -U dan -Z 2fe59ff619562212dac3a249eb517d01 +P 41b79bde4a4b6510b41cc9175ff2527fbd3ca9209812361783754f24cf67ef9e +R 95cdbd2d905cbccddf7c07f68d5125cd +T *branch * two-argument-iif +T *sym-two-argument-iif * +T -sym-trunk * +U drh +Z 4fbc11636a3ec850ec89d3d2892ea5e5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 60ed7fd51d..cd297ba8a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41b79bde4a4b6510b41cc9175ff2527fbd3ca9209812361783754f24cf67ef9e +a251ee645e11e24b67473d8a5bd3f8b72fde1ac9d5fda074f5da2297deb2faa8 diff --git a/src/func.c b/src/func.c index 419ce24c62..2d25803e0d 100644 --- a/src/func.c +++ b/src/func.c @@ -2814,7 +2814,10 @@ void sqlite3RegisterBuiltinFunctions(void){ #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ FUNCTION(sign, 1, 0, 0, signFunc ), INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), + INLINE_FUNC(iif, 2, INLINEFUNC_iif, 0 ), INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), + INLINE_FUNC(if, 2, INLINEFUNC_iif, 0 ), + INLINE_FUNC(if, 3, INLINEFUNC_iif, 0 ), }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); diff --git a/test/e_expr.test b/test/e_expr.test index 0db63a8ac4..6e2b649796 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1232,12 +1232,18 @@ db nullvalue {} # EVIDENCE-OF: R-13943-13592 A NULL result is considered untrue when # evaluating WHEN terms. # -do_execsql_test e_expr-21.4.1 { +do_execsql_test e_expr-21.4.1a { SELECT CASE WHEN NULL THEN 'A' WHEN 1 THEN 'B' END, iif(NULL,8,99); } {B 99} -do_execsql_test e_expr-21.4.2 { +do_execsql_test e_expr-21.4.1b { + SELECT CASE WHEN NULL THEN 'A' WHEN 1 THEN 'B' END, if(NULL,8,99); +} {B 99} +do_execsql_test e_expr-21.4.2a { SELECT CASE WHEN 0 THEN 'A' WHEN NULL THEN 'B' ELSE 'C' END, iif(0,8,99); } {C 99} +do_execsql_test e_expr-21.4.2b { + SELECT CASE WHEN 0 THEN 'A' WHEN NULL THEN 'B' ELSE 'C' END, if(0,8,99); +} {C 99} # EVIDENCE-OF: R-38620-19499 In a CASE with a base expression, the base # expression is evaluated just once and the result is compared against @@ -1969,9 +1975,12 @@ do_execsql_test e_expr-37.5 { # EVIDENCE-OF: R-55532-10108 Values 1, 1.0, 0.1, -0.1 and '1english' are # considered to be true. # -do_execsql_test e_expr-37.6 { +do_execsql_test e_expr-37.6a { SELECT CASE WHEN 1 THEN 'true' ELSE 'false' END, iif(1,'true','false'); } {true true} +do_execsql_test e_expr-37.6b { + SELECT CASE WHEN 1 THEN 'true' ELSE 'false' END, if(1,'true'); +} {true true} do_execsql_test e_expr-37.7 { SELECT CASE WHEN 1.0 THEN 'true' ELSE 'false' END, iif(1.0,'true','false'); } {true true} From 966a158831cbfc3f5451736959fbbcf91b960c2b Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 26 Nov 2024 23:30:49 +0000 Subject: [PATCH 405/522] New test cases. FossilOrigin-Name: f1cb1a815a09d71eb52d5c7f2f4e5c7689535232dee365e46ac41cce7fd86c01 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- test/json102.test | 24 ++++++++++++++++++++++++ test/subtype1.test | 10 ++++++++++ 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 5b9a043667..39768dacac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Provide\sa\stwo-argument\sversion\sof\sthe\siif()\sfunction,\splus\san\salternative\nspelling\sthat\sonly\srequires\sa\ssingle\s"i". -D 2024-11-26T20:56:03.273 +C New\stest\scases. +D 2024-11-26T23:30:49.285 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1380,7 +1380,7 @@ F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb9 F test/json/json-speed-check.sh 912ee03e700a65c827ee0c7b4752c21ec5ef69cf7679d2f482ca817042bead52 x F test/json/jsonb-q1.txt 1e180fe6491efab307e318b22879e3a736ac9a96539bbde7911a13ee5b33abc7 F test/json101.test 30db5b055b103ccabc53a29cfe6cda3345d07e171aeb25403dafa04f19e98b19 -F test/json102.test 4b3a0f94535f033239b67c13dbee8b47d2b5ee467e0f2fdab5eadf370bbe5fd3 +F test/json102.test 9b2e5ada10845ff84853b3feaae2ce51ce7145ae458f74c6a6cecc6ef6ee3ae1 F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1 F test/json105.test 043838b56e68f3252a0dcf5be1689016f6f3f05056f8dcfcdc9d074f4d932988 @@ -1697,7 +1697,7 @@ F test/subquery.test 903abf41049f8404256f7be24b3151328304a5b25162e17ab0079460237 F test/subquery2.test 90cf944b9de8204569cf656028391e4af1ccc8c0cc02d4ef38ee3be8de1ffb12 F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303 F test/substr.test a673e3763e247e9b5e497a6cacbaf3da2bd8ec8921c0677145c109f2e633f36b -F test/subtype1.test 7a9c55ed84d4ce551203d18046f925e293d75f69da81bff71aaf2696e4a2a748 +F test/subtype1.test 96fd2a59bfc845c955b5f339d23b37ef4d50de5f8a04acd1450a68605fa2e3e7 F test/superlock.test 85256830339a6871ce36a2ef591c3f67716a701b5497788fb2068b90159c2442 F test/swarmvtab.test 250231404fcac88f61a6c147bb0e3a118ed879278cd3ccb0ae2d3a729e1e8e26 F test/swarmvtab2.test c948cb2fdfc5b01d85e8f6d6504854202dc1a0782ab2a0ed61538f27cbd0aa5c @@ -2201,11 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 41b79bde4a4b6510b41cc9175ff2527fbd3ca9209812361783754f24cf67ef9e -R 95cdbd2d905cbccddf7c07f68d5125cd -T *branch * two-argument-iif -T *sym-two-argument-iif * -T -sym-trunk * +P a251ee645e11e24b67473d8a5bd3f8b72fde1ac9d5fda074f5da2297deb2faa8 +R 824c1bcdb1f9c6fee7135023d460cb90 U drh -Z 4fbc11636a3ec850ec89d3d2892ea5e5 +Z ccd3808eb790ff48c86b29439b672954 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cd297ba8a5..fb01172fbb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a251ee645e11e24b67473d8a5bd3f8b72fde1ac9d5fda074f5da2297deb2faa8 +f1cb1a815a09d71eb52d5c7f2f4e5c7689535232dee365e46ac41cce7fd86c01 diff --git a/test/json102.test b/test/json102.test index 1a00cb67ae..54a0e1e0e0 100644 --- a/test/json102.test +++ b/test/json102.test @@ -745,6 +745,30 @@ do_execsql_test json102-1610 { 5 {{"b":9}} json {{"b":9}} text {{"b":9}} json \ 6 {} null {} null {} null ] +do_execsql_test json102-1620 { + DELETE FROM t1; + INSERT INTO t1(x) VALUES('[null,123,4.5,"six",[7,8],{"b":9}]'); + WITH c(y) AS (VALUES(0),(1),(2),(3),(4),(5),(6)) + SELECT + y, + x->y AS '->', + CASE WHEN subtype(if(json_valid(x),x->y)) THEN 'json' + ELSE typeof(x->y) END AS 'type', + x->>y AS '->>', + CASE WHEN subtype(x->>y) THEN 'json' ELSE typeof(x->>y) END AS 'type', + json_extract(x,format('$[%d]',y)) AS 'json_extract', + CASE WHEN subtype(json_extract(x,format('$[%d]',y))) + THEN 'json' ELSE typeof(json_extract(x,format('$[%d]',y))) END AS 'type' + FROM c, t1 ORDER BY y; +} [list \ + 0 null json {} null {} null \ + 1 123 json 123 integer 123 integer \ + 2 4.5 json 4.5 real 4.5 real \ + 3 {"six"} json six text six text \ + 4 {[7,8]} json {[7,8]} text {[7,8]} json \ + 5 {{"b":9}} json {{"b":9}} text {{"b":9}} json \ + 6 {} null {} null {} null +] reset_db do_execsql_test json102-1700 { diff --git a/test/subtype1.test b/test/subtype1.test index 4d8e68e6af..6d0df4fa6b 100644 --- a/test/subtype1.test +++ b/test/subtype1.test @@ -73,5 +73,15 @@ do_execsql_test subtype1-320 { WHERE json_quote(y)='"1"'; } {1 {"1"}} +# 2024-11-26 +# subtype survives if() +# +do_execsql_test subtype1-400 { + WITH t400(id,j) AS (VALUES + (1,'{a:{x:1,y:2},b:{x:3,y:4}}'), + (2,'not json') + ) + SELECT id, subtype(if(json_valid(j,6),j->'a')) FROM t400; +} {1 74 2 0} finish_test From 0bce1d6c9fa87c5bdcbe1779deef0692ff629e4e Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 27 Nov 2024 18:01:25 +0000 Subject: [PATCH 406/522] Fix an inaccuracy in the documentation in fts5.h. FossilOrigin-Name: ec3ca6f17972a9624018ae352e5a4be8dc34602a4569c80e827e09cd7fbed7f7 --- ext/fts5/fts5.h | 4 +--- manifest | 15 +++++++-------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index 6c4d238959..907ea232a4 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -298,9 +298,7 @@ struct Fts5PhraseIter { ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, ** output variable (*ppToken) is set to point to a buffer containing the ** matching document token, and (*pnToken) to the size of that buffer in -** bytes. This API is not available if the specified token matches a -** prefix query term. In that case both output variables are always set -** to 0. +** bytes. ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this diff --git a/manifest b/manifest index b0e612caa9..2c47dca7a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\siif()\sfunction\sto\swork\swith\stwo\sarguments.\s\sThe\sthird\sargument\sis\nthen\sassumed\sto\sbe\sNULL.\s\sAlso\sallow\sif()\sas\san\salternative\sspelling\sfor\siif(). -D 2024-11-26T23:40:54.327 +C Fix\san\sinaccuracy\sin\sthe\sdocumentation\sin\sfts5.h. +D 2024-11-27T18:01:25.186 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -103,7 +103,7 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl 63db9624ccf70d4887836c320eda93ab552f21008f3be7ede551eac3ead62baa F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15 -F ext/fts5/fts5.h df1741b4dbf8446f663ba30ce6eca51ef1cef0dbc481806273fc8a0cc159f4b8 +F ext/fts5/fts5.h ff5d3cc88b29e41612bfb29eb723e29e38973de62ca75ba3e8f94ccb67f5b5f2 F ext/fts5/fts5Int.h 6abff7dd770dc5969c994c281e6e77fc277ce414d56cc4a62c145cc7036b0b67 F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 @@ -2201,9 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 41b79bde4a4b6510b41cc9175ff2527fbd3ca9209812361783754f24cf67ef9e f1cb1a815a09d71eb52d5c7f2f4e5c7689535232dee365e46ac41cce7fd86c01 -R 824c1bcdb1f9c6fee7135023d460cb90 -T +closed f1cb1a815a09d71eb52d5c7f2f4e5c7689535232dee365e46ac41cce7fd86c01 -U drh -Z f391a3d677bdf348a89a60afcfdaaa8e +P 1e405c39a8405e2081ce061559d1aacc70055fc74ab86d886b973076a3fb124b +R 306a37bedf7a72c95bbfd16141af1dca +U dan +Z 0f8994542e0c6b090d32b7bcc99e7877 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6f170f7b2f..2abc82dd83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e405c39a8405e2081ce061559d1aacc70055fc74ab86d886b973076a3fb124b +ec3ca6f17972a9624018ae352e5a4be8dc34602a4569c80e827e09cd7fbed7f7 From 60ad5266394ae6b5fe879618eaf81a42df081188 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 28 Nov 2024 00:34:20 +0000 Subject: [PATCH 407/522] Enhancements to sqlite3ExprImpliesExpr() so that it realizes that "iif(A,B)" implies "A". FossilOrigin-Name: d96ecbee59b50eca25447456dfff2c168e8eade7a68e542932d5829f97debb31 --- manifest | 19 ++++++----- manifest.uuid | 2 +- src/expr.c | 90 ++++++++++++++++++++++++++++++++++++++++----------- src/where.c | 1 - 4 files changed, 83 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 2c47dca7a7..a34db27f4e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sinaccuracy\sin\sthe\sdocumentation\sin\sfts5.h. -D 2024-11-27T18:01:25.186 +C Enhancements\sto\ssqlite3ExprImpliesExpr()\sso\sthat\sit\srealizes\sthat\n"iif(A,B)"\simplies\s"A". +D 2024-11-28T00:34:20.169 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -726,7 +726,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c a9d9f5fdfbdd3b2c94d7af1b11f181464b8a641736cf32cb92fa3c5e7ecb30df +F src/expr.c bc1e0266dfd88c996e509550220b74b46c7654b0818909adba8ba8227452cd3e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 @@ -860,7 +860,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 8b7e309a8012659ac9275ad8cdcc6acaf73fa04b1090e38a01335f230fd10681 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c 504d72098437ab97dfd3a71cea85e554381650f9dffde277c66603f3e34daddc +F src/where.c b34adb09fdb2a4f57a0bafd4194b501047ef383976fef9f0ac3f395f4881694d F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca F src/wherecode.c 0c3d3199a2b769a5e2bb70feb5003dc85b3d86842ecaf903a47f2b4205ca5dab F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f @@ -2201,8 +2201,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1e405c39a8405e2081ce061559d1aacc70055fc74ab86d886b973076a3fb124b -R 306a37bedf7a72c95bbfd16141af1dca -U dan -Z 0f8994542e0c6b090d32b7bcc99e7877 +P ec3ca6f17972a9624018ae352e5a4be8dc34602a4569c80e827e09cd7fbed7f7 +R 7e7059a06e37f0bd3101b74065b6331a +T *branch * expr-implies-expr +T *sym-expr-implies-expr * +T -sym-trunk * +U drh +Z 9da80189eab742fa7806914a5f17a037 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2abc82dd83..f8884a526d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec3ca6f17972a9624018ae352e5a4be8dc34602a4569c80e827e09cd7fbed7f7 +d96ecbee59b50eca25447456dfff2c168e8eade7a68e542932d5829f97debb31 diff --git a/src/expr.c b/src/expr.c index cc915987dd..68cb60012d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -6180,16 +6180,20 @@ void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){ ** same as that currently bound to variable pVar, non-zero is returned. ** Otherwise, if the values are not the same or if pExpr is not a simple ** SQL value, zero is returned. +** +** If the SQLITE_EnableQPSG flag is set on the database connection, then +** this routine always returns false. */ -static int exprCompareVariable( +static SQLITE_NOINLINE int exprCompareVariable( const Parse *pParse, const Expr *pVar, const Expr *pExpr ){ - int res = 0; + int res = 2; int iVar; sqlite3_value *pL, *pR = 0; + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2; sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); if( pR ){ iVar = pVar->iColumn; @@ -6199,12 +6203,11 @@ static int exprCompareVariable( if( sqlite3_value_type(pL)==SQLITE_TEXT ){ sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */ } - res = 0==sqlite3MemCompare(pL, pR, 0); + res = sqlite3MemCompare(pL, pR, 0) ? 2 : 0; } sqlite3ValueFree(pR); sqlite3ValueFree(pL); } - return res; } @@ -6230,12 +6233,10 @@ static int exprCompareVariable( ** just might result in some slightly slower code. But returning ** an incorrect 0 or 1 could lead to a malfunction. ** -** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in -** pParse->pReprepare can be matched against literals in pB. The -** pParse->pVdbe->expmask bitmask is updated for each variable referenced. -** If pParse is NULL (the normal case) then any TK_VARIABLE term in -** Argument pParse should normally be NULL. If it is not NULL and pA or -** pB causes a return value of 2. +** If pParse is not NULL and SQLITE_EnableQPSG is off then TK_VARIABLE +** terms in pA with bindings in pParse->pReprepare can be matched against +** literals in pB. The pParse->pVdbe->expmask bitmask is updated for +** each variable referenced. */ int sqlite3ExprCompare( const Parse *pParse, @@ -6247,8 +6248,8 @@ int sqlite3ExprCompare( if( pA==0 || pB==0 ){ return pB==pA ? 0 : 2; } - if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){ - return 0; + if( pParse && pA->op==TK_VARIABLE ){ + return exprCompareVariable(pParse, pA, pB); } combinedFlags = pA->flags | pB->flags; if( combinedFlags & EP_IntValue ){ @@ -6443,18 +6444,66 @@ static int exprImpliesNotNull( return 0; } +/* +** Return true if the boolean value of the expression is always either +** FALSE or NULL. +*/ +static int sqlite3ExprIsNotTrue(Expr *pExpr){ + int v; + if( pExpr->op==TK_NULL ) return 1; + if( pExpr->op==TK_TRUEFALSE && sqlite3ExprTruthValue(pExpr)==0 ) return 1; + v = 1; + if( sqlite3ExprIsInteger(pExpr, &v, 0) && v==0 ) return 1; + return 0; +} + +/* +** Return true if the expression is one of the following: +** +** CASE WHEN x THEN y END +** CASE WHEN x THEN y ELSE NULL END +** CASE WHEN x THEN y ELSE false END +** iif(x,y) +** iif(x,y,NULL) +** iif(x,y,false) +*/ +static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){ + ExprList *pList; + if( pExpr->op==TK_FUNCTION ){ + const char *z = pExpr->u.zToken; + FuncDef *pDef; + if( (z[0]!='i' && z[0]!='I') ) return 0; + if( pExpr->x.pList==0 ) return 0; + pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0); + if( pDef==0 ) return 0; + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0; + if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0; + }else if( pExpr->op==TK_CASE ){ + if( pExpr->pLeft!=0 ) return 0; + }else{ + return 0; + } + pList = pExpr->x.pList; + assert( pList!=0 ); + if( pList->nExpr==2 ) return 1; + if( pList->nExpr==3 && sqlite3ExprIsNotTrue(pList->a[2].pExpr) ) return 1; + return 0; +} + /* ** Return true if we can prove the pE2 will always be true if pE1 is ** true. Return false if we cannot complete the proof or if pE2 might ** be false. Examples: ** -** pE1: x==5 pE2: x==5 Result: true -** pE1: x>0 pE2: x==5 Result: false -** pE1: x=21 pE2: x=21 OR y=43 Result: true -** pE1: x!=123 pE2: x IS NOT NULL Result: true -** pE1: x!=?1 pE2: x IS NOT NULL Result: true -** pE1: x IS NULL pE2: x IS NOT NULL Result: false -** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: iif(x,y) pE2: x Result: true +** PE1: iif(x,y,0) pE2: x Result: true ** ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has ** Expr.iTable<0 then assume a table number given by iTab. @@ -6488,6 +6537,9 @@ int sqlite3ExprImpliesExpr( ){ return 1; } + if( sqlite3ExprIsIIF(pParse->db, pE1) ){ + return sqlite3ExprImpliesExpr(pParse,pE1->x.pList->a[0].pExpr,pE2,iTab); + } return 0; } diff --git a/src/where.c b/src/where.c index 1315a8cc37..5abb40eced 100644 --- a/src/where.c +++ b/src/where.c @@ -3564,7 +3564,6 @@ static int whereUsablePartialIndex( if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } - if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ Expr *pExpr; pExpr = pTerm->pExpr; From bfb7f77a8cbad0958abd2e436431d46b345609bb Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 28 Nov 2024 00:58:37 +0000 Subject: [PATCH 408/522] Add two NEVER() conditions. FossilOrigin-Name: 4f358ad20dc8a45e7aaa1a1996b40abd39caf34be6556ed54e1e0c80572b7ac0 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/expr.c | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index a34db27f4e..142c278cbf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\ssqlite3ExprImpliesExpr()\sso\sthat\sit\srealizes\sthat\n"iif(A,B)"\simplies\s"A". -D 2024-11-28T00:34:20.169 +C Add\stwo\sNEVER()\sconditions. +D 2024-11-28T00:58:37.403 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -726,7 +726,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c bc1e0266dfd88c996e509550220b74b46c7654b0818909adba8ba8227452cd3e +F src/expr.c 9084ade243ef14259986230a5f3599459eaf7cf200b87b5fe8dc29187cdcde2c F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 @@ -2201,11 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ec3ca6f17972a9624018ae352e5a4be8dc34602a4569c80e827e09cd7fbed7f7 -R 7e7059a06e37f0bd3101b74065b6331a -T *branch * expr-implies-expr -T *sym-expr-implies-expr * -T -sym-trunk * +P d96ecbee59b50eca25447456dfff2c168e8eade7a68e542932d5829f97debb31 +R c1720db3ecd4ced84ca8ae6628cd5f49 U drh -Z 9da80189eab742fa7806914a5f17a037 +Z c947295bb77ac6e7f18a91b6b404684e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f8884a526d..59b628059b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d96ecbee59b50eca25447456dfff2c168e8eade7a68e542932d5829f97debb31 +4f358ad20dc8a45e7aaa1a1996b40abd39caf34be6556ed54e1e0c80572b7ac0 diff --git a/src/expr.c b/src/expr.c index 68cb60012d..6c7a93118e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -6475,9 +6475,9 @@ static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){ if( (z[0]!='i' && z[0]!='I') ) return 0; if( pExpr->x.pList==0 ) return 0; pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0); - if( pDef==0 ) return 0; + if( NEVER(pDef==0) ) return 0; if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0; - if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0; + if( NEVER(SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif) ) return 0; }else if( pExpr->op==TK_CASE ){ if( pExpr->pLeft!=0 ) return 0; }else{ From 3ff6aa6e3999a0e9fadbc80926e69e3f2b91ad68 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 28 Nov 2024 01:47:44 +0000 Subject: [PATCH 409/522] The sqlite3ExprCompare() routine should always compare the same variables as equal to one another, regardless of whether or not QPSG is set. FossilOrigin-Name: df95d5209a77c0302e08ea7b1f248646fb2a062ba5beca898678aee0a1d03a3a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 9 +++++++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 142c278cbf..24769f2a3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stwo\sNEVER()\sconditions. -D 2024-11-28T00:58:37.403 +C The\ssqlite3ExprCompare()\sroutine\sshould\salways\scompare\sthe\ssame\svariables\nas\sequal\sto\sone\sanother,\sregardless\sof\swhether\sor\snot\sQPSG\sis\sset. +D 2024-11-28T01:47:44.201 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -726,7 +726,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c 9084ade243ef14259986230a5f3599459eaf7cf200b87b5fe8dc29187cdcde2c +F src/expr.c 4c63e54936581c817ae8016206d166d80984767dcbe8260335d30a3a949b46b8 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d96ecbee59b50eca25447456dfff2c168e8eade7a68e542932d5829f97debb31 -R c1720db3ecd4ced84ca8ae6628cd5f49 +P 4f358ad20dc8a45e7aaa1a1996b40abd39caf34be6556ed54e1e0c80572b7ac0 +R bf789819bbc729d8b5b556765482541d U drh -Z c947295bb77ac6e7f18a91b6b404684e +Z cce72d62fb16414e1a59b528ee955fa0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 59b628059b..f688f406bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4f358ad20dc8a45e7aaa1a1996b40abd39caf34be6556ed54e1e0c80572b7ac0 +df95d5209a77c0302e08ea7b1f248646fb2a062ba5beca898678aee0a1d03a3a diff --git a/src/expr.c b/src/expr.c index 6c7a93118e..709d90fad4 100644 --- a/src/expr.c +++ b/src/expr.c @@ -6193,6 +6193,15 @@ static SQLITE_NOINLINE int exprCompareVariable( int iVar; sqlite3_value *pL, *pR = 0; + if( pExpr->op==TK_VARIABLE ){ + assert( pVar->u.zToken!=0 ); + assert( pExpr->u.zToken!=0 ); + if( pVar->iColumn==pExpr->iColumn + && strcmp(pVar->u.zToken,pExpr->u.zToken)==0 + ){ + return 0; + } + } if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2; sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); if( pR ){ From dc7b94e63f682db6ccda6ae41bf105ce8bbb0a5c Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 28 Nov 2024 02:09:27 +0000 Subject: [PATCH 410/522] Simplification to the fix in the prior check-in. FossilOrigin-Name: f79cb748c9447ca4d2184a24219feb19571eb79870e0bedf14704743a3d5f8b9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 10 ++-------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 24769f2a3d..08329b81dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\ssqlite3ExprCompare()\sroutine\sshould\salways\scompare\sthe\ssame\svariables\nas\sequal\sto\sone\sanother,\sregardless\sof\swhether\sor\snot\sQPSG\sis\sset. -D 2024-11-28T01:47:44.201 +C Simplification\sto\sthe\sfix\sin\sthe\sprior\scheck-in. +D 2024-11-28T02:09:27.502 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -726,7 +726,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c 4c63e54936581c817ae8016206d166d80984767dcbe8260335d30a3a949b46b8 +F src/expr.c b838969c58a38dfedabec18c432204895c7333d7a509a20fa63c39bf92001f0e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4f358ad20dc8a45e7aaa1a1996b40abd39caf34be6556ed54e1e0c80572b7ac0 -R bf789819bbc729d8b5b556765482541d +P df95d5209a77c0302e08ea7b1f248646fb2a062ba5beca898678aee0a1d03a3a +R 2a463ba8c7e54a6e85c2163c1e1ce03b U drh -Z cce72d62fb16414e1a59b528ee955fa0 +Z 5b8128e8d052469f340725fed84274b9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f688f406bf..d656caede7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df95d5209a77c0302e08ea7b1f248646fb2a062ba5beca898678aee0a1d03a3a +f79cb748c9447ca4d2184a24219feb19571eb79870e0bedf14704743a3d5f8b9 diff --git a/src/expr.c b/src/expr.c index 709d90fad4..d0282f7147 100644 --- a/src/expr.c +++ b/src/expr.c @@ -6193,14 +6193,8 @@ static SQLITE_NOINLINE int exprCompareVariable( int iVar; sqlite3_value *pL, *pR = 0; - if( pExpr->op==TK_VARIABLE ){ - assert( pVar->u.zToken!=0 ); - assert( pExpr->u.zToken!=0 ); - if( pVar->iColumn==pExpr->iColumn - && strcmp(pVar->u.zToken,pExpr->u.zToken)==0 - ){ - return 0; - } + if( pExpr->op==TK_VARIABLE && pVar->iColumn==pExpr->iColumn ){ + return 0; } if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2; sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); From fed5234fb324d7b91db24227f844f979f6815ea7 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 28 Nov 2024 15:52:21 +0000 Subject: [PATCH 411/522] ext/icu/README.txt: clean up EOL whitespace and add a mention of the --with-icu-... configure flags available as of version 3.48. FossilOrigin-Name: 4976ac717bec2f2c89d94ac1d9b96afd1da573ba34e3c78637c3937287635e72 --- ext/icu/README.txt | 36 ++++++++++++++++++++---------------- manifest | 15 +++++++-------- manifest.uuid | 2 +- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/ext/icu/README.txt b/ext/icu/README.txt index c3c35a2c6f..40def24662 100644 --- a/ext/icu/README.txt +++ b/ext/icu/README.txt @@ -1,19 +1,18 @@ - This directory contains source code for the SQLite "ICU" extension, an integration of the "International Components for Unicode" library with SQLite. Documentation follows. 1. Features - + 1.1 SQL Scalars upper() and lower() 1.2 Unicode Aware LIKE Operator 1.3 ICU Collation Sequences 1.4 SQL REGEXP Operator - + 2. Compilation and Usage - + 3. Bugs, Problems and Security Issues - + 3.1 The "case_sensitive_like" Pragma 3.2 The SQLITE_MAX_LIKE_PATTERN_LENGTH Macro 3.3 Collation Sequence Security Issue @@ -23,10 +22,10 @@ SQLite. Documentation follows. 1.1 SQL Scalars upper() and lower() - SQLite's built-in implementations of these two functions only + SQLite's built-in implementations of these two functions only provide case mapping for the 26 letters used in the English language. The ICU based functions provided by this extension - provide case mapping, where defined, for the full range of + provide case mapping, where defined, for the full range of unicode characters. ICU provides two types of case mapping, "general" case mapping and @@ -36,7 +35,7 @@ SQLite. Documentation follows. http://www.icu-project.org/userguide/caseMappings.html http://www.icu-project.org/userguide/posix.html#case_mappings - To utilise "general" case mapping, the upper() or lower() scalar + To utilise "general" case mapping, the upper() or lower() scalar functions are invoked with one argument: upper('abc') -> 'ABC' @@ -57,7 +56,7 @@ SQLite. Documentation follows. operator understands case equivalence for the 26 letters of the English language alphabet. The implementation of LIKE included in this extension uses the ICU function u_foldCase() to provide case - independent comparisons for the full range of unicode characters. + independent comparisons for the full range of unicode characters. The U_FOLD_CASE_DEFAULT flag is passed to u_foldCase(), meaning the dotless 'I' character used in the Turkish language is considered @@ -66,9 +65,9 @@ SQLite. Documentation follows. 1.3 ICU Collation Sequences - A special SQL scalar function, icu_load_collation() is provided that + A special SQL scalar function, icu_load_collation() is provided that may be used to register ICU collation sequences with SQLite. It - is always called with exactly two arguments, the ICU locale + is always called with exactly two arguments, the ICU locale identifying the collation sequence to ICU, and the name of the SQLite collation sequence to create. For example, to create an SQLite collation sequence named "turkish" using Turkish language @@ -87,7 +86,7 @@ SQLite. Documentation follows. australian_penpal_name TEXT COLLATE australian, turkish_penpal_name TEXT COLLATE turkish ); - + 1.4 SQL REGEXP Operator This extension provides an implementation of the SQL binary @@ -116,7 +115,7 @@ SQLite. Documentation follows. and use it as a dynamically loadable SQLite extension. To do this using gcc on *nix: - gcc -fPIC -shared icu.c `pkg-config --libs --cflags icu-uc icu-io` \ + gcc -fPIC -shared icu.c `pkg-config --libs --cflags icu-io` \ -o libSqliteIcu.so You may need to add "-I" flags so that gcc can find sqlite3ext.h @@ -124,6 +123,11 @@ SQLite. Documentation follows. loaded into sqlite in the same way as any other dynamically loadable extension. + As of version 3.48, it can be enabled in the canonical build process + by passing one of --with-icu-config or --with-icu-ldflags to the + configure script, optionally together with --enable-icu-collations. + See the configure --help for more details. + 3 BUGS, PROBLEMS AND SECURITY ISSUES @@ -144,13 +148,13 @@ SQLite. Documentation follows. SQLITE_MAX_LIKE_PATTERN_LENGTH macro as the maximum length of a pattern in bytes (irrespective of encoding). The default value is defined in internal header file "limits.h". - - The ICU extension LIKE implementation suffers from the same + + The ICU extension LIKE implementation suffers from the same problem and uses the same solution. However, since the ICU extension code does not include the SQLite file "limits.h", modifying the default value therein does not affect the ICU extension. The default value of SQLITE_MAX_LIKE_PATTERN_LENGTH used by - the ICU extension LIKE operator is 50000, defined in source + the ICU extension LIKE operator is 50000, defined in source file "icu.c". 3.3 Collation Sequence Security diff --git a/manifest b/manifest index 6acd2d5b11..b7f9c03141 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\ssqlite3ExprImpliesExpr()\sso\sthat\sit\srecognizes\sthat\sexpressions\slike\s"iif(X,Y)"\sand\s"CASE\sWHEN\sX\sTHEN\sY\sEND"\simply\sX. -D 2024-11-28T11:52:18.714 +C ext/icu/README.txt:\sclean\sup\sEOL\swhitespace\sand\sadd\sa\smention\sof\sthe\s--with-icu-...\sconfigure\sflags\savailable\sas\sof\sversion\s3.48. +D 2024-11-28T15:52:21.879 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -270,7 +270,7 @@ F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl 135b9e160f8e10211c10c5873d5e8c3eaebd3da9ec56a12ae4db157d4738ffe4 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c -F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 +F ext/icu/README.txt 1f8d76e10d2385fc77914a14ccd99acfbaf68111dfcf26a360ad9063787f57fb F ext/icu/icu.c 9837f4611915baad1edbe38222f3ee7d1b5e118ab16fec9ba603720f72c78b2a F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 F ext/intck/intck1.test f3a3cba14b6aeff145ffa5515546dd22f7510dad91512e519f43b92b56514012 @@ -2201,9 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ec3ca6f17972a9624018ae352e5a4be8dc34602a4569c80e827e09cd7fbed7f7 f79cb748c9447ca4d2184a24219feb19571eb79870e0bedf14704743a3d5f8b9 -R 2a463ba8c7e54a6e85c2163c1e1ce03b -T +closed f79cb748c9447ca4d2184a24219feb19571eb79870e0bedf14704743a3d5f8b9 -U drh -Z d7886908d3bdbdc117a1626da09a8266 +P eb5ac9e5b9a4f9c85a2203107697da14c07c1667037dff672f9d786cea964a37 +R 78a02244626590a5fbc0925d20e4f240 +U stephan +Z fdab33deaf1f469df2a1f2ef0d0eef73 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2b2172d181..cd1048f863 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb5ac9e5b9a4f9c85a2203107697da14c07c1667037dff672f9d786cea964a37 +4976ac717bec2f2c89d94ac1d9b96afd1da573ba34e3c78637c3937287635e72 From 187c115a692aad44703d1ebd6bf6d242d4c4ff53 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 28 Nov 2024 16:14:19 +0000 Subject: [PATCH 412/522] Configure script doc updates and cleanups. Skip check for EMSDK when doing an out-of-tree build, as ext/wasm does not support that build mode. FossilOrigin-Name: 9d2f4148db1641e9bf2989c2b1adf5b9dcb2b123526ecacd063bca208b3c36cf --- auto.def | 207 +++++++++++++++++++++++---------------------- autosetup/proj.tcl | 7 +- manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 119 insertions(+), 111 deletions(-) diff --git a/auto.def b/auto.def index fc86c58bed..9cea6a3dc1 100644 --- a/auto.def +++ b/auto.def @@ -36,14 +36,15 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # # 1) --debug is used by autosetup itself, so we have to rename it to # --with-debug. We cannot use --enable-debug because that is, for -# autosetup, and alias for --debug=1. Alternately, we can patch +# autosetup, an alias for --debug=1. Alternately, we can patch # autosetup to use --autosetup-debug for its own purposes instead. # # 2) In autosetup, all flags starting with (--enable, --disable) are # forced to be booleans and receive special handling in how they're # resolved. Because of that we have to rename: # -# 2.1) --enable-tempstore[=no] to --with-tempstore[=no]. +# 2.1) --enable-tempstore[=no] to --with-tempstore[=no], noting that +# it has four legal values, not two. # ######################################################################## # A gentle introduction to flags handling in autosetup @@ -65,17 +66,16 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # # Autosetup does no small amount of specialized handling for flags, # especially booleans. Each bool-type --FLAG implicitly gets -# --enable-FLAG and --disable-FLAG forms, and explicitly adding flags -# with those prefixes will force them to be boolean flags. e.g. we -# define a flag "readline", which will be interpreted in one of two -# ways, depending on how it's invoked and how its default is defined: +# --enable-FLAG and --disable-FLAG forms. e.g. we define a flag +# "readline", which will be interpreted in one of two ways, depending +# on how it's invoked and how its default is defined: # # --enable-readline ==> boolean true # --disable-readline ==> boolean false # -# Trying to pass --readline or --readline=1 or --readline=0 will -# result in an "unrecognized option" error, despite the the [options] -# call listing the flag as "readline". +# Passing --readline or --readline=1 is equivalent to passing +# --enable-readline, and --readline=0 is equivalent to +# --disable-readline. # # The behavior described above can lead lead to some confusion when # writing help text. For example: @@ -83,7 +83,7 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # options { json=1 {Disable JSON functions} } # # The reason the help text says "disable" is because a boolean option -# defaulting to true is, in the --help text, rendered as: +# which defaults to true is, in the --help text, rendered as: # # --disable-json Disable JSON functions # @@ -93,22 +93,7 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # # Non-boolean flags, in contrast, use the names specifically given to # them in the [options] invocation. e.g. "with-tcl" is the --with-tcl -# flag. Autosetup may, however, choose to automatically alter the help -# text, as demonstrated here: -# -# options { -# readline=1 => {Disable readline support} -# with-readline-lib: => {Readline library} -# with-readline-inc: => {Readline include paths} -# } -# -# $ ./configure --help | grep readline -# --disable-readline disable readline support -# --with-readline-lib specify readline library -# --with-readline-inc specify readline include paths -# -# Note that it prefixed and lower-case the help message. Whether -# that's a feature or a bug can be debated. +# flag. # # Fetching values for flags: # @@ -120,12 +105,15 @@ set DUMP_DEFINES_JSON ""; #./config.defines.json # # Non-boolean (i.e. string) flags: # - [opt-val FLAG ?default?] +# - [opt-str ...] - see the docs in ./autosetup/autosetup # ######################################################################## set flags { # When writing {help text blocks}, be aware that autosetup formats - # them differently (left-aligned, under the --flag, if the block - # starts with a newline. + # them differently (left-aligned, directly under the --flag) if the + # block starts with a newline. It does NOT expand vars and commands, + # but we use a [subst] call below which will replace (only) var + # refs. # shared=1 => {Disable build of shared libary} @@ -153,7 +141,9 @@ set flags { # with-tcl:DIR => {Directory containing tclConfig.sh or a directory one level up from - that, from which we can derive a directory containing tclConfig.sh.} + that, from which we can derive a directory containing tclConfig.sh. + A dir name of "prefix" is equivalent to the directory specified by + the --prefix flag.} with-tclsh:PATH => {Full pathname of tclsh to use. It is used for (A) trying to find tclConfig.sh and (B) all TCL-based code generation. Warning: if @@ -315,18 +305,17 @@ proj-file-extensions if {".exe" eq [get-define TARGET_EXEEXT]} { define SQLITE_OS_UNIX 0 define SQLITE_OS_WIN 1 - # todo? add -DSQLITE_OS_WIN=1 to CFLAGS or CFLAGS_sqlite3_os? } else { define SQLITE_OS_UNIX 1 define SQLITE_OS_WIN 0 - # todo? add -DSQLITE_OS_UNIX=1 to CFLAGS or CFLAGS_sqlite3_os } ######### # Programs needed -cc-check-tools ld ar ; # must come before sqlite-check-wasi-sdk +cc-check-tools ld ar ; # must come before [sqlite-check-wasi-sdk] if {"" eq [proj-bin-define install]} { proj-warn "Cannot find install binary, so 'make install' will not work." + define BIN_INSTALL false } ######################################################################## @@ -341,21 +330,18 @@ define BUILD_CFLAGS [proj-get-env BUILD_CFLAGS {-g}] proj-if-opt-truthy dev { # --enable-dev needs to come early so that the downstream tests - # which check for these flags will show the user their updated - # state. + # which check for the following flags use their updated state. proj-opt-set all 1 proj-opt-set debug 1 proj-opt-set amalgamation 0 define CFLAGS [get-env CFLAGS {-O0 -g}] } -define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided dynlink-tools] - ######################################################################## # Handle --with-wasi-sdk=DIR # -# This must be run early on because it may change the toolchain and -# disable a number of config options. +# This must be run relatively early on because it may change the +# toolchain and disable a number of config options. proc sqlite-check-wasi-sdk {} { set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end] define HAVE_WASI_SDK 0 @@ -374,6 +360,7 @@ proc sqlite-check-wasi-sdk {} { msg-result "Using wasi-sdk clang. Disabling CLI shell modifying config flags:" # Boolean (--enable-/--disable-) flags which must be switched off: foreach opt { + dynlink-tools editline gcov icu-collations @@ -425,6 +412,11 @@ proc sqlite-check-wasi-sdk {} { }; # sqlite-check-wasi-sdk sqlite-check-wasi-sdk +######################################################################## +# --dynlink-tools tells the build to dynamically link certain binaries +# to libsqlite3.so instead of embedding a copy of the amalgamation. +define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided dynlink-tools] + # # Enable large file support (if special flags are necessary) define HAVE_LFS 0 @@ -475,7 +467,11 @@ apply {{} { if {[proj-opt-was-provided soname]} { set soname [join [opt-val soname] ""] } else { - set soname none; # enabling soname breaks linking for the --dynlink-tools feature + # Enabling soname breaks linking for the --dynlink-tools feature, + # and this project has no direct use for soname, so default to + # none. Package maintainers, on the other hand, like to have an + # soname. + set soname none } switch -exact -- $soname { none - "" { return 0 } @@ -498,6 +494,7 @@ apply {{} { # --soname was explicitly requested but not available, so fail fatally proj-fatal "This environment does not support SONAME." } else { + # --soname was not explicitly requested but not available, so just warn msg-result "This environment does not support SONAME." } }} @@ -560,6 +557,7 @@ proj-if-opt-truthy debug { # failure to find TCL is not fatal but a loud warning will be emitted. # proc sqlite-check-tcl {} { + rename sqlite-check-tcl "" define TCLSH_CMD false ; # Significant is that it exits with non-0 define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search define TCLLIBDIR "" ; # Installation dir for TCL extension lib @@ -568,8 +566,8 @@ proc sqlite-check-tcl {} { if {![opt-bool tcl]} { proj-indented-notice { NOTE: TCL is disabled via --disable-tcl. This means that none - of the TCL-based components, including tests and sqlite3_analyzer, - will be built. + of the TCL-based components will be built, including tests + and sqlite3_analyzer. } return } @@ -687,8 +685,8 @@ proc sqlite-check-tcl {} { # in main.mk (search it for T.tcl.env.sh) so that # static/hand-written makefiles which import main.mk do not have # to define that before importing main.mk. Even so, we export - # TCLLIBDIR from here, which will cause the makefile to use this - # one rather than to re-calculate it at make-time. + # TCLLIBDIR from here, which will cause the canonical makefile to + # use this one rather than to re-calculate it at make-time. set tcllibdir [get-env TCLLIBDIR ""] if {"" eq $tcllibdir} { # Attempt to extract TCLLIBDIR from TCL's $auto_path @@ -743,7 +741,7 @@ sqlite-check-tcl # sqlite-determine-codegen-tcl checks which TCL to use as a code # generator. By default, prefer jimsh simply because we have it # in-tree (it's part of autosetup) unless --with-tclsh=X is used, in -# which case prefix X. +# which case prefer X. # # Returns the human-readable name of the TCL it selects. Fails fatally # if it cannot detect a TCL appropriate for code generation. @@ -759,9 +757,16 @@ sqlite-check-tcl set useJimForCodeGen 0 ; # Set to 1 when using jimsh for code generation. # May affect later decisions. proc sqlite-determine-codegen-tcl {} { + rename sqlite-determine-codegen-tcl "" msg-result "Checking for TCL to use for code generation... " define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}] set cgtcl [opt-val with-tclsh jimsh] + if {"jimsh" ne $cgtcl} { + # When --with-tclsh=X is used, use that for all TCL purposes, + # including in-tree code generation, per developer request. + define BTCLSH "\$(TCLSH_CMD)" + return $cgtcl + } set flagsToRestore {CC CFLAGS AS_CFLAGS CPPFLAGS AS_CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} define-push $flagsToRestore { # We have to swap CC to CC_FOR_BUILD for purposes of the various @@ -775,56 +780,50 @@ proc sqlite-determine-codegen-tcl {} { # block. foreach flag $flagsToRestore {define $flag ""} define CC [get-define CC_FOR_BUILD] - if {"jimsh" ne $cgtcl} { - # When --with-tclsh=X is used, use that for all TCL purposes, - # including in-tree code generation, per developer request. + # These headers are technically optional for JimTCL but necessary if + # we want to use it for code generation: + set sysh [cc-check-includes dirent.h sys/time.h] + # jimsh0.c hard-codes #define's for HAVE_DIRENT_H and + # HAVE_SYS_TIME_H on the platforms it supports, so we do not + # need to add -D... flags for those. We check for them here only + # so that we can avoid the situation that we later, at + # make-time, try to compile jimsh but it then fails due to + # missing headers (i.e. fail earlier rather than later). + if {$sysh && [cc-check-functions realpath]} { + define-append CFLAGS_JIMSH -DHAVE_REALPATH + define BTCLSH "\$(JIMSH)" + set ::useJimForCodeGen 1 + } elseif {$sysh && [cc-check-functions _fullpath]} { + # _fullpath() is a Windows API. It's not entirely clear + # whether we need to add {-DHAVE_SYS_TIME_H -DHAVE_DIRENT_H} + # to CFLAGS_JIMSH in this case. On MinGW32 we definitely do + # not want to because it already hard-codes them. On _MSC_VER + # builds it does not. + define-append CFLAGS_JIMSH -DHAVE__FULLPATH + define BTCLSH "\$(JIMSH)" + set ::useJimForCodeGen 1 + } elseif {[file-isexec [get-define TCLSH_CMD]]} { + set cgtcl [get-define TCLSH_CMD] define BTCLSH "\$(TCLSH_CMD)" } else { - # These headers are technically optional for JimTCL but necessary if - # we want to use it for code generation: - set sysh [cc-check-includes dirent.h sys/time.h] - # jimsh0.c hard-codes #define's for HAVE_DIRENT_H and - # HAVE_SYS_TIME_H on the platforms it supports, so we do not - # need to add -D... flags for those. We check for them here only - # so that we can avoid the situation that we later, at - # make-time, try to compile jimsh but it then fails due to - # missing headers (i.e. fail earlier rather than later). - if {$sysh && [cc-check-functions realpath]} { - define-append CFLAGS_JIMSH -DHAVE_REALPATH - define BTCLSH "\$(JIMSH)" - set ::useJimForCodeGen 1 - } elseif {$sysh && [cc-check-functions _fullpath]} { - # _fullpath() is a Windows API. It's not entirely clear - # whether we need to add {-DHAVE_SYS_TIME_H -DHAVE_DIRENT_H} - # to CFLAGS_JIMSH in this case. On MinGW32 we definitely do - # not want to because it already hard-codes them. On _MSC_VER - # builds it does not. - define-append CFLAGS_JIMSH -DHAVE__FULLPATH - define BTCLSH "\$(JIMSH)" - set ::useJimForCodeGen 1 - } elseif {[file-isexec [get-define TCLSH_CMD]]} { - set cgtcl [get-define TCLSH_CMD] - define BTCLSH "\$(TCLSH_CMD)" - } else { - # One last-ditch effort to find TCLSH_CMD: use info from - # tclConfig.sh to try to find a tclsh - if {"" eq [get-define TCLSH_CMD]} { - set tpre [get-define TCL_EXEC_PREFIX] - if {"" ne $tpre} { - set tv [get-define TCL_VERSION] - if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { - define TCLSH_CMD "${tpre}/bin/tclsh${tv}" - } elseif {[file-isexec "${tpre}/bin/tclsh"]} { - define TCLSH_CMD "${tpre}/bin/tclsh" - } + # One last-ditch effort to find TCLSH_CMD: use info from + # tclConfig.sh to try to find a tclsh + if {"" eq [get-define TCLSH_CMD]} { + set tpre [get-define TCL_EXEC_PREFIX] + if {"" ne $tpre} { + set tv [get-define TCL_VERSION] + if {[file-isexec "${tpre}/bin/tclsh${tv}"]} { + define TCLSH_CMD "${tpre}/bin/tclsh${tv}" + } elseif {[file-isexec "${tpre}/bin/tclsh"]} { + define TCLSH_CMD "${tpre}/bin/tclsh" } } - set cgtcl [get-define TCLSH_CMD] - if {![file-isexec $cgtcl]} { - proj-fatal "Cannot find a tclsh to use for code generation." - } - define BTCLSH "\$(TCLSH_CMD)" } + set cgtcl [get-define TCLSH_CMD] + if {![file-isexec $cgtcl]} { + proj-fatal "Cannot find a tclsh to use for code generation." + } + define BTCLSH "\$(TCLSH_CMD)" } }; # CC swap-out return $cgtcl @@ -845,6 +844,8 @@ proj-if-opt-truthy threadsafe { } define LDFLAGS_PTHREAD [get-define lib_pthread_create] undefine lib_pthread_create + # Recall that LDFLAGS_PTHREAD might be empty even if pthreads if + # found because it's in -lc on some platforms. } { msg-result no sqlite-add-feature-flag -DSQLITE_THREADSAFE=0 @@ -858,7 +859,7 @@ apply {{} { set ts [opt-val with-tempstore no] set tsn 1 msg-checking "Use an in-RAM database for temporary tables? " - switch -- $ts { + switch -exact -- $ts { never { set tsn 0 } no { set tsn 1 } yes { set tsn 2 } @@ -908,6 +909,7 @@ apply {{} { # corresponding --FEATURE flag was explicitly given, fail fatally, # else fail silently. proc sqlite-check-line-editing {} { + rename sqlite-check-line-editing "" msg-result "Checking for line-editing capability..." define HAVE_READLINE 0 define HAVE_LINENOISE 0 @@ -1161,22 +1163,13 @@ proj-if-opt-truthy math { # are cumulative. If neither are provided, icu-collations is not # honored and a warning is emitted if it is provided. # -# Design note: though we can automatically enable ICU if the +# Design note: though we could automatically enable ICU if the # icu-config binary or (pkg-config icu-io) are found, we specifically # do not. ICU is always an opt-in feature. -# -# Maintenance reminder: check-in 09caa94c9e84 added pkg-config support -# to this but the result fails to link on both Linux and OpenBSD -# (other systems were untested) because the pkg-config results are -# missing a required library. proc sqlite-check-icu {} { + rename sqlite-check-icu "" define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]] define CFLAGS_ICU [join [opt-val with-icu-cflags ""]] - # Flags sets seen in the wild for ICU: - # - -licui18n -licuuc -licudata - # - -licui18n -licuuc - # - /usr/local/bin/icu-config --ldflags - # if {[proj-opt-was-provided with-icu-config]} { set icuConfigBin [opt-val with-icu-config] set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config @@ -1237,8 +1230,18 @@ sqlite-check-icu ######################################################################## # Check for the Emscripten SDK for building the web-based wasm -# components. +# components. The core lib and tools do not require this but ext/wasm +# does. apply {{} { + if {$::autosetup(srcdir) ne $::autosetup(builddir)} { + # The EMSDK pieces require writing to the original source tree + # even when doing an out-of-tree build. The ext/wasm pieces do not + # support an out-of-tree build so we catch that case and treat it + # as if EMSDK were not found. + msg-result "Out-of tree build: not checking for EMSDK." + define EMCC_WRAPPER "" + return + } set emccsh $::srcdir/tool/emcc.sh if {![get-define HAVE_WASI_SDK] && [proj-check-emsdk]} { define EMCC_WRAPPER $emccsh diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 7da0b0fa35..a469c898de 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -138,7 +138,12 @@ proc proj-indented-notice {args} { } set lines [split [join $args] \n] foreach line $lines { - $outFunc " [string trimleft $line]" + set line [string trimleft $line] + if {"" eq $line} { + $outFunc $line + } else { + $outFunc " $line" + } } if {"" ne $fErr} { show-notices diff --git a/manifest b/manifest index b7f9c03141..bb43461239 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C ext/icu/README.txt:\sclean\sup\sEOL\swhitespace\sand\sadd\sa\smention\sof\sthe\s--with-icu-...\sconfigure\sflags\savailable\sas\sof\sversion\s3.48. -D 2024-11-28T15:52:21.879 +C Configure\sscript\sdoc\supdates\sand\scleanups.\sSkip\scheck\sfor\sEMSDK\swhen\sdoing\san\sout-of-tree\sbuild,\sas\sext/wasm\sdoes\snot\ssupport\sthat\sbuild\smode. +D 2024-11-28T16:14:19.067 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 961d2cf22b65d31f9eb97470b50cbbdca34b999cf86f438811c1ec214b296b8b +F auto.def a82198f9ab1db4b54a5e134196bb0256d414789f747bbed6bacb67805c4bc0db F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -49,7 +49,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 22556a325c964aa5377d4d881722385f41fcd7c1b60102ba8965f7814c83e9ce +F autosetup/proj.tcl 2e817159b997077cb79bd871f6255276b787558f386dfc0830b0f825f6a53767 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P eb5ac9e5b9a4f9c85a2203107697da14c07c1667037dff672f9d786cea964a37 -R 78a02244626590a5fbc0925d20e4f240 +P 4976ac717bec2f2c89d94ac1d9b96afd1da573ba34e3c78637c3937287635e72 +R dfe7e573ed6abcbcf47ed2c31d6d6772 U stephan -Z fdab33deaf1f469df2a1f2ef0d0eef73 +Z 69e72e81037eeb2ecac489de03503f03 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cd1048f863..a75e9a5e27 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4976ac717bec2f2c89d94ac1d9b96afd1da573ba34e3c78637c3937287635e72 +9d2f4148db1641e9bf2989c2b1adf5b9dcb2b123526ecacd063bca208b3c36cf From 25e042c0b0a30c79cbe330bc4c1317b29263b1ad Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 28 Nov 2024 20:46:51 +0000 Subject: [PATCH 413/522] Typo fixes and cleanups in autosetup/README.md. FossilOrigin-Name: 7f366565f41fa4eb532cfaf83074106e235436bfc377116e3bf823ac08fd01a5 --- autosetup/README.md | 53 +++++++++++++++++++++++++-------------------- manifest | 12 +++++----- manifest.uuid | 2 +- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/autosetup/README.md b/autosetup/README.md index 4e15d750f6..fd426d56d9 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -56,14 +56,13 @@ In (mostly) alphabetical order: - **`file-isexec filename`**\ Should be used in place of `[file executable]`, as it will also check for `${filename}.exe` on Windows platforms. However, on such - platforms is also assumes that _any_ existing file is executable. + platforms it also assumes that _any_ existing file is executable. - **`get-env VAR ?default?`**\ - Will fetch an "environment variable" - from the first of either: (1) a KEY=VALUE passed to the configure - script or (2) the system's environment variables. Not to be confused - with `getenv`, which only does the latter and is rarely, if ever, - useful in this tree. + Will fetch an "environment variable" from the first of either: (1) a + KEY=VALUE passed to the configure script or (2) the system's + environment variables. Not to be confused with `getenv`, which only + does the latter and is rarely, if ever, useful in this tree. - **`proj-get-env VAR ?default?`**\ Works like `get-env` but will, if that function finds no match, look for a file named `./.env-$VAR` and, if found, return its @@ -73,8 +72,8 @@ In (mostly) alphabetical order: - **`define-for-opt flag defineName ?checkingMsg? ?yesVal=1? ?noVal=0?`**\ `[define $defineName]` to either `$yesVal` or `$noVal`, depending on whether `--$flag` is truthy or not. `$checkingMsg` is a - human-readable description of the check being made, e.g. "enable foo - bar baz?" If no `checkingMsg` is provided, the operation is silent.\ + human-readable description of the check being made, e.g. "enable foo?" + If no `checkingMsg` is provided, the operation is silent.\ Potential TODO: change the final two args to `-yes` and `-no` flags. They're rarely needed, though: search [auto.def][] for `TSTRNNR_OPTS` for an example of where they are used. @@ -113,14 +112,16 @@ In (mostly) alphabetical order: (described below). - **`sqlite-add-feature-flag ?-shell? FLAG...`**\ - Adds the given feature flag to the CFLAGS which are specific to building - the library. It's intended to be passed one or more `-DSQLITE_ENABLE_...`, - or similar, flags. If the `-shell` flag is used then it also passes - its arguments to `sqlite-add-shell-opt`. This is a no-op if `FLAG` - is not provided or is empty. + Adds the given feature flag to the CFLAGS which are specific to + building libsqlite3. It's intended to be passed one or more + `-DSQLITE_ENABLE_...`, or similar, flags. If the `-shell` flag is + used then it also passes its arguments to + `sqlite-add-shell-opt`. This is a no-op if `FLAG` is not provided or + is empty. - **`sqlite-add-shell-opt FLAG...`**\ - The shell-specific counterpart of `sqlite-add-feature-flag`. + The shell-specific counterpart of `sqlite-add-feature-flag` which + only adds the given flag(s) to the CLI-shell-specific CFLAGS. - **`user-notice msg`**\ Queues `$msg` to be sent to stderr, but does not emit it until @@ -130,6 +131,7 @@ In (mostly) alphabetical order: its resulting "yes/no/whatever" message in such a way as to not spoil the layout of such messages. + Ensuring TCL Compatibility ======================================================================== @@ -169,14 +171,14 @@ compatibility across TCL implementations: before looking for a system-level `tclsh`. Be aware, though, that `make distclean` will remove that file. -**Note that `jimsh0` is distinctly different** from the `jimsh` which -gets built for code-generation purposes. The latter requires +**Note that `jimsh0` is distinctly different from the `jimsh`** which +gets built for code-generation purposes. The latter requires non-default build flags to enable features which are platform-dependent, most notably to make its `[file normalize]` work. This means, for example, that the configure script and its utility -APIs must not use `[file normalize]`, but autosetup provides a TCL -implementation of `[file-normalize]` (note the dash) for portable use -in the configure script. +APIs must not use `[file normalize]`, but autosetup provides a +TCL-only implementation of `[file-normalize]` (note the dash) for +portable use in the configure script. @@ -193,7 +195,7 @@ Symbolic Names of Feature Flags Historically, the project's makefile has exclusively used `UPPER_UNDERSCORE` form for makefile variables. This build, however, primarily uses `X.y` format, where `X` is often a category label, -e.g. `CFLAGS` and `y` is the specific instance of that category, +e.g. `CFLAGS`, and `y` is the specific instance of that category, e.g. `CFLAGS.readline`. When the configure script exports flags for consumption by filtered @@ -244,7 +246,7 @@ that approach include: _after_ the test for zlib because the results of the `-rpath` test implicitly modified global state which broke the zlib feature test. Because the feature tests no longer (intentionally) modify - global state, that is not an issue.) + shared global state, that is not an issue.) In this build, cases where feature tests modify global state in such a way that it may impact later feature tests are either (A) very @@ -305,9 +307,9 @@ $ fossil status # show the modified files ``` Unless the upgrade made any incompatible changes (which is exceedingly -rare), that's all there is to it. Then **apply a patch for the change -described in the following section**, test the configure process, and -check it in. +rare), that's all there is to it. After that's done, **apply a patch +for the change described in the following section**, test the +configure process, and check it in. Patching Autosetup for Project-local Changes @@ -322,6 +324,9 @@ requires (as of this writing) four small edits in [](/file/autosetup/autosetup), as demonstrated in [check-in 3296c8d3](/info/3296c8d3). +If autosetup is upgraded and this patch is _not_ applied the invoking +`./configure` will fail loudly because of the declaration of the +`debug` flag in `auto.def` - duplicated flags are not permitted. [Autosetup]: https://msteveb.github.io/autosetup/ diff --git a/manifest b/manifest index bb43461239..3aec50dc71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Configure\sscript\sdoc\supdates\sand\scleanups.\sSkip\scheck\sfor\sEMSDK\swhen\sdoing\san\sout-of-tree\sbuild,\sas\sext/wasm\sdoes\snot\ssupport\sthat\sbuild\smode. -D 2024-11-28T16:14:19.067 +C Typo\sfixes\sand\scleanups\sin\sautosetup/README.md. +D 2024-11-28T20:46:51.863 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 083b4417637f134875709dfa8ca149ce9b3634725b65e0f7d9b96f2bf56caa3a +F autosetup/README.md 1a02f5a94fd460eb7ffc8dea5d6f1657e38ddf8ffa2d6c5dce9a630b97021a69 F autosetup/autosetup df8b53928b1fe3c67db5bc77c8e1eb8160c1b6a26c370e9a06c68748f803b7e4 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4976ac717bec2f2c89d94ac1d9b96afd1da573ba34e3c78637c3937287635e72 -R dfe7e573ed6abcbcf47ed2c31d6d6772 +P 9d2f4148db1641e9bf2989c2b1adf5b9dcb2b123526ecacd063bca208b3c36cf +R 51f81e989696c60babea027477d55ce3 U stephan -Z 69e72e81037eeb2ecac489de03503f03 +Z b5c978735ffc965433e9d3c2347bdbb9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a75e9a5e27..6a5ab7063d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d2f4148db1641e9bf2989c2b1adf5b9dcb2b123526ecacd063bca208b3c36cf +7f366565f41fa4eb532cfaf83074106e235436bfc377116e3bf823ac08fd01a5 From 2aac89661170be2d0a0ad91baa83d11e13df4bea Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 28 Nov 2024 23:55:35 +0000 Subject: [PATCH 414/522] Remove some outdated docs from Makefile.in. FossilOrigin-Name: cc2c5fc98b2d1957bd26f41f0b646921ecabe2ffe544b3c3565965ba8850b2ff --- Makefile.in | 46 ++++++---------------------------------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 47 deletions(-) diff --git a/Makefile.in b/Makefile.in index 59963f3ced..75c1f47dcf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -41,45 +41,13 @@ all: # that contains this "Makefile.in" and the "configure" script. # TOP = @abs_top_srcdir@ -# -# Just testing some default dir expansions... -# srcdir = @srcdir@ -# builddir = @builddir@ -# top_srcdir = @top_srcdir@ -# abs_top_srcdir = @abs_top_srcdir@ -# abs_top_builddir = @abs_top_builddir@ -# # # Autotools-conventional vars which are used by package installation -# rules in main.mk. -# -# Autosetup allows the various XYZdir vars to be overridden at -# configure-time with, e.g. --libdir=X and --mandir=Y. However, -# defining them at configure-time, instead of at make-time, leads to -# later awkwardness: -# -# $ ./configure --prefix=/usr -# $ make prefix=/bar -# -# In that invocation, libdir will be /usr/foo, not /bar/foo as it -# normally should, unless the user _also_ passes libdir=... to make. -# -# In 99%+ of use cases, setting prefix=X has the desired effect of -# calculating conventional defaults for various other dirs, like -# $prefix/lib, $prefix/include, etc. If, however, we export those at -# configure-time, the passing prefix=... to make will update only -# $prefix and none of its derived dirs. -# -# Because it is more important (for our use cases) that these vars be -# overridable via a make invocation than a configure invocation, and -# they conventionally derive from $(prefix) in all but the most exotic -# of use cases, we do not export the configure-defined overrides of -# those vars to this makefile. Instead, we export only $prefix and -# its derived vars are set to their conventional default values in -# main.mk, which users can then override at make-time as needed. -# Overriding $prefix via make will also calculate any derived vars, as -# one would expect, unless each is specifically overridden. +# rules in main.mk. To get sane handling when a user overrides only +# a subset of these, we perform some acrobatics with these vars +# in the configure script: see [proj-remap-autoconf-dir-vars] for +# full details. # # For completeness's sake, the aforementioned conventional vars which # are relevant to our installation rules are: @@ -128,9 +96,7 @@ T.cc = $(CC) # are, in that build, no uses of CPPFLAGS in the configure-expanded # Makefile. Ergo: if a client configures with CPPFLAGS=... and then # explicitly passes CFLAGS=... to make, the CPPFLAGS will be -# lost. That behavior is retained in 3.48+ because also honoring -# CPPFLAGS at make-time may have undesired side effects on any number -# of builds. +# lost. That behavior is retained in 3.48+. # CFLAGS = @CFLAGS@ @CPPFLAGS@ # @@ -248,7 +214,7 @@ TCLLIBDIR = @TCLLIBDIR@ # # Additional options when running tests using testrunner.tcl -# This is usually either blank, or else --status +# This is usually either blank or --status. # TSTRNNR_OPTS = @TSTRNNR_OPTS@ diff --git a/manifest b/manifest index 3aec50dc71..39e9e9043b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Typo\sfixes\sand\scleanups\sin\sautosetup/README.md. -D 2024-11-28T20:46:51.863 +C Remove\ssome\soutdated\sdocs\sfrom\sMakefile.in. +D 2024-11-28T23:55:35.415 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in 85f2c740cadf969abbd9a6210b8b76636dbf231b9d3efe977b060c3055fac5b9 +F Makefile.in 86e81bdb118bf332a27865090b7dce96ddde93c2f1586e1b911569acaa228f19 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9d2f4148db1641e9bf2989c2b1adf5b9dcb2b123526ecacd063bca208b3c36cf -R 51f81e989696c60babea027477d55ce3 +P 7f366565f41fa4eb532cfaf83074106e235436bfc377116e3bf823ac08fd01a5 +R d7c111a7470180e499663f2f26933967 U stephan -Z b5c978735ffc965433e9d3c2347bdbb9 +Z f66a560c68c0b33c3bb1d4fe2506daed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6a5ab7063d..7d063ea487 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f366565f41fa4eb532cfaf83074106e235436bfc377116e3bf823ac08fd01a5 +cc2c5fc98b2d1957bd26f41f0b646921ecabe2ffe544b3c3565965ba8850b2ff From 5c208f36a453c821cfcb021d643872e5ebfadbff Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Nov 2024 11:49:05 +0000 Subject: [PATCH 415/522] Fix a NEVER() in the iif() logic that can be true if compiled with SQLITE_ENABLE_UNKNOWN_SQL_FUNCTIONS. Problem introduced by [eb5ac9e5b9a4f9c8]. FossilOrigin-Name: 3ec2df5a6c731b59b0ab132ee59c74d107f9c4bd32cf47d9776887858b9c0dea --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 39e9e9043b..dcb89335c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\soutdated\sdocs\sfrom\sMakefile.in. -D 2024-11-28T23:55:35.415 +C Fix\sa\sNEVER()\sin\sthe\siif()\slogic\sthat\scan\sbe\strue\sif\scompiled\swith\nSQLITE_ENABLE_UNKNOWN_SQL_FUNCTIONS.\s\sProblem\sintroduced\sby\s[eb5ac9e5b9a4f9c8]. +D 2024-11-29T11:49:05.152 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -726,7 +726,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c b838969c58a38dfedabec18c432204895c7333d7a509a20fa63c39bf92001f0e +F src/expr.c 954fe794e30c5b692c7c32da2b6df6ee57259c0220da571fc79922c8d07ad41f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7f366565f41fa4eb532cfaf83074106e235436bfc377116e3bf823ac08fd01a5 -R d7c111a7470180e499663f2f26933967 -U stephan -Z f66a560c68c0b33c3bb1d4fe2506daed +P cc2c5fc98b2d1957bd26f41f0b646921ecabe2ffe544b3c3565965ba8850b2ff +R e3074278b35f54a5f11f21d9d8c2e74e +U drh +Z 8d6d5519eaac914fe913f5864cf877bd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7d063ea487..9a5fc8625e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc2c5fc98b2d1957bd26f41f0b646921ecabe2ffe544b3c3565965ba8850b2ff +3ec2df5a6c731b59b0ab132ee59c74d107f9c4bd32cf47d9776887858b9c0dea diff --git a/src/expr.c b/src/expr.c index d0282f7147..afa9ba00f5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -6478,7 +6478,11 @@ static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){ if( (z[0]!='i' && z[0]!='I') ) return 0; if( pExpr->x.pList==0 ) return 0; pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 ) return 0; +#else if( NEVER(pDef==0) ) return 0; +#endif if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0; if( NEVER(SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif) ) return 0; }else if( pExpr->op==TK_CASE ){ From 03e306b3a19091906a563794b6659ca463f8d7cc Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Nov 2024 12:00:38 +0000 Subject: [PATCH 416/522] A NEVER() that was added by [eb5ac9e5b9a4f9c8] is violated by the ifnull() in-line function. This check-in fixes that problem. FossilOrigin-Name: 2220ccf4d6fea2413015c72fd318003b4b5afeae7cb7586b714fce36212d8c49 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index dcb89335c8..02e95f2475 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sNEVER()\sin\sthe\siif()\slogic\sthat\scan\sbe\strue\sif\scompiled\swith\nSQLITE_ENABLE_UNKNOWN_SQL_FUNCTIONS.\s\sProblem\sintroduced\sby\s[eb5ac9e5b9a4f9c8]. -D 2024-11-29T11:49:05.152 +C A\sNEVER()\sthat\swas\sadded\sby\s[eb5ac9e5b9a4f9c8]\sis\sviolated\sby\sthe\sifnull()\nin-line\sfunction.\s\sThis\scheck-in\sfixes\sthat\sproblem. +D 2024-11-30T12:00:38.558 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -726,7 +726,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c 954fe794e30c5b692c7c32da2b6df6ee57259c0220da571fc79922c8d07ad41f +F src/expr.c cd85c48b408f67ce077155ad17b2822214b040afc2269cfcbe6510d945cc6986 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cc2c5fc98b2d1957bd26f41f0b646921ecabe2ffe544b3c3565965ba8850b2ff -R e3074278b35f54a5f11f21d9d8c2e74e +P 3ec2df5a6c731b59b0ab132ee59c74d107f9c4bd32cf47d9776887858b9c0dea +R bbde09ca9109487c159b50c815e366a3 U drh -Z 8d6d5519eaac914fe913f5864cf877bd +Z d347c790e4473436a571b458a4266fa7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9a5fc8625e..35fa364846 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ec2df5a6c731b59b0ab132ee59c74d107f9c4bd32cf47d9776887858b9c0dea +2220ccf4d6fea2413015c72fd318003b4b5afeae7cb7586b714fce36212d8c49 diff --git a/src/expr.c b/src/expr.c index afa9ba00f5..435ec9d780 100644 --- a/src/expr.c +++ b/src/expr.c @@ -6484,7 +6484,7 @@ static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){ if( NEVER(pDef==0) ) return 0; #endif if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0; - if( NEVER(SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif) ) return 0; + if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0; }else if( pExpr->op==TK_CASE ){ if( pExpr->pLeft!=0 ) return 0; }else{ From c5b9da34f2bc23fe9382ff07196dfbfb3e2f467d Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Nov 2024 14:13:35 +0000 Subject: [PATCH 417/522] In sqlite_dbpage, cancel any pending truncate operation if there an error occurs later in the transaction. FossilOrigin-Name: 1abab10f85a4dba5ffe51a30eeef30853c120e5566ed97b3af1526fff597c647 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/dbpage.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 02e95f2475..3061fed911 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\sNEVER()\sthat\swas\sadded\sby\s[eb5ac9e5b9a4f9c8]\sis\sviolated\sby\sthe\sifnull()\nin-line\sfunction.\s\sThis\scheck-in\sfixes\sthat\sproblem. -D 2024-11-30T12:00:38.558 +C In\ssqlite_dbpage,\scancel\sany\spending\struncate\soperation\sif\sthere\san\serror\noccurs\slater\sin\sthe\stransaction. +D 2024-11-30T14:13:35.669 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -723,7 +723,7 @@ F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d49 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a -F src/dbpage.c db1be8adaf1f839ad733c08baeac5c22aa912f7b535865c0c061382602081360 +F src/dbpage.c 6c52074b0edb914d526c85541ca0f1fd23822b5dac39b6ee9b7f375d9fa592e9 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c cd85c48b408f67ce077155ad17b2822214b040afc2269cfcbe6510d945cc6986 @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3ec2df5a6c731b59b0ab132ee59c74d107f9c4bd32cf47d9776887858b9c0dea -R bbde09ca9109487c159b50c815e366a3 +P 2220ccf4d6fea2413015c72fd318003b4b5afeae7cb7586b714fce36212d8c49 +R f154a3e6dd4944fdbd4f1ae39e54884f U drh -Z d347c790e4473436a571b458a4266fa7 +Z a3278a97e32db442096a47b4ce1a54d9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 35fa364846..b31bc4e555 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2220ccf4d6fea2413015c72fd318003b4b5afeae7cb7586b714fce36212d8c49 +1abab10f85a4dba5ffe51a30eeef30853c120e5566ed97b3af1526fff597c647 diff --git a/src/dbpage.c b/src/dbpage.c index a0ee9246dc..124952456c 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -393,6 +393,8 @@ static int dbpageUpdate( memcpy(aPage, pData, szPage); pTab->pgnoTrunc = 0; } + }else{ + pTab->pgnoTrunc = 0; } sqlite3PagerUnref(pDbPage); return rc; From d6d9c54bb20e2df6dbceaaff5f106b4679a8f0ef Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 30 Nov 2024 17:48:31 +0000 Subject: [PATCH 418/522] At the end of the configure script ensure that none of the files which are filtered for @VARS@ contain any unresolved @VAR@ placeholders, failing fatally if any do. FossilOrigin-Name: 301df5c2beb08e8e2944f7a9e46a10114603518385c05a9c30a838ab436369d4 --- auto.def | 23 +++++++++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index 9cea6a3dc1..c39dc55bc8 100644 --- a/auto.def +++ b/auto.def @@ -1400,3 +1400,26 @@ proj-if-opt-truthy dump-defines { undefine OPT_SHELL.list } } + +######################################################################## +# Perform some high-level validation on the generated files... +# +# 1) Ensure that no unresolved @VAR@ placeholders are in files which +# use those. +# +# 2) TBD +apply {{} { + # Check #1: ensure that files which get filtered for @VAR@ do not + # contain any unresolved @VAR@ refs. That may indicate an + # unexported/unused var or a typo. + foreach f "Makefile sqlite3.pc $::srcdir/tool/emcc.sh" { + if {![file exists $f]} continue + set lnno 1 + foreach line [proj-file-content-list $f] { + if {[regexp {(@[A-Za-z_]+@)} $line match]} { + error "Unresolved reference to $match at line $lnno of $f" + } + incr lnno + } + } +}} diff --git a/manifest b/manifest index 3061fed911..a6b58921cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\ssqlite_dbpage,\scancel\sany\spending\struncate\soperation\sif\sthere\san\serror\noccurs\slater\sin\sthe\stransaction. -D 2024-11-30T14:13:35.669 +C At\sthe\send\sof\sthe\sconfigure\sscript\sensure\sthat\snone\sof\sthe\sfiles\swhich\sare\sfiltered\sfor\s@VARS@\scontain\sany\sunresolved\s@VAR@\splaceholders,\sfailing\sfatally\sif\sany\sdo. +D 2024-11-30T17:48:31.521 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def a82198f9ab1db4b54a5e134196bb0256d414789f747bbed6bacb67805c4bc0db +F auto.def a0e22c70e043c860dce809d436dad667c29981d9b98342b47e25747df08aaf28 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2201,8 +2201,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2220ccf4d6fea2413015c72fd318003b4b5afeae7cb7586b714fce36212d8c49 -R f154a3e6dd4944fdbd4f1ae39e54884f -U drh -Z a3278a97e32db442096a47b4ce1a54d9 +P 1abab10f85a4dba5ffe51a30eeef30853c120e5566ed97b3af1526fff597c647 +R e64febb3fe4e77d46b80ded354868cd5 +U stephan +Z c8dd07770a4ac68eb48e0cf5cc49ca34 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b31bc4e555..559f3d7c89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1abab10f85a4dba5ffe51a30eeef30853c120e5566ed97b3af1526fff597c647 +301df5c2beb08e8e2944f7a9e46a10114603518385c05a9c30a838ab436369d4 From 9bc351b3c7b073f10301bc077322752ff1ca0c32 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 1 Dec 2024 14:02:19 +0000 Subject: [PATCH 419/522] Export a clipped copy of sqlite370.eps as sqlite370.svg, based on discussion in [forum:1bbd6d17ca|forum post 1bbd6d17ca]. FossilOrigin-Name: dd3a13c1209d0bac3d6eb105826429ef29b36682c347995dc266bf42e46a2193 --- art/sqlite370.svg | 107 ++++++++++++++++++++++++++++++++++++++++++++++ manifest | 11 ++--- manifest.uuid | 2 +- 3 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 art/sqlite370.svg diff --git a/art/sqlite370.svg b/art/sqlite370.svg new file mode 100644 index 0000000000..f780a397c1 --- /dev/null +++ b/art/sqlite370.svg @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/manifest b/manifest index a6b58921cd..03fbe9fa17 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C At\sthe\send\sof\sthe\sconfigure\sscript\sensure\sthat\snone\sof\sthe\sfiles\swhich\sare\sfiltered\sfor\s@VARS@\scontain\sany\sunresolved\s@VAR@\splaceholders,\sfailing\sfatally\sif\sany\sdo. -D 2024-11-30T17:48:31.521 +C Export\sa\sclipped\scopy\sof\ssqlite370.eps\sas\ssqlite370.svg,\sbased\son\sdiscussion\sin\s[forum:1bbd6d17ca|forum\spost\s1bbd6d17ca]. +D 2024-12-01T14:02:19.835 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,6 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 +F art/sqlite370.svg ed79b61a056ca722027f18cd63395d5bc324f925e7b8be76cdc5458a1addc77a F auto.def a0e22c70e043c860dce809d436dad667c29981d9b98342b47e25747df08aaf28 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 @@ -2201,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1abab10f85a4dba5ffe51a30eeef30853c120e5566ed97b3af1526fff597c647 -R e64febb3fe4e77d46b80ded354868cd5 +P 301df5c2beb08e8e2944f7a9e46a10114603518385c05a9c30a838ab436369d4 +R 773c9906e32101746f3856fce79cbd87 U stephan -Z c8dd07770a4ac68eb48e0cf5cc49ca34 +Z 2cfac5616be613d3912055ea36a00d71 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 559f3d7c89..ab7993438f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -301df5c2beb08e8e2944f7a9e46a10114603518385c05a9c30a838ab436369d4 +dd3a13c1209d0bac3d6eb105826429ef29b36682c347995dc266bf42e46a2193 From a13a645cdfbfe7bdf677cdeed1c6cc1bb70a8a24 Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 1 Dec 2024 14:14:50 +0000 Subject: [PATCH 420/522] Re-export sqlite370.svg to retain the gradient part and clip the size using the cutting guides in sqlite370.eps. FossilOrigin-Name: 12017b01c8e6c12fdd8de3c3c325e56b5be80343a1a392538b6e6ed066e46cee --- art/sqlite370.svg | 147 +++++++++++++++++++++++----------------------- manifest | 12 ++-- manifest.uuid | 2 +- 3 files changed, 81 insertions(+), 80 deletions(-) diff --git a/art/sqlite370.svg b/art/sqlite370.svg index f780a397c1..9356f721c3 100644 --- a/art/sqlite370.svg +++ b/art/sqlite370.svg @@ -2,106 +2,107 @@ + id="defs467"> + + + + id="linearGradient51"> + id="stop43" /> + id="stop45" /> + id="stop47" /> + id="stop49" /> - - - - - - + id="layer1" + transform="translate(-30.325426,-80.061905)"> - - - - - - - - - + id="g614"> + + + + + + + + + + + + + + diff --git a/manifest b/manifest index 03fbe9fa17..17638ac1aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Export\sa\sclipped\scopy\sof\ssqlite370.eps\sas\ssqlite370.svg,\sbased\son\sdiscussion\sin\s[forum:1bbd6d17ca|forum\spost\s1bbd6d17ca]. -D 2024-12-01T14:02:19.835 +C Re-export\ssqlite370.svg\sto\sretain\sthe\sgradient\spart\sand\sclip\sthe\ssize\susing\sthe\scutting\sguides\sin\ssqlite370.eps. +D 2024-12-01T14:14:50.481 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F art/sqlite370.svg ed79b61a056ca722027f18cd63395d5bc324f925e7b8be76cdc5458a1addc77a +F art/sqlite370.svg e2bf2fe17f602cc08db00cc6b48c31a25fcfdd3fce2b99441b0d22a6b1d4bbbf F auto.def a0e22c70e043c860dce809d436dad667c29981d9b98342b47e25747df08aaf28 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 301df5c2beb08e8e2944f7a9e46a10114603518385c05a9c30a838ab436369d4 -R 773c9906e32101746f3856fce79cbd87 +P dd3a13c1209d0bac3d6eb105826429ef29b36682c347995dc266bf42e46a2193 +R e66632f480fa9889a528b2ea980ca4b7 U stephan -Z 2cfac5616be613d3912055ea36a00d71 +Z 9fd04893b998b4cf42cad44ece8528fb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ab7993438f..c3a3279179 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd3a13c1209d0bac3d6eb105826429ef29b36682c347995dc266bf42e46a2193 +12017b01c8e6c12fdd8de3c3c325e56b5be80343a1a392538b6e6ed066e46cee From fd66549cb693073f323573a6d36453970bf6740c Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 1 Dec 2024 14:20:19 +0000 Subject: [PATCH 421/522] Correct the fill color for the background of sqlite370.svg - it was slightly darker than it should have been. FossilOrigin-Name: 732132407b3881aaa7fee151baafb6569664f1d2b82ef7743d89bd0a86cf0a09 --- art/sqlite370.svg | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/art/sqlite370.svg b/art/sqlite370.svg index 9356f721c3..46b0045aeb 100644 --- a/art/sqlite370.svg +++ b/art/sqlite370.svg @@ -51,7 +51,7 @@ Date: Sun, 1 Dec 2024 15:23:40 +0000 Subject: [PATCH 422/522] Trim a bit more from the sqlite370.svg border to get it closer in scaled size to the logo currently on the docsrc site. FossilOrigin-Name: 81c7277fc59af833365f0ee5af603db49c19a6ba87bd5f252ecdfe72df252d4e --- art/sqlite370.svg | 108 ++++++++++++++++++++++------------------------ manifest | 12 +++--- manifest.uuid | 2 +- 3 files changed, 59 insertions(+), 63 deletions(-) diff --git a/art/sqlite370.svg b/art/sqlite370.svg index 46b0045aeb..9a050b593d 100644 --- a/art/sqlite370.svg +++ b/art/sqlite370.svg @@ -2,9 +2,9 @@ + id="g337"> + - + id="g465" + transform="translate(-56.57816,-61.353828)"> + + + + + + + - + id="g37" + clip-path="url(#clipPath41)" + transform="matrix(0.03527778,0,0,-0.03527778,42.828565,121.98722)"> - - - - - - - - - + d="m 994.055,997.609 c 6.725,-11.629 35.115,-61.371 40.815,-77.398 6.42,-18.121 7.77,-23.313 7.77,-23.313 0,0 -15.57,80.114 -41.12,126.862 5.6,18.9 12.29,39.79 19.86,62.12 8.85,-15.53 28.96,-51.2 36.23,-68.1 0.27,3.19 0.54,6.38 0.82,9.54 -6.44,24.75 -16.22,57.15 -28.74,82.54 32.14,167.25 135.59,386.25 247.04,504.48 H 509.602 c -37.883,0 -68.711,-30.82 -68.711,-68.71 V 731.789 c 173.738,66.68 383.23,127.633 563.529,125.02 -6.693,25.812 -14.315,49.152 -22.318,62.679 -4.122,6.981 0.449,35.653 11.953,78.121" + style="fill:url(#linearGradient51);fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path53" /> + diff --git a/manifest b/manifest index 042485a162..1529ee3021 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sthe\sfill\scolor\sfor\sthe\sbackground\sof\ssqlite370.svg\s-\sit\swas\sslightly\sdarker\sthan\sit\sshould\shave\sbeen. -D 2024-12-01T14:20:19.627 +C Trim\sa\sbit\smore\sfrom\sthe\ssqlite370.svg\sborder\sto\sget\sit\scloser\sin\sscaled\ssize\sto\sthe\slogo\scurrently\son\sthe\sdocsrc\ssite. +D 2024-12-01T15:23:40.866 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F art/sqlite370.svg dba5c47cc680aa38041ca4756cc91f82ae7b4bc05e39bfd23adf355af8280262 +F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531 F auto.def a0e22c70e043c860dce809d436dad667c29981d9b98342b47e25747df08aaf28 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 12017b01c8e6c12fdd8de3c3c325e56b5be80343a1a392538b6e6ed066e46cee -R 4fe8c345587f741b6f487d0e07c2ea64 +P 732132407b3881aaa7fee151baafb6569664f1d2b82ef7743d89bd0a86cf0a09 +R a8b303cba2f0568fafb9e7b313f76e76 U stephan -Z d56d01cf37eb6543db3618f85182577e +Z 8571445bebcabe4056fe395c6d20e2a7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9681846435..8193539bb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -732132407b3881aaa7fee151baafb6569664f1d2b82ef7743d89bd0a86cf0a09 +81c7277fc59af833365f0ee5af603db49c19a6ba87bd5f252ecdfe72df252d4e From 224e356081182c5690d44f1c5df49c40c796981b Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Dec 2024 13:29:29 +0000 Subject: [PATCH 423/522] Slighly less confusing output from treeview during debugging. FossilOrigin-Name: 7aef0b93050cdb79cae68361e84047cea2e8e7251d0581ce917da03352bb1f16 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/treeview.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1529ee3021..d8adcc4005 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Trim\sa\sbit\smore\sfrom\sthe\ssqlite370.svg\sborder\sto\sget\sit\scloser\sin\sscaled\ssize\sto\sthe\slogo\scurrently\son\sthe\sdocsrc\ssite. -D 2024-12-01T15:23:40.866 +C Slighly\sless\sconfusing\soutput\sfrom\streeview\sduring\sdebugging. +D 2024-12-02T13:29:29.510 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -839,7 +839,7 @@ F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68 -F src/treeview.c 4eeb155abefd88a60d0c37cc00bcfac38a8dd566970f019e4af7e02672ee2599 +F src/treeview.c 921392561385e05ef5703f20a7a72f0a0a45c1fb749558d7467fae2c3f525006 F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 732132407b3881aaa7fee151baafb6569664f1d2b82ef7743d89bd0a86cf0a09 -R a8b303cba2f0568fafb9e7b313f76e76 -U stephan -Z 8571445bebcabe4056fe395c6d20e2a7 +P 81c7277fc59af833365f0ee5af603db49c19a6ba87bd5f252ecdfe72df252d4e +R e1b4d376f6d1b8ae5226a7733e409232 +U drh +Z fd572b187ecdf020733ce40c075270b8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8193539bb8..55eb9ee7ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81c7277fc59af833365f0ee5af603db49c19a6ba87bd5f252ecdfe72df252d4e +7aef0b93050cdb79cae68361e84047cea2e8e7251d0581ce917da03352bb1f16 diff --git a/src/treeview.c b/src/treeview.c index 865de9991c..30592d35b2 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -218,7 +218,7 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); } if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ - sqlite3_str_appendf(&x, " ON"); + sqlite3_str_appendf(&x, " isOn"); } if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); From 3e1f302dbe3f5c108bcc1eaeed304cc80fc2a147 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Dec 2024 13:47:53 +0000 Subject: [PATCH 424/522] Enable MEMSYS5 with the --dev configure option. FossilOrigin-Name: 9e09d5d60ac91423e1dec1169e9eb60a531f84261b48490c550cf4529540e6dc --- auto.def | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index c39dc55bc8..ba8b1adbf7 100644 --- a/auto.def +++ b/auto.def @@ -519,7 +519,7 @@ proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \ msg-checking "SQLITE_DEBUG build? " proj-if-opt-truthy debug { define SQLITE_DEBUG 1 - define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} + define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_MEMSYS5 -O0 -Wall} msg-result yes } { define TARGET_DEBUG {-DNDEBUG} diff --git a/manifest b/manifest index d8adcc4005..2bfdd7a1e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slighly\sless\sconfusing\soutput\sfrom\streeview\sduring\sdebugging. -D 2024-12-02T13:29:29.510 +C Enable\sMEMSYS5\swith\sthe\s--dev\sconfigure\soption. +D 2024-12-02T13:47:53.444 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -14,7 +14,7 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531 -F auto.def a0e22c70e043c860dce809d436dad667c29981d9b98342b47e25747df08aaf28 +F auto.def 411c5b5538d4890c601eb0bf3aa0e401e507209c3aaacde063977b6f0dafe69f F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 81c7277fc59af833365f0ee5af603db49c19a6ba87bd5f252ecdfe72df252d4e -R e1b4d376f6d1b8ae5226a7733e409232 +P 7aef0b93050cdb79cae68361e84047cea2e8e7251d0581ce917da03352bb1f16 +R e48a17285a227782715f071b22aa748e U drh -Z fd572b187ecdf020733ce40c075270b8 +Z afc76fb7a8a09f7eb558217a5434a8b5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 55eb9ee7ec..ce0f809bc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7aef0b93050cdb79cae68361e84047cea2e8e7251d0581ce917da03352bb1f16 +9e09d5d60ac91423e1dec1169e9eb60a531f84261b48490c550cf4529540e6dc From ed7fe45c7c035e9b5c97d67885c73ee8409f6273 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 2 Dec 2024 14:14:30 +0000 Subject: [PATCH 425/522] Reformulate [9e09d5d6] so that memsys5 shows up in the late-config summary as being enabled and does the right thing if both --debug and --memsys3 are used. FossilOrigin-Name: 447db1cd0a6575432996e9735e78bbb09c83827c5e3080339b34df176ab86af0 --- auto.def | 3 ++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index ba8b1adbf7..e4ddbbd46f 100644 --- a/auto.def +++ b/auto.def @@ -519,7 +519,8 @@ proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \ msg-checking "SQLITE_DEBUG build? " proj-if-opt-truthy debug { define SQLITE_DEBUG 1 - define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_MEMSYS5 -O0 -Wall} + define TARGET_DEBUG {-g -DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall} + proj-opt-set memsys5 msg-result yes } { define TARGET_DEBUG {-DNDEBUG} diff --git a/manifest b/manifest index 2bfdd7a1e1..a00285bf1b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sMEMSYS5\swith\sthe\s--dev\sconfigure\soption. -D 2024-12-02T13:47:53.444 +C Reformulate\s[9e09d5d6]\sso\sthat\smemsys5\sshows\sup\sin\sthe\slate-config\ssummary\sas\sbeing\senabled\sand\sdoes\sthe\sright\sthing\sif\sboth\s--debug\sand\s--memsys3\sare\sused. +D 2024-12-02T14:14:30.676 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -14,7 +14,7 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531 -F auto.def 411c5b5538d4890c601eb0bf3aa0e401e507209c3aaacde063977b6f0dafe69f +F auto.def 6de760c0b88ace5550403544a2eb83eb6834be99997c845d824c19774e056dc5 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7aef0b93050cdb79cae68361e84047cea2e8e7251d0581ce917da03352bb1f16 -R e48a17285a227782715f071b22aa748e -U drh -Z afc76fb7a8a09f7eb558217a5434a8b5 +P 9e09d5d60ac91423e1dec1169e9eb60a531f84261b48490c550cf4529540e6dc +R d9d8b14ef1a08757ec20208f0b613d4c +U stephan +Z 4b6795ed2210994cf6151e4f8f333a77 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ce0f809bc6..0d8e1c2577 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e09d5d60ac91423e1dec1169e9eb60a531f84261b48490c550cf4529540e6dc +447db1cd0a6575432996e9735e78bbb09c83827c5e3080339b34df176ab86af0 From bfdeb1f6d561f5a9ea53a662810704b6fcb4e213 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Dec 2024 16:07:38 +0000 Subject: [PATCH 426/522] Fix a harmless typo in debugging output. FossilOrigin-Name: 578f76cfb2e298fe6bfd278b545091fe682d01feb0be56ef57b6c9f2c179ac61 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a00285bf1b..ceb4442469 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reformulate\s[9e09d5d6]\sso\sthat\smemsys5\sshows\sup\sin\sthe\slate-config\ssummary\sas\sbeing\senabled\sand\sdoes\sthe\sright\sthing\sif\sboth\s--debug\sand\s--memsys3\sare\sused. -D 2024-12-02T14:14:30.676 +C Fix\sa\sharmless\stypo\sin\sdebugging\soutput. +D 2024-12-02T16:07:38.007 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -777,7 +777,7 @@ F src/printf.c 96f7f8baeedc7639da94e4e7a4a2c200e2537c4eec9e5e1c2ffc821f40eb3105 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe +F src/select.c c8165a8dff9c7b0f038b566f02a1ea983f4e0fdf8a3308e357727f4c9d8b07a5 F src/shell.c.in 7aa68b305246391984c48f10725416079394a64bf0349fa4087d835c41ef733d F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9e09d5d60ac91423e1dec1169e9eb60a531f84261b48490c550cf4529540e6dc -R d9d8b14ef1a08757ec20208f0b613d4c -U stephan -Z 4b6795ed2210994cf6151e4f8f333a77 +P 447db1cd0a6575432996e9735e78bbb09c83827c5e3080339b34df176ab86af0 +R 251b3cd2cc3712f9285159fa5af5f855 +U drh +Z cb8855e74c77702fc96adfcd8b429854 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0d8e1c2577..d98737fa2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -447db1cd0a6575432996e9735e78bbb09c83827c5e3080339b34df176ab86af0 +578f76cfb2e298fe6bfd278b545091fe682d01feb0be56ef57b6c9f2c179ac61 diff --git a/src/select.c b/src/select.c index 9fcf30ff4a..916bd831e5 100644 --- a/src/select.c +++ b/src/select.c @@ -7821,7 +7821,7 @@ int sqlite3Select( #endif assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); }else{ - TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); + TREETRACE(0x4000,pParse,p,("WHERE-clause push-down not possible\n")); } /* Convert unused result columns of the subquery into simple NULL From c9ac238b92a5d1af3e91b3bb38e182b2a472c287 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Dec 2024 16:24:47 +0000 Subject: [PATCH 427/522] Fix a comment typo on the sqlite3ExprIsSingleTableConstraint() routine. FossilOrigin-Name: 346a845bf1cd1c7e542f7bf763d86c197d9a3b4f3ea38ade416790a1cf80e6f2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ceb4442469..8855823756 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\stypo\sin\sdebugging\soutput. -D 2024-12-02T16:07:38.007 +C Fix\sa\scomment\stypo\son\sthe\ssqlite3ExprIsSingleTableConstraint()\sroutine. +D 2024-12-02T16:24:47.122 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -727,7 +727,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c 6c52074b0edb914d526c85541ca0f1fd23822b5dac39b6ee9b7f375d9fa592e9 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c cd85c48b408f67ce077155ad17b2822214b040afc2269cfcbe6510d945cc6986 +F src/expr.c ae41eb87e73a7b2e8748b0cf1e8e1d6b2e57fcb9abd093ef3da78f16fed36f33 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 447db1cd0a6575432996e9735e78bbb09c83827c5e3080339b34df176ab86af0 -R 251b3cd2cc3712f9285159fa5af5f855 +P 578f76cfb2e298fe6bfd278b545091fe682d01feb0be56ef57b6c9f2c179ac61 +R 4f8aa96fb5dc4e807fa23513f1b51f86 U drh -Z cb8855e74c77702fc96adfcd8b429854 +Z d928f2574431a0b1dc02438a266e7594 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d98737fa2d..f585aba157 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -578f76cfb2e298fe6bfd278b545091fe682d01feb0be56ef57b6c9f2c179ac61 +346a845bf1cd1c7e542f7bf763d86c197d9a3b4f3ea38ade416790a1cf80e6f2 diff --git a/src/expr.c b/src/expr.c index 435ec9d780..37923bc84a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2646,7 +2646,7 @@ static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){ ** (4a) pExpr must come from an ON clause.. ** (4b) and specifically the ON clause associated with the LEFT JOIN. ** -** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** (5) If pSrc is the right operand of a LEFT JOIN or the left ** operand of a RIGHT JOIN, then pExpr must be from the WHERE ** clause, not an ON clause. ** From 4b491d85650f4a47a4869d9b1f805e97ad343d6e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 2 Dec 2024 17:21:52 +0000 Subject: [PATCH 428/522] Ensure that the query flattener does not change an ON clause term to a WHERE clause term. FossilOrigin-Name: bdd408a2557ff05c9ea962a94b442f7c078d8e1ec27035aa95bc23d4d2bd5606 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 28 ++++++++++++++-------------- test/pushdown.test | 31 +++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 8855823756..6acd483d76 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scomment\stypo\son\sthe\ssqlite3ExprIsSingleTableConstraint()\sroutine. -D 2024-12-02T16:24:47.122 +C Ensure\sthat\sthe\squery\sflattener\sdoes\snot\schange\san\sON\sclause\sterm\sto\sa\sWHERE\sclause\sterm. +D 2024-12-02T17:21:52.631 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -777,7 +777,7 @@ F src/printf.c 96f7f8baeedc7639da94e4e7a4a2c200e2537c4eec9e5e1c2ffc821f40eb3105 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c c8165a8dff9c7b0f038b566f02a1ea983f4e0fdf8a3308e357727f4c9d8b07a5 +F src/select.c 1334b0606dbdc753c8333f41bff441c97f77ef8ad9e33f3701e8adfe3b587c28 F src/shell.c.in 7aa68b305246391984c48f10725416079394a64bf0349fa4087d835c41ef733d F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1541,7 +1541,7 @@ F test/printf.test 685fec5a0c5af2490ab0632775a301554361d674211d690f5bee0a97b0533 F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224cce60 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc -F test/pushdown.test 84b525767442b3695d671f9df59dd91cf0ed8fb24cbbcdc55959f0dadeee8b39 +F test/pushdown.test 46a626ef1c0ca79b85296ff2e078b9da20a50e9b804b38f441590c3987580ddd F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quickcheck.test a4b7e878cd97e46108291c409b0bf8214f29e18fddd68a42bc5c1375ad1fb80a @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 578f76cfb2e298fe6bfd278b545091fe682d01feb0be56ef57b6c9f2c179ac61 -R 4f8aa96fb5dc4e807fa23513f1b51f86 -U drh -Z d928f2574431a0b1dc02438a266e7594 +P 346a845bf1cd1c7e542f7bf763d86c197d9a3b4f3ea38ade416790a1cf80e6f2 +R 3d9ca48b4ce75be7e80d82495e9e7ffe +U dan +Z f342386cec8099c31eae45b11308d89c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f585aba157..8518415b4d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -346a845bf1cd1c7e542f7bf763d86c197d9a3b4f3ea38ade416790a1cf80e6f2 +bdd408a2557ff05c9ea962a94b442f7c078d8e1ec27035aa95bc23d4d2bd5606 diff --git a/src/select.c b/src/select.c index 916bd831e5..285e9133e7 100644 --- a/src/select.c +++ b/src/select.c @@ -3911,32 +3911,32 @@ static Expr *substExpr( if( pSubst->isOuterJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } - if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ - sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, - pExpr->flags & (EP_OuterON|EP_InnerON)); - } - sqlite3ExprDelete(db, pExpr); - pExpr = pNew; - if( pExpr->op==TK_TRUEFALSE ){ - pExpr->u.iValue = sqlite3ExprTruthValue(pExpr); - pExpr->op = TK_INTEGER; - ExprSetProperty(pExpr, EP_IntValue); + if( pNew->op==TK_TRUEFALSE ){ + pNew->u.iValue = sqlite3ExprTruthValue(pNew); + pNew->op = TK_INTEGER; + ExprSetProperty(pNew, EP_IntValue); } /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ { - CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pNew); CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pSubst->pCList->a[iColumn].pExpr ); - if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){ - pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + if( pNat!=pColl || (pNew->op!=TK_COLUMN && pNew->op!=TK_COLLATE) ){ + pNew = sqlite3ExprAddCollateString(pSubst->pParse, pNew, (pColl ? pColl->zName : "BINARY") ); } } - ExprClearProperty(pExpr, EP_Collate); + ExprClearProperty(pNew, EP_Collate); + if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, + pExpr->flags & (EP_OuterON|EP_InnerON)); + } + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; } } }else{ diff --git a/test/pushdown.test b/test/pushdown.test index 271d412e7e..cb9042d258 100644 --- a/test/pushdown.test +++ b/test/pushdown.test @@ -325,4 +325,35 @@ do_eqp_test 6.3 { `--REUSE LIST SUBQUERY xxxxxx } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 7.0 { + CREATE TABLE t0_1(a INT , b INT, c INT); + CREATE TABLE t0_2(a INT , b INT, c INT); + + INSERT INTO t0_1 (a, b, c) VALUES (1, 0, 1); + INSERT INTO t0_2 (a, b, c) VALUES (1, 0, 1); + + CREATE TABLE empty1(x); + CREATE TABLE empty2(y); +} + +do_execsql_test 7.1 { + SELECT t0_2.c + FROM (SELECT '0000' AS c0 FROM empty2 RIGHT JOIN t0_1 ON 1) AS v0 + LEFT JOIN empty1 ON v0.c0, t0_2 + RIGHT JOIN ( + SELECT 5678 AS col0 FROM (SELECT 0) + ) AS sub1 ON 1; +} {1} + +do_execsql_test 7.2 { + SELECT t0_2.c + FROM (SELECT '0000' AS c0 FROM empty2 RIGHT JOIN t0_1 ON 1) AS v0 + LEFT JOIN empty1 ON v0.c0, t0_2 + RIGHT JOIN ( + SELECT 5678 AS col0 FROM (SELECT 0) + ) AS sub1 ON 1 WHERE +t0_2.c; +} {1} + finish_test From 33c120f9b7de84fb0dd2625efe11097015c0e116 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Dec 2024 19:55:39 +0000 Subject: [PATCH 429/522] Improve the output from the ".testctrl opt" command in the CLI. FossilOrigin-Name: de7064d118c33aab0fff39d072593b287c291870b843d093045300bde464420f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 32 +++++++++++++++++++------------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 6acd483d76..72a90586a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\squery\sflattener\sdoes\snot\schange\san\sON\sclause\sterm\sto\sa\sWHERE\sclause\sterm. -D 2024-12-02T17:21:52.631 +C Improve\sthe\soutput\sfrom\sthe\s".testctrl\sopt"\scommand\sin\sthe\sCLI. +D 2024-12-02T19:55:39.686 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -778,7 +778,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 1334b0606dbdc753c8333f41bff441c97f77ef8ad9e33f3701e8adfe3b587c28 -F src/shell.c.in 7aa68b305246391984c48f10725416079394a64bf0349fa4087d835c41ef733d +F src/shell.c.in 660da73720fc0783a00317568aa098ff1887a0a5cbc0c49138d348d9fc890961 F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 346a845bf1cd1c7e542f7bf763d86c197d9a3b4f3ea38ade416790a1cf80e6f2 -R 3d9ca48b4ce75be7e80d82495e9e7ffe -U dan -Z f342386cec8099c31eae45b11308d89c +P bdd408a2557ff05c9ea962a94b442f7c078d8e1ec27035aa95bc23d4d2bd5606 +R 3b9b24c843f161d7a50bbe824bc3a3d8 +U drh +Z 5d7beb581213ea354b6d427078135558 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8518415b4d..85c6e4778b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bdd408a2557ff05c9ea962a94b442f7c078d8e1ec27035aa95bc23d4d2bd5606 +de7064d118c33aab0fff39d072593b287c291870b843d093045300bde464420f diff --git a/src/shell.c.in b/src/shell.c.in index b4d7fc287f..2df54d5b3a 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -11465,7 +11465,9 @@ static int do_meta_command(char *zLine, ShellState *p){ }; unsigned int curOpt; unsigned int newOpt; + unsigned int m; int ii; + int nOff; sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt); newOpt = curOpt; for(ii=2; iidb,newOpt); - }else if( nArg<3 ){ - curOpt = ~newOpt; } - if( newOpt==0 ){ - sqlite3_fputs("+All\n", p->out); - }else if( newOpt==0xffffffff ){ - sqlite3_fputs("-All\n", p->out); + for(ii=nOff=0, m=1; ii<32; ii++, m <<= 1){ + if( m & newOpt ) nOff++; + } + if( nOff<12 ){ + sqlite3_fputs("+All", p->out); + for(ii=0; iiout, " -%s", aLabel[ii].zLabel); + } + } }else{ - int jj; - for(jj=0; jjout, "%c%s\n", (newOpt & m)==0 ? '+' : '-', - aLabel[jj].zLabel); + sqlite3_fputs("-All", p->out); + for(ii=0; iiout, " +%s", aLabel[ii].zLabel); } } } + sqlite3_fputs("\n", p->out); rc2 = isOk = 3; break; } From 76412af157c2af07c9b3dde98326cffeab51577d Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 4 Dec 2024 16:01:25 +0000 Subject: [PATCH 430/522] Minor doc correction in ext/misc/shathree.c, as reported in the forum. No functional changes. FossilOrigin-Name: 3b82d2c6b732617b9be205efadd07326057c93b71c47ffd42de63fc05093667b --- ext/misc/shathree.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/misc/shathree.c b/ext/misc/shathree.c index 72ca7278ca..fc05a3b73a 100644 --- a/ext/misc/shathree.c +++ b/ext/misc/shathree.c @@ -12,7 +12,7 @@ ** ** This SQLite extension implements functions that compute SHA3 hashes ** in the way described by the (U.S.) NIST FIPS 202 SHA-3 Standard. -** Two SQL functions are implemented: +** Three SQL functions are implemented: ** ** sha3(X,SIZE) ** sha3_agg(Y,SIZE) diff --git a/manifest b/manifest index 72a90586a4..21ebd8c453 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\soutput\sfrom\sthe\s".testctrl\sopt"\scommand\sin\sthe\sCLI. -D 2024-12-02T19:55:39.686 +C Minor\sdoc\scorrection\sin\sext/misc/shathree.c,\sas\sreported\sin\sthe\sforum.\sNo\sfunctional\schanges. +D 2024-12-04T16:01:25.587 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -437,7 +437,7 @@ F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d385 F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 F ext/misc/series.c cbdda2e2eb8159a1331974d246984c6e2693c6ea93930e6165046c8dbb8db0e9 F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9 -F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c +F ext/misc/shathree.c f3a778f27bf3e71b666a77f28e463a3b931c4dbe4219447e61bb678b4bc121c3 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bdd408a2557ff05c9ea962a94b442f7c078d8e1ec27035aa95bc23d4d2bd5606 -R 3b9b24c843f161d7a50bbe824bc3a3d8 -U drh -Z 5d7beb581213ea354b6d427078135558 +P de7064d118c33aab0fff39d072593b287c291870b843d093045300bde464420f +R 86e86c5653d7da9aeabbd5fff5f5fa8b +U stephan +Z 756ded1a59123f8adfff343351124b4b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 85c6e4778b..2f657db6ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -de7064d118c33aab0fff39d072593b287c291870b843d093045300bde464420f +3b82d2c6b732617b9be205efadd07326057c93b71c47ffd42de63fc05093667b From eed134c4d3080dc03303ff2c21affcc94c3bba80 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 5 Dec 2024 23:53:16 +0000 Subject: [PATCH 431/522] Fix the build of sqlite3_analyzer.exe on Windows that was broken by check-in [80f3bf8c2ee31ba1]. FossilOrigin-Name: 223f47b2db8d80629d60a642942eb8b288611e3e466cf904964285229a5809fc --- Makefile.msc | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 32b8143768..6da1e399d2 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2669,7 +2669,7 @@ 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) - $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@ + $(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 \ diff --git a/manifest b/manifest index 21ebd8c453..53e511b0a1 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Minor\sdoc\scorrection\sin\sext/misc/shathree.c,\sas\sreported\sin\sthe\sforum.\sNo\sfunctional\schanges. -D 2024-12-04T16:01:25.587 +C Fix\sthe\sbuild\sof\ssqlite3_analyzer.exe\son\sWindows\sthat\swas\sbroken\sby\ncheck-in\s[80f3bf8c2ee31ba1]. +D 2024-12-05T23:53:16.868 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in 86e81bdb118bf332a27865090b7dce96ddde93c2f1586e1b911569acaa228f19 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 +F Makefile.msc f8b4097dd93bd19df8fda39ca8b530904c2e7134a28094f490c0dc11abd47ce2 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P de7064d118c33aab0fff39d072593b287c291870b843d093045300bde464420f -R 86e86c5653d7da9aeabbd5fff5f5fa8b -U stephan -Z 756ded1a59123f8adfff343351124b4b +P 3b82d2c6b732617b9be205efadd07326057c93b71c47ffd42de63fc05093667b +R 24123a0459182d20f8acb8c7b97c6d23 +U drh +Z 4aebafa1987ff29c0a240fdab74f1ca1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2f657db6ca..1009c8aa46 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b82d2c6b732617b9be205efadd07326057c93b71c47ffd42de63fc05093667b +223f47b2db8d80629d60a642942eb8b288611e3e466cf904964285229a5809fc From 0448e00aaf727a8120ae0a2f3a455ac2eb162e1c Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 6 Dec 2024 00:09:05 +0000 Subject: [PATCH 432/522] Ensure that the post-config checks for @UNEXPANDED_VARS@ pass even if --disable-tcl is used, as reported in [forum:74ef8059fc|forum post 74ef8059fc]. FossilOrigin-Name: a38606bf44a1b5d0f684f67174c33f8c88c7927e23fc6a715e8d3ae7a6614bbd --- auto.def | 7 +++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/auto.def b/auto.def index e4ddbbd46f..ffc10ab54c 100644 --- a/auto.def +++ b/auto.def @@ -563,6 +563,13 @@ proc sqlite-check-tcl {} { define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search define TCLLIBDIR "" ; # Installation dir for TCL extension lib define TCL_CONFIG_SH ""; # full path to tclConfig.sh + + # Clear out all vars which would be set by tclConfigToAutoDef.sh, so that the late-config + # validation of @VARS@ works... + foreach k {TCL_INCLUDE_SPEC TCL_LIB_SPEC TCL_STUB_LIB_SPEC TCL_EXEC_PREFIX TCL_VERSION} { + define $k "" + } + file delete -force ".tclenv.sh"; # ensure no stale state from previous configures. if {![opt-bool tcl]} { proj-indented-notice { diff --git a/manifest b/manifest index 53e511b0a1..5374b6c218 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuild\sof\ssqlite3_analyzer.exe\son\sWindows\sthat\swas\sbroken\sby\ncheck-in\s[80f3bf8c2ee31ba1]. -D 2024-12-05T23:53:16.868 +C Ensure\sthat\sthe\spost-config\schecks\sfor\s@UNEXPANDED_VARS@\spass\seven\sif\s--disable-tcl\sis\sused,\sas\sreported\sin\s[forum:74ef8059fc|forum\spost\s74ef8059fc]. +D 2024-12-06T00:09:05.046 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -14,7 +14,7 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531 -F auto.def 6de760c0b88ace5550403544a2eb83eb6834be99997c845d824c19774e056dc5 +F auto.def 9f72325769bb436b895e59830754420bbcf511e97cad46d3d02b8238c74fb2de F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3b82d2c6b732617b9be205efadd07326057c93b71c47ffd42de63fc05093667b -R 24123a0459182d20f8acb8c7b97c6d23 -U drh -Z 4aebafa1987ff29c0a240fdab74f1ca1 +P 223f47b2db8d80629d60a642942eb8b288611e3e466cf904964285229a5809fc +R 5615d7d2067b25d2e740958008f1a1e0 +U stephan +Z d55afe31ff3364c8edd502e77c937df9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1009c8aa46..7afeea1703 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -223f47b2db8d80629d60a642942eb8b288611e3e466cf904964285229a5809fc +a38606bf44a1b5d0f684f67174c33f8c88c7927e23fc6a715e8d3ae7a6614bbd From c40329c9bf497896c3b58bf8918840a574f64b86 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 6 Dec 2024 00:12:43 +0000 Subject: [PATCH 433/522] Minor doc update in auto.def. No functional changes. FossilOrigin-Name: d324be296de443bd2853c732b10960178bf3ba9f18c80c509f6b41e2cfb2f3af --- auto.def | 5 +++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/auto.def b/auto.def index ffc10ab54c..7b57e9599b 100644 --- a/auto.def +++ b/auto.def @@ -564,8 +564,9 @@ proc sqlite-check-tcl {} { define TCLLIBDIR "" ; # Installation dir for TCL extension lib define TCL_CONFIG_SH ""; # full path to tclConfig.sh - # Clear out all vars which would be set by tclConfigToAutoDef.sh, so that the late-config - # validation of @VARS@ works... + # Clear out all vars which would be set by tclConfigToAutoDef.sh, so + # that the late-config validation of @VARS@ works even if + # --disable-tcl is used. foreach k {TCL_INCLUDE_SPEC TCL_LIB_SPEC TCL_STUB_LIB_SPEC TCL_EXEC_PREFIX TCL_VERSION} { define $k "" } diff --git a/manifest b/manifest index 5374b6c218..150300a272 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\spost-config\schecks\sfor\s@UNEXPANDED_VARS@\spass\seven\sif\s--disable-tcl\sis\sused,\sas\sreported\sin\s[forum:74ef8059fc|forum\spost\s74ef8059fc]. -D 2024-12-06T00:09:05.046 +C Minor\sdoc\supdate\sin\sauto.def.\sNo\sfunctional\schanges. +D 2024-12-06T00:12:43.147 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -14,7 +14,7 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531 -F auto.def 9f72325769bb436b895e59830754420bbcf511e97cad46d3d02b8238c74fb2de +F auto.def 8f15c373e88c4c5296d6100e3d35893bd6edb57cebcb6a8c1e827e6faaef52e4 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 223f47b2db8d80629d60a642942eb8b288611e3e466cf904964285229a5809fc -R 5615d7d2067b25d2e740958008f1a1e0 +P a38606bf44a1b5d0f684f67174c33f8c88c7927e23fc6a715e8d3ae7a6614bbd +R 33caa7144247a27ce977090c08431529 U stephan -Z d55afe31ff3364c8edd502e77c937df9 +Z 799ae7852d1959c2ef269cb9b60fc9dd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7afeea1703..cbe3ae4ef5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a38606bf44a1b5d0f684f67174c33f8c88c7927e23fc6a715e8d3ae7a6614bbd +d324be296de443bd2853c732b10960178bf3ba9f18c80c509f6b41e2cfb2f3af From ef636cc3cd72b2a7f5803777b95419b279baacab Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 6 Dec 2024 18:35:16 +0000 Subject: [PATCH 434/522] Add the SQLITE_PREPARE_DONT_LOG option for sqlite3_prepare_v3(), that prevents errors in the compilation of the SQL from being sent to sqlite3_log(). FossilOrigin-Name: 870403425493866232cf9e8fa62288861b7d0a4091b15d75727f8bb31da46f94 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/pragma.c | 3 ++- src/sqlite.h.in | 11 +++++++++++ src/tokenize.c | 4 +++- src/vdbe.h | 2 +- test/pragma4.test | 21 +++++++++++++++++++++ 7 files changed, 50 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 150300a272..d179789cb4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sdoc\supdate\sin\sauto.def.\sNo\sfunctional\schanges. -D 2024-12-06T00:12:43.147 +C Add\sthe\sSQLITE_PREPARE_DONT_LOG\soption\sfor\ssqlite3_prepare_v3(),\sthat\sprevents\nerrors\sin\sthe\scompilation\sof\sthe\sSQL\sfrom\sbeing\ssent\sto\ssqlite3_log(). +D 2024-12-06T18:35:16.856 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -770,7 +770,7 @@ F src/parse.y dcf45a81b61223ac93e61fdfe9b22d635dd371c446e8222634d90aa37e25e5f6 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 -F src/pragma.c a2ec3657a953fa7dea7c1e680e4358b6ce6ae570b6c5234e0f5ef219d308d223 +F src/pragma.c 767accbbbe53f6bacd05d35cfe2b3e6b830b01719010e8c684cb8b126dbad46e F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126 F src/printf.c 96f7f8baeedc7639da94e4e7a4a2c200e2537c4eec9e5e1c2ffc821f40eb3105 @@ -779,7 +779,7 @@ F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 1334b0606dbdc753c8333f41bff441c97f77ef8ad9e33f3701e8adfe3b587c28 F src/shell.c.in 660da73720fc0783a00317568aa098ff1887a0a5cbc0c49138d348d9fc890961 -F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6 +F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1 @@ -838,7 +838,7 @@ F src/test_windirent.h da2e5b73c32d09905fbdd00f27cd802212a32a58ead882736fe4f5eb7 F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68 +F src/tokenize.c fe17e03175cae35b6694d0f879e7bc3d1ddea2fd4ab148cba9bbd025b7a7bb12 F src/treeview.c 921392561385e05ef5703f20a7a72f0a0a45c1fb749558d7467fae2c3f525006 F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 @@ -847,7 +847,7 @@ F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba F src/util.c ceebf912f673247e305f16f97f0bb7285fca1d37413b79680714a553a9021d33 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 -F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a +F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e F src/vdbeapi.c 6353de05e8e78e497ccb33381ba5662ccc11c0339e5b1455faff01b6dacc3075 F src/vdbeaux.c f0706ad786b8a6c5bc7ea622f3916c2ba2b883abc872d0b4911c4f021945c0e5 @@ -1532,7 +1532,7 @@ F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b76 F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 92a46bbea12322dd94a404f49edcfbfc913a2c98115f0d030a7459bb4712ef31 -F test/pragma4.test f93f317693e90ece4ed0f5505d9035cae03f9fc684b718278433f2e48703f693 +F test/pragma4.test 336b99c2a9fd35af3cc6da94f794b4cba09bbdb18f0ecbd3f734bb6bb8e1c15c F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d9102 F test/pragma6.test c5ec577ba087954b4dfa619a3cbe97b155b60a0af487527abe89b10fc17e6512 F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a38606bf44a1b5d0f684f67174c33f8c88c7927e23fc6a715e8d3ae7a6614bbd -R 33caa7144247a27ce977090c08431529 -U stephan -Z 799ae7852d1959c2ef269cb9b60fc9dd +P d324be296de443bd2853c732b10960178bf3ba9f18c80c509f6b41e2cfb2f3af +R ec11279f510ab644cd4a136e6f39dd62 +U drh +Z 8980c884368db10cb1cda65aa0a82ff3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cbe3ae4ef5..ab7dd98ed5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d324be296de443bd2853c732b10960178bf3ba9f18c80c509f6b41e2cfb2f3af +870403425493866232cf9e8fa62288861b7d0a4091b15d75727f8bb31da46f94 diff --git a/src/pragma.c b/src/pragma.c index 785676e04e..ae0c86f039 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1279,7 +1279,8 @@ void sqlite3Pragma( char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName); if( zSql ){ sqlite3_stmt *pDummy = 0; - (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0); + (void)sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_DONT_LOG, + &pDummy, 0); (void)sqlite3_finalize(pDummy); sqlite3DbFree(db, zSql); } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b84938b45c..9a117fa54e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4204,11 +4204,22 @@ int sqlite3_limit(sqlite3*, int id, int newVal); **
        The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler ** to return an error (error code SQLITE_ERROR) if the statement uses ** any virtual tables. +** +** [[SQLITE_PREPARE_DONT_LOG]]
        SQLITE_PREPARE_DONT_LOG
        +**
        The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler +** errors from being sent to the error log defined by +** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test +** compiles to see if some SQL syntax is well-formed, without generating +** messages on the global error log when it is not. If the test compile +** fails, the sqlite3_prepare_v3() call returns the same error indications +** with or without this flag; it just omits the call to [sqlite3_log()] that +** logs the error. ** */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 #define SQLITE_PREPARE_NO_VTAB 0x04 +#define SQLITE_PREPARE_DONT_LOG 0x10 /* ** CAPI3REF: Compiling An SQL Statement diff --git a/src/tokenize.c b/src/tokenize.c index 65d1fbf350..b49b2aa16e 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -728,7 +728,9 @@ int sqlite3RunParser(Parse *pParse, const char *zSql){ if( pParse->zErrMsg==0 ){ pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); } - sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){ + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + } nErr++; } pParse->zTail = zSql; diff --git a/src/vdbe.h b/src/vdbe.h index f40f68d24b..71aae29a08 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -185,7 +185,7 @@ typedef struct VdbeOpList VdbeOpList; ** Additional non-public SQLITE_PREPARE_* flags */ #define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */ -#define SQLITE_PREPARE_MASK 0x0f /* Mask of public flags */ +#define SQLITE_PREPARE_MASK 0x1f /* Mask of public flags */ /* ** Prototypes for the VDBE interface. See comments on the implementation diff --git a/test/pragma4.test b/test/pragma4.test index 5360fbac40..0466960cab 100644 --- a/test/pragma4.test +++ b/test/pragma4.test @@ -281,6 +281,27 @@ ifcapable vtab { JOIN pragma_table_info(f."table", t.schema) AS i WHERE i.pk; } {t2 t1 d a 1} + + # With a corrupt VIEW in the schema, the PRAGMA table_list command + # will generate internal errors. Confirm that these internal errors + # do not appears on the log. https://sqlite.org/src/forumpost/00ee467e + test_sqlite3_log [list lappend ::log] + set ::log {} + do_execsql_test 6.1 { + CREATE VIEW v1 AS SELECT abs(a) FROM t1; + PRAGMA writable_schema=ON; + UPDATE sqlite_schema + SET sql=replace(sql,'abs(a)','nosuchfunc(a)') + WHERE name='v1'; + PRAGMA writable_schema=RESET; + } {} + do_execsql_test 6.2 { + PRAGMA table_list; + } {main v1 view 0 0 0 main t2 table 2 0 0 main t1 table 2 0 0 main sqlite_schema table 5 0 0 temp sqlite_temp_schema table 5 0 0} + do_test 6.3 { + set ::log + } {} + test_sqlite3_log {} } # 2024-05-08 https://sqlite.org/forum/forumpost/cf29a33e94 From 1a4b2117f11fba43ca892936df22681a7c496d46 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 7 Dec 2024 14:48:55 +0000 Subject: [PATCH 435/522] On x64 hardware, round-trip uint64_t→double→uint64_t conversions fail for values greater than UINT64_MAX-2047. This caused the SQLite text-to-float converter routine to give incorrect results for values between '1.8446744073709550592eNNN' and '1.8446744073709551609eNNN' for any exponent NNN. This problem was introduced by check-in [761d8fd18b0ee868] and first appeared in version 3.47.0 and was reported by [forum:/forumpost/569a7209179a7f5e|forum post 569a7209179a7f5e]. Fixed by this check-in. FossilOrigin-Name: 81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/util.c | 14 ++++++++++---- test/atof1.test | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d179789cb4..20304efaa2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_PREPARE_DONT_LOG\soption\sfor\ssqlite3_prepare_v3(),\sthat\sprevents\nerrors\sin\sthe\scompilation\sof\sthe\sSQL\sfrom\sbeing\ssent\sto\ssqlite3_log(). -D 2024-12-06T18:35:16.856 +C On\sx64\shardware,\sround-trip\suint64_t→double→uint64_t\sconversions\nfail\sfor\svalues\sgreater\sthan\sUINT64_MAX-2047.\s\sThis\scaused\sthe\sSQLite\ntext-to-float\sconverter\sroutine\sto\sgive\sincorrect\sresults\sfor\svalues\nbetween\s'1.8446744073709550592eNNN'\sand\s'1.8446744073709551609eNNN'\sfor\sany\nexponent\sNNN.\s\sThis\sproblem\swas\sintroduced\sby\scheck-in\s[761d8fd18b0ee868]\nand\sfirst\sappeared\sin\sversion\s3.47.0\sand\swas\sreported\sby\n[forum:/forumpost/569a7209179a7f5e|forum\spost\s569a7209179a7f5e].\s\sFixed\nby\sthis\scheck-in. +D 2024-12-07T14:48:55.778 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -844,7 +844,7 @@ F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba -F src/util.c ceebf912f673247e305f16f97f0bb7285fca1d37413b79680714a553a9021d33 +F src/util.c fde9ad9ce18841a844ce277b4eb4ace4ada7ca4110f9bed5d1d5ce89dabaf957 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 @@ -910,7 +910,7 @@ F test/analyzeE.test d2ec7921c162cdc33ac8e7eb01f9ebf78100610af7c94c8552bbf551de1 F test/analyzeF.test 40b5cc3ad7b10e81020d7ca86f1417647ecfae7477cfd88acc5aa7ae1068f949 F test/analyzeG.test 623be33038c49648872746c8dd8b23b5792c08fef173c55e82f1b12fca259852 F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49 -F test/atof1.test 7ec56debc04b32e8f9dc87239f4bbb07d84550fb83dd7475b0ead9e83beb35da +F test/atof1.test bd21c4a0e718ab1470de07a2a79f2544d7903be34feebcc80de04beee4807b00 F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061 F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da F test/atrc.c c388fac43dbba05c804432a7135ae688b32e8f25818e9994ffba4b64cf60c27c @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d324be296de443bd2853c732b10960178bf3ba9f18c80c509f6b41e2cfb2f3af -R ec11279f510ab644cd4a136e6f39dd62 +P 870403425493866232cf9e8fa62288861b7d0a4091b15d75727f8bb31da46f94 +R 2d1ae3d1053fb61b1868786464dea794 U drh -Z 8980c884368db10cb1cda65aa0a82ff3 +Z 8f0bbc8ae68469d8947e1d3fa193444c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ab7dd98ed5..78b1357e6c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -870403425493866232cf9e8fa62288861b7d0a4091b15d75727f8bb31da46f94 +81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036 diff --git a/src/util.c b/src/util.c index 52c2a744ca..31b05666a0 100644 --- a/src/util.c +++ b/src/util.c @@ -643,7 +643,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ e = (e*esign) + d; /* Try to adjust the exponent to make it smaller */ - while( e>0 && s<(LARGEST_UINT64/10) ){ + while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){ s *= 10; e--; } @@ -653,11 +653,17 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ } rr[0] = (double)s; - s2 = (u64)rr[0]; + if( s<(LARGEST_UINT64-0x7ff) ){ + s2 = (u64)rr[0]; #if defined(_MSC_VER) && _MSC_VER<1700 - if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } + if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } #endif - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + }else{ + s2 = s; + rr[1] = 0.0; + } + if( e>0 ){ while( e>=100 ){ e -= 100; diff --git a/test/atof1.test b/test/atof1.test index 1a5db2cc79..39747e5da5 100644 --- a/test/atof1.test +++ b/test/atof1.test @@ -82,5 +82,43 @@ do_execsql_test atof1-2.40 { SELECT randomblob(0) - 1; } {-1} +# 2024-12-07 https://sqlite.org/forum/forumpost/569a7209179a7f5e +# Incorrect conversion of floating point or integer literals that +# have significant digits that begin with 1844674407370955 followed +# by more digits in the range 0592 throgh 1609. +# +do_execsql_test atof-3.1 { + WITH RECURSIVE bigval(i,vtxt) AS ( + SELECT 0, '18446744073709550000' + UNION ALL + SELECT i+1, format('1844674407370955%04d',i+1) FROM bigval + WHERE i+1<=9999 + ) + SELECT vtxt, CAST(vtxt AS REAL) FROM bigval + WHERE CAST(vtxt AS REAL) NOT GLOB '1.8446744073709[56]*'; +} {} +do_execsql_test atof-3.2 { + WITH RECURSIVE bigval(i,vtxt) AS ( + SELECT 0, '18.446744073709550000' + UNION ALL + SELECT i+1, format('18.44674407370955%04d',i+1) FROM bigval + WHERE i+1<=9999 + ) + SELECT vtxt, CAST(vtxt AS REAL) FROM bigval + WHERE CAST(vtxt AS REAL) NOT GLOB '18.446744073709*'; +} {} +do_execsql_test atof-3.3 { + WITH RECURSIVE exp(n,v1,v2) AS ( + SELECT -200, '1.8446744073709550592e-200', '1.8446744073709551609e-200' + UNION ALL + SELECT n+1, ('1.8446744073709550592e'||n),('1.8446744073709551609e'||n) + FROM exp WHERE n<200 + ) + SELECT n, v1, v2 + FROM exp + WHERE format('%.10e',CAST(v1 AS REAL)) NOT GLOB '1.8446*' + OR format('%.10e',CAST(v2 AS REAL)) NOT GLOB '1.8446*'; +} {} + finish_test From 45978701089cd4e143aa7b72843390417c4e43be Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 7 Dec 2024 16:53:42 +0000 Subject: [PATCH 436/522] Fix harmless compiler warning caused by the previous check-in. FossilOrigin-Name: 462700aeb7c183d739ead4d726ce5384b3297bcf7929abd010987fa3a5f64807 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 20304efaa2..9b7583d7cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C On\sx64\shardware,\sround-trip\suint64_t→double→uint64_t\sconversions\nfail\sfor\svalues\sgreater\sthan\sUINT64_MAX-2047.\s\sThis\scaused\sthe\sSQLite\ntext-to-float\sconverter\sroutine\sto\sgive\sincorrect\sresults\sfor\svalues\nbetween\s'1.8446744073709550592eNNN'\sand\s'1.8446744073709551609eNNN'\sfor\sany\nexponent\sNNN.\s\sThis\sproblem\swas\sintroduced\sby\scheck-in\s[761d8fd18b0ee868]\nand\sfirst\sappeared\sin\sversion\s3.47.0\sand\swas\sreported\sby\n[forum:/forumpost/569a7209179a7f5e|forum\spost\s569a7209179a7f5e].\s\sFixed\nby\sthis\scheck-in. -D 2024-12-07T14:48:55.778 +C Fix\sharmless\scompiler\swarning\scaused\sby\sthe\sprevious\scheck-in. +D 2024-12-07T16:53:42.327 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -844,7 +844,7 @@ F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba -F src/util.c fde9ad9ce18841a844ce277b4eb4ace4ada7ca4110f9bed5d1d5ce89dabaf957 +F src/util.c 196a1498ed9ab5d3cca55db73ba10348c058c840b0a534e9d5d90db1862a50a1 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 870403425493866232cf9e8fa62288861b7d0a4091b15d75727f8bb31da46f94 -R 2d1ae3d1053fb61b1868786464dea794 +P 81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036 +R e75637f5d04864b72a3d36ee13db9474 U drh -Z 8f0bbc8ae68469d8947e1d3fa193444c +Z f6c4d3a013c59065246d07d8eff3b3d4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 78b1357e6c..c622ec5bdf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036 +462700aeb7c183d739ead4d726ce5384b3297bcf7929abd010987fa3a5f64807 diff --git a/src/util.c b/src/util.c index 31b05666a0..bb676c5fbb 100644 --- a/src/util.c +++ b/src/util.c @@ -540,7 +540,6 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ double rr[2]; - u64 s2; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ @@ -654,13 +653,12 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ rr[0] = (double)s; if( s<(LARGEST_UINT64-0x7ff) ){ - s2 = (u64)rr[0]; + u64 s2 = (u64)rr[0]; #if defined(_MSC_VER) && _MSC_VER<1700 if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } #endif rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); }else{ - s2 = s; rr[1] = 0.0; } From 92d252e06db3fcfb06e5d3f45f4aa6f5e0c7cedc Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 7 Dec 2024 17:08:13 +0000 Subject: [PATCH 437/522] Fix more harmless compiler warnings. FossilOrigin-Name: f5b8fd77635e5e6d2d88a1ce74e1bd6c4311260a2b695e5055b898b880bf5718 --- ext/fts5/fts5_main.c | 1 + ext/misc/vfstrace.c | 4 ++-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 2 ++ 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index d1a45e4e26..876420f24d 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -3667,6 +3667,7 @@ static void fts5InsttokenFunc( sqlite3_value **apArg /* Function arguments */ ){ assert( nArg==1 ); + (void)nArg; sqlite3_result_value(pCtx, apArg[0]); sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE); } diff --git a/ext/misc/vfstrace.c b/ext/misc/vfstrace.c index 3ca32dbd17..e8b51cdd03 100644 --- a/ext/misc/vfstrace.c +++ b/ext/misc/vfstrace.c @@ -637,7 +637,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ } if( zArg[0]=='x' && isalpha(zArg[1]) ) zArg++; for(n=0; isalpha(zArg[n]); n++){} - for(jj=0; jjmTrace |= aKw[jj].m; @@ -796,7 +796,7 @@ static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ if( flags & ~(0xf) ){ sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags); } - if( ofst>=0 && ofst=0 && ofst<(int)(sizeof(azLockName)/sizeof(azLockName[0])) ){ vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d(%s),n=%d,%s)", pInfo->zVfsName, p->zFName, ofst, azLockName[ofst], n, &zLck[1]); diff --git a/manifest b/manifest index 9b7583d7cd..1442a766fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\scaused\sby\sthe\sprevious\scheck-in. -D 2024-12-07T16:53:42.327 +C Fix\smore\sharmless\scompiler\swarnings. +D 2024-12-07T17:08:13.773 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -112,7 +112,7 @@ F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773 F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 F ext/fts5/fts5_index.c cef6791bd9f9db4305494292d6dd5d24a7379aabf370a4d6b559e16b740fa88e -F ext/fts5/fts5_main.c a4f6a46e5ede02d40fc23655d3de37e55f75210ae3856b2b518a2295d3331543 +F ext/fts5/fts5_main.c 72527efa1d634054b93a21eafe854763cbc5c270e8a4ab99bbb589557b818482 F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -453,7 +453,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917 F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d -F ext/misc/vfstrace.c 2f68da859f87be350ede0e8eb94f754219d406161c1595250fc0ca55907460f6 +F ext/misc/vfstrace.c 4d8b39570cbede1a05928c77e2142f8a744468443bf649cf86da3924e5e60fca F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 @@ -778,7 +778,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 1334b0606dbdc753c8333f41bff441c97f77ef8ad9e33f3701e8adfe3b587c28 -F src/shell.c.in 660da73720fc0783a00317568aa098ff1887a0a5cbc0c49138d348d9fc890961 +F src/shell.c.in 883d1470893d15b65724a42a865a25f12e02ee865ab252480d04d467881f87e4 F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036 -R e75637f5d04864b72a3d36ee13db9474 +P 462700aeb7c183d739ead4d726ce5384b3297bcf7929abd010987fa3a5f64807 +R 9ca7022ab896402e14e56ef4a0122fef U drh -Z f6c4d3a013c59065246d07d8eff3b3d4 +Z 5b81dd5db542d45ebbd1ee1a952722cd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c622ec5bdf..db4908810c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -462700aeb7c183d739ead4d726ce5384b3297bcf7929abd010987fa3a5f64807 +f5b8fd77635e5e6d2d88a1ce74e1bd6c4311260a2b695e5055b898b880bf5718 diff --git a/src/shell.c.in b/src/shell.c.in index 2df54d5b3a..e5276258d2 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6637,6 +6637,8 @@ static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){ int rc, i, j; unsigned char bShow[256]; /* Characters ok to display */ + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(azArg); memset(bShow, '.', sizeof(bShow)); for(i=' '; i<='~'; i++){ if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i; From 8703642803df6dc3920239ed85654e92b4cc5451 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 7 Dec 2024 19:06:25 +0000 Subject: [PATCH 438/522] A cleaner and more robust solution to the floating-point conversion problem originally fixed by [81342fa6dd03fffb]. FossilOrigin-Name: 351de57f80b73045448c71d3402d877ff5d72418b1f5fc34c8147a04f7c5cb78 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 17 +++++++++-------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 1442a766fd..8c3849164d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smore\sharmless\scompiler\swarnings. -D 2024-12-07T17:08:13.773 +C A\scleaner\sand\smore\srobust\ssolution\sto\sthe\sfloating-point\sconversion\sproblem\noriginally\sfixed\sby\s[81342fa6dd03fffb]. +D 2024-12-07T19:06:25.786 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -844,7 +844,7 @@ F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba -F src/util.c 196a1498ed9ab5d3cca55db73ba10348c058c840b0a534e9d5d90db1862a50a1 +F src/util.c bf4e641c1e2d5cf40501f5f6990df412d2b6c301880a74750e7eefc4315f72bc F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 462700aeb7c183d739ead4d726ce5384b3297bcf7929abd010987fa3a5f64807 -R 9ca7022ab896402e14e56ef4a0122fef +P f5b8fd77635e5e6d2d88a1ce74e1bd6c4311260a2b695e5055b898b880bf5718 +R 8f59f36dbcd9cf41cdce9fb59aaabbba U drh -Z 5b81dd5db542d45ebbd1ee1a952722cd +Z 7774bee9e6cea167bb38890889846afb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index db4908810c..24849f9a8a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5b8fd77635e5e6d2d88a1ce74e1bd6c4311260a2b695e5055b898b880bf5718 +351de57f80b73045448c71d3402d877ff5d72418b1f5fc34c8147a04f7c5cb78 diff --git a/src/util.c b/src/util.c index bb676c5fbb..e134f7a7d8 100644 --- a/src/util.c +++ b/src/util.c @@ -539,6 +539,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ int eValid = 1; /* True exponent is either not used or is well-formed */ int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ + u64 s2; /* round-tripped significand */ double rr[2]; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); @@ -652,16 +653,16 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ } rr[0] = (double)s; - if( s<(LARGEST_UINT64-0x7ff) ){ - u64 s2 = (u64)rr[0]; -#if defined(_MSC_VER) && _MSC_VER<1700 - if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } -#endif - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); - }else{ + s2 = (u64)rr[0]; + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + if( rr[1]>1e-10*rr[0] ){ + /* On some floating-point processing units, doing the round + ** trip from u64 to double back to u64 can give a wonky value + ** when the original u64 is close to LARGEST_UINT64. If we + ** did get an overly large error value, just set it to zero. */ rr[1] = 0.0; } - + if( e>0 ){ while( e>=100 ){ e -= 100; From 9f53d0c8179a3b69f788bd31749fc7c15092be87 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 7 Dec 2024 19:57:30 +0000 Subject: [PATCH 439/522] Yet another iteration of the solution to the floating-point conversion problem - this what avoids complaints about oversize double values from -fsanitize. FossilOrigin-Name: fc6904a508eb732b1cb5cc12321a0d637d97e1e066a022a2c93cb50595f3a86a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 8c3849164d..37a1d128b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\scleaner\sand\smore\srobust\ssolution\sto\sthe\sfloating-point\sconversion\sproblem\noriginally\sfixed\sby\s[81342fa6dd03fffb]. -D 2024-12-07T19:06:25.786 +C Yet\sanother\siteration\sof\sthe\ssolution\sto\sthe\sfloating-point\sconversion\nproblem\s-\sthis\swhat\savoids\scomplaints\sabout\soversize\sdouble\svalues\nfrom\s-fsanitize. +D 2024-12-07T19:57:30.181 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -844,7 +844,7 @@ F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba -F src/util.c bf4e641c1e2d5cf40501f5f6990df412d2b6c301880a74750e7eefc4315f72bc +F src/util.c aaafeaa62045ad6bc7c62a91d462800fd68f1e441ad944b4350c90930d2b26e4 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f5b8fd77635e5e6d2d88a1ce74e1bd6c4311260a2b695e5055b898b880bf5718 -R 8f59f36dbcd9cf41cdce9fb59aaabbba +P 351de57f80b73045448c71d3402d877ff5d72418b1f5fc34c8147a04f7c5cb78 +R 9235bc27c60f84c2f272e364b7977ec9 U drh -Z 7774bee9e6cea167bb38890889846afb +Z 7dbec0e81d7a36c7e20ad06b81edda4b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 24849f9a8a..cde712b675 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -351de57f80b73045448c71d3402d877ff5d72418b1f5fc34c8147a04f7c5cb78 +fc6904a508eb732b1cb5cc12321a0d637d97e1e066a022a2c93cb50595f3a86a diff --git a/src/util.c b/src/util.c index e134f7a7d8..ab8249c8d5 100644 --- a/src/util.c +++ b/src/util.c @@ -653,15 +653,15 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ } rr[0] = (double)s; - s2 = (u64)rr[0]; - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); - if( rr[1]>1e-10*rr[0] ){ - /* On some floating-point processing units, doing the round - ** trip from u64 to double back to u64 can give a wonky value - ** when the original u64 is close to LARGEST_UINT64. If we - ** did get an overly large error value, just set it to zero. */ + assert( sizeof(s2)==sizeof(rr[0]) ); + memcpy(&s2, &rr[0], sizeof(s2)); + if( s2<=0x43efffffffffffffLL ){ + s2 = (u64)rr[0]; + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + }else{ rr[1] = 0.0; } + assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */ if( e>0 ){ while( e>=100 ){ From 29d1d91502daa2b35a3cd816cb7357ca89991aaa Mon Sep 17 00:00:00 2001 From: stephan Date: Sun, 8 Dec 2024 18:38:40 +0000 Subject: [PATCH 440/522] Add a note in Makefile.msc about EXTRA_SRC files possibly requiring manual editing, as discussed in [forum:903f721f3e7c0d25|forum thread 903f721f3e7c0d25]. FossilOrigin-Name: 229c2f013c171bc220148c78f7db5396578f2c6aac28ad6ff9b687c9fa4998ac --- Makefile.msc | 4 +++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 6da1e399d2..14f2ab8c67 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -19,7 +19,9 @@ USE_AMALGAMATION = 1 # <> # Optionally set EXTRA_SRC to a list of C files to append to -# the generated sqlite3.c. +# the generated sqlite3.c. Any sqlite3 extensions added this +# way may require manual editing, as described in +# https://sqlite.org/forum/forumpost/903f721f3e7c0d25 # !IFNDEF EXTRA_SRC EXTRA_SRC = diff --git a/manifest b/manifest index 37a1d128b2..8409fd7ac5 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Yet\sanother\siteration\sof\sthe\ssolution\sto\sthe\sfloating-point\sconversion\nproblem\s-\sthis\swhat\savoids\scomplaints\sabout\soversize\sdouble\svalues\nfrom\s-fsanitize. -D 2024-12-07T19:57:30.181 +C Add\sa\snote\sin\sMakefile.msc\sabout\sEXTRA_SRC\sfiles\spossibly\srequiring\smanual\sediting,\sas\sdiscussed\sin\s[forum:903f721f3e7c0d25|forum\sthread\s903f721f3e7c0d25]. +D 2024-12-08T18:38:40.817 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in 86e81bdb118bf332a27865090b7dce96ddde93c2f1586e1b911569acaa228f19 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc f8b4097dd93bd19df8fda39ca8b530904c2e7134a28094f490c0dc11abd47ce2 +F Makefile.msc f402bb6ea63b44f5143aa3c637aa3f69794cf14b1cc964eb97c4f53124198561 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 351de57f80b73045448c71d3402d877ff5d72418b1f5fc34c8147a04f7c5cb78 -R 9235bc27c60f84c2f272e364b7977ec9 -U drh -Z 7dbec0e81d7a36c7e20ad06b81edda4b +P fc6904a508eb732b1cb5cc12321a0d637d97e1e066a022a2c93cb50595f3a86a +R 3e289435836b044f0b3a05a6e7cf9761 +U stephan +Z ff68f775396c11772c2696190687380e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cde712b675..d416251529 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc6904a508eb732b1cb5cc12321a0d637d97e1e066a022a2c93cb50595f3a86a +229c2f013c171bc220148c78f7db5396578f2c6aac28ad6ff9b687c9fa4998ac From fd360c39437e05a7e8bf5388152b12ed186b1dd8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 9 Dec 2024 10:52:28 +0000 Subject: [PATCH 441/522] Resynchronize autoconf/Makefile.msc FossilOrigin-Name: 8f9c640818871c451e69f186224bf276f8a03c8d31a76806d81f34922a169f82 --- autoconf/Makefile.msc | 4 +++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 29bb7174fb..c23bbf494a 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -19,7 +19,9 @@ TOP = . # Optionally set EXTRA_SRC to a list of C files to append to -# the generated sqlite3.c. +# the generated sqlite3.c. Any sqlite3 extensions added this +# way may require manual editing, as described in +# https://sqlite.org/forum/forumpost/903f721f3e7c0d25 # !IFNDEF EXTRA_SRC EXTRA_SRC = diff --git a/manifest b/manifest index 8409fd7ac5..91254c4f46 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snote\sin\sMakefile.msc\sabout\sEXTRA_SRC\sfiles\spossibly\srequiring\smanual\sediting,\sas\sdiscussed\sin\s[forum:903f721f3e7c0d25|forum\sthread\s903f721f3e7c0d25]. -D 2024-12-08T18:38:40.817 +C Resynchronize\sautoconf/Makefile.msc +D 2024-12-09T10:52:28.934 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -18,7 +18,7 @@ F auto.def 8f15c373e88c4c5296d6100e3d35893bd6edb57cebcb6a8c1e827e6faaef52e4 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.msc 1162ef7b7937ba6927b038f824b050855784d417e785fe35ab71d20afd18022b +F autoconf/Makefile.msc 0735351f6002f0bf78b73b3b7a6a120cff38573dd37c37005b682ecc44c25bc2 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 5e946ffb6fbdbb114c81e1bdc862df27fce8beab557d7b0421820b0fe8fc048f F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fc6904a508eb732b1cb5cc12321a0d637d97e1e066a022a2c93cb50595f3a86a -R 3e289435836b044f0b3a05a6e7cf9761 -U stephan -Z ff68f775396c11772c2696190687380e +P 229c2f013c171bc220148c78f7db5396578f2c6aac28ad6ff9b687c9fa4998ac +R 50045aa0a973371ebf0a05224448e665 +U drh +Z 15c9820ccf429ada5e7694a1bec9cb28 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d416251529..603d2bc368 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -229c2f013c171bc220148c78f7db5396578f2c6aac28ad6ff9b687c9fa4998ac +8f9c640818871c451e69f186224bf276f8a03c8d31a76806d81f34922a169f82 From 4f5ae3fc4ec70b440d11154d5072961977264765 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 9 Dec 2024 11:12:12 +0000 Subject: [PATCH 442/522] Fix an obscure problem with multiple outer joins, ON clauses and query flattening. Forum [forum:5c8a069d23|thread 5c8a069d23]. FossilOrigin-Name: 289daf6cee39625e8f068179cd58efcc1d28242f46064e58ec4175a019cf48ad --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/select.c | 3 ++- test/select6.test | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 20304efaa2..482a6c0e87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C On\sx64\shardware,\sround-trip\suint64_t→double→uint64_t\sconversions\nfail\sfor\svalues\sgreater\sthan\sUINT64_MAX-2047.\s\sThis\scaused\sthe\sSQLite\ntext-to-float\sconverter\sroutine\sto\sgive\sincorrect\sresults\sfor\svalues\nbetween\s'1.8446744073709550592eNNN'\sand\s'1.8446744073709551609eNNN'\sfor\sany\nexponent\sNNN.\s\sThis\sproblem\swas\sintroduced\sby\scheck-in\s[761d8fd18b0ee868]\nand\sfirst\sappeared\sin\sversion\s3.47.0\sand\swas\sreported\sby\n[forum:/forumpost/569a7209179a7f5e|forum\spost\s569a7209179a7f5e].\s\sFixed\nby\sthis\scheck-in. -D 2024-12-07T14:48:55.778 +C Fix\san\sobscure\sproblem\swith\smultiple\souter\sjoins,\sON\sclauses\sand\squery\sflattening.\sForum\s[forum:5c8a069d23|thread\s5c8a069d23]. +D 2024-12-09T11:12:12.968 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -777,7 +777,7 @@ F src/printf.c 96f7f8baeedc7639da94e4e7a4a2c200e2537c4eec9e5e1c2ffc821f40eb3105 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 1334b0606dbdc753c8333f41bff441c97f77ef8ad9e33f3701e8adfe3b587c28 +F src/select.c 1c2b2321e1658e02f96da96d3071abcaa6839a1d75edd960a75a0ab11b6041bb F src/shell.c.in 660da73720fc0783a00317568aa098ff1887a0a5cbc0c49138d348d9fc890961 F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1607,7 +1607,7 @@ F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 180223af31e1ca5537dd395ef9708ae18e651a233777fd366fd0d75469fc19c6 F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae -F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f +F test/select6.test d455cc36cb5658ba7002ccbf23d3d392801403e64ac6516190266a8ce167ad39 F test/select7.test b825420da8a0b5722fdb77f3369f6396a3d198c46e8787eb26ff9425d4ac9d27 F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test f7586b207ce2304ab80dc93d3146469a28fd4403621dd3a82d06644563d3c812 @@ -2202,8 +2202,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 870403425493866232cf9e8fa62288861b7d0a4091b15d75727f8bb31da46f94 -R 2d1ae3d1053fb61b1868786464dea794 -U drh -Z 8f0bbc8ae68469d8947e1d3fa193444c +P 81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036 +R 3188b2c87a9e8a8a9fb6e913f7cbbec8 +T *branch * forum-5c8a069d23-fix +T *sym-forum-5c8a069d23-fix * +T -sym-trunk * +U dan +Z 0a776cf65bcb8516c8a437501b7f2ac9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 78b1357e6c..ab418d5284 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036 +289daf6cee39625e8f068179cd58efcc1d28242f46064e58ec4175a019cf48ad diff --git a/src/select.c b/src/select.c index 285e9133e7..9d35e1832c 100644 --- a/src/select.c +++ b/src/select.c @@ -4673,6 +4673,7 @@ static int flattenSubquery( /* Transfer the FROM clause terms from the subquery into the ** outer query. */ + iNewParent = pSubSrc->a[0].iCursor; for(i=0; ia[i+iFrom]; assert( pItem->fg.isTabFunc==0 ); @@ -4682,7 +4683,6 @@ static int flattenSubquery( if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); *pItem = pSubSrc->a[i]; pItem->fg.jointype |= ltorj; - iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].fg.jointype &= JT_LTORJ; @@ -4722,6 +4722,7 @@ static int flattenSubquery( pWhere = pSub->pWhere; pSub->pWhere = 0; if( isOuterJoin>0 ){ + assert( pSubSrc->nSrc==1 ); sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON); } if( pWhere ){ diff --git a/test/select6.test b/test/select6.test index 612afefa6f..f748ab47a4 100644 --- a/test/select6.test +++ b/test/select6.test @@ -628,4 +628,43 @@ do_execsql_test 12.100 { SELECT * from t2); } {1 3} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 13.100 { + + CREATE TABLE t1(y INT); + INSERT INTO t1 (y) VALUES (1); + + CREATE TABLE t2(x INTEGER); + INSERT INTO t2 VALUES(0); + + CREATE TABLE empty1(z); +} + +do_execsql_test 13.110 { + SELECT t1.y + FROM ( SELECT 'AAA' ) + INNER JOIN ( + SELECT 1 AS abc FROM ( + SELECT 1 FROM t2 LEFT JOIN empty1 + ) + ) AS sub0 ON sub0.abc + , t1 + RIGHT JOIN (SELECT 'BBB' FROM ( SELECT 'CCC' )) +} {1} + +do_execsql_test 13.120 { + SELECT t1.y + FROM ( SELECT 'AAA' ) + INNER JOIN ( + SELECT 1 AS abc FROM ( + SELECT 1 FROM t2 LEFT JOIN empty1 + ) + ) AS sub0 ON sub0.abc + , t1 + RIGHT JOIN (SELECT 'BBB' FROM ( SELECT 'CCC' )) + WHERE t1.y +} {1} + + finish_test From 54f96dc50e8e9cf97e83284a4291a6016083a9e1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 9 Dec 2024 11:47:28 +0000 Subject: [PATCH 443/522] Further improvements to the decimal-to-float conversion for values close to LARGEST_UINT64. FossilOrigin-Name: 453c949914770e8f7b9b9dd882db492bf8756c212c816f87bb2e3ed98bcd64e3 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/util.c | 10 ++++++++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b8a72d15c7..d9a39bf5b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobscure\sproblem\swith\smultiple\souter\sjoins,\sON\sclauses\sand\squery\sflattening.\sForum\s[forum:5c8a069d23|thread\s5c8a069d23]. -D 2024-12-09T11:37:37.074 +C Further\simprovements\sto\sthe\sdecimal-to-float\sconversion\sfor\svalues\sclose\nto\sLARGEST_UINT64. +D 2024-12-09T11:47:28.504 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -844,7 +844,7 @@ F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba -F src/util.c aaafeaa62045ad6bc7c62a91d462800fd68f1e441ad944b4350c90930d2b26e4 +F src/util.c e5f6a5eeaa26b69054a43bbd0048cfe3d2851f6961052b35aed8f695df922850 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 @@ -2202,9 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a0a36bad454fab55ff39cbada68bf9ec6494d48dc4fc88496c0f637ab100734c 289daf6cee39625e8f068179cd58efcc1d28242f46064e58ec4175a019cf48ad -R 28fa23921e04e393ea4b0633ec5e0abc -T +closed 289daf6cee39625e8f068179cd58efcc1d28242f46064e58ec4175a019cf48ad -U dan -Z 5885f8e9d357b34718ed1f6864ffaf31 +P a350ea7c6b89725ba1a0058c77fc8e918f5cb78e868d100f5425cdee114d1320 +R 9484d813df6a2b3aa12236684aa7bcae +U drh +Z f68f61b73a99f8ed300b60501f5b051a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e16bbd3a34..a0cb8c5331 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a350ea7c6b89725ba1a0058c77fc8e918f5cb78e868d100f5425cdee114d1320 +453c949914770e8f7b9b9dd882db492bf8756c212c816f87bb2e3ed98bcd64e3 diff --git a/src/util.c b/src/util.c index ab8249c8d5..ecce460e01 100644 --- a/src/util.c +++ b/src/util.c @@ -654,8 +654,14 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ rr[0] = (double)s; assert( sizeof(s2)==sizeof(rr[0]) ); - memcpy(&s2, &rr[0], sizeof(s2)); - if( s2<=0x43efffffffffffffLL ){ +#ifdef SQLITE_DEBUG + rr[1] = 18446744073709549568.0; + memcpy(&s2, &rr[1], sizeof(s2)); + assert( s2==0x43efffffffffffffLL ); +#endif + /* Largest double that can be safely converted to u64 + ** vvvvvvvvvvvvvvvvvvvvvv */ + if( rr[0]<=18446744073709549568.0 ){ s2 = (u64)rr[0]; rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); }else{ From c29bc733beaff046e231db7681197df726657acc Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 9 Dec 2024 13:02:13 +0000 Subject: [PATCH 444/522] Add NEVER() around branches that seems to have been made obsolete by [a350ea7c6b89725b]. FossilOrigin-Name: cb5bad5c748b7435c43f3ec051736c1cf91ced2be317b0519e5e22523c137290 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d9a39bf5b8..8da7413b69 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprovements\sto\sthe\sdecimal-to-float\sconversion\sfor\svalues\sclose\nto\sLARGEST_UINT64. -D 2024-12-09T11:47:28.504 +C Add\sNEVER()\saround\sbranches\sthat\sseems\sto\shave\sbeen\smade\sobsolete\sby\n[a350ea7c6b89725b]. +D 2024-12-09T13:02:13.294 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -861,7 +861,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 8b7e309a8012659ac9275ad8cdcc6acaf73fa04b1090e38a01335f230fd10681 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c b34adb09fdb2a4f57a0bafd4194b501047ef383976fef9f0ac3f395f4881694d +F src/where.c 377f3363983251ec6b23aad5a3963822199d9bff2ad4072a5e006959ee5a2abb F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca F src/wherecode.c 0c3d3199a2b769a5e2bb70feb5003dc85b3d86842ecaf903a47f2b4205ca5dab F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a350ea7c6b89725ba1a0058c77fc8e918f5cb78e868d100f5425cdee114d1320 -R 9484d813df6a2b3aa12236684aa7bcae +P 453c949914770e8f7b9b9dd882db492bf8756c212c816f87bb2e3ed98bcd64e3 +R 0384aceb4a3c9ceb2d3aa9887b35dede U drh -Z f68f61b73a99f8ed300b60501f5b051a +Z 41154152da333de7653292dbe9c04f92 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a0cb8c5331..d9834fbaf7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -453c949914770e8f7b9b9dd882db492bf8756c212c816f87bb2e3ed98bcd64e3 +cb5bad5c748b7435c43f3ec051736c1cf91ced2be317b0519e5e22523c137290 diff --git a/src/where.c b/src/where.c index 5abb40eced..20ebaa8cd9 100644 --- a/src/where.c +++ b/src/where.c @@ -839,7 +839,7 @@ static int constraintCompatibleWithOuterJoin( return 0; } if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 - && ExprHasProperty(pTerm->pExpr, EP_InnerON) + && NEVER(ExprHasProperty(pTerm->pExpr, EP_InnerON)) ){ return 0; } @@ -6224,7 +6224,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( } if( hasRightJoin && ExprHasProperty(pTerm->pExpr, EP_InnerON) - && pTerm->pExpr->w.iJoin==pItem->iCursor + && NEVER(pTerm->pExpr->w.iJoin==pItem->iCursor) ){ break; /* restriction (5) */ } From e85e33d39c502f16c30f697f5c591a67615b155d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 9 Dec 2024 20:37:18 +0000 Subject: [PATCH 445/522] Enhance the ".import" command of the CLI so that it is able to insert into a view that has an instead-of trigger. [forum:/info/3e03c73150f8b9f8|Forum post 3e03c73150f8b9f8]. FossilOrigin-Name: 7dcc3731a9057a91f1b173fbab2841d8a666a945d9bc61d4c20f8a2a279d5ff1 --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/shell.c.in | 26 +++++++++++++++++--------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 8da7413b69..9924c0fa36 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sNEVER()\saround\sbranches\sthat\sseems\sto\shave\sbeen\smade\sobsolete\sby\n[a350ea7c6b89725b]. -D 2024-12-09T13:02:13.294 +C Enhance\sthe\s".import"\scommand\sof\sthe\sCLI\sso\sthat\sit\sis\sable\sto\sinsert\sinto\sa\nview\sthat\shas\san\sinstead-of\strigger.\n[forum:/info/3e03c73150f8b9f8|Forum\spost\s3e03c73150f8b9f8]. +D 2024-12-09T20:37:18.846 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -778,7 +778,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 1c2b2321e1658e02f96da96d3071abcaa6839a1d75edd960a75a0ab11b6041bb -F src/shell.c.in 883d1470893d15b65724a42a865a25f12e02ee865ab252480d04d467881f87e4 +F src/shell.c.in ee54de10e9bd5572f689a6bc0c8e6fa58a8870e1670978ded44412d2715fd908 F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2202,8 +2202,9 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 453c949914770e8f7b9b9dd882db492bf8756c212c816f87bb2e3ed98bcd64e3 -R 0384aceb4a3c9ceb2d3aa9887b35dede +P cb5bad5c748b7435c43f3ec051736c1cf91ced2be317b0519e5e22523c137290 +Q +c71acee1cf45abf0429e8b1668315c75b155d7c300d53833aeacd92c9bb3395d +R 8d63ad55d843d7344792036678b73c10 U drh -Z 41154152da333de7653292dbe9c04f92 +Z 4eb938e60b80d29845130c936d5be640 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d9834fbaf7..57f04dbeef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb5bad5c748b7435c43f3ec051736c1cf91ced2be317b0519e5e22523c137290 +7dcc3731a9057a91f1b173fbab2841d8a666a945d9bc61d4c20f8a2a279d5ff1 diff --git a/src/shell.c.in b/src/shell.c.in index e5276258d2..cad8c92c57 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6501,14 +6501,20 @@ static void output_reset(ShellState *p){ /* ** Run an SQL command and return the single integer result. */ -static int db_int(sqlite3 *db, const char *zSql){ +static int db_int(sqlite3 *db, const char *zSql, ...){ sqlite3_stmt *pStmt; int res = 0; - sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + char *z; + va_list ap; + va_start(ap, zSql); + z = sqlite3_vmprintf(zSql, ap); + va_end(ap); + sqlite3_prepare_v2(db, z, -1, &pStmt, 0); if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ res = sqlite3_column_int(pStmt,0); } sqlite3_finalize(pStmt); + sqlite3_free(z); return res; } @@ -6611,9 +6617,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb); } for(i=0; idb, zSql); - sqlite3_free(zSql); + int val = db_int(p->db, aQuery[i].zSql, zSchemaTab); sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); } sqlite3_free(zSchemaTab); @@ -8271,8 +8275,8 @@ FROM (\ }else{ /* Formulate the columns spec, close the DB, zero *pDb. */ char *zColsSpec = 0; - int hasDupes = db_int(*pDb, zHasDupes); - int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0; + int hasDupes = db_int(*pDb, "%s", zHasDupes); + int nDigits = (hasDupes)? db_int(*pDb, "%s", zColDigits) : 0; if( hasDupes ){ #ifdef SHELL_COLUMN_RENAME_CLEAN rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0); @@ -8287,7 +8291,7 @@ FROM (\ sqlite3_finalize(pStmt); if( rc!=SQLITE_DONE ) rc_err_oom_die(SQLITE_NOMEM); } - assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */ + assert(db_int(*pDb, "%s", zHasDupes)==0); /* Consider: remove this */ rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0); rc_err_oom_die(rc); rc = sqlite3_step(pStmt); @@ -9337,7 +9341,11 @@ static int do_meta_command(char *zLine, ShellState *p){ while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){} } import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ - if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0) ){ + if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0) + && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema" + " WHERE name=%Q AND type='view'", + zSchema ? zSchema : "main", zTable) + ){ /* Table does not exist. Create it. */ sqlite3 *dbCols = 0; char *zRenames = 0; From e57527c14f7b7cfa6e32eeab5c549d50c4fa3674 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 9 Dec 2024 20:46:36 +0000 Subject: [PATCH 446/522] Make the TCL interface more rebust against very large strings coming out of TCL9. FossilOrigin-Name: e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 8 +++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 9924c0fa36..9f8827e138 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\s".import"\scommand\sof\sthe\sCLI\sso\sthat\sit\sis\sable\sto\sinsert\sinto\sa\nview\sthat\shas\san\sinstead-of\strigger.\n[forum:/info/3e03c73150f8b9f8|Forum\spost\s3e03c73150f8b9f8]. -D 2024-12-09T20:37:18.846 +C Make\sthe\sTCL\sinterface\smore\srebust\sagainst\svery\slarge\sstrings\scoming\nout\sof\sTCL9. +D 2024-12-09T20:46:36.165 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -786,7 +786,7 @@ F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2c F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 1c2f697cb12a1d49f5e0b448327f7cf614809423bb43753b2d97f87354298113 +F src/tclsqlite.c 90441d3cc16f966a23499d9096a3d2d971e5e8fddb4d1413b096b79c2b2cff07 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 @@ -2202,9 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cb5bad5c748b7435c43f3ec051736c1cf91ced2be317b0519e5e22523c137290 -Q +c71acee1cf45abf0429e8b1668315c75b155d7c300d53833aeacd92c9bb3395d -R 8d63ad55d843d7344792036678b73c10 +P 7dcc3731a9057a91f1b173fbab2841d8a666a945d9bc61d4c20f8a2a279d5ff1 +R e19f4142a15244f80b542d1a07f443fa U drh -Z 4eb938e60b80d29845130c936d5be640 +Z 5bb7b8fb1e527b79d5e286156e101c7f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 57f04dbeef..cc189860b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7dcc3731a9057a91f1b173fbab2841d8a666a945d9bc61d4c20f8a2a279d5ff1 +e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653 diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 4406ceef67..f0b5c3e814 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1133,7 +1133,8 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ } default: { data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); - sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT); + sqlite3_result_text64(context, (char *)data, n, SQLITE_TRANSIENT, + SQLITE_UTF8); break; } } @@ -1519,7 +1520,8 @@ static int dbPrepareAndBind( sqlite3_bind_int64(pStmt, i, v); }else{ data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); - sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC); + sqlite3_bind_text64(pStmt, i, (char *)data, n, SQLITE_STATIC, + SQLITE_UTF8); Tcl_IncrRefCount(pVar); pPreStmt->apParm[iParm++] = pVar; } @@ -3422,7 +3424,7 @@ static int SQLITE_TCLAPI DbObjCmd( enum TTYPE_enum { TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE }; - int i; + Tcl_Size i; if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){ return TCL_ERROR; } From 6e53f67c63771b72d5419265038f428c34fa99d5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 10 Dec 2024 12:32:34 +0000 Subject: [PATCH 447/522] Fix harmless typo in a comment describing the columnMallocFailure() function. FossilOrigin-Name: 0f3b484fd71fd77947a1de7c24f35f8eed2911d0565d03edb7970b8f3092a5da --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeapi.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9f8827e138..b00387a4af 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sTCL\sinterface\smore\srebust\sagainst\svery\slarge\sstrings\scoming\nout\sof\sTCL9. -D 2024-12-09T20:46:36.165 +C Fix\sharmless\stypo\sin\sa\scomment\sdescribing\sthe\scolumnMallocFailure()\sfunction. +D 2024-12-10T12:32:34.191 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -849,7 +849,7 @@ F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e -F src/vdbeapi.c 6353de05e8e78e497ccb33381ba5662ccc11c0339e5b1455faff01b6dacc3075 +F src/vdbeapi.c 38c252a202d70b56cfb734460bc888ddbd581afec1a10cd4d6c894c9e0b5baea F src/vdbeaux.c f0706ad786b8a6c5bc7ea622f3916c2ba2b883abc872d0b4911c4f021945c0e5 F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797 F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7dcc3731a9057a91f1b173fbab2841d8a666a945d9bc61d4c20f8a2a279d5ff1 -R e19f4142a15244f80b542d1a07f443fa +P e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653 +R 2598afb576d42f15287920900e8ec8ce U drh -Z 5bb7b8fb1e527b79d5e286156e101c7f +Z 1b0b57ce5dbae36a7c77d0612b9489d6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cc189860b1..fd05a4c44e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653 +0f3b484fd71fd77947a1de7c24f35f8eed2911d0565d03edb7970b8f3092a5da diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 014ad95393..e33cb2e4d3 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1335,7 +1335,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ ** sqlite3_column_int64() ** sqlite3_column_text() ** sqlite3_column_text16() -** sqlite3_column_real() +** sqlite3_column_double() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() ** sqlite3_column_blob() From 35d302ccb1d79b801d0b8c6a564ab6c1e492df43 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 12 Dec 2024 15:11:27 +0000 Subject: [PATCH 448/522] Increase the maximum number of arguments on an SQL function to 1000 with the capability to increase it further up to 32767 using a compile-time option. FossilOrigin-Name: e8d7d68ba0bb0bc2f948db5d9966990a5d23597fc3658b7cd0bc99d53c7353a9 --- manifest | 32 ++++++++++++++++---------------- manifest.uuid | 2 +- src/expr.c | 2 +- src/main.c | 4 ++-- src/pragma.c | 2 +- src/select.c | 4 ++-- src/sqliteInt.h | 2 +- src/sqliteLimit.h | 6 +++++- src/test_func.c | 4 ++-- src/trigger.c | 2 +- src/vdbeInt.h | 2 +- src/window.c | 2 +- test/func.test | 10 +++++++--- 13 files changed, 41 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index b00387a4af..b23d66dd8b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\stypo\sin\sa\scomment\sdescribing\sthe\scolumnMallocFailure()\sfunction. -D 2024-12-10T12:32:34.191 +C Increase\sthe\smaximum\snumber\sof\sarguments\son\san\sSQL\sfunction\sto\s1000\swith\sthe\ncapability\sto\sincrease\sit\sfurther\sup\sto\s32767\susing\sa\scompile-time\soption. +D 2024-12-12T15:11:27.591 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -727,7 +727,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c 6c52074b0edb914d526c85541ca0f1fd23822b5dac39b6ee9b7f375d9fa592e9 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c ae41eb87e73a7b2e8748b0cf1e8e1d6b2e57fcb9abd093ef3da78f16fed36f33 +F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 @@ -740,7 +740,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70 F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 -F src/main.c efacea3a809ba236233c4bc7648e623c28cb5fd1e1a343e74fe772005f142d8c +F src/main.c 13d20512d7be9c8c316a85b24d0fd0f377a046c4830eb87da08598bd3f49b10f F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 @@ -770,20 +770,20 @@ F src/parse.y dcf45a81b61223ac93e61fdfe9b22d635dd371c446e8222634d90aa37e25e5f6 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 -F src/pragma.c 767accbbbe53f6bacd05d35cfe2b3e6b830b01719010e8c684cb8b126dbad46e +F src/pragma.c ce1182217aa540e034c6da2f17515e3706bf52c837e8222361be9ccd7a9d495a F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126 F src/printf.c 96f7f8baeedc7639da94e4e7a4a2c200e2537c4eec9e5e1c2ffc821f40eb3105 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 1c2b2321e1658e02f96da96d3071abcaa6839a1d75edd960a75a0ab11b6041bb +F src/select.c 83e88fbb36f89b6703b348777491619554f0fd6f917c9fdf51e4c2e9cda6c04e F src/shell.c.in ee54de10e9bd5572f689a6bc0c8e6fa58a8870e1670978ded44412d2715fd908 F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1 -F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88 +F src/sqliteInt.h 3f20dfb5ae54e787b2643edc0b5bae0cecddfb89988e28afdc3c0b05892e25cc +F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 90441d3cc16f966a23499d9096a3d2d971e5e8fddb4d1413b096b79c2b2cff07 @@ -806,7 +806,7 @@ F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383 F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86 F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5 -F src/test_func.c 8c0e89192f70fac307822d1ac2911ee51751288780b3db0c5ab5ca75fa0fe851 +F src/test_func.c 858d4dddb7acf88222ebcba7cffb585f6dde83e4a15b838c0d05ccdf8d5219b9 F src/test_hexio.c 7449504e4bde876ba91b202617a9228c7c8c2e7bd8b957302f3803ac0e9e353c F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5 @@ -840,7 +840,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c fe17e03175cae35b6694d0f879e7bc3d1ddea2fd4ab148cba9bbd025b7a7bb12 F src/treeview.c 921392561385e05ef5703f20a7a72f0a0a45c1fb749558d7467fae2c3f525006 -F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461 +F src/trigger.c 247e2d712d5edc6021d52a169f6ac9a9c10d7144bc4ac7ea06c1ed2aa414659f F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba @@ -848,7 +848,7 @@ F src/util.c e5f6a5eeaa26b69054a43bbd0048cfe3d2851f6961052b35aed8f695df922850 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 -F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e +F src/vdbeInt.h bf294a0c8fc4cc80779e74b04b8bd82c6e1197b3137cefe0b16cdf002fc7dfd6 F src/vdbeapi.c 38c252a202d70b56cfb734460bc888ddbd581afec1a10cd4d6c894c9e0b5baea F src/vdbeaux.c f0706ad786b8a6c5bc7ea622f3916c2ba2b883abc872d0b4911c4f021945c0e5 F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797 @@ -865,7 +865,7 @@ F src/where.c 377f3363983251ec6b23aad5a3963822199d9bff2ad4072a5e006959ee5a2abb F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca F src/wherecode.c 0c3d3199a2b769a5e2bb70feb5003dc85b3d86842ecaf903a47f2b4205ca5dab F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f -F src/window.c 6c386af5972a58f9a9847bba9d7ca70c4c682391ab8478d94a6e046b22a0dbb3 +F src/window.c 2bf01f9941a64fbcead61a0e3cb5db3fca5094b30d2ff0d23274c2a81d2e2385 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9 @@ -1258,7 +1258,7 @@ F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f75 F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9 F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test 098d28ecd1284e0625797a981c9dbf7c1664763af2900f96b9716af80e6cbe40 +F test/func.test e643522c6c67e18b14ac6453f28b39daa7e01d4cdf3b17bee6ec544804be85af F test/func2.test 69f6ae3751b4ec765bdc3b803c0a255aa0f693f28f44805bef03e6b4a3fd242f F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test a02e695f62beb31cb092dccf6873ff97543407fff97a5f3ec4da70b5b337bc84 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653 -R 2598afb576d42f15287920900e8ec8ce +P 0f3b484fd71fd77947a1de7c24f35f8eed2911d0565d03edb7970b8f3092a5da +R d2087c5724f1e2048a55b1212074add0 U drh -Z 1b0b57ce5dbae36a7c77d0612b9489d6 +Z 41468182a628258b57cf14eaed6c922f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fd05a4c44e..dc27bf4513 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f3b484fd71fd77947a1de7c24f35f8eed2911d0565d03edb7970b8f3092a5da +e8d7d68ba0bb0bc2f948db5d9966990a5d23597fc3658b7cd0bc99d53c7353a9 diff --git a/src/expr.c b/src/expr.c index 37923bc84a..86c966683c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -479,7 +479,7 @@ static int codeCompare( p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); - sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); + sqlite3VdbeChangeP5(pParse->pVdbe, (u16)p5); return addr; } diff --git a/src/main.c b/src/main.c index 3a535e3cde..5e9a03a474 100644 --- a/src/main.c +++ b/src/main.c @@ -2857,8 +2857,8 @@ static const int aHardLimit[] = { #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif -#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127 -# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127 +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>32767 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 32767 #endif #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 # error SQLITE_MAX_ATTACHED must be between 0 and 125 diff --git a/src/pragma.c b/src/pragma.c index ae0c86f039..291ccf7af1 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1761,7 +1761,7 @@ void sqlite3Pragma( /* Do the b-tree integrity checks */ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); - sqlite3VdbeChangeP5(v, (u8)i); + sqlite3VdbeChangeP5(v, (u16)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), diff --git a/src/select.c b/src/select.c index 9d35e1832c..cf25c8e678 100644 --- a/src/select.c +++ b/src/select.c @@ -6826,7 +6826,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, iTop); sqlite3ReleaseTempRange(pParse, regAgg, nArg); @@ -6989,7 +6989,7 @@ static void updateAccumulator( } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); } if( addrNext ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index dbdf36200d..b8c9136a59 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1925,7 +1925,7 @@ struct sqlite3 { ** field is used by per-connection app-def functions. */ struct FuncDef { - i8 nArg; /* Number of arguments. -1 means unlimited */ + i16 nArg; /* Number of arguments. -1 means unlimited */ u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index c7185b1c52..620b0f8e5a 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -89,9 +89,13 @@ /* ** The maximum number of arguments to an SQL function. +** +** This value has a hard upper limit of 32767 due to storage +** constraints (it needs to fit inside a i16). We keep it +** lower than that to prevent abuse. */ #ifndef SQLITE_MAX_FUNCTION_ARG -# define SQLITE_MAX_FUNCTION_ARG 127 +# define SQLITE_MAX_FUNCTION_ARG 1000 #endif /* diff --git a/src/test_func.c b/src/test_func.c index 8c06705ae4..82f7b3d9ca 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -773,7 +773,7 @@ static int SQLITE_TCLAPI abuse_create_function( rc = sqlite3_create_function(db, "tx", -2, SQLITE_UTF8, 0, tStep, 0, 0); if( rc!=SQLITE_MISUSE ) goto abuse_err; - rc = sqlite3_create_function(db, "tx", 128, SQLITE_UTF8, 0, tStep, 0, 0); + rc = sqlite3_create_function(db, "tx", 32768, SQLITE_UTF8, 0, tStep, 0, 0); if( rc!=SQLITE_MISUSE ) goto abuse_err; rc = sqlite3_create_function(db, "funcxx" @@ -789,7 +789,7 @@ static int SQLITE_TCLAPI abuse_create_function( ** a no-op function (that always returns NULL) and which has the ** maximum-length function name and the maximum number of parameters. */ - sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, 10000); + sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, 1000000); mxArg = sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, -1); rc = sqlite3_create_function(db, "nullx" "_123456789_123456789_123456789_123456789_123456789" diff --git a/src/trigger.c b/src/trigger.c index ff2df82cbc..e306a2e664 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -1409,7 +1409,7 @@ void sqlite3CodeRowTriggerDirect( ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ - sqlite3VdbeChangeP5(v, (u8)bRecursive); + sqlite3VdbeChangeP5(v, (u16)bRecursive); } } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 467f488905..2cb4f8c2a1 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -393,7 +393,7 @@ struct sqlite3_context { int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ - u8 argc; /* Number of arguments */ + u16 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; diff --git a/src/window.c b/src/window.c index acc6ea8546..8373e36413 100644 --- a/src/window.c +++ b/src/window.c @@ -1751,7 +1751,7 @@ static void windowAggStep( sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); if( pWin->bExprArgs ){ sqlite3ReleaseTempRange(pParse, regArg, nArg); } diff --git a/test/func.test b/test/func.test index 228adcc2d6..73ff2b7355 100644 --- a/test/func.test +++ b/test/func.test @@ -1183,7 +1183,9 @@ set midargs {} unset -nocomplain midres set midres {} unset -nocomplain result -for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} { +set limit [sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1] +if {$limit>400} {set limit 400} +for {set i 1} {$i<$limit} {incr i} { append midargs ,'/$i' append midres /$i set result [md5 \ @@ -1261,7 +1263,8 @@ do_test func-26.1 { # do_test func-26.2 { set a {} - for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} { + set limit $::SQLITE_MAX_FUNCTION_ARG + for {set i 1} {$i<=$limit} {incr i} { lappend a $i } db eval " @@ -1279,7 +1282,8 @@ do_test func-26.3 { } {1 {too many arguments on function nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789}} do_test func-26.4 { set a {} - for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} { + set limit [expr {$::SQLITE_MAX_FUNCTION_ARG-1}] + for {set i 1} {$i<=$limit} {incr i} { lappend a $i } catchsql " From 9ee02515c45b8de7586e01024221cd9eb4d9b40b Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 13 Dec 2024 01:29:22 +0000 Subject: [PATCH 449/522] Fix a harmless compiler warning that comes up when using SQLITE_DEBUG in separate compilation mode. FossilOrigin-Name: 52e0f8cab9852538da0778d5f57dd85b0774e764157692111a007aecd963f10a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 2 -- src/where.c | 1 + 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index b23d66dd8b..37a5ca6607 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\smaximum\snumber\sof\sarguments\son\san\sSQL\sfunction\sto\s1000\swith\sthe\ncapability\sto\sincrease\sit\sfurther\sup\sto\s32767\susing\sa\scompile-time\soption. -D 2024-12-12T15:11:27.591 +C Fix\sa\sharmless\scompiler\swarning\sthat\scomes\sup\swhen\susing\sSQLITE_DEBUG\sin\nseparate\scompilation\smode. +D 2024-12-13T01:29:22.397 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -740,7 +740,7 @@ F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70 F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 -F src/main.c 13d20512d7be9c8c316a85b24d0fd0f377a046c4830eb87da08598bd3f49b10f +F src/main.c a19dc8b47760ed95f3fbb255cfa8d3f7146b33c263eb4af05ab05e0115d161b9 F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 @@ -861,7 +861,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 8b7e309a8012659ac9275ad8cdcc6acaf73fa04b1090e38a01335f230fd10681 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c 377f3363983251ec6b23aad5a3963822199d9bff2ad4072a5e006959ee5a2abb +F src/where.c 9ad3dea8003a8913da6a4ca8322e2fe30773f46e88a0d4fbf9db13bdb999efa2 F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca F src/wherecode.c 0c3d3199a2b769a5e2bb70feb5003dc85b3d86842ecaf903a47f2b4205ca5dab F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0f3b484fd71fd77947a1de7c24f35f8eed2911d0565d03edb7970b8f3092a5da -R d2087c5724f1e2048a55b1212074add0 +P e8d7d68ba0bb0bc2f948db5d9966990a5d23597fc3658b7cd0bc99d53c7353a9 +R 5cbe0e5d51e97ea31f8e1a24559f27b0 U drh -Z 41468182a628258b57cf14eaed6c922f +Z 0752bc133a053f7fece0328823dfa9c8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dc27bf4513..4e1eaec06a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8d7d68ba0bb0bc2f948db5d9966990a5d23597fc3658b7cd0bc99d53c7353a9 +52e0f8cab9852538da0778d5f57dd85b0774e764157692111a007aecd963f10a diff --git a/src/main.c b/src/main.c index 5e9a03a474..1163deb6e3 100644 --- a/src/main.c +++ b/src/main.c @@ -4270,7 +4270,6 @@ int sqlite3_test_control(int op, ...){ /* Invoke these debugging routines so that the compiler does not ** issue "defined but not used" warnings. */ if( x==9999 ){ - sqlite3ShowExpr(0); sqlite3ShowExpr(0); sqlite3ShowExprList(0); sqlite3ShowIdList(0); @@ -4288,7 +4287,6 @@ int sqlite3_test_control(int op, ...){ sqlite3ShowWinFunc(0); #endif sqlite3ShowSelect(0); - sqlite3ShowWhereTerm(0); } #endif break; diff --git a/src/where.c b/src/where.c index 20ebaa8cd9..c9698699b3 100644 --- a/src/where.c +++ b/src/where.c @@ -7144,6 +7144,7 @@ WhereInfo *sqlite3WhereBegin( ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; sqlite3VdbePrintOp(0, pc, pOp); + sqlite3ShowWhereTerm(0); /* So compiler won't complain about unused func */ } #endif From bba19534264983f79c3027cd964940e24a76eaed Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 16 Dec 2024 07:03:12 +0000 Subject: [PATCH 450/522] Tiny makefile/configure script doc tweaks. No functional changes. FossilOrigin-Name: ed5e912622839dce76dfb7352b56bb6fc698ecffde195f48db8d3339e9628cb5 --- Makefile.in | 4 ++-- auto.def | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Makefile.in b/Makefile.in index 75c1f47dcf..5b17c0e426 100644 --- a/Makefile.in +++ b/Makefile.in @@ -207,8 +207,8 @@ TCL_CONFIG_SH = @TCL_CONFIG_SH@ # $(TCLLIBDIR) = where to install the tcl plugin. If this is empty, it # is calculated at make-time by the targets which need it but we # export it here so that it can be set at configure-time, so that -# clients are not required to pass it at make-time, or set it in their -# environment, to override it. +# clients are not required to pass it at make-time, or may set it in +# their environment to override it. # TCLLIBDIR = @TCLLIBDIR@ diff --git a/auto.def b/auto.def index 7b57e9599b..c52ce44986 100644 --- a/auto.def +++ b/auto.def @@ -1358,7 +1358,7 @@ apply {{} { # # We do this late in the config process, immediately before we export # the Makefile and other generated files, so that configure tests -# which may make use of the autotools-conventional flags +# which make make use of the autotools-conventional flags # (e.g. [proj-check-rpath]) may do so before we "mangle" them here. proj-remap-autoconf-dir-vars diff --git a/manifest b/manifest index 37a5ca6607..706d45185b 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sa\sharmless\scompiler\swarning\sthat\scomes\sup\swhen\susing\sSQLITE_DEBUG\sin\nseparate\scompilation\smode. -D 2024-12-13T01:29:22.397 +C Tiny\smakefile/configure\sscript\sdoc\stweaks.\sNo\sfunctional\schanges. +D 2024-12-16T07:03:12.241 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d -F Makefile.in 86e81bdb118bf332a27865090b7dce96ddde93c2f1586e1b911569acaa228f19 +F Makefile.in ad349acf91b3569033439fe498fa197aa530cafaa01362eb7daad2f84e43d265 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc f402bb6ea63b44f5143aa3c637aa3f69794cf14b1cc964eb97c4f53124198561 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -14,7 +14,7 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531 -F auto.def 8f15c373e88c4c5296d6100e3d35893bd6edb57cebcb6a8c1e827e6faaef52e4 +F auto.def f2876c94403be1055db47273dde33e8fea0998b1c1d36a386f76698919ea36ad F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e8d7d68ba0bb0bc2f948db5d9966990a5d23597fc3658b7cd0bc99d53c7353a9 -R 5cbe0e5d51e97ea31f8e1a24559f27b0 -U drh -Z 0752bc133a053f7fece0328823dfa9c8 +P 52e0f8cab9852538da0778d5f57dd85b0774e764157692111a007aecd963f10a +R 89eec167649f7e56f45710cfe9ae12c6 +U stephan +Z da9c21e8a76fc0e0ce1fc5f35c3f13d0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4e1eaec06a..284e95940f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52e0f8cab9852538da0778d5f57dd85b0774e764157692111a007aecd963f10a +ed5e912622839dce76dfb7352b56bb6fc698ecffde195f48db8d3339e9628cb5 From 276172e4a3cb1ca03e6b498776b735378030efdb Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 16 Dec 2024 12:08:47 +0000 Subject: [PATCH 451/522] Remove unnecessary end-of-line whitespace. FossilOrigin-Name: ae580443d210811c12209866112fc8b0b83281e24945504b748a17d93ad84062 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wal.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 706d45185b..ca3037f8a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tiny\smakefile/configure\sscript\sdoc\stweaks.\sNo\sfunctional\schanges. -D 2024-12-16T07:03:12.241 +C Remove\sunnecessary\send-of-line\swhitespace. +D 2024-12-16T12:08:47.781 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -858,7 +858,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 8b7e309a8012659ac9275ad8cdcc6acaf73fa04b1090e38a01335f230fd10681 +F src/wal.c fcbc36c31df200daa4ed398923ab55a02dbbed9ce22a8a31c5d9bf447a130126 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 9ad3dea8003a8913da6a4ca8322e2fe30773f46e88a0d4fbf9db13bdb999efa2 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 52e0f8cab9852538da0778d5f57dd85b0774e764157692111a007aecd963f10a -R 89eec167649f7e56f45710cfe9ae12c6 -U stephan -Z da9c21e8a76fc0e0ce1fc5f35c3f13d0 +P ed5e912622839dce76dfb7352b56bb6fc698ecffde195f48db8d3339e9628cb5 +R 50452c481dab7840c92f4813a0b34c39 +U drh +Z 629c78c1cfb191194be6c80039586a1c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 284e95940f..2dbca5c412 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed5e912622839dce76dfb7352b56bb6fc698ecffde195f48db8d3339e9628cb5 +ae580443d210811c12209866112fc8b0b83281e24945504b748a17d93ad84062 diff --git a/src/wal.c b/src/wal.c index ea9bc4df88..7bd122562a 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3737,12 +3737,12 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ SEH_TRY { /* Restore the clients cache of the wal-index header to the state it - ** was in before the client began writing to the database. + ** was in before the client began writing to the database. */ memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); - - for(iFrame=pWal->hdr.mxFrame+1; - ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; + + for(iFrame=pWal->hdr.mxFrame+1; + ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; iFrame++ ){ /* This call cannot fail. Unless the page for which the page number From bd1a5932d9fe3b9b75a6cf22bb7e96063f28ccec Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 16 Dec 2024 13:25:49 +0000 Subject: [PATCH 452/522] Changes for better alignment with the wal2 branch. FossilOrigin-Name: 4fab85b3d0d1cad2d185f2456de7ddf281badf8561cc051e10e16655441dcc84 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 16 +--------------- src/pager.h | 16 ++++++++++++++++ 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index ca3037f8a3..ec51b7c0e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\send-of-line\swhitespace. -D 2024-12-16T12:08:47.781 +C Changes\sfor\sbetter\salignment\swith\sthe\swal2\sbranch. +D 2024-12-16T13:25:49.902 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -764,8 +764,8 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210 F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6 F src/os_win.c 49c7725b500f5867e8360e75eeb30f9d70b62fa1f05c8a101da627210578df32 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9 -F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a +F src/pager.c 2fdd489447aa6bb0f672973bacb801ced92225ca9a1c874ed9b856d2741dc54e +F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 F src/parse.y dcf45a81b61223ac93e61fdfe9b22d635dd371c446e8222634d90aa37e25e5f6 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ed5e912622839dce76dfb7352b56bb6fc698ecffde195f48db8d3339e9628cb5 -R 50452c481dab7840c92f4813a0b34c39 +P ae580443d210811c12209866112fc8b0b83281e24945504b748a17d93ad84062 +R dc9095f065111bf3b125973079f69b6b U drh -Z 629c78c1cfb191194be6c80039586a1c +Z 26e0562f544e2adce22ef893d4b0b579 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2dbca5c412..9fb6b9c8db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae580443d210811c12209866112fc8b0b83281e24945504b748a17d93ad84062 +4fab85b3d0d1cad2d185f2456de7ddf281badf8561cc051e10e16655441dcc84 diff --git a/src/pager.c b/src/pager.c index 4f616f0c7f..e2dbbeae3f 100644 --- a/src/pager.c +++ b/src/pager.c @@ -789,20 +789,6 @@ static const unsigned char aJournalMagic[] = { # define USEFETCH(x) 0 #endif -/* -** The argument to this macro is a file descriptor (type sqlite3_file*). -** Return 0 if it is not open, or non-zero (but not 1) if it is. -** -** This is so that expressions can be written as: -** -** if( isOpen(pPager->jfd) ){ ... -** -** instead of -** -** if( pPager->jfd->pMethods ){ ... -*/ -#define isOpen(pFd) ((pFd)->pMethods!=0) - #ifdef SQLITE_DIRECT_OVERFLOW_READ /* ** Return true if page pgno can be read directly from the database file @@ -2088,7 +2074,7 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ } pPager->journalOff = 0; }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST - || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) + || (pPager->exclusiveMode && pPager->journalModetempFile); pPager->journalOff = 0; diff --git a/src/pager.h b/src/pager.h index 7ef9a237ae..9b2cfc0bcf 100644 --- a/src/pager.h +++ b/src/pager.h @@ -83,6 +83,22 @@ typedef struct PgHdr DbPage; #define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ #define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ +#define isWalMode(x) ((x)==PAGER_JOURNALMODE_WAL) + +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods!=0) + /* ** Flags that make up the mask passed to sqlite3PagerGet(). */ From 32dd04b41e6d4f32b1181163b95317515b689b35 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 16 Dec 2024 18:04:39 +0000 Subject: [PATCH 453/522] Code formatting changes to make trunk more like wal2. FossilOrigin-Name: 8f725472b0fe62359a4cd3237b43d7b834e042d8ce425abde06e3ed6c62dbafa --- manifest | 12 +-- manifest.uuid | 2 +- src/wal.c | 254 +++++++++++++++++++++++++------------------------- 3 files changed, 135 insertions(+), 133 deletions(-) diff --git a/manifest b/manifest index ec51b7c0e9..09541b416a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sfor\sbetter\salignment\swith\sthe\swal2\sbranch. -D 2024-12-16T13:25:49.902 +C Code\sformatting\schanges\sto\smake\strunk\smore\slike\swal2. +D 2024-12-16T18:04:39.151 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -858,7 +858,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c fcbc36c31df200daa4ed398923ab55a02dbbed9ce22a8a31c5d9bf447a130126 +F src/wal.c 4e6181d8780ab0af2e1388d0754cbe6f2f04593d2b1ab6c41699a89942fd8997 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 9ad3dea8003a8913da6a4ca8322e2fe30773f46e88a0d4fbf9db13bdb999efa2 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ae580443d210811c12209866112fc8b0b83281e24945504b748a17d93ad84062 -R dc9095f065111bf3b125973079f69b6b +P 4fab85b3d0d1cad2d185f2456de7ddf281badf8561cc051e10e16655441dcc84 +R 9aaaecad314aea90d45c80b60798b57a U drh -Z 26e0562f544e2adce22ef893d4b0b579 +Z 2a765bcb487b40c3fb2da87580a07616 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9fb6b9c8db..2eb63b396b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4fab85b3d0d1cad2d185f2456de7ddf281badf8561cc051e10e16655441dcc84 +8f725472b0fe62359a4cd3237b43d7b834e042d8ce425abde06e3ed6c62dbafa diff --git a/src/wal.c b/src/wal.c index 7bd122562a..42ce3cb97b 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2986,11 +2986,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ */ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ - u32 mxReadMark; /* Largest aReadMark[] value */ - int mxI; /* Index of largest aReadMark[] value */ - int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ - u32 mxFrame; /* Wal frame to lock to */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT int nBlockTmout = 0; #endif @@ -3096,141 +3092,147 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ assert( pWal->apWiData[0]!=0 ); pInfo = walCkptInfo(pWal); SEH_INJECT_FAULT; - if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame + { + u32 mxReadMark; /* Largest aReadMark[] value */ + int mxI; /* Index of largest aReadMark[] value */ + int i; /* Loop counter */ + u32 mxFrame; /* Wal frame to lock to */ + if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT - && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) + && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) #endif - ){ - /* The WAL has been completely backfilled (or it is empty). - ** and can be safely ignored. - */ - rc = walLockShared(pWal, WAL_READ_LOCK(0)); - walShmBarrier(pWal); - if( rc==SQLITE_OK ){ - if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ - /* It is not safe to allow the reader to continue here if frames - ** may have been appended to the log before READ_LOCK(0) was obtained. - ** When holding READ_LOCK(0), the reader ignores the entire log file, - ** which implies that the database file contains a trustworthy - ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from - ** happening, this is usually correct. - ** - ** However, if frames have been appended to the log (or if the log - ** is wrapped and written for that matter) before the READ_LOCK(0) - ** is obtained, that is not necessarily true. A checkpointer may - ** have started to backfill the appended frames but crashed before - ** it finished. Leaving a corrupt image in the database file. - */ - walUnlockShared(pWal, WAL_READ_LOCK(0)); - return WAL_RETRY; + ){ + /* The WAL has been completely backfilled (or it is empty). + ** and can be safely ignored. + */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + walShmBarrier(pWal); + if( rc==SQLITE_OK ){ + if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr,sizeof(WalIndexHdr)) ){ + /* It is not safe to allow the reader to continue here if frames + ** may have been appended to the log before READ_LOCK(0) was obtained. + ** When holding READ_LOCK(0), the reader ignores the entire log file, + ** which implies that the database file contains a trustworthy + ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from + ** happening, this is usually correct. + ** + ** However, if frames have been appended to the log (or if the log + ** is wrapped and written for that matter) before the READ_LOCK(0) + ** is obtained, that is not necessarily true. A checkpointer may + ** have started to backfill the appended frames but crashed before + ** it finished. Leaving a corrupt image in the database file. + */ + walUnlockShared(pWal, WAL_READ_LOCK(0)); + return WAL_RETRY; + } + pWal->readLock = 0; + return SQLITE_OK; + }else if( rc!=SQLITE_BUSY ){ + return rc; } - pWal->readLock = 0; - return SQLITE_OK; - }else if( rc!=SQLITE_BUSY ){ - return rc; } - } - - /* If we get this far, it means that the reader will want to use - ** the WAL to get at content from recent commits. The job now is - ** to select one of the aReadMark[] entries that is closest to - ** but not exceeding pWal->hdr.mxFrame and lock that entry. - */ - mxReadMark = 0; - mxI = 0; - mxFrame = pWal->hdr.mxFrame; + + /* If we get this far, it means that the reader will want to use + ** the WAL to get at content from recent commits. The job now is + ** to select one of the aReadMark[] entries that is closest to + ** but not exceeding pWal->hdr.mxFrame and lock that entry. + */ + mxReadMark = 0; + mxI = 0; + mxFrame = pWal->hdr.mxFrame; #ifdef SQLITE_ENABLE_SNAPSHOT - if( pWal->pSnapshot && pWal->pSnapshot->mxFramepSnapshot->mxFrame; - } -#endif - for(i=1; iaReadMark+i); SEH_INJECT_FAULT; - if( mxReadMark<=thisMark && thisMark<=mxFrame ){ - assert( thisMark!=READMARK_NOT_USED ); - mxReadMark = thisMark; - mxI = i; + if( pWal->pSnapshot && pWal->pSnapshot->mxFramepSnapshot->mxFrame; } - } - if( (pWal->readOnly & WAL_SHM_RDONLY)==0 - && (mxReadMarkaReadMark+i,mxFrame); - mxReadMark = mxFrame; + u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; + if( mxReadMark<=thisMark && thisMark<=mxFrame ){ + assert( thisMark!=READMARK_NOT_USED ); + mxReadMark = thisMark; mxI = i; - walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); - break; - }else if( rc!=SQLITE_BUSY ){ - return rc; } } - } - if( mxI==0 ){ - assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); - return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; - } - - (void)walEnableBlockingMs(pWal, nBlockTmout); - rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); - walDisableBlocking(pWal); - if( rc ){ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - if( rc==SQLITE_BUSY_TIMEOUT ){ - *pCnt |= WAL_RETRY_BLOCKED_MASK; + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMarkaReadMark+i,mxFrame); + mxReadMark = mxFrame; + mxI = i; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + break; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + } + if( mxI==0 ){ + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; } + + (void)walEnableBlockingMs(pWal, nBlockTmout); + rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + walDisableBlocking(pWal); + if( rc ){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } #else - assert( rc!=SQLITE_BUSY_TIMEOUT ); + assert( rc!=SQLITE_BUSY_TIMEOUT ); #endif - assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT ); - return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; - } - /* Now that the read-lock has been obtained, check that neither the - ** value in the aReadMark[] array or the contents of the wal-index - ** header have changed. - ** - ** It is necessary to check that the wal-index header did not change - ** between the time it was read and when the shared-lock was obtained - ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility - ** that the log file may have been wrapped by a writer, or that frames - ** that occur later in the log than pWal->hdr.mxFrame may have been - ** copied into the database by a checkpointer. If either of these things - ** happened, then reading the database with the current value of - ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry - ** instead. - ** - ** Before checking that the live wal-index header has not changed - ** since it was read, set Wal.minFrame to the first frame in the wal - ** file that has not yet been checkpointed. This client will not need - ** to read any frames earlier than minFrame from the wal file - they - ** can be safely read directly from the database file. - ** - ** Because a ShmBarrier() call is made between taking the copy of - ** nBackfill and checking that the wal-header in shared-memory still - ** matches the one cached in pWal->hdr, it is guaranteed that the - ** checkpointer that set nBackfill was not working with a wal-index - ** header newer than that cached in pWal->hdr. If it were, that could - ** cause a problem. The checkpointer could omit to checkpoint - ** a version of page X that lies before pWal->minFrame (call that version - ** A) on the basis that there is a newer version (version B) of the same - ** page later in the wal file. But if version B happens to like past - ** frame pWal->hdr.mxFrame - then the client would incorrectly assume - ** that it can read version A from the database file. However, since - ** we can guarantee that the checkpointer that set nBackfill could not - ** see any pages past pWal->hdr.mxFrame, this problem does not come up. - */ - pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; - walShmBarrier(pWal); - if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark - || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) - ){ - walUnlockShared(pWal, WAL_READ_LOCK(mxI)); - return WAL_RETRY; - }else{ - assert( mxReadMark<=pWal->hdr.mxFrame ); - pWal->readLock = (i16)mxI; + assert((rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT); + return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; + } + /* Now that the read-lock has been obtained, check that neither the + ** value in the aReadMark[] array or the contents of the wal-index + ** header have changed. + ** + ** It is necessary to check that the wal-index header did not change + ** between the time it was read and when the shared-lock was obtained + ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility + ** that the log file may have been wrapped by a writer, or that frames + ** that occur later in the log than pWal->hdr.mxFrame may have been + ** copied into the database by a checkpointer. If either of these things + ** happened, then reading the database with the current value of + ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry + ** instead. + ** + ** Before checking that the live wal-index header has not changed + ** since it was read, set Wal.minFrame to the first frame in the wal + ** file that has not yet been checkpointed. This client will not need + ** to read any frames earlier than minFrame from the wal file - they + ** can be safely read directly from the database file. + ** + ** Because a ShmBarrier() call is made between taking the copy of + ** nBackfill and checking that the wal-header in shared-memory still + ** matches the one cached in pWal->hdr, it is guaranteed that the + ** checkpointer that set nBackfill was not working with a wal-index + ** header newer than that cached in pWal->hdr. If it were, that could + ** cause a problem. The checkpointer could omit to checkpoint + ** a version of page X that lies before pWal->minFrame (call that version + ** A) on the basis that there is a newer version (version B) of the same + ** page later in the wal file. But if version B happens to like past + ** frame pWal->hdr.mxFrame - then the client would incorrectly assume + ** that it can read version A from the database file. However, since + ** we can guarantee that the checkpointer that set nBackfill could not + ** see any pages past pWal->hdr.mxFrame, this problem does not come up. + */ + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; + walShmBarrier(pWal); + if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark + || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) + ){ + walUnlockShared(pWal, WAL_READ_LOCK(mxI)); + return WAL_RETRY; + }else{ + assert( mxReadMark<=pWal->hdr.mxFrame ); + pWal->readLock = (i16)mxI; + } } return rc; } From 2fb488d10af0068581b9096225d1a68c9563562f Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 17 Dec 2024 14:32:37 +0000 Subject: [PATCH 454/522] Do not attempt to truncate a database in sqlite_dbpage if the database is not larger than the requested truncation size. FossilOrigin-Name: cf8b99e17872c054e7ac0832d12633ce497c843dfc67148daf3b17762fd2b424 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/dbpage.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 09541b416a..bdec535f48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Code\sformatting\schanges\sto\smake\strunk\smore\slike\swal2. -D 2024-12-16T18:04:39.151 +C Do\snot\sattempt\sto\struncate\sa\sdatabase\sin\ssqlite_dbpage\sif\sthe\sdatabase\sis\nnot\slarger\sthan\sthe\srequested\struncation\ssize. +D 2024-12-17T14:32:37.037 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -724,7 +724,7 @@ F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d49 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a -F src/dbpage.c 6c52074b0edb914d526c85541ca0f1fd23822b5dac39b6ee9b7f375d9fa592e9 +F src/dbpage.c d1778e74b15549e3967974b5addf740462db1a9d441da35666177f5a6ccf34c5 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4fab85b3d0d1cad2d185f2456de7ddf281badf8561cc051e10e16655441dcc84 -R 9aaaecad314aea90d45c80b60798b57a +P 8f725472b0fe62359a4cd3237b43d7b834e042d8ce425abde06e3ed6c62dbafa +R f83865aeabb05b29d2a4c65bc73bad9b U drh -Z 2a765bcb487b40c3fb2da87580a07616 +Z 186addad6fd799939fab1f666168b1b5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2eb63b396b..b955e088a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f725472b0fe62359a4cd3237b43d7b834e042d8ce425abde06e3ed6c62dbafa +cf8b99e17872c054e7ac0832d12633ce497c843dfc67148daf3b17762fd2b424 diff --git a/src/dbpage.c b/src/dbpage.c index 124952456c..3bb18b6775 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -428,7 +428,9 @@ static int dbpageSync(sqlite3_vtab *pVtab){ if( pTab->pgnoTrunc>0 ){ Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt; Pager *pPager = sqlite3BtreePager(pBt); - sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); + if( pTab->pgnoTruncpgnoTrunc); + } } pTab->pgnoTrunc = 0; return SQLITE_OK; From 0c34eab477b78431615a75319d918200ed59c5fe Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 18 Dec 2024 03:41:29 +0000 Subject: [PATCH 455/522] Rename some var refs in ext/lsm1/Makefile for the new build process. FossilOrigin-Name: 0ce42fa586049e8864c5fd1a1d8703722f8549ba0a20ca748b887b7975ba9eb7 --- ext/lsm1/Makefile | 10 +++++----- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/lsm1/Makefile b/ext/lsm1/Makefile index 7056432d2d..d497a1d133 100644 --- a/ext/lsm1/Makefile +++ b/ext/lsm1/Makefile @@ -46,11 +46,11 @@ LSMTESTSRC = $(LSMDIR)/lsm-test/lsmtest1.c $(LSMDIR)/lsm-test/lsmtest2.c \ LSMOPTS += -fPIC -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB lsm.so: $(LSMOBJ) - $(TCCX) -shared -fPIC -o lsm.so $(LSMOBJ) + $(T.link) -shared -fPIC -o lsm.so $(LSMOBJ) %.o: $(LSMDIR)/%.c $(LSMHDR) sqlite3.h - $(TCCX) $(LSMOPTS) -c $< - + $(T.link) $(LSMOPTS) -c $< + lsmtest$(EXE): $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) sqlite3.o - # $(TCPPX) -c $(TOP)/lsm-test/lsmtest_tdb2.cc - $(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) -lz + # $(T.link) -c $(TOP)/lsm-test/lsmtest_tdb2.cc + $(T.link) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) -lz diff --git a/manifest b/manifest index bdec535f48..e451f68c58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sattempt\sto\struncate\sa\sdatabase\sin\ssqlite_dbpage\sif\sthe\sdatabase\sis\nnot\slarger\sthan\sthe\srequested\struncation\ssize. -D 2024-12-17T14:32:37.037 +C Rename\ssome\svar\srefs\sin\sext/lsm1/Makefile\sfor\sthe\snew\sbuild\sprocess. +D 2024-12-18T03:41:29.636 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -350,7 +350,7 @@ F ext/jni/src/org/sqlite/jni/wrapper1/WindowFunction.java c7d1452f9ff26175b3c19b F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745 F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70 F ext/jni/src/tests/900-001-fts.test bf0ce17a8d082773450e91f2388f5bbb2dfa316d0b676c313c637a91198090f0 -F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9 +F ext/lsm1/Makefile 851a8108af2f00d6086b7be8a76fe54eabe2dd4cfd4171fd39285c5b11bee90d F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 F ext/lsm1/lsm-test/lsmtest.h cf58528ffe0cfe535e91b44584e2ec5fb1caacdabecef0d8dcf83bf83168bf28 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8f725472b0fe62359a4cd3237b43d7b834e042d8ce425abde06e3ed6c62dbafa -R f83865aeabb05b29d2a4c65bc73bad9b -U drh -Z 186addad6fd799939fab1f666168b1b5 +P cf8b99e17872c054e7ac0832d12633ce497c843dfc67148daf3b17762fd2b424 +R 01b5a3081c9c82dd29ec02ca22f387c4 +U stephan +Z 4f1059aef64fc0c129910f0aeaff4182 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b955e088a9..d9be76ac96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf8b99e17872c054e7ac0832d12633ce497c843dfc67148daf3b17762fd2b424 +0ce42fa586049e8864c5fd1a1d8703722f8549ba0a20ca748b887b7975ba9eb7 From 47bc07d4256b6f2509bd63d998acc6b49dc51659 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 18 Dec 2024 18:29:19 +0000 Subject: [PATCH 456/522] Avoid 32-bit roundoff error on the second argument to round(). [forum:/forumpost/170aeab92a|Forum post 170aeab92a]. FossilOrigin-Name: a9759fc78d6cb0df7c81f20c2c5c358729e571ebee50ee2b1441a15239d0b4b6 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/func.c | 4 ++-- test/func.test | 3 +++ 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index e451f68c58..b48881d98e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\ssome\svar\srefs\sin\sext/lsm1/Makefile\sfor\sthe\snew\sbuild\sprocess. -D 2024-12-18T03:41:29.636 +C Avoid\s32-bit\sroundoff\serror\son\sthe\ssecond\sargument\sto\sround().\n[forum:/forumpost/170aeab92a|Forum\spost\s170aeab92a]. +D 2024-12-18T18:29:19.106 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -730,7 +730,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f -F src/func.c 49489dcce46d2d491cedb451e974264150c473e5f5bba448498a9aa4c1993537 +F src/func.c 33d06376d6fed6dfce22deb475f99317b0b76694e688f06e9fce9480ff44a5c9 F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 @@ -1258,7 +1258,7 @@ F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f75 F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9 F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test e643522c6c67e18b14ac6453f28b39daa7e01d4cdf3b17bee6ec544804be85af +F test/func.test 4b8d5e7f1356ca42084e56e6c6f28f9e380db727756fb40dc319107c7632b157 F test/func2.test 69f6ae3751b4ec765bdc3b803c0a255aa0f693f28f44805bef03e6b4a3fd242f F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test a02e695f62beb31cb092dccf6873ff97543407fff97a5f3ec4da70b5b337bc84 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cf8b99e17872c054e7ac0832d12633ce497c843dfc67148daf3b17762fd2b424 -R 01b5a3081c9c82dd29ec02ca22f387c4 -U stephan -Z 4f1059aef64fc0c129910f0aeaff4182 +P 0ce42fa586049e8864c5fd1a1d8703722f8549ba0a20ca748b887b7975ba9eb7 +R fec4eb95d4677d8b995343c16db49fdb +U drh +Z 79885f3615d84c43267a5b2a5adaf77f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d9be76ac96..9781afa1e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ce42fa586049e8864c5fd1a1d8703722f8549ba0a20ca748b887b7975ba9eb7 +a9759fc78d6cb0df7c81f20c2c5c358729e571ebee50ee2b1441a15239d0b4b6 diff --git a/src/func.c b/src/func.c index 2d25803e0d..00dad97e43 100644 --- a/src/func.c +++ b/src/func.c @@ -440,13 +440,13 @@ static void substrFunc( */ #ifndef SQLITE_OMIT_FLOATING_POINT static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - int n = 0; + i64 n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; - n = sqlite3_value_int(argv[1]); + n = sqlite3_value_int64(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } diff --git a/test/func.test b/test/func.test index 73ff2b7355..b8a2cd6659 100644 --- a/test/func.test +++ b/test/func.test @@ -339,6 +339,9 @@ ifcapable floatingpoint { do_test func-4.39 { string tolower [db eval {SELECT round(1e500), round(-1e500);}] } {inf -inf} + do_execsql_test func-4.40 { + SELECT round(123.456 , 4294967297); + } {123.456} } # Test the upper() and lower() functions From b097ef29d12788153f7381bb5598430d6028d7f7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 18 Dec 2024 20:29:29 +0000 Subject: [PATCH 457/522] Fix possible integer oveflow in the second and third argument to substr(). FossilOrigin-Name: b04b4006f38f83d36eaf43c4bace7d53866b02b45e0ddcf1704266fed3bfc11c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/func.c | 4 ++-- test/func.test | 6 ++++++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index b48881d98e..266012a6f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\s32-bit\sroundoff\serror\son\sthe\ssecond\sargument\sto\sround().\n[forum:/forumpost/170aeab92a|Forum\spost\s170aeab92a]. -D 2024-12-18T18:29:19.106 +C Fix\spossible\sinteger\soveflow\sin\sthe\ssecond\sand\sthird\sargument\sto\ssubstr(). +D 2024-12-18T20:29:29.783 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -730,7 +730,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f -F src/func.c 33d06376d6fed6dfce22deb475f99317b0b76694e688f06e9fce9480ff44a5c9 +F src/func.c 92f1c5a5116fd96e009f1a6ae59c15ee571985f75cbcddab0ba10f84035a2805 F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 @@ -1258,7 +1258,7 @@ F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f75 F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9 F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test 4b8d5e7f1356ca42084e56e6c6f28f9e380db727756fb40dc319107c7632b157 +F test/func.test 59ae5fbfc2d5d565e3475824b25df2acc6f1b728d1a8d8e3e719ce64c494f69d F test/func2.test 69f6ae3751b4ec765bdc3b803c0a255aa0f693f28f44805bef03e6b4a3fd242f F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test a02e695f62beb31cb092dccf6873ff97543407fff97a5f3ec4da70b5b337bc84 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0ce42fa586049e8864c5fd1a1d8703722f8549ba0a20ca748b887b7975ba9eb7 -R fec4eb95d4677d8b995343c16db49fdb +P a9759fc78d6cb0df7c81f20c2c5c358729e571ebee50ee2b1441a15239d0b4b6 +R 0e55189459a80d645412fd9406897915 U drh -Z 79885f3615d84c43267a5b2a5adaf77f +Z ddc339cbca9c68ef9d9f1e1df3d93e64 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9781afa1e5..3e1bf40a1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9759fc78d6cb0df7c81f20c2c5c358729e571ebee50ee2b1441a15239d0b4b6 +b04b4006f38f83d36eaf43c4bace7d53866b02b45e0ddcf1704266fed3bfc11c diff --git a/src/func.c b/src/func.c index 00dad97e43..e4c628047d 100644 --- a/src/func.c +++ b/src/func.c @@ -363,7 +363,7 @@ static void substrFunc( return; } p0type = sqlite3_value_type(argv[0]); - p1 = sqlite3_value_int(argv[1]); + p1 = sqlite3_value_int64(argv[1]); if( p0type==SQLITE_BLOB ){ len = sqlite3_value_bytes(argv[0]); z = sqlite3_value_blob(argv[0]); @@ -388,7 +388,7 @@ static void substrFunc( if( p1==0 ) p1 = 1; /* */ #endif if( argc==3 ){ - p2 = sqlite3_value_int(argv[2]); + p2 = sqlite3_value_int64(argv[2]); if( p2<0 ){ p2 = -p2; negP2 = 1; diff --git a/test/func.test b/test/func.test index b8a2cd6659..2b25c94340 100644 --- a/test/func.test +++ b/test/func.test @@ -117,6 +117,12 @@ do_test func-2.9 { do_test func-2.10 { execsql {SELECT substr(a,2,2) FROM t2} } {{} {} 45 {} 78} +do_test func-2.11 { + execsql {SELECT substr('abcdefg',0x100000001,2)} +} {{}} +do_test func-2.12 { + execsql {SELECT substr('abcdefg',1,0x100000002)} +} {abcdefg} # Only do the following tests if TCL has UTF-8 capabilities # From 2dcd4fad6b1a4cfbaa0c1e106b840d15caf574dd Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 19 Dec 2024 12:08:39 +0000 Subject: [PATCH 458/522] Fix additional integer overflow problems in the substr() function. FossilOrigin-Name: 472abb492f1d1553ae6bdf53cc64bebfe75423526335beab7eaff26cc495cd7d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/func.c | 6 ++++-- test/func.test | 3 +++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 266012a6f8..890f176556 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\spossible\sinteger\soveflow\sin\sthe\ssecond\sand\sthird\sargument\sto\ssubstr(). -D 2024-12-18T20:29:29.783 +C Fix\sadditional\sinteger\soverflow\sproblems\sin\sthe\ssubstr()\sfunction. +D 2024-12-19T12:08:39.381 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -730,7 +730,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f -F src/func.c 92f1c5a5116fd96e009f1a6ae59c15ee571985f75cbcddab0ba10f84035a2805 +F src/func.c 3772ea69ace31835841629f893d86c9316a6facbc489f8113c7a205ec373de29 F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 @@ -1258,7 +1258,7 @@ F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f75 F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9 F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test 59ae5fbfc2d5d565e3475824b25df2acc6f1b728d1a8d8e3e719ce64c494f69d +F test/func.test 15f686741608294340bbea9f35f751074b4cf7df3797724dda40a9f4905ddbe1 F test/func2.test 69f6ae3751b4ec765bdc3b803c0a255aa0f693f28f44805bef03e6b4a3fd242f F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test a02e695f62beb31cb092dccf6873ff97543407fff97a5f3ec4da70b5b337bc84 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a9759fc78d6cb0df7c81f20c2c5c358729e571ebee50ee2b1441a15239d0b4b6 -R 0e55189459a80d645412fd9406897915 +P b04b4006f38f83d36eaf43c4bace7d53866b02b45e0ddcf1704266fed3bfc11c +R 345d60c42f9cb58fb08744de2e2cd750 U drh -Z ddc339cbca9c68ef9d9f1e1df3d93e64 +Z 5a2ba1d4ac587b2805dae851878da0c3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3e1bf40a1b..50afdd985d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b04b4006f38f83d36eaf43c4bace7d53866b02b45e0ddcf1704266fed3bfc11c +472abb492f1d1553ae6bdf53cc64bebfe75423526335beab7eaff26cc495cd7d diff --git a/src/func.c b/src/func.c index e4c628047d..2fe50f0155 100644 --- a/src/func.c +++ b/src/func.c @@ -427,9 +427,11 @@ static void substrFunc( sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, SQLITE_UTF8); }else{ - if( p1+p2>len ){ + if( p1>=len ){ + p1 = p2 = 0; + }else if( p2>len-p1 ){ p2 = len-p1; - if( p2<0 ) p2 = 0; + assert( p2>0 ); } sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); } diff --git a/test/func.test b/test/func.test index 2b25c94340..85c9ada7eb 100644 --- a/test/func.test +++ b/test/func.test @@ -123,6 +123,9 @@ do_test func-2.11 { do_test func-2.12 { execsql {SELECT substr('abcdefg',1,0x100000002)} } {abcdefg} +do_test func-2.13 { + execsql {SELECT quote(substr(x'313233343536373839',0x7ffffffffffffffe,5))} +} {X''} # Only do the following tests if TCL has UTF-8 capabilities # From 543ee479eb3ec73c9611e23b28934871f9ec9331 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 19 Dec 2024 13:36:36 +0000 Subject: [PATCH 459/522] Enhance lemon so that it accepts the -U command-line option that undefines a preprocessor macro. FossilOrigin-Name: e2188a3edf3576963b45e9ffe6ef53e2a85aa68ea3dfb3243b4943d06ffaf829 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 890f176556..feb0519e3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sadditional\sinteger\soverflow\sproblems\sin\sthe\ssubstr()\sfunction. -D 2024-12-19T12:08:39.381 +C Enhance\slemon\sso\sthat\sit\saccepts\sthe\s-U\scommand-line\soption\sthat\sundefines\na\spreprocessor\smacro. +D 2024-12-19T13:36:36.903 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2131,7 +2131,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c d048516b2c3ad4119b1c1154a73f4f9435b275fea076318959f817effe23b827 +F tool/lemon.c 2418ee31f65764d150f7dd87ef00b4408f1b01a55db0b30bed673a3e336ae718 F tool/lempar.c e6b649778e5c027c8365ff01d7ef39297cd7285fa1f881cce31792689541e79f F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b04b4006f38f83d36eaf43c4bace7d53866b02b45e0ddcf1704266fed3bfc11c -R 345d60c42f9cb58fb08744de2e2cd750 +P 472abb492f1d1553ae6bdf53cc64bebfe75423526335beab7eaff26cc495cd7d +R 9ee08cc86a2ab41c90aabb4242760c7f U drh -Z 5a2ba1d4ac587b2805dae851878da0c3 +Z 57993657619d1e9f48e898579d8c0801 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 50afdd985d..2dfb20d161 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -472abb492f1d1553ae6bdf53cc64bebfe75423526335beab7eaff26cc495cd7d +e2188a3edf3576963b45e9ffe6ef53e2a85aa68ea3dfb3243b4943d06ffaf829 diff --git a/tool/lemon.c b/tool/lemon.c index d92df2a1a7..5747520b6e 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -1628,6 +1628,23 @@ static void handle_D_option(char *z){ *z = 0; } +/* This routine is called with the argument to each -U command-line option. +** Omit a previously defined macro. +*/ +static void handle_U_option(char *z){ + int i; + for(i=0; i Date: Thu, 19 Dec 2024 14:08:06 +0000 Subject: [PATCH 460/522] Fix the Microsoft makefile so that it does not set SQLITE_TEMP_STORE unnecessarily. FossilOrigin-Name: f9b92f9513def690311a5ca46b68cab02bedec7984960d44e7dea5c2d196725a --- Makefile.msc | 9 --------- autoconf/Makefile.msc | 9 --------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 8 insertions(+), 26 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 14f2ab8c67..942f759eed 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1103,15 +1103,6 @@ RCC = $(RCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1 TLIBS = !ENDIF -# Flags controlling use of the in memory btree implementation -# -# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to -# default to file, 2 to default to memory, and 3 to force temporary -# tables to always be in memory. -# -TCC = $(TCC) -DSQLITE_TEMP_STORE=1 -RCC = $(RCC) -DSQLITE_TEMP_STORE=1 - # Enable/disable loadable extensions, and other optional features # based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). # The same set of OMIT and ENABLE flags should be passed to the diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index c23bbf494a..1f0e42db4b 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -801,15 +801,6 @@ RCC = $(RCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1 TLIBS = !ENDIF -# Flags controlling use of the in memory btree implementation -# -# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to -# default to file, 2 to default to memory, and 3 to force temporary -# tables to always be in memory. -# -TCC = $(TCC) -DSQLITE_TEMP_STORE=1 -RCC = $(RCC) -DSQLITE_TEMP_STORE=1 - # Enable/disable loadable extensions, and other optional features # based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). # The same set of OMIT and ENABLE flags should be passed to the diff --git a/manifest b/manifest index feb0519e3d..adf5f72696 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Enhance\slemon\sso\sthat\sit\saccepts\sthe\s-U\scommand-line\soption\sthat\sundefines\na\spreprocessor\smacro. -D 2024-12-19T13:36:36.903 +C Fix\sthe\sMicrosoft\smakefile\sso\sthat\sit\sdoes\snot\sset\sSQLITE_TEMP_STORE\nunnecessarily. +D 2024-12-19T14:08:06.761 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in ad349acf91b3569033439fe498fa197aa530cafaa01362eb7daad2f84e43d265 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc f402bb6ea63b44f5143aa3c637aa3f69794cf14b1cc964eb97c4f53124198561 +F Makefile.msc eed0c40c365d100f3329e8fb7d0e18bad09a6f0c026aa1e4dc7f88270378929d F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -18,7 +18,7 @@ F auto.def f2876c94403be1055db47273dde33e8fea0998b1c1d36a386f76698919ea36ad F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.msc 0735351f6002f0bf78b73b3b7a6a120cff38573dd37c37005b682ecc44c25bc2 +F autoconf/Makefile.msc ffff61fe851443015ddb6600ab69a9df503cfec25459b336be7ba8c9a9e473f8 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 5e946ffb6fbdbb114c81e1bdc862df27fce8beab557d7b0421820b0fe8fc048f F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 472abb492f1d1553ae6bdf53cc64bebfe75423526335beab7eaff26cc495cd7d -R 9ee08cc86a2ab41c90aabb4242760c7f +P e2188a3edf3576963b45e9ffe6ef53e2a85aa68ea3dfb3243b4943d06ffaf829 +R fca299ca2e778dc1f6b849301fe4d4fb U drh -Z 57993657619d1e9f48e898579d8c0801 +Z 5ca71bb0728c1324bb94823ee29eaeef # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2dfb20d161..bc9b17953b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2188a3edf3576963b45e9ffe6ef53e2a85aa68ea3dfb3243b4943d06ffaf829 +f9b92f9513def690311a5ca46b68cab02bedec7984960d44e7dea5c2d196725a From 166f4eb5cf5ae25ba203f860e48efb9a258bf1f6 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 19 Dec 2024 14:09:35 +0000 Subject: [PATCH 461/522] configure script: only set the SQLITE_TEMP_STORE feature flag if --with-tempstore is explicitly set, to avoid colliding with that flag being set by other means via the test fixture scripts. FossilOrigin-Name: c7839b80972fb31df6ac81af38cf6d04c9542714c20fbaa7457c1eaf955f9222 --- auto.def | 35 ++++++++++++++++++++--------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/auto.def b/auto.def index c52ce44986..c9aa0cb9d1 100644 --- a/auto.def +++ b/auto.def @@ -864,22 +864,27 @@ proj-if-opt-truthy threadsafe { ######################################################################## # Do we want temporary databases in memory? # -apply {{} { - set ts [opt-val with-tempstore no] - set tsn 1 - msg-checking "Use an in-RAM database for temporary tables? " - switch -exact -- $ts { - never { set tsn 0 } - no { set tsn 1 } - yes { set tsn 2 } - always { set tsn 3 } - default { - user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always" +# The test fixture likes to set SQLITE_TEMP_STORE on its own, so do +# not set that feature flag unless it was explicitly provided to the +# configure script. +if {[proj-opt-was-provided with-tempstore]} { + apply {{} { + set ts [opt-val with-tempstore no] + set tsn 1 + msg-checking "Use an in-RAM database for temporary tables? " + switch -exact -- $ts { + never { set tsn 0 } + no { set tsn 1 } + yes { set tsn 2 } + always { set tsn 3 } + default { + user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always" + } } - } - msg-result $ts - sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn -}} + msg-result $ts + sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn + }} +} ######################################################################## # sqlite-check-line-editing jumps through proverbial hoops to try to diff --git a/manifest b/manifest index adf5f72696..476bc293f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sMicrosoft\smakefile\sso\sthat\sit\sdoes\snot\sset\sSQLITE_TEMP_STORE\nunnecessarily. -D 2024-12-19T14:08:06.761 +C configure\sscript:\sonly\sset\sthe\sSQLITE_TEMP_STORE\sfeature\sflag\sif\s--with-tempstore\sis\sexplicitly\sset,\sto\savoid\scolliding\swith\sthat\sflag\sbeing\sset\sby\sother\smeans\svia\sthe\stest\sfixture\sscripts. +D 2024-12-19T14:09:35.677 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -14,7 +14,7 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531 -F auto.def f2876c94403be1055db47273dde33e8fea0998b1c1d36a386f76698919ea36ad +F auto.def 63dfbbc58b041d1c5c516f31a02679cce8d79123c89ad87fd2783f4ef26dedbb F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e2188a3edf3576963b45e9ffe6ef53e2a85aa68ea3dfb3243b4943d06ffaf829 -R fca299ca2e778dc1f6b849301fe4d4fb -U drh -Z 5ca71bb0728c1324bb94823ee29eaeef +P f9b92f9513def690311a5ca46b68cab02bedec7984960d44e7dea5c2d196725a +R 1677c650b894e550921b2c6865a336f8 +U stephan +Z 945c85e044fc70c85b4eacbaf56b56af # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bc9b17953b..7c5ebd691d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9b92f9513def690311a5ca46b68cab02bedec7984960d44e7dea5c2d196725a +c7839b80972fb31df6ac81af38cf6d04c9542714c20fbaa7457c1eaf955f9222 From f2d422c528475e8f39a5b71e108c37b4083d5385 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 19 Dec 2024 14:20:47 +0000 Subject: [PATCH 462/522] Fix the sort4.test module so that the first two test cases are omitted when SQLite has been compiled using SQLITE_MAX_WORKER_THREADS=0. FossilOrigin-Name: 5b96dcf5f6bf41dcb89ced64efd4585e36dce718c428c2324d94e4942905c3bb --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/sort4.test | 30 ++++++++++++++++-------------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 476bc293f5..0da317676b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C configure\sscript:\sonly\sset\sthe\sSQLITE_TEMP_STORE\sfeature\sflag\sif\s--with-tempstore\sis\sexplicitly\sset,\sto\savoid\scolliding\swith\sthat\sflag\sbeing\sset\sby\sother\smeans\svia\sthe\stest\sfixture\sscripts. -D 2024-12-19T14:09:35.677 +C Fix\sthe\ssort4.test\smodule\sso\sthat\sthe\sfirst\stwo\stest\scases\sare\somitted\nwhen\sSQLite\shas\sbeen\scompiled\susing\sSQLITE_MAX_WORKER_THREADS=0. +D 2024-12-19T14:20:47.005 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1664,7 +1664,7 @@ F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test f86751134159abb5e5fd4381a0d7038c91013638cd1e3fa1d7850901f6df6196 F test/sort2.test 2f8c66402a03adebe77ce7aafca129fbf32df27d6c9b8f7a9f1b958e39f56da8 F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5 -F test/sort4.test cca6f4b0b5255882645bbbe346a6a9f4a5c7b6a18513a6a7bf4ac1c4761ddc19 +F test/sort4.test c7a88629aecc8eec3c919eda54b221da5cf7a1b48f0cd372e7e832188d6737d8 F test/sort5.test 6b43ae0e2169b5ceed441844492e55ba7f1ae0790528395ddf7888ab3094525d F test/sorterref.test 9a606c86a4c682db5eeaaefa0565b52102778db53e48ca7101cd4f9ebcc0ad94 F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f9b92f9513def690311a5ca46b68cab02bedec7984960d44e7dea5c2d196725a -R 1677c650b894e550921b2c6865a336f8 -U stephan -Z 945c85e044fc70c85b4eacbaf56b56af +P c7839b80972fb31df6ac81af38cf6d04c9542714c20fbaa7457c1eaf955f9222 +R c12eed049f52c9f1b08689c19a769296 +U drh +Z 0f8a15c21cb4f473505e48e4b944f5d1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7c5ebd691d..410230928d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7839b80972fb31df6ac81af38cf6d04c9542714c20fbaa7457c1eaf955f9222 +5b96dcf5f6bf41dcb89ced64efd4585e36dce718c428c2324d94e4942905c3bb diff --git a/test/sort4.test b/test/sort4.test index 84125885ab..17aa28baec 100644 --- a/test/sort4.test +++ b/test/sort4.test @@ -26,20 +26,22 @@ sqlite3_initialize sqlite3 db test.db -# Configure the sorter to use 3 background threads. -# -# EVIDENCE-OF: R-19249-32353 SQLITE_LIMIT_WORKER_THREADS The maximum -# number of auxiliary worker threads that a single prepared statement -# may start. -# -do_test sort4-init001 { - db eval {PRAGMA threads=5} - sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS -1 -} {5} -do_test sort4-init002 { - sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS 3 - db eval {PRAGMA threads} -} {3} +if {![string match *MAX_WORKER_THREADS=0* [db eval {PRAGMA compile_options}]]} { + # Configure the sorter to use 3 background threads. + # + # EVIDENCE-OF: R-19249-32353 SQLITE_LIMIT_WORKER_THREADS The maximum + # number of auxiliary worker threads that a single prepared statement + # may start. + # + do_test sort4-init001 { + db eval {PRAGMA threads=5} + sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS -1 + } {5} + do_test sort4-init002 { + sqlite3_limit db SQLITE_LIMIT_WORKER_THREADS 3 + db eval {PRAGMA threads} + } {3} +} # Minimum number of seconds to run for. If the value is 0, each test From be2a40d48967fbcb68250b51d556f9a2fb4ad649 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 19 Dec 2024 19:02:09 +0000 Subject: [PATCH 463/522] The BTree mutex must be held when calling sqlite3BtreeLastPage(). This check-in fixes a bug introduced by [cf8b99e17872c054]. FossilOrigin-Name: e6c30ee52c5cdc193804cec63374d558b45e4d67fc6bde58771ca78485ca0acf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/dbpage.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 0da317676b..cd5c02a999 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssort4.test\smodule\sso\sthat\sthe\sfirst\stwo\stest\scases\sare\somitted\nwhen\sSQLite\shas\sbeen\scompiled\susing\sSQLITE_MAX_WORKER_THREADS=0. -D 2024-12-19T14:20:47.005 +C The\sBTree\smutex\smust\sbe\sheld\swhen\scalling\ssqlite3BtreeLastPage().\s\sThis\ncheck-in\sfixes\sa\sbug\sintroduced\sby\s[cf8b99e17872c054]. +D 2024-12-19T19:02:09.632 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -724,7 +724,7 @@ F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d49 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a -F src/dbpage.c d1778e74b15549e3967974b5addf740462db1a9d441da35666177f5a6ccf34c5 +F src/dbpage.c b1aeb47c1004f26c39c6800f0045b8d729d232aca24f6aa430c491b83003d033 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c7839b80972fb31df6ac81af38cf6d04c9542714c20fbaa7457c1eaf955f9222 -R c12eed049f52c9f1b08689c19a769296 +P 5b96dcf5f6bf41dcb89ced64efd4585e36dce718c428c2324d94e4942905c3bb +R 0d5d0fe22a08bb0bc92b56fa701d1de4 U drh -Z 0f8a15c21cb4f473505e48e4b944f5d1 +Z e8045b14a30fff6abbf0f3c593a246f0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 410230928d..c49f5bdd66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b96dcf5f6bf41dcb89ced64efd4585e36dce718c428c2324d94e4942905c3bb +e6c30ee52c5cdc193804cec63374d558b45e4d67fc6bde58771ca78485ca0acf diff --git a/src/dbpage.c b/src/dbpage.c index 3bb18b6775..74f345570e 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -428,9 +428,11 @@ static int dbpageSync(sqlite3_vtab *pVtab){ if( pTab->pgnoTrunc>0 ){ Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt; Pager *pPager = sqlite3BtreePager(pBt); + sqlite3BtreeEnter(pBt); if( pTab->pgnoTruncpgnoTrunc); } + sqlite3BtreeLeave(pBt); } pTab->pgnoTrunc = 0; return SQLITE_OK; From ccfb50d55efa27006fdd07d88ad7f4f2c51f5152 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 19 Dec 2024 19:52:13 +0000 Subject: [PATCH 464/522] Correction to check-in [a9759fc78d6cb0df] - printf() parameters values must be integers. FossilOrigin-Name: 2db531d1911369ea932d3559abcc02389e5f9ad72b46b0801dfb6063855aee1b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index cd5c02a999..f9217095bd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sBTree\smutex\smust\sbe\sheld\swhen\scalling\ssqlite3BtreeLastPage().\s\sThis\ncheck-in\sfixes\sa\sbug\sintroduced\sby\s[cf8b99e17872c054]. -D 2024-12-19T19:02:09.632 +C Correction\sto\scheck-in\s[a9759fc78d6cb0df]\s-\sprintf()\sparameters\svalues\smust\nbe\sintegers. +D 2024-12-19T19:52:13.470 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -730,7 +730,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f -F src/func.c 3772ea69ace31835841629f893d86c9316a6facbc489f8113c7a205ec373de29 +F src/func.c e6e997efb9ffaf8b07842e745159695669fdfa020f03635a2f774adab8b0f4af F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5b96dcf5f6bf41dcb89ced64efd4585e36dce718c428c2324d94e4942905c3bb -R 0d5d0fe22a08bb0bc92b56fa701d1de4 +P e6c30ee52c5cdc193804cec63374d558b45e4d67fc6bde58771ca78485ca0acf +R f31f33bbdca91555eb20e3616452ac98 U drh -Z e8045b14a30fff6abbf0f3c593a246f0 +Z 72db1b78a2863ce7bb7c272a3115f243 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c49f5bdd66..459988f0ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e6c30ee52c5cdc193804cec63374d558b45e4d67fc6bde58771ca78485ca0acf +2db531d1911369ea932d3559abcc02389e5f9ad72b46b0801dfb6063855aee1b diff --git a/src/func.c b/src/func.c index 2fe50f0155..a4b72ecc4d 100644 --- a/src/func.c +++ b/src/func.c @@ -463,7 +463,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ - zBuf = sqlite3_mprintf("%!.*f",n,r); + zBuf = sqlite3_mprintf("%!.*f",(int)n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; From 142c5de4dd603deea49189c84a301ef18293a5a8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 19 Dec 2024 20:29:36 +0000 Subject: [PATCH 465/522] Fix a test case in sqllimits1.test so that it works with the Apple configuration which changes the default SQLITE_MAX_LENGTH. FossilOrigin-Name: 536fff14acb3335ad00fb1165cfb2f97e7a31c36273b9b97ffdb4b572fe72c08 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/sqllimits1.test | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f9217095bd..903d85a92a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correction\sto\scheck-in\s[a9759fc78d6cb0df]\s-\sprintf()\sparameters\svalues\smust\nbe\sintegers. -D 2024-12-19T19:52:13.470 +C Fix\sa\stest\scase\sin\ssqllimits1.test\sso\sthat\sit\sworks\swith\sthe\sApple\nconfiguration\swhich\schanges\sthe\sdefault\sSQLITE_MAX_LENGTH. +D 2024-12-19T20:29:36.166 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1682,7 +1682,7 @@ F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb F test/sqldiff1.test 1b7ab4f312442c5cc6b3a5f299fa8ca051416d1dd173cb1126fd51bf64f2c3fb -F test/sqllimits1.test 7fa5027c2686e0a752f9a35616966eabfb9959ce041701b091932692c4bb6448 +F test/sqllimits1.test 408131e4975d61868711c83f101a56d4602313cc5cae88d3eee81c1da364fd89 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/starschema1.test a84205f97fe278a015ac39546c86b97228d22043af28f3a2ef809e8d5637ce1d F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e6c30ee52c5cdc193804cec63374d558b45e4d67fc6bde58771ca78485ca0acf -R f31f33bbdca91555eb20e3616452ac98 +P 2db531d1911369ea932d3559abcc02389e5f9ad72b46b0801dfb6063855aee1b +R a03a4dd396ef02112c6a33e420d224ad U drh -Z 72db1b78a2863ce7bb7c272a3115f243 +Z 911cb8ba7f00f67e5f02965dae2fd664 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 459988f0ee..3af7305020 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2db531d1911369ea932d3559abcc02389e5f9ad72b46b0801dfb6063855aee1b +536fff14acb3335ad00fb1165cfb2f97e7a31c36273b9b97ffdb4b572fe72c08 diff --git a/test/sqllimits1.test b/test/sqllimits1.test index e6283e4e4a..efe656db6a 100644 --- a/test/sqllimits1.test +++ b/test/sqllimits1.test @@ -78,8 +78,8 @@ do_test sqllimits1-1.23 { # Minimum value for SQLITE_LIMIT_LENGTH is 30 # do_test sqllimits1-1.30 { - sqlite3_limit db SQLITE_LIMIT_LENGTH 1 - sqlite3_limit db SQLITE_LIMIT_LENGTH 1000000000 + set prior [sqlite3_limit db SQLITE_LIMIT_LENGTH 1] + sqlite3_limit db SQLITE_LIMIT_LENGTH $prior } 30 From 9591d3fe93936533c8c3b0dc4d025ac999539e11 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 22 Dec 2024 21:17:27 +0000 Subject: [PATCH 466/522] In the (debugging) rtreenode() function, do not override an error coming out of sqlite3_result_text(). FossilOrigin-Name: 286559dfb3ad01fcf34360991a108dbe6bf81e7919c461ada6c691ee8f43868f --- ext/rtree/rtree.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 6efa20d162..8ed8978bde 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3775,8 +3775,8 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ sqlite3_str_append(pOut, "}", 1); } errCode = sqlite3_str_errcode(pOut); - sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free); sqlite3_result_error_code(ctx, errCode); + sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free); } /* This routine implements an SQL function that returns the "depth" parameter diff --git a/manifest b/manifest index 903d85a92a..2e54ede973 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sin\ssqllimits1.test\sso\sthat\sit\sworks\swith\sthe\sApple\nconfiguration\swhich\schanges\sthe\sdefault\sSQLITE_MAX_LENGTH. -D 2024-12-19T20:29:36.166 +C In\sthe\s(debugging)\srtreenode()\sfunction,\sdo\snot\soverride\san\serror\scoming\sout\nof\ssqlite3_result_text(). +D 2024-12-22T21:17:27.858 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -536,7 +536,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/geopoly.c 0dd4775e896cee6067979d67aff7c998e75c2c9d9cd8d62a1a790c09cde7adca -F ext/rtree/rtree.c e002d8c58bf128d812db662ecc72b61c00ff14408ec807e103d5312a6d29817a +F ext/rtree/rtree.c 4c58755830a0902435322bf61b2994ae02951a039daefb31cff9457d3e2aa201 F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2db531d1911369ea932d3559abcc02389e5f9ad72b46b0801dfb6063855aee1b -R a03a4dd396ef02112c6a33e420d224ad +P 536fff14acb3335ad00fb1165cfb2f97e7a31c36273b9b97ffdb4b572fe72c08 +R 4447fcd0ccb80498c83515e29fbbdcc2 U drh -Z 911cb8ba7f00f67e5f02965dae2fd664 +Z 75ed33204df12b76c729fccd2a0270dd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3af7305020..7604fcbe51 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -536fff14acb3335ad00fb1165cfb2f97e7a31c36273b9b97ffdb4b572fe72c08 +286559dfb3ad01fcf34360991a108dbe6bf81e7919c461ada6c691ee8f43868f From e0190a6984207b7a3f4da58f6a9ff06c790447a3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 28 Dec 2024 12:32:01 +0000 Subject: [PATCH 467/522] Fixes to the substr() SQL function so that it can handle ridiculously large numbers in its 2nd and 3rd arguments without signed integer overflows. FossilOrigin-Name: c1de8f916ea617109a903c436c57d082756fbb2b933ba9ce6998b9b912b12dea --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 23 +++++++++++------------ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 2e54ede973..04000a5492 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\s(debugging)\srtreenode()\sfunction,\sdo\snot\soverride\san\serror\scoming\sout\nof\ssqlite3_result_text(). -D 2024-12-22T21:17:27.858 +C Fixes\sto\sthe\ssubstr()\sSQL\sfunction\sso\sthat\sit\scan\shandle\sridiculously\slarge\nnumbers\sin\sits\s2nd\sand\s3rd\sarguments\swithout\ssigned\sinteger\soverflows. +D 2024-12-28T12:32:01.085 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -730,7 +730,7 @@ F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f -F src/func.c e6e997efb9ffaf8b07842e745159695669fdfa020f03635a2f774adab8b0f4af +F src/func.c 89b733a5f513c4bc06b7271384363d5693d62782de8295bc87b97d79862c9714 F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 536fff14acb3335ad00fb1165cfb2f97e7a31c36273b9b97ffdb4b572fe72c08 -R 4447fcd0ccb80498c83515e29fbbdcc2 +P 286559dfb3ad01fcf34360991a108dbe6bf81e7919c461ada6c691ee8f43868f +R 6fd56d72396565e46db9a7e82d5a2906 U drh -Z 75ed33204df12b76c729fccd2a0270dd +Z 2ed81eb220ab467fd47b108b1040a471 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7604fcbe51..7b634f4341 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -286559dfb3ad01fcf34360991a108dbe6bf81e7919c461ada6c691ee8f43868f +c1de8f916ea617109a903c436c57d082756fbb2b933ba9ce6998b9b912b12dea diff --git a/src/func.c b/src/func.c index a4b72ecc4d..7a4774527d 100644 --- a/src/func.c +++ b/src/func.c @@ -354,7 +354,6 @@ static void substrFunc( int len; int p0type; i64 p1, p2; - int negP2 = 0; assert( argc==3 || argc==2 ); if( sqlite3_value_type(argv[1])==SQLITE_NULL @@ -389,18 +388,17 @@ static void substrFunc( #endif if( argc==3 ){ p2 = sqlite3_value_int64(argv[2]); - if( p2<0 ){ - p2 = -p2; - negP2 = 1; - } }else{ p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; } if( p1<0 ){ p1 += len; if( p1<0 ){ - p2 += p1; - if( p2<0 ) p2 = 0; + if( p2<0 ){ + p2 = 0; + }else{ + p2 += p1; + } p1 = 0; } }else if( p1>0 ){ @@ -408,12 +406,13 @@ static void substrFunc( }else if( p2>0 ){ p2--; } - if( negP2 ){ - p1 -= p2; - if( p1<0 ){ - p2 += p1; - p1 = 0; + if( p2<0 ){ + if( p2<-p1 ){ + p2 = p1; + }else{ + p2 = -p2; } + p1 -= p2; } assert( p1>=0 && p2>=0 ); if( p0type!=SQLITE_BLOB ){ From 8b689021281d8297003ad580b81ff6c3f743432c Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 28 Dec 2024 13:04:31 +0000 Subject: [PATCH 468/522] Show ETC in fuzzcheck with the --spinner option when there is only one input file. FossilOrigin-Name: 809699aeaaa4bae67e7ddeae3d42c7133f7deadbb4eb869cfb7e99dd97bdea99 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 29 +++++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 04000a5492..83b9298fd6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sthe\ssubstr()\sSQL\sfunction\sso\sthat\sit\scan\shandle\sridiculously\slarge\nnumbers\sin\sits\s2nd\sand\s3rd\sarguments\swithout\ssigned\sinteger\soverflows. -D 2024-12-28T12:32:01.085 +C Show\sETC\sin\sfuzzcheck\swith\sthe\s--spinner\soption\swhen\sthere\sis\sonly\sone\sinput\nfile. +D 2024-12-28T13:04:31.448 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1274,7 +1274,7 @@ F test/fuzz3.test 70ba57260364b83e964707b9d4b5625284239768ab907dd387c740c0370ce3 F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 89b71d92b150a532e945e489d6e0721a4b15353c9255e079c198ed2a1958018b +F test/fuzzcheck.c 1671559091b3e134ec807490f624d306b24bd9a8f03b12aa97e292f4b31e5d96 F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517 F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 286559dfb3ad01fcf34360991a108dbe6bf81e7919c461ada6c691ee8f43868f -R 6fd56d72396565e46db9a7e82d5a2906 +P c1de8f916ea617109a903c436c57d082756fbb2b933ba9ce6998b9b912b12dea +R c040710ee01619bb4db43dcfabab289e U drh -Z 2ed81eb220ab467fd47b108b1040a471 +Z 7ae0fec8e974918548c014471849b63b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7b634f4341..9d76ba4003 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1de8f916ea617109a903c436c57d082756fbb2b933ba9ce6998b9b912b12dea +809699aeaaa4bae67e7ddeae3d42c7133f7deadbb4eb869cfb7e99dd97bdea99 diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 9f339096bc..390d804df1 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -1917,6 +1917,7 @@ int main(int argc, char **argv){ int bTimer = 0; /* Show elapse time for each test */ int nV; /* How much to increase verbosity with -vvvv */ sqlite3_int64 tmStart; /* Start of each test */ + int iEstTime = 0; /* LPF for the time-to-go */ sqlite3_config(SQLITE_CONFIG_URI,1); registerOomSimulator(); @@ -2416,9 +2417,29 @@ int main(int argc, char **argv){ if( bScript ){ /* No progress output */ }else if( bSpinner ){ - int nTotal =g.nSql; + int nTotal = g.nSql; int idx = pSql->seq; - printf("\r%s: %d/%d ", zDbName, idx, nTotal); + if( nSrcDb==1 && nTotal>idx && idx>=20 ){ + int iToGo = (timeOfDay() - iBegin)*(nTotal-idx)/(idx*1000); + int hr, min, sec; + if( idx==20 ){ + iEstTime = iToGo; + }else{ + iEstTime = (iToGo + 7*iEstTime)/8; + } + hr = iEstTime/3600; + min = (iEstTime/60)%60; + sec = iEstTime%60; + if( hr>0 ){ + printf("\r%s: %d/%d ETC %d:%02d:%02d ", + zDbName, idx, nTotal, hr, min, sec); + }else{ + printf("\r%s: %d/%d ETC %02d:%02d ", + zDbName, idx, nTotal, min, sec); + } + }else{ + printf("\r%s: %d/%d ", zDbName, idx, nTotal); + } fflush(stdout); }else if( verboseFlag>1 ){ printf("%s\n", g.zTestName); @@ -2457,7 +2478,7 @@ int main(int argc, char **argv){ }else if( bSpinner ){ int nTotal = g.nDb*g.nSql; int idx = pSql->seq*g.nDb + pDb->id - 1; - printf("\r%s: %d/%d ", zDbName, idx, nTotal); + printf("\r%s: %d/%d ", zDbName, idx, nTotal); fflush(stdout); }else if( verboseFlag>1 ){ printf("%s\n", g.zTestName); @@ -2560,7 +2581,7 @@ int main(int argc, char **argv){ /* No progress output */ }else if( bSpinner ){ int nTotal = g.nDb*g.nSql; - printf("\r%s: %d/%d \n", zDbName, nTotal, nTotal); + printf("\r%s: %d/%d \n", zDbName, nTotal, nTotal); }else if( !quietFlag && verboseFlag<2 ){ printf(" 100%% - %d tests\n", g.nDb*g.nSql); } From 4112a63b8fa8357133f2c8e089dcd9193fc2926b Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 29 Dec 2024 11:54:12 +0000 Subject: [PATCH 469/522] Four new assert() statements to help with static analysis. FossilOrigin-Name: e7f7c9d22be8a17b9a4d8f954fcdd40591ba9da5fb674f1184f960bca5f3d30b --- ext/fts5/fts5_index.c | 4 ++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 8730b69509..242258af70 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6651,6 +6651,7 @@ static void fts5SetupPrefixIter( } pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING); + assert( pData!=0 || p->rc!=SQLITE_OK ); if( pData ){ pData->p = (u8*)&pData[1]; pData->nn = pData->szLeaf = s.doclist.n; @@ -6658,6 +6659,7 @@ static void fts5SetupPrefixIter( fts5MultiIterNew2(p, pData, bDesc, ppIter); } + assert( (*ppIter)!=0 || p->rc!=SQLITE_OK ); if( p->rc==SQLITE_OK && s.pTokendata ){ fts5TokendataIterSortMap(p, s2.pT); (*ppIter)->pTokenDataIter = s2.pT; @@ -7289,6 +7291,7 @@ int sqlite3Fts5IndexQuery( int iIdx = 0; /* Index to search */ int iPrefixIdx = 0; /* +1 prefix index */ int bTokendata = pConfig->bTokendata; + assert( buf.p!=0 ); if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); /* The NOTOKENDATA flag is set when each token in a tokendata=1 table @@ -7450,6 +7453,7 @@ static int fts5SetupPrefixIterTokendata( memset(&ctx, 0, sizeof(ctx)); fts5BufferGrow(&p->rc, &token, nToken+1); + assert( token.p!=0 || p->rc!=SQLITE_OK ); ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT)); if( p->rc==SQLITE_OK ){ diff --git a/manifest b/manifest index 83b9298fd6..b26114a8c1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Show\sETC\sin\sfuzzcheck\swith\sthe\s--spinner\soption\swhen\sthere\sis\sonly\sone\sinput\nfile. -D 2024-12-28T13:04:31.448 +C Four\snew\sassert()\sstatements\sto\shelp\swith\sstatic\sanalysis. +D 2024-12-29T11:54:12.033 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -111,7 +111,7 @@ F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70 F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c cef6791bd9f9db4305494292d6dd5d24a7379aabf370a4d6b559e16b740fa88e +F ext/fts5/fts5_index.c 1a7312b7bb0fd0853266d211764cd519a803f01bbf6e486df9a85551ad4257cb F ext/fts5/fts5_main.c 72527efa1d634054b93a21eafe854763cbc5c270e8a4ab99bbb589557b818482 F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c1de8f916ea617109a903c436c57d082756fbb2b933ba9ce6998b9b912b12dea -R c040710ee01619bb4db43dcfabab289e +P 809699aeaaa4bae67e7ddeae3d42c7133f7deadbb4eb869cfb7e99dd97bdea99 +R e65009700ed066053c3d65387514268c U drh -Z 7ae0fec8e974918548c014471849b63b +Z c0857ad3c43398292371098755c936e4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9d76ba4003..c280946b6a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -809699aeaaa4bae67e7ddeae3d42c7133f7deadbb4eb869cfb7e99dd97bdea99 +e7f7c9d22be8a17b9a4d8f954fcdd40591ba9da5fb674f1184f960bca5f3d30b From 6b19c72f26d15317a445b4dd1165b2cba1cd83c5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Dec 2024 12:29:18 +0000 Subject: [PATCH 470/522] Add an extra assert() to releaseMemArray() just to prove that the sqlite3_value.db field is never NULL. FossilOrigin-Name: b969ef1def5121c7ff54e3586528274f006ca994b308cf88ccaa9d4f56bf30df --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index b26114a8c1..5571665cf9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Four\snew\sassert()\sstatements\sto\shelp\swith\sstatic\sanalysis. -D 2024-12-29T11:54:12.033 +C Add\san\sextra\sassert()\sto\sreleaseMemArray()\sjust\sto\sprove\sthat\sthe\nsqlite3_value.db\sfield\sis\snever\sNULL. +D 2024-12-30T12:29:18.018 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -850,7 +850,7 @@ F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 F src/vdbeInt.h bf294a0c8fc4cc80779e74b04b8bd82c6e1197b3137cefe0b16cdf002fc7dfd6 F src/vdbeapi.c 38c252a202d70b56cfb734460bc888ddbd581afec1a10cd4d6c894c9e0b5baea -F src/vdbeaux.c f0706ad786b8a6c5bc7ea622f3916c2ba2b883abc872d0b4911c4f021945c0e5 +F src/vdbeaux.c 1969b208ab554f0a6560a86c339dad5faf68d3ef861f96be86792d7eec23575d F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797 F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2 F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 809699aeaaa4bae67e7ddeae3d42c7133f7deadbb4eb869cfb7e99dd97bdea99 -R e65009700ed066053c3d65387514268c +P e7f7c9d22be8a17b9a4d8f954fcdd40591ba9da5fb674f1184f960bca5f3d30b +R f8a1fde40935ca24cba561f520c119c6 U drh -Z c0857ad3c43398292371098755c936e4 +Z 3a5e22afa8456e78923838b8f35ae4a2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c280946b6a..98b845261c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7f7c9d22be8a17b9a4d8f954fcdd40591ba9da5fb674f1184f960bca5f3d30b +b969ef1def5121c7ff54e3586528274f006ca994b308cf88ccaa9d4f56bf30df diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 4414f7a2ec..3d918be32e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2169,6 +2169,7 @@ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; + assert( db!=0 ); if( db->pnBytesFreed ){ do{ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); From 71d6456f59c7008ccb0a8e917d4a9117081bdd66 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Dec 2024 13:54:52 +0000 Subject: [PATCH 471/522] New assert() statements to show that the sqlite3_value.db field is initialized for MemArrays. FossilOrigin-Name: 7cd8ccf57d1ae0f597ec5004201395f61ef4750728f3c1b9c4dd52d28916a4f7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5571665cf9..8f744aa29b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sextra\sassert()\sto\sreleaseMemArray()\sjust\sto\sprove\sthat\sthe\nsqlite3_value.db\sfield\sis\snever\sNULL. -D 2024-12-30T12:29:18.018 +C New\sassert()\sstatements\sto\sshow\sthat\sthe\ssqlite3_value.db\sfield\sis\sinitialized\nfor\sMemArrays. +D 2024-12-30T13:54:52.618 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -850,7 +850,7 @@ F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 F src/vdbeInt.h bf294a0c8fc4cc80779e74b04b8bd82c6e1197b3137cefe0b16cdf002fc7dfd6 F src/vdbeapi.c 38c252a202d70b56cfb734460bc888ddbd581afec1a10cd4d6c894c9e0b5baea -F src/vdbeaux.c 1969b208ab554f0a6560a86c339dad5faf68d3ef861f96be86792d7eec23575d +F src/vdbeaux.c 5fcbc642a3d3d88c5ea15cadf2c8b8e4e067cb9ff374beb1875c9d209001299e F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797 F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2 F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f @@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e7f7c9d22be8a17b9a4d8f954fcdd40591ba9da5fb674f1184f960bca5f3d30b -R f8a1fde40935ca24cba561f520c119c6 +P b969ef1def5121c7ff54e3586528274f006ca994b308cf88ccaa9d4f56bf30df +R 18406ff7db8174f76f6c592dc7e8fcab U drh -Z 3a5e22afa8456e78923838b8f35ae4a2 +Z 815773c1659cf7d73e9358310c714bdb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 98b845261c..0b15193ff2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b969ef1def5121c7ff54e3586528274f006ca994b308cf88ccaa9d4f56bf30df +7cd8ccf57d1ae0f597ec5004201395f61ef4750728f3c1b9c4dd52d28916a4f7 diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 3d918be32e..b9e8b3cdf8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2144,6 +2144,7 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ ** will be initialized before use. */ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ + assert( db!=0 ); if( N>0 ){ do{ p->flags = flags; @@ -2650,6 +2651,7 @@ void sqlite3VdbeMakeReady( assert( pParse!=0 ); assert( p->eVdbeState==VDBE_INIT_STATE ); assert( pParse==p->pParse ); + assert( pParse->db==p->db ); p->pVList = pParse->pVList; pParse->pVList = 0; db = p->db; From 95f6df5b8d55e67d1e34d2bff217305a2f21b1fb Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 30 Dec 2024 21:23:53 +0000 Subject: [PATCH 472/522] Add the convenience makefile target (unix-only) "src-archives" that builds the various tarballs and ZIP archives that go on the download page. This is intended to make it easier and less error prone to put up new "draft" download pages for testing. FossilOrigin-Name: 2b17bc49655c577029919c2d409de994b0d252f8efb5da1ba0913f2c96bee552 --- main.mk | 15 +++++++++++++++ manifest | 14 ++++++++------ manifest.uuid | 2 +- tool/mkamalzip.tcl | 15 +++++++++++++++ tool/mksrczip.tcl | 14 ++++++++++++++ 5 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 tool/mkamalzip.tcl create mode 100644 tool/mksrczip.tcl diff --git a/main.mk b/main.mk index f98850731e..660cf54bd3 100644 --- a/main.mk +++ b/main.mk @@ -1929,6 +1929,21 @@ amalgamation-tarball: sqlite3.c sqlite3rc.h snapshot-tarball: sqlite3.c sqlite3rc.h TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot +# Build a ZIP archive snapshot of the latest check-in. +# +sqlite-src.zip: $(TOP)/tool/mksrczip.tcl + $(TCLSH_CMD) $(TOP)/tool/mksrczip.tcl + +# Build a ZIP archive of the amaglamation +# +sqlite-amalgamation.zip: $(TOP)/tool/mkamalzip.tcl sqlite3.c sqlite3.h shell.c sqlite3ext.h + $(TCLSH_CMD) $(TOP)/tool/mkamalzip.tcl + +# Build all the source code deliverables +# +src-archives: sqlite-amalgamation.zip amalgamation-tarball sqlite-src.zip + ls -ltr *.zip *.tar.gz | tail -3 + # Build a ZIP archive containing various command-line tools. # tool-zip: testfixture$(T.exe) sqlite3$(T.exe) sqldiff$(T.exe) \ diff --git a/manifest b/manifest index 8f744aa29b..2f45824ace 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sassert()\sstatements\sto\sshow\sthat\sthe\ssqlite3_value.db\sfield\sis\sinitialized\nfor\sMemArrays. -D 2024-12-30T13:54:52.618 +C Add\sthe\sconvenience\smakefile\starget\s(unix-only)\s"src-archives"\sthat\sbuilds\nthe\svarious\starballs\sand\sZIP\sarchives\sthat\sgo\son\sthe\sdownload\spage.\s\sThis\sis\nintended\sto\smake\sit\seasier\sand\sless\serror\sprone\sto\sput\sup\snew\s"draft"\sdownload\npages\sfor\stesting. +D 2024-12-30T21:23:53.148 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 1ec3c7a81198397b14bf75c9304f01e891a5d464797cd402d4f3781feadd3331 +F main.mk fde6ef9167ab1972f6273c0cc06a7d2d776f562d06f44f4987868335910f3803 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2138,6 +2138,7 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 +F tool/mkamalzip.tcl 8a1b21fb6a7f990eb9625e08daa2dd0e03cb551bccc69ccd1cdd5bd975e8177a F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a F tool/mkccode.tcl 210159febe0ef0ecbc53c79833500663ceaba0115b2b374405818dc835b5f84b x F tool/mkctimec.tcl ef6a67ec82e5b6fc19152a4c79f237227b18bf67ff16d155bac7adb94355d9cf x @@ -2154,6 +2155,7 @@ F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6 F tool/mksqlite3c.tcl 9e88a30981280e33489fe4782f4ab1e5349ba1866603fba7f1a948d5599b9124 F tool/mksqlite3h.tcl 7a4648fef5efb33308d575c7775eb242855d71d5bf89065df3f006b9a634a0a1 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b +F tool/mksrczip.tcl 81efd9974dbb36005383f2cd655520057a2ae5aa85ac2441a80c7c28f803ac52 F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c7a27c F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845 @@ -2202,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b969ef1def5121c7ff54e3586528274f006ca994b308cf88ccaa9d4f56bf30df -R 18406ff7db8174f76f6c592dc7e8fcab +P 7cd8ccf57d1ae0f597ec5004201395f61ef4750728f3c1b9c4dd52d28916a4f7 +R f56cb98bdebf27e28da45a1d08491799 U drh -Z 815773c1659cf7d73e9358310c714bdb +Z 0ad30bdc3b0bb40aad0de043d83aa269 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0b15193ff2..60af841357 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cd8ccf57d1ae0f597ec5004201395f61ef4750728f3c1b9c4dd52d28916a4f7 +2b17bc49655c577029919c2d409de994b0d252f8efb5da1ba0913f2c96bee552 diff --git a/tool/mkamalzip.tcl b/tool/mkamalzip.tcl new file mode 100644 index 0000000000..a7c6587566 --- /dev/null +++ b/tool/mkamalzip.tcl @@ -0,0 +1,15 @@ +#!/usr/bin/tclsh +# +# Build a ZIP archive for the amalgamation source code found in the current +# directory. +# +set VERSION-file [file dirname [file dirname [file normalize $argv0]]]/VERSION +set fd [open ${VERSION-file} rb] +set vers [read $fd] +close $fd +scan $vers %d.%d.%d major minor patch +set numvers [format {3%02d%02d00} $minor $patch] +set cmd "zip sqlite-amalgamation-$numvers.zip\ + sqlite3.c sqlite3.h shell.c sqlite3ext.h" +puts $cmd +exec {*}$cmd diff --git a/tool/mksrczip.tcl b/tool/mksrczip.tcl new file mode 100644 index 0000000000..4431c3d666 --- /dev/null +++ b/tool/mksrczip.tcl @@ -0,0 +1,14 @@ +#!/usr/bin/tclsh +# +# Build a ZIP archive for the complete, unedited source code that +# corresponds to the current check-out. +# +set VERSION-file [file dirname [file dirname [file normalize $argv0]]]/VERSION +set fd [open ${VERSION-file} rb] +set vers [read $fd] +close $fd +scan $vers %d.%d.%d major minor patch +set numvers [format {3%02d%02d00} $minor $patch] +set cmd "fossil zip current sqlite-src-$numvers.zip --name sqlite-src-$numvers" +puts $cmd +exec {*}$cmd From f7fcf7f910dcbc765eac670d74f36ccddbfe81c3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 1 Jan 2025 12:24:01 +0000 Subject: [PATCH 473/522] Fix the vfstrace.c extension so that it supports xFetch and xUnfetch. FossilOrigin-Name: c7132b7e62422378f0560dcf0837888db5aa70cded9d783ab389581aa43dc5c8 --- ext/misc/vfstrace.c | 29 ++++++++++++++++++++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/ext/misc/vfstrace.c b/ext/misc/vfstrace.c index e8b51cdd03..fed87e88f3 100644 --- a/ext/misc/vfstrace.c +++ b/ext/misc/vfstrace.c @@ -188,6 +188,7 @@ struct vfstrace_file { #define VTR_SLEEP 0x02000000 #define VTR_CURTIME 0x04000000 #define VTR_LASTERR 0x08000000 +#define VTR_FETCH 0x10000000 /* Also coverse xUnfetch */ /* ** Method declarations for vfstrace_file. @@ -617,6 +618,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ { "currenttime", VTR_CURTIME }, { "currenttimeint64", VTR_CURTIME }, { "getlasterror", VTR_LASTERR }, + { "fetch", VTR_FETCH }, }; int onOff = 1; while( zArg[0] ){ @@ -844,7 +846,28 @@ static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){ vfstrace_print_errcode(pInfo, " -> %s\n", rc); return rc; } - +static int vfstraceFetch(sqlite3_file *pFile, i64 iOff, int nAmt, void **pptr){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_FETCH); + vfstrace_printf(pInfo, "%s.xFetch(%s,iOff=%lld,nAmt=%d,p=%p)", + pInfo->zVfsName, p->zFName, iOff, nAmt, *pptr); + rc = p->pReal->pMethods->xFetch(p->pReal, iOff, nAmt, pptr); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} +static int vfstraceUnfetch(sqlite3_file *pFile, i64 iOff, void *ptr){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_FETCH); + vfstrace_printf(pInfo, "%s.xUnfetch(%s,iOff=%lld,p=%p)", + pInfo->zVfsName, p->zFName, iOff, ptr); + rc = p->pReal->pMethods->xUnfetch(p->pReal, iOff, ptr); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} /* @@ -891,6 +914,10 @@ static int vfstraceOpen( pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0; pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0; } + if( pNew->iVersion>=3 ){ + pNew->xFetch = pSub->xFetch ? vfstraceFetch : 0; + pNew->xUnfetch = pSub->xUnfetch ? vfstraceUnfetch : 0; + } pFile->pMethods = pNew; } vfstrace_print_errcode(pInfo, " -> %s", rc); diff --git a/manifest b/manifest index 2f45824ace..72166caccb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sconvenience\smakefile\starget\s(unix-only)\s"src-archives"\sthat\sbuilds\nthe\svarious\starballs\sand\sZIP\sarchives\sthat\sgo\son\sthe\sdownload\spage.\s\sThis\sis\nintended\sto\smake\sit\seasier\sand\sless\serror\sprone\sto\sput\sup\snew\s"draft"\sdownload\npages\sfor\stesting. -D 2024-12-30T21:23:53.148 +C Fix\sthe\svfstrace.c\sextension\sso\sthat\sit\ssupports\sxFetch\sand\sxUnfetch. +D 2025-01-01T12:24:01.620 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -453,7 +453,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917 F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d -F ext/misc/vfstrace.c 4d8b39570cbede1a05928c77e2142f8a744468443bf649cf86da3924e5e60fca +F ext/misc/vfstrace.c 9c4abd2f67ae2760e7a241eca2e8517c64480ac2c3e66a499326e688a9bbee22 F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7cd8ccf57d1ae0f597ec5004201395f61ef4750728f3c1b9c4dd52d28916a4f7 -R f56cb98bdebf27e28da45a1d08491799 +P 2b17bc49655c577029919c2d409de994b0d252f8efb5da1ba0913f2c96bee552 +R 1a7b3740d0d7b0156ecda7d86d9b3eae U drh -Z 0ad30bdc3b0bb40aad0de043d83aa269 +Z ba39083b8910dae572ba02a04ab64577 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 60af841357..1eb7acbbfc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b17bc49655c577029919c2d409de994b0d252f8efb5da1ba0913f2c96bee552 +c7132b7e62422378f0560dcf0837888db5aa70cded9d783ab389581aa43dc5c8 From 66985fb8fff34b7d46980202b9a245f3bb9db26a Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 1 Jan 2025 18:18:49 +0000 Subject: [PATCH 474/522] Fix the tool/omittest.tcl script, broken by [d8c0e0184226bdae]. FossilOrigin-Name: 4f6c36a61c2b27e204c00bd7467453098f756c7e596b7e62d47da8784fbd2026 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/omittest.tcl | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 72166caccb..a4764f5808 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\svfstrace.c\sextension\sso\sthat\sit\ssupports\sxFetch\sand\sxUnfetch. -D 2025-01-01T12:24:01.620 +C Fix\sthe\stool/omittest.tcl\sscript,\sbroken\sby\s[d8c0e0184226bdae]. +D 2025-01-01T18:18:49.769 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2160,7 +2160,7 @@ F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845 F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08 -F tool/omittest.tcl 5ca5e4e01716d5f35b48b00fd351d929f01fbb98169a5a3cd00baf3d2e2019a9 +F tool/omittest.tcl bec70ef0e16255c8d9eb06ecd7edf823c07a60a836186cdbce3528fb34b67995 F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a F tool/pagesig.c f98909b4168d9cac11a2de7f031adea0e2f3131faa7515a72807c03ec58eafeb F tool/replace.tcl 511c61acfe563dfb58675efb4628bb158a13d48ff8322123ac447e9d25a82d9a @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2b17bc49655c577029919c2d409de994b0d252f8efb5da1ba0913f2c96bee552 -R 1a7b3740d0d7b0156ecda7d86d9b3eae +P c7132b7e62422378f0560dcf0837888db5aa70cded9d783ab389581aa43dc5c8 +R b61fb2d8724df93fbff2b6eed5e91f66 U drh -Z ba39083b8910dae572ba02a04ab64577 +Z 966756dbeab414c1a4d72e1421c875b3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1eb7acbbfc..5f61c67895 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7132b7e62422378f0560dcf0837888db5aa70cded9d783ab389581aa43dc5c8 +4f6c36a61c2b27e204c00bd7467453098f756c7e596b7e62d47da8784fbd2026 diff --git a/tool/omittest.tcl b/tool/omittest.tcl index e9033c0bdd..0452a4c6f6 100644 --- a/tool/omittest.tcl +++ b/tool/omittest.tcl @@ -200,8 +200,8 @@ foreach sym $CompileOptionsToTest { } else { set opts OPT_FEATURE_FLAGS=-D$sym } - puts "make tidy sqlite3.lo $opts" - if {[catch {exec make tidy sqlite3.lo $opts >& $logfile}]} { + puts "make tidy sqlite3.o $opts" + if {[catch {exec make tidy sqlite3.o $opts >& $logfile}]} { puts "BUILD FAILED: see $logfile for details" if {[info exists FailIsOk($sym)]} { set Failure($sym) 1 From e0b6ee51859720138fcaafd042eb605a2ecdeeb4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 2 Jan 2025 12:14:01 +0000 Subject: [PATCH 475/522] Update the build instructions for Windows to note that VS2015 or later is required to avoid the need to install tclsh.exe. FossilOrigin-Name: da0ef0567be55648413bcbf2e129f348776a908dbad2ac8582ee3e27ac459e3b --- doc/compile-for-windows.md | 9 +++++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/compile-for-windows.md b/doc/compile-for-windows.md index b3a48549a6..5cecfbf547 100644 --- a/doc/compile-for-windows.md +++ b/doc/compile-for-windows.md @@ -7,6 +7,15 @@ canonical source on a new Windows 11 PC, as of 2024-10-09: will work fine. Do a standard install for C++ development. SQLite only needs the "cl" compiler and the "nmake" build tool. +
        • Note: + VS2015 or later is required for the procedures below to + all work. You *might* be able to get the build to work with + earlier versions of MSVC, but in that case the TCL installation + of step 3 will be required, since the "jimsh0.c" program of + Autosetup that is used as a substitute for "tclsh.exe" won't + compile with versions of Visual Studio prior to VS2015. In any + event, building SQLite from canonical source code on Windows + is not supported for earlier versions of Visual Studio.
        2. Under the "Start" menu, find "All Apps" then go to "Visual Studio 20XX" and find "x64 Native Tools Command Prompt for VS 20XX". Pin that diff --git a/manifest b/manifest index a4764f5808..677b44875c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\stool/omittest.tcl\sscript,\sbroken\sby\s[d8c0e0184226bdae]. -D 2025-01-01T18:18:49.769 +C Update\sthe\sbuild\sinstructions\sfor\sWindows\sto\snote\sthat\sVS2015\sor\slater\sis\nrequired\sto\savoid\sthe\sneed\sto\sinstall\stclsh.exe. +D 2025-01-02T12:14:01.327 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -56,7 +56,7 @@ F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/compile-for-unix.md 7d6a5770611ea0643de456b385581923dac7c0a7c3758825dda810d12fc3e5b2 -F doc/compile-for-windows.md 17e1491897a117ff0247531a61671b26d487bc1dad25c3894c04ad4fca936a7f +F doc/compile-for-windows.md 791f1754fcd669b0a8fdcdc0fdd56eff8c148add7457e8bf4863b46829966fc1 F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c7132b7e62422378f0560dcf0837888db5aa70cded9d783ab389581aa43dc5c8 -R b61fb2d8724df93fbff2b6eed5e91f66 +P 4f6c36a61c2b27e204c00bd7467453098f756c7e596b7e62d47da8784fbd2026 +R c359455d12a83b16327a4eb96d1245c3 U drh -Z 966756dbeab414c1a4d72e1421c875b3 +Z 5fb03700b1eda71764ba1102db353cb9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5f61c67895..cf83b9aeb5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4f6c36a61c2b27e204c00bd7467453098f756c7e596b7e62d47da8784fbd2026 +da0ef0567be55648413bcbf2e129f348776a908dbad2ac8582ee3e27ac459e3b From a683b055fbecd8a9e78602003bad558eb1a61420 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 2 Jan 2025 15:03:13 +0000 Subject: [PATCH 476/522] Improvements to the way that truncation is implemented in sqlite_dbpage(). FossilOrigin-Name: ac4bb2e4ecf0bdb0d8ac12b1ccb42d51af02f519a038cfc79faab5c216971056 --- manifest | 16 ++++---- manifest.uuid | 2 +- src/dbpage.c | 36 +++++++++++------ test/dbpage.test | 92 +++++++++++++++++++++++++++++++++++++++++++ test/dbpagefault.test | 26 ++++++++++++ 5 files changed, 152 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 677b44875c..62bfd24b2b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sbuild\sinstructions\sfor\sWindows\sto\snote\sthat\sVS2015\sor\slater\sis\nrequired\sto\savoid\sthe\sneed\sto\sinstall\stclsh.exe. -D 2025-01-02T12:14:01.327 +C Improvements\sto\sthe\sway\sthat\struncation\sis\simplemented\sin\ssqlite_dbpage(). +D 2025-01-02T15:03:13.323 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -724,7 +724,7 @@ F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d49 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a -F src/dbpage.c b1aeb47c1004f26c39c6800f0045b8d729d232aca24f6aa430c491b83003d033 +F src/dbpage.c cfa9ed0a490bd2e07e4cdba68503ccd5e587dcb4ac9c7ae9ed382a9cd924f29b F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f @@ -1076,8 +1076,8 @@ F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test 6c9a4622029d69dc38926f115864b055cb2f39badd25ec22cbfb130c8ba8e9c3 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23 -F test/dbpage.test fce29035c7566fd7835ec0f19422cb4b9c6944ce0e1b936ff8452443f92e887d -F test/dbpagefault.test 35f06cfb2ef100a9b19d25754e8141b9cba9b7daabd4c60fa5af93fcce884435 +F test/dbpage.test dba7b6048c461125595278bd838e66d01bba67d8ad1da94489a7851439e8fa86 +F test/dbpagefault.test ea39de2ca86041a9c6df1135645180a76d0a8da93ac159e2fafe38e39636530b F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef F test/decimal.test ef731887b43ee32ef86e1c8fddb61a40789f988332c029c601dcf2c319277e9e @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4f6c36a61c2b27e204c00bd7467453098f756c7e596b7e62d47da8784fbd2026 -R c359455d12a83b16327a4eb96d1245c3 +P da0ef0567be55648413bcbf2e129f348776a908dbad2ac8582ee3e27ac459e3b +R 963301e91789659974012d48c99b5d2d U drh -Z 5fb03700b1eda71764ba1102db353cb9 +Z dc0b704adc2bca53154303a0d3643971 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cf83b9aeb5..be9b420eed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da0ef0567be55648413bcbf2e129f348776a908dbad2ac8582ee3e27ac459e3b +ac4bb2e4ecf0bdb0d8ac12b1ccb42d51af02f519a038cfc79faab5c216971056 diff --git a/src/dbpage.c b/src/dbpage.c index 74f345570e..e435dcfec7 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -317,6 +317,24 @@ static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ return SQLITE_OK; } +/* +** Open write transactions. Since we do not know in advance which database +** files will be written by the sqlite_dbpage virtual table, start a write +** transaction on them all. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int dbpageBeginTrans(DbpageTable *pTab){ + sqlite3 *db = pTab->db; + int rc = SQLITE_OK; + int i; + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ) rc = sqlite3BtreeBeginTrans(pBt, 1, 0); + } + return rc; +} + static int dbpageUpdate( sqlite3_vtab *pVtab, int argc, @@ -384,6 +402,12 @@ static int dbpageUpdate( goto update_fail; } } + + if( dbpageBeginTrans(pTab)!=SQLITE_OK ){ + zErr = "failed to open transaction"; + goto update_fail; + } + pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ @@ -405,18 +429,8 @@ static int dbpageUpdate( return SQLITE_ERROR; } -/* Since we do not know in advance which database files will be -** written by the sqlite_dbpage virtual table, start a write transaction -** on them all. -*/ static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; - sqlite3 *db = pTab->db; - int i; - for(i=0; inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); - } pTab->pgnoTrunc = 0; return SQLITE_OK; } @@ -474,7 +488,7 @@ int sqlite3DbpageRegister(sqlite3 *db){ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ - dbpageRollbackTo, /* xRollbackTo */ + 0/*dbpageRollbackTo*/, /* xRollbackTo */ 0, /* xShadowName */ 0 /* xIntegrity */ }; diff --git a/test/dbpage.test b/test/dbpage.test index 0646a70b02..2c07253073 100644 --- a/test/dbpage.test +++ b/test/dbpage.test @@ -108,4 +108,96 @@ do_execsql_test 300 { SELECT * FROM sqlite_temp_schema, sqlite_dbpage; } {} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 400 { + ATTACH ':memory:' AS aux1; + BEGIN; + CREATE VIRTUAL TABLE aux1.t1 USING sqlite_dbpage; + INSERT INTO t1 VALUES(17, NULL); + COMMIT; +} + +#------------------------------------------------------------------------- +reset_db +forcedelete test.db2 +sqlite3 db2 test.db2 +db2 eval { + CREATE TABLE t1(x, y); +} + +do_execsql_test 500 { + CREATE TABLE x1(a); + INSERT INTO x1 VALUES( hex(randomblob(2000)) ); + INSERT INTO x1 VALUES( hex(randomblob(2000)) ); + INSERT INTO x1 VALUES( hex(randomblob(2000)) ); + INSERT INTO x1 VALUES( hex(randomblob(2000)) ); + PRAGMA page_count; +} {18} + +do_test 510 { + db eval BEGIN + db2 eval { PRAGMA page_count } { + db eval { + INSERT INTO sqlite_dbpage values($page_count, NULL); + } + } + db2 eval { SELECT pgno, data FROM sqlite_dbpage } { + db eval { + INSERT INTO sqlite_dbpage values($pgno, $data); + } + } + + db eval COMMIT +} {} + +db close +sqlite3 db test.db + +do_execsql_test 520 { + PRAGMA page_count; + SELECT * FROM t1; +} {2} + +#------------------------------------------------------------------------- +reset_db +forcedelete test.db2 +do_execsql_test 610 { + ATTACH 'test.db2' AS aux; + CREATE TABLE t1(x); + CREATE TABLE t2(y); + INSERT INTO t1 VALUES(1234); + CREATE TABLE aux.x1(z); +} + +set pgno [db one {SELECT max(rootpage) FROM sqlite_schema}] +sqlite3 db2 test.db2 +db2 eval { + BEGIN; + SELECT * FROM x1; +} + +do_catchsql_test 620 { + UPDATE sqlite_dbpage SET data = ( + SELECT data FROM sqlite_dbpage WHERE pgno=$pgno-1 + ) WHERE pgno = $pgno; +} {1 {database is locked}} + +db2 eval { + COMMIT; +} + +do_catchsql_test 630 { + UPDATE sqlite_dbpage SET data = ( + SELECT data FROM sqlite_dbpage WHERE pgno=$pgno-1 + ) WHERE pgno = $pgno; +} {0 {}} + +db close +sqlite3 db test.db + +do_execsql_test 640 { + SELECT * FROM t2; +} {1234} + finish_test diff --git a/test/dbpagefault.test b/test/dbpagefault.test index f27741cba1..e5b246fc94 100644 --- a/test/dbpagefault.test +++ b/test/dbpagefault.test @@ -82,5 +82,31 @@ do_catchsql_test 3.2 { # faultsim_test_result {0 {}} #} +reset_db +forcedelete test.db2 +do_execsql_test 4.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('one'); + CREATE TABLE t2(x); + INSERT INTO t2 VALUES('two'); + ATTACH 'test.db2' AS aux; + CREATE TABLE aux.x1(x); +} + +set pgno [db one {SELECT max(rootpage) FROM sqlite_schema}] + +faultsim_save_and_close +do_faultsim_test 4 -prep { + faultsim_restore_and_reopen + execsql { ATTACH 'test.db2' AS aux; } +} -body { + execsql { + UPDATE sqlite_dbpage SET data = ( + SELECT data FROM sqlite_dbpage WHERE pgno=($pgno-1) + ) WHERE pgno = $pgno; + } +} -test { + faultsim_test_result {0 {}} {1 {unable to open a temporary database file for storing temporary tables}} +} finish_test From 3835cf6ea1f0bee954426c9c196fda9f2ee4662d Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 2 Jan 2025 15:27:15 +0000 Subject: [PATCH 477/522] Add a test case for ROLLBACK TO of database truncate operations made through the sqlite_dbpage vtab. FossilOrigin-Name: eb335beb1eb9ebbea4cb793d24f65787d0d9d8539bc6b5971e4e4298fdfce0c2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/dbpage.c | 4 ++-- test/dbpage.test | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 62bfd24b2b..0cfa467e80 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sway\sthat\struncation\sis\simplemented\sin\ssqlite_dbpage(). -D 2025-01-02T15:03:13.323 +C Add\sa\stest\scase\sfor\sROLLBACK\sTO\sof\sdatabase\struncate\soperations\smade\sthrough\sthe\ssqlite_dbpage\svtab. +D 2025-01-02T15:27:15.310 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -724,7 +724,7 @@ F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d49 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c d35723024b963edce9c0fad5b3303e8bb9266083784844baed10a6dedfe26f3b F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a -F src/dbpage.c cfa9ed0a490bd2e07e4cdba68503ccd5e587dcb4ac9c7ae9ed382a9cd924f29b +F src/dbpage.c e90410e5d4c0217dfddc4184a81e38ec4903c25d4ec0f201060a0e54e7c2099f F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f @@ -1076,7 +1076,7 @@ F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test 6c9a4622029d69dc38926f115864b055cb2f39badd25ec22cbfb130c8ba8e9c3 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23 -F test/dbpage.test dba7b6048c461125595278bd838e66d01bba67d8ad1da94489a7851439e8fa86 +F test/dbpage.test 901ff31a7f5c80875b909d8cb5241e7d3ddfc08cd812a2f0ab9630e720e9e9c2 F test/dbpagefault.test ea39de2ca86041a9c6df1135645180a76d0a8da93ac159e2fafe38e39636530b F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P da0ef0567be55648413bcbf2e129f348776a908dbad2ac8582ee3e27ac459e3b -R 963301e91789659974012d48c99b5d2d -U drh -Z dc0b704adc2bca53154303a0d3643971 +P ac4bb2e4ecf0bdb0d8ac12b1ccb42d51af02f519a038cfc79faab5c216971056 +R ae6fe4d4378dd5bb82a68cd1b247b9d9 +U dan +Z 138def969ceba9d851c4d9f22f7101e9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index be9b420eed..0832c70d5f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ac4bb2e4ecf0bdb0d8ac12b1ccb42d51af02f519a038cfc79faab5c216971056 +eb335beb1eb9ebbea4cb793d24f65787d0d9d8539bc6b5971e4e4298fdfce0c2 diff --git a/src/dbpage.c b/src/dbpage.c index e435dcfec7..40ebe4f14a 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -466,7 +466,7 @@ static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){ */ int sqlite3DbpageRegister(sqlite3 *db){ static sqlite3_module dbpage_module = { - 0, /* iVersion */ + 2, /* iVersion */ dbpageConnect, /* xCreate */ dbpageConnect, /* xConnect */ dbpageBestIndex, /* xBestIndex */ @@ -488,7 +488,7 @@ int sqlite3DbpageRegister(sqlite3 *db){ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ - 0/*dbpageRollbackTo*/, /* xRollbackTo */ + dbpageRollbackTo, /* xRollbackTo */ 0, /* xShadowName */ 0 /* xIntegrity */ }; diff --git a/test/dbpage.test b/test/dbpage.test index 2c07253073..5344937c95 100644 --- a/test/dbpage.test +++ b/test/dbpage.test @@ -200,4 +200,50 @@ do_execsql_test 640 { SELECT * FROM t2; } {1234} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 700 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES( hex(randomblob(1000)) ); + INSERT INTO t1 VALUES( hex(randomblob(1000)) ); + INSERT INTO t1 VALUES( hex(randomblob(1000)) ); +} + +forcedelete test.db2 +sqlite3 db2 test.db2 +db2 eval { + CREATE TABLE y1(y); + INSERT INTO y1 VALUES( hex(randomblob(1000)) ); +} + +set max [db2 one {PRAGMA page_count}] + +do_test 710 { + execsql { + BEGIN; + } + + for {set ii 1} {$ii <= $max} {incr ii} { + set data [db2 one {SELECT data FROM sqlite_dbpage WHERE pgno=$ii}] + execsql { + UPDATE sqlite_dbpage SET data=$data WHERE pgno=$ii + } + } + + execsql { + SAVEPOINT abc; + INSERT INTO sqlite_dbpage VALUES(2, NULL); + ROLLBACK TO abc; + COMMIT; + } +} {} + +db close +sqlite3 db test.db + +do_execsql_test 720 { + PRAGMA integrity_check +} {ok} + + finish_test From 52c87ac084ddb84901580c86ff2acbd7e30ff1df Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 2 Jan 2025 15:39:54 +0000 Subject: [PATCH 478/522] Fix recent test cases so that they work even when auto_vacuum defaults to on. FossilOrigin-Name: 41f6e46695b547dece4daf2f3714e29f231aa04774f57fbd31aeb0a4290c0e7d --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/dbpage.test | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0cfa467e80..97c5634d26 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sfor\sROLLBACK\sTO\sof\sdatabase\struncate\soperations\smade\sthrough\sthe\ssqlite_dbpage\svtab. -D 2025-01-02T15:27:15.310 +C Fix\srecent\stest\scases\sso\sthat\sthey\swork\seven\swhen\sauto_vacuum\sdefaults\sto\son. +D 2025-01-02T15:39:54.534 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1076,7 +1076,7 @@ F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test 6c9a4622029d69dc38926f115864b055cb2f39badd25ec22cbfb130c8ba8e9c3 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23 -F test/dbpage.test 901ff31a7f5c80875b909d8cb5241e7d3ddfc08cd812a2f0ab9630e720e9e9c2 +F test/dbpage.test 6ff0b526c4781ef3383ada4aba60c9e12233df66d0355a38dd5ed3e0936abefd F test/dbpagefault.test ea39de2ca86041a9c6df1135645180a76d0a8da93ac159e2fafe38e39636530b F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ac4bb2e4ecf0bdb0d8ac12b1ccb42d51af02f519a038cfc79faab5c216971056 -R ae6fe4d4378dd5bb82a68cd1b247b9d9 -U dan -Z 138def969ceba9d851c4d9f22f7101e9 +P eb335beb1eb9ebbea4cb793d24f65787d0d9d8539bc6b5971e4e4298fdfce0c2 +R 599467a5ae33e37cee7d650d64a24003 +U drh +Z c0514aaa061ec3b7bb05aecaa83b03ff # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0832c70d5f..4ffc4a615d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb335beb1eb9ebbea4cb793d24f65787d0d9d8539bc6b5971e4e4298fdfce0c2 +41f6e46695b547dece4daf2f3714e29f231aa04774f57fbd31aeb0a4290c0e7d diff --git a/test/dbpage.test b/test/dbpage.test index 5344937c95..27d532bf98 100644 --- a/test/dbpage.test +++ b/test/dbpage.test @@ -123,10 +123,12 @@ reset_db forcedelete test.db2 sqlite3 db2 test.db2 db2 eval { + PRAGMA auto_vacuum=NONE; CREATE TABLE t1(x, y); } do_execsql_test 500 { + PRAGMA auto_vacuum=NONE; CREATE TABLE x1(a); INSERT INTO x1 VALUES( hex(randomblob(2000)) ); INSERT INTO x1 VALUES( hex(randomblob(2000)) ); From 1426d2a26473f1a9cb197d18d50c142b2f306e48 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 2 Jan 2025 17:56:11 +0000 Subject: [PATCH 479/522] Close database connections in test/dbpage.test, for Windows. FossilOrigin-Name: 322d255ed89c1dee08745e89f3c2bcf495283fd87b7526e70d6525a6e96b0ecf --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/dbpage.test | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 97c5634d26..4f1c7060e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\srecent\stest\scases\sso\sthat\sthey\swork\seven\swhen\sauto_vacuum\sdefaults\sto\son. -D 2025-01-02T15:39:54.534 +C Close\sdatabase\sconnections\sin\stest/dbpage.test,\sfor\sWindows. +D 2025-01-02T17:56:11.889 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -1076,7 +1076,7 @@ F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test 6c9a4622029d69dc38926f115864b055cb2f39badd25ec22cbfb130c8ba8e9c3 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23 -F test/dbpage.test 6ff0b526c4781ef3383ada4aba60c9e12233df66d0355a38dd5ed3e0936abefd +F test/dbpage.test 63fab1eb026bada121107e53436fa749bbf83281dc9dea17af422f7a5c0f289f F test/dbpagefault.test ea39de2ca86041a9c6df1135645180a76d0a8da93ac159e2fafe38e39636530b F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P eb335beb1eb9ebbea4cb793d24f65787d0d9d8539bc6b5971e4e4298fdfce0c2 -R 599467a5ae33e37cee7d650d64a24003 +P 41f6e46695b547dece4daf2f3714e29f231aa04774f57fbd31aeb0a4290c0e7d +R ad33df8723391488642db5cd87f0ab29 U drh -Z c0514aaa061ec3b7bb05aecaa83b03ff +Z 2ad32d699feaca719fd3e1c4c9618a89 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4ffc4a615d..532729f0d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41f6e46695b547dece4daf2f3714e29f231aa04774f57fbd31aeb0a4290c0e7d +322d255ed89c1dee08745e89f3c2bcf495283fd87b7526e70d6525a6e96b0ecf diff --git a/test/dbpage.test b/test/dbpage.test index 27d532bf98..8039e0e1be 100644 --- a/test/dbpage.test +++ b/test/dbpage.test @@ -161,6 +161,8 @@ do_execsql_test 520 { SELECT * FROM t1; } {2} +db2 close + #------------------------------------------------------------------------- reset_db forcedelete test.db2 @@ -202,6 +204,8 @@ do_execsql_test 640 { SELECT * FROM t2; } {1234} +db2 close + #------------------------------------------------------------------------- reset_db do_execsql_test 700 { From db258d8ff74163dcd1c58730581c99bd08ef03c6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 2 Jan 2025 18:43:29 +0000 Subject: [PATCH 480/522] Improvements to the display of subqueries in the FROM clause for treeview output. (Debug and analysis code only - does not affect production builds.) FossilOrigin-Name: 4a2d65cdcdd3d21bb7d9ea0efb434484f1b8642c2bb6457db58bc2a5f4fc16e5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 3 --- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4f1c7060e7..bc7d18e071 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Close\sdatabase\sconnections\sin\stest/dbpage.test,\sfor\sWindows. -D 2025-01-02T17:56:11.889 +C Improvements\sto\sthe\sdisplay\sof\ssubqueries\sin\sthe\sFROM\sclause\sfor\streeview\noutput.\s\s(Debug\sand\sanalysis\scode\sonly\s-\sdoes\snot\saffect\sproduction\sbuilds.) +D 2025-01-02T18:43:29.883 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -839,7 +839,7 @@ F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c fe17e03175cae35b6694d0f879e7bc3d1ddea2fd4ab148cba9bbd025b7a7bb12 -F src/treeview.c 921392561385e05ef5703f20a7a72f0a0a45c1fb749558d7467fae2c3f525006 +F src/treeview.c e5848f30a6000ca0f9a918131c220f5dff652aa08b220c1de4dc45862ca27c88 F src/trigger.c 247e2d712d5edc6021d52a169f6ac9a9c10d7144bc4ac7ea06c1ed2aa414659f F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 41f6e46695b547dece4daf2f3714e29f231aa04774f57fbd31aeb0a4290c0e7d -R ad33df8723391488642db5cd87f0ab29 +P 322d255ed89c1dee08745e89f3c2bcf495283fd87b7526e70d6525a6e96b0ecf +R 880caaa332dedbabd2ac0f19d743a7f2 U drh -Z 2ad32d699feaca719fd3e1c4c9618a89 +Z 4a0cd1fd6c1443c6320e9f6723abbf4c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 532729f0d0..b0e812626c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -322d255ed89c1dee08745e89f3c2bcf495283fd87b7526e70d6525a6e96b0ecf +4a2d65cdcdd3d21bb7d9ea0efb434484f1b8642c2bb6457db58bc2a5f4fc16e5 diff --git a/src/treeview.c b/src/treeview.c index 30592d35b2..ab32774d4b 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -246,9 +246,6 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); - sqlite3TreeViewPush(&pView, 0); - sqlite3TreeViewLine(pView, "SUBQUERY"); - sqlite3TreeViewPop(&pView); sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); } if( pItem->fg.isTabFunc ){ From 04364cb3cc108a044a0d9dc7162f4d550adb2f99 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 2 Jan 2025 21:23:25 +0000 Subject: [PATCH 481/522] Improve the treeview output for CteUse objects. FossilOrigin-Name: 2b16d6947ca4a102ddab4d5ba3e340a75e1e5c28e45e874ee5ff52f9b5fb964f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index bc7d18e071..f56dd89bbd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sdisplay\sof\ssubqueries\sin\sthe\sFROM\sclause\sfor\streeview\noutput.\s\s(Debug\sand\sanalysis\scode\sonly\s-\sdoes\snot\saffect\sproduction\sbuilds.) -D 2025-01-02T18:43:29.883 +C Improve\sthe\streeview\soutput\sfor\sCteUse\sobjects. +D 2025-01-02T21:23:25.211 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -839,7 +839,7 @@ F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c fe17e03175cae35b6694d0f879e7bc3d1ddea2fd4ab148cba9bbd025b7a7bb12 -F src/treeview.c e5848f30a6000ca0f9a918131c220f5dff652aa08b220c1de4dc45862ca27c88 +F src/treeview.c d1f3003cb21846828f314a304cf9117f5e80ce0be259315a681d25147004d26d F src/trigger.c 247e2d712d5edc6021d52a169f6ac9a9c10d7144bc4ac7ea06c1ed2aa414659f F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 322d255ed89c1dee08745e89f3c2bcf495283fd87b7526e70d6525a6e96b0ecf -R 880caaa332dedbabd2ac0f19d743a7f2 +P 4a2d65cdcdd3d21bb7d9ea0efb434484f1b8642c2bb6457db58bc2a5f4fc16e5 +R c71f9b806da01da7c4d2eda55e40e335 U drh -Z 4a0cd1fd6c1443c6320e9f6723abbf4c +Z 07fa7dcff94b36dfa3368297cbe48fff # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b0e812626c..66ca9c4f52 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a2d65cdcdd3d21bb7d9ea0efb434484f1b8642c2bb6457db58bc2a5f4fc16e5 +2b16d6947ca4a102ddab4d5ba3e340a75e1e5c28e45e874ee5ff52f9b5fb964f diff --git a/src/treeview.c b/src/treeview.c index ab32774d4b..2cfcfb69b0 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -215,7 +215,10 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3_str_appendf(&x, " DDL"); } if( pItem->fg.isCte ){ - sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); + static const char *aMat[] = {",MAT", "", ",NO-MAT"}; + sqlite3_str_appendf(&x, " CteUse=%d%s", + pItem->u2.pCteUse->nUse, + aMat[pItem->u2.pCteUse->eM10d]); } if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ sqlite3_str_appendf(&x, " isOn"); From 8d6e3f513c049a07d34f77ab526259c916418af6 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 3 Jan 2025 11:22:01 +0000 Subject: [PATCH 482/522] Avoid using Int32x32To64() with a 64-bit argument in fileio.c - this level of micro-optimization is not really necessary there. FossilOrigin-Name: 1291b013a8c93e7001fe25783bc98d12f5f7c341d1f728e6852632e18a38af58 --- ext/misc/fileio.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/misc/fileio.c b/ext/misc/fileio.c index 483ef0187f..80ac3b3e7c 100644 --- a/ext/misc/fileio.c +++ b/ext/misc/fileio.c @@ -437,7 +437,7 @@ static int writeFile( GetSystemTime(¤tTime); SystemTimeToFileTime(¤tTime, &lastAccess); - intervals = Int32x32To64(mtime, 10000000) + 116444736000000000; + intervals = (mtime*10000000) + 116444736000000000; lastWrite.dwLowDateTime = (DWORD)intervals; lastWrite.dwHighDateTime = intervals >> 32; zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); diff --git a/manifest b/manifest index f56dd89bbd..db2048f8a2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\streeview\soutput\sfor\sCteUse\sobjects. -D 2025-01-02T21:23:25.211 +C Avoid\susing\sInt32x32To64()\swith\sa\s64-bit\sargument\sin\sfileio.c\s-\sthis\slevel\sof\smicro-optimization\sis\snot\sreally\snecessary\sthere. +D 2025-01-03T11:22:01.656 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -415,7 +415,7 @@ F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f82 F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b -F ext/misc/fileio.c e6b34db4df4b55b96265086c0010264e257b6eab1644e665697a6da587659403 +F ext/misc/fileio.c 07cf3109ec6452789e3a989a010234e2a17b599ce82ea29212c948572456abac F ext/misc/fossildelta.c 8c026e086e406e2b69947f1856fa3b848fff5379962276430d10085b8756b05a F ext/misc/fuzzer.c 8b28acf1a7e95d50e332bdd47e792ff27054ad99d3f9bc2e91273814d4b31a5a F ext/misc/ieee754.c 62a90978204d2c956d5036eb89e548e736ca5fac0e965912867ddd7bb833256d @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4a2d65cdcdd3d21bb7d9ea0efb434484f1b8642c2bb6457db58bc2a5f4fc16e5 -R c71f9b806da01da7c4d2eda55e40e335 -U drh -Z 07fa7dcff94b36dfa3368297cbe48fff +P 2b16d6947ca4a102ddab4d5ba3e340a75e1e5c28e45e874ee5ff52f9b5fb964f +R 5009b44122ef97a1941b73b1f68f9841 +U dan +Z 3d41d92a3c50a0c7b4d04240befaa9e5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 66ca9c4f52..a708ba3fee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b16d6947ca4a102ddab4d5ba3e340a75e1e5c28e45e874ee5ff52f9b5fb964f +1291b013a8c93e7001fe25783bc98d12f5f7c341d1f728e6852632e18a38af58 From ded37f337b7b2e916657a83732aaec40eb146282 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 3 Jan 2025 11:51:50 +0000 Subject: [PATCH 483/522] Add comment to the columnIsGoodIndexCandidate() routine to record the results of a failed experiment. No changes to code. FossilOrigin-Name: 9ee57a30a49d9813bf2669a5d8346f7e018e3fbf1792739951311a8d3a249d45 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index db2048f8a2..dbe9f57581 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\susing\sInt32x32To64()\swith\sa\s64-bit\sargument\sin\sfileio.c\s-\sthis\slevel\sof\smicro-optimization\sis\snot\sreally\snecessary\sthere. -D 2025-01-03T11:22:01.656 +C Add\scomment\sto\sthe\scolumnIsGoodIndexCandidate()\sroutine\sto\srecord\sthe\sresults\nof\sa\sfailed\sexperiment.\s\sNo\schanges\sto\scode. +D 2025-01-03T11:51:50.103 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -861,7 +861,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4e6181d8780ab0af2e1388d0754cbe6f2f04593d2b1ab6c41699a89942fd8997 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c 9ad3dea8003a8913da6a4ca8322e2fe30773f46e88a0d4fbf9db13bdb999efa2 +F src/where.c d519bc93b4a05928f10ba4925b1afc77cbd71c1b1b5148583ab4868925c639fb F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca F src/wherecode.c 0c3d3199a2b769a5e2bb70feb5003dc85b3d86842ecaf903a47f2b4205ca5dab F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f @@ -2204,8 +2204,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2b16d6947ca4a102ddab4d5ba3e340a75e1e5c28e45e874ee5ff52f9b5fb964f -R 5009b44122ef97a1941b73b1f68f9841 -U dan -Z 3d41d92a3c50a0c7b4d04240befaa9e5 +P 1291b013a8c93e7001fe25783bc98d12f5f7c341d1f728e6852632e18a38af58 +R 0507e66ed59bfa5a55bc14583a9d765f +U drh +Z 3304d535a779543ccf066c65753e6b08 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a708ba3fee..d506d57c15 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1291b013a8c93e7001fe25783bc98d12f5f7c341d1f728e6852632e18a38af58 +9ee57a30a49d9813bf2669a5d8346f7e018e3fbf1792739951311a8d3a249d45 diff --git a/src/where.c b/src/where.c index c9698699b3..4325374bce 100644 --- a/src/where.c +++ b/src/where.c @@ -860,6 +860,11 @@ static int constraintCompatibleWithOuterJoin( ** more than 20, then return false. ** ** 3. If no disqualifying conditions above are found, return true. +** +** 2025-01-03: I experimented with a new rule that returns false if the +** the datatype of the column is "BOOLEAN". This did not improve +** performance on any queries at hand, but it did burn CPU cycles, so the +** idea was not committed. */ static SQLITE_NOINLINE int columnIsGoodIndexCandidate( const Table *pTab, From 8f1bdc0f73af1b80989c1624bef6633cf9259180 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 4 Jan 2025 14:10:45 +0000 Subject: [PATCH 484/522] Add new tcl-extension-testing.md document. The Windows side is not yet working. FossilOrigin-Name: 9dc805df1b1c26196ca53baa6b1b8c2f7e59e0150d02ead53228c77a63ad40f4 --- doc/tcl-extension-testing.md | 142 +++++++++++++++++++++++++++++++++++ manifest | 14 ++-- manifest.uuid | 2 +- 3 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 doc/tcl-extension-testing.md diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md new file mode 100644 index 0000000000..7dab3eafbd --- /dev/null +++ b/doc/tcl-extension-testing.md @@ -0,0 +1,142 @@ +# Test Procedures For The SQLite TCL Extension + + +## 1.0 Testing On Unix-like Systems (Including Mac) + +### 1.1 Setup + +
          +
        1. + [Fossil](https://fossil-scm.org/) installed. +
        2. + A Fossil check-out of the TCL source tree. Let the directory + of this check-out be called **$TCLCO** (mnemonic: "TCL Check-Out"). +
        3. + A Fossil check-out of the SQLite source tree. Let the directory + of this check-out be called **$SRCCO** (mnemonic: "SouRCe Check-Out"). +
        4. + Let **$TCLTD** (mnemonic: "TCL Test Directory") be the name of a directory + that does not exist at the start of the test, and which will be + deleted at the end of the test, that will contain the test builds + of the TCL libraries and the SQLite TCL Extensions. +
        + +### 1.2 Building the TCL libraries and tclsh executables + +
          +
        1. `mkdir $TCLTD $TCLTD/tcl86 $TCLTD/tcl90` +
        2. `cd $TCLCO/unix` +
        3. `fossil up core-8-6-16` ← or some other version of Tcl8.6. +
        4. `fossil clean -x` +
        5. `./configure --prefix=$TCLTD/tcl86` +
        6. `make install` +
        7. `fossil up core-9-0-0` ← or some other version of Tcl9 +
        8. `fossil clean -x` +
        9. `./configure --prefix=$TCLTD/tcl90` +
        10. `make install` +
        + +### 1.3 Building the SQLite TCL extension + +
          +
        1. `cd $SRCCO` +
        2. `fossil clean -x` +
        3. `./configure --with-tclsh=$TCLTD/tcl86/bin/tclsh8.6` +
        4. `make tclextension-install` +
        5. → Verify extension installed at $TCLTD/tcl86/lib/tcl8.6/sqlite3.* +
        6. `fossil clean -x` +
        7. `./configure --with-tclsh=$TCLTD/tcl90/bin/tclsh9.0` +
        8. `make tclextension-install` +
        9. → Verify extension installed at $TCLTD/tcl90/lib/sqlite3.* +
        + +### 1.4 Testing the extension + +
          +
        1. + `$TCLTD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain` +
        2. ↑ Verify thousands of lines of output with no errors +
        3. `$TCLTD/tcl90/bin/tclsh9.0 test/testrunner.tcl release --explain` +
        4. ↑ Verify thousands of lines of output with no errors +
        + +### 1.5 Cleanup + +
          +
        1. `rm -rf $TCLTD` +
        + +## 2.0 Testing On Windows + +### 2.1 Setup for Windows + +
          +
        1. + [Fossil](https://fossil-scm.org/) installed. +
        2. + A Fossil check-out of the TCL source tree. Let the directory + of this check-out be called **%TCLCO%** (mnemonic: "TCL Check-Out"). +
        3. + A Fossil check-out of the SQLite source tree. Let the directory + of this check-out be called **%SRCCO%** (mnemonic: "SouRCe Check-Out"). +
        4. + Let **%TCLTD%** (mnemonic: "TCL Test Directory") be the name of a directory + that does not exist at the start of the test, and which will be + deleted at the end of the test, that will contain the test builds + of the TCL libraries and the SQLite TCL Extensions. +
        5. + Unix-like command-line tools installed. Example: + [unxutils](https://unxutils.sourceforge.net/) +
        6. [Visual Studio](https://visualstudio.microsoft.com/vs/community/) + installed. VS2015 or later required. +
        7. `set ORIGINALPATH=%PATH%` ← remember the original %PATH% value +
        + +### 2.2 Building the TCL libraries and tclsh.exe executables on Windows + +
          +
        1. `mkdir %TCLTD% %TCLTD%\tcl86 %TCLTD%\tcl90` +
        2. `cd %TCLCO%\win` +
        3. `fossil up core-8-6-16` ← or some other version of Tcl8.6. +
        4. `fossil clean -x` +
        5. `nmake /f makefile.vc INSTALLDIR=%TCLTD%\tcl86 release install` +
        6. `fossil up core-9-0-0` ← or some other version of Tcl9 +
        7. `fossil clean -x` +
        8. `nmake /f makefile.vc INSTALLDIR=%TCLTD%\tcl86 release install` +
        + +### 2.3 Building the SQLite TCL extension on Windows + +
          +
        1. `cd %SRCCO%` +
        2. `fossil clean -x` +
        3. `set TCLDIR=%TCLTD%\tcl86` +
        4. `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%` +
        5. `set TCLSH_CMD=%TCLTD%\tcl86\bin\tclsh86t.exe` +
        6. `nmake /f Makefile.msc tclextension-install` +
        7. → Verify extension installed at %TCLTD%\tcl86\lib\tcl8.6\sqlite3.* +
        8. `fossil clean -x` +
        9. `set TCLDIR=%TCLTD%\tcl90` +
        10. `set PATH=%TCLTD%\tcl90\bin;%ORIGINALPATH%` +
        11. `set TCLSH_CMD=%TCLTD%\tcl90\bin\tclsh90.exe` +
        12. `nmake /f Makefile.msc tclextension-install` +
        13. → Verify extension installed at %TCLTD%\tcl906\lib\sqlite3.* +
        + +### 2.4 Testing on Windows + +
          +
        1. + `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%` +
        2. `tclsh86t test/testrunner.tcl release --explain` +
        3. ↑ Verify thousands of lines of output with no errors +
        4. `set PATH=%TCLTD%\tcl90\bin;%ORIGINALPATH%` +
        5. `tclsh90 test/testrunner.tcl release --explain` +
        6. ↑ Verify thousands of lines of output with no errors +
        + +### 2.5 Cleanup + +
          +
        1. `rm -rf %TCLTD%` +
        diff --git a/manifest b/manifest index dbe9f57581..ceadd6eb7b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scomment\sto\sthe\scolumnIsGoodIndexCandidate()\sroutine\sto\srecord\sthe\sresults\nof\sa\sfailed\sexperiment.\s\sNo\schanges\sto\scode. -D 2025-01-03T11:51:50.103 +C Add\snew\stcl-extension-testing.md\sdocument.\s\sThe\sWindows\sside\sis\snot\syet\nworking. +D 2025-01-04T14:10:45.730 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -61,6 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 +F doc/tcl-extension-testing.md e7ce7dbd7394c411d5d3c1d29b86455e81203d750af1765304d603fd12973a27 F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2204,8 +2205,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1291b013a8c93e7001fe25783bc98d12f5f7c341d1f728e6852632e18a38af58 -R 0507e66ed59bfa5a55bc14583a9d765f +P 9ee57a30a49d9813bf2669a5d8346f7e018e3fbf1792739951311a8d3a249d45 +R 33caf2e9f23e286037be195e768a7a16 +T *branch * test-procedures +T *sym-test-procedures * +T -sym-trunk * U drh -Z 3304d535a779543ccf066c65753e6b08 +Z a6ccc4c86b9da5c35c8534fa7413feee # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d506d57c15..ce9315f27f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ee57a30a49d9813bf2669a5d8346f7e018e3fbf1792739951311a8d3a249d45 +9dc805df1b1c26196ca53baa6b1b8c2f7e59e0150d02ead53228c77a63ad40f4 From 8272128211e195e46eb3470156d50cf6f1e7dca8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 4 Jan 2025 15:51:30 +0000 Subject: [PATCH 485/522] Adjust the Windows Makefile.msc so that it can build the tclextension with Tcl8.6 successfully. Updates to the tcl-extension test procedure document. FossilOrigin-Name: 0c2cdc632f26d6acac2d508def4ecfcc97462ebcddc20c84f8847e02e42b3a1d --- Makefile.msc | 8 +++-- doc/tcl-extension-testing.md | 69 ++++++++++++++++++++++-------------- manifest | 17 ++++----- manifest.uuid | 2 +- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 942f759eed..7ebfcc8a32 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -984,10 +984,14 @@ TCLLIBS = !ENDIF !IFNDEF LIBTCLSTUB -!IF EXISTS("$(TCLLIBDIR)\tclstub$(TCLSUFFIX).lib") +!IF EXISTS("$(TCLLIBDIR)\tclstub$(TCLVERSION)$(TCLSUFFIX).lib") +LIBTCLSTUB = tclstub$(TCLVERSION)$(TCLSUFFIX).lib +!ELSEIF EXISTS("$(TCLLIBDIR)\tclstub$(TCLSUFFIX).lib") LIBTCLSTUB = tclstub$(TCLSUFFIX).lib +!ELSEIF EXISTS("$(TCLLIBDIR)\tclstub$(TCLVERSION).lib") +LIBTCLSTUB = tclstub$(TCLVERSION).lib !ELSE -LIBTCLSTUB = tclstub$(TCLVERSION)$(TCLSUFFIX).lib +LIBTCLSTUB = tclstub.lib !ENDIF !ENDIF diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index 7dab3eafbd..0b81b922c9 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -26,11 +26,13 @@
        1. `mkdir $TCLTD $TCLTD/tcl86 $TCLTD/tcl90`
        2. `cd $TCLCO/unix` -
        3. `fossil up core-8-6-16` ← or some other version of Tcl8.6. +
        4. `fossil up core-8-6-16`
          + ↑ Or some other version of Tcl8.6.
        5. `fossil clean -x`
        6. `./configure --prefix=$TCLTD/tcl86`
        7. `make install` -
        8. `fossil up core-9-0-0` ← or some other version of Tcl9 +
        9. `fossil up core-9-0-0`
          + ↑ Or some other version of Tcl9
        10. `fossil clean -x`
        11. `./configure --prefix=$TCLTD/tcl90`
        12. `make install` @@ -42,28 +44,28 @@
        13. `cd $SRCCO`
        14. `fossil clean -x`
        15. `./configure --with-tclsh=$TCLTD/tcl86/bin/tclsh8.6` -
        16. `make tclextension-install` -
        17. → Verify extension installed at $TCLTD/tcl86/lib/tcl8.6/sqlite3.* +
        18. `make tclextension-install`
          + ↑ Verify extension installed at $TCLTD/tcl86/lib/tcl8.6/sqlite3.*
        19. `fossil clean -x`
        20. `./configure --with-tclsh=$TCLTD/tcl90/bin/tclsh9.0` -
        21. `make tclextension-install` -
        22. → Verify extension installed at $TCLTD/tcl90/lib/sqlite3.* +
        23. `make tclextension-install`
          + ↑ Verify extension installed at $TCLTD/tcl90/lib/sqlite3.*
        ### 1.4 Testing the extension
          -
        1. - `$TCLTD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain` -
        2. ↑ Verify thousands of lines of output with no errors -
        3. `$TCLTD/tcl90/bin/tclsh9.0 test/testrunner.tcl release --explain` -
        4. ↑ Verify thousands of lines of output with no errors +
        5. + `$TCLTD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain`
          + ↑ Verify thousands of lines of output with no errors +
        6. `$TCLTD/tcl90/bin/tclsh9.0 test/testrunner.tcl release --explain`
          + ↑ Verify thousands of lines of output with no errors
        ### 1.5 Cleanup
          -
        1. `rm -rf $TCLTD` +
        2. `rm -rf $TCLTD`
        ## 2.0 Testing On Windows @@ -89,7 +91,8 @@ [unxutils](https://unxutils.sourceforge.net/)
      • [Visual Studio](https://visualstudio.microsoft.com/vs/community/) installed. VS2015 or later required. -
      • `set ORIGINALPATH=%PATH%` ← remember the original %PATH% value +
      • `set ORIGINALPATH=%PATH%`
        + ↑ remember the original %PATH% value ### 2.2 Building the TCL libraries and tclsh.exe executables on Windows @@ -97,42 +100,54 @@
        1. `mkdir %TCLTD% %TCLTD%\tcl86 %TCLTD%\tcl90`
        2. `cd %TCLCO%\win` -
        3. `fossil up core-8-6-16` ← or some other version of Tcl8.6. +
        4. `fossil up core-8-6-16`
          + ↑ Or some other version of Tcl8.6.
        5. `fossil clean -x` -
        6. `nmake /f makefile.vc INSTALLDIR=%TCLTD%\tcl86 release install` -
        7. `fossil up core-9-0-0` ← or some other version of Tcl9 +
        8. `set INSTALLDIR=%TCLTD%\tcl86` +
        9. `nmake /f makefile.vc release`
          + ⇅ You *must* invoke the "release" and "install" targets + using separate invocations of "nmake" or tclsh86t.exe won't be + installed. +
        10. `nmake /f makefile.vc install` +
        11. `fossil up core-9-0-0`
          + ↑ Or some other version of Tcl9
        12. `fossil clean -x` -
        13. `nmake /f makefile.vc INSTALLDIR=%TCLTD%\tcl86 release install` +
        14. `set INSTALLDIR=%TCLTD%\tcl90` +
        15. `nmake /f makefile.vc release`
          + ⇅ You *must* invoke the "release" and "install" targets + using separate invocations of "nmake" or tclsh90.exe won't be + installed. +
        16. `nmake /f makefile.vc install`
        ### 2.3 Building the SQLite TCL extension on Windows
          -
        1. `cd %SRCCO%` +
        2. `cd %SRCCO%`
        3. `fossil clean -x`
        4. `set TCLDIR=%TCLTD%\tcl86`
        5. `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%`
        6. `set TCLSH_CMD=%TCLTD%\tcl86\bin\tclsh86t.exe` -
        7. `nmake /f Makefile.msc tclextension-install` -
        8. → Verify extension installed at %TCLTD%\tcl86\lib\tcl8.6\sqlite3.* +
        9. `nmake /f Makefile.msc tclextension-install`
          + ↑ Verify extension installed at %TCLTD%\\tcl86\\lib\\tcl8.6\\sqlite3.*
        10. `fossil clean -x`
        11. `set TCLDIR=%TCLTD%\tcl90`
        12. `set PATH=%TCLTD%\tcl90\bin;%ORIGINALPATH%`
        13. `set TCLSH_CMD=%TCLTD%\tcl90\bin\tclsh90.exe` -
        14. `nmake /f Makefile.msc tclextension-install` -
        15. → Verify extension installed at %TCLTD%\tcl906\lib\sqlite3.* +
        16. `nmake /f Makefile.msc tclextension-install`
          + ↑ Verify extension installed at %TCLTD%\\tcl90\\lib\\sqlite3.*
        ### 2.4 Testing on Windows
          -
        1. +
        2. `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%` -
        3. `tclsh86t test/testrunner.tcl release --explain` -
        4. ↑ Verify thousands of lines of output with no errors +
        5. `tclsh86t test/testrunner.tcl release --explain`
          + ↑ Verify thousands of lines of output with no errors
        6. `set PATH=%TCLTD%\tcl90\bin;%ORIGINALPATH%` -
        7. `tclsh90 test/testrunner.tcl release --explain` -
        8. ↑ Verify thousands of lines of output with no errors +
        9. `tclsh90 test/testrunner.tcl release --explain`
          + ↑ Verify thousands of lines of output with no errors
        ### 2.5 Cleanup diff --git a/manifest b/manifest index ceadd6eb7b..81708d8dda 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Add\snew\stcl-extension-testing.md\sdocument.\s\sThe\sWindows\sside\sis\snot\syet\nworking. -D 2025-01-04T14:10:45.730 +C Adjust\sthe\sWindows\sMakefile.msc\sso\sthat\sit\scan\sbuild\sthe\stclextension\swith\nTcl8.6\ssuccessfully.\s\sUpdates\sto\sthe\stcl-extension\stest\sprocedure\sdocument. +D 2025-01-04T15:51:30.848 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in ad349acf91b3569033439fe498fa197aa530cafaa01362eb7daad2f84e43d265 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc eed0c40c365d100f3329e8fb7d0e18bad09a6f0c026aa1e4dc7f88270378929d +F Makefile.msc a62f84e521a23168c61018420c6844a9fbb424950010dc6a3e084ffd8618312e F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md e7ce7dbd7394c411d5d3c1d29b86455e81203d750af1765304d603fd12973a27 +F doc/tcl-extension-testing.md 1c7225115cede8dadd8fb173d5a1ada31d0ac566d53dcbec2013bbf97464933d F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,11 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9ee57a30a49d9813bf2669a5d8346f7e018e3fbf1792739951311a8d3a249d45 -R 33caf2e9f23e286037be195e768a7a16 -T *branch * test-procedures -T *sym-test-procedures * -T -sym-trunk * +P 9dc805df1b1c26196ca53baa6b1b8c2f7e59e0150d02ead53228c77a63ad40f4 +R c39856b8b1c55486d94efa9f4d6e65f7 U drh -Z a6ccc4c86b9da5c35c8534fa7413feee +Z 7ec4aefc8fdf87ac85e59e4d4ae3a188 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ce9315f27f..aaa74e46f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9dc805df1b1c26196ca53baa6b1b8c2f7e59e0150d02ead53228c77a63ad40f4 +0c2cdc632f26d6acac2d508def4ecfcc97462ebcddc20c84f8847e02e42b3a1d From 7a3d03b1fd8241899ab6fadce5a8e9d605f73537 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 4 Jan 2025 16:30:05 +0000 Subject: [PATCH 486/522] Fix a problem in the sessions extension allowing changesets containing foreign key violations to be committed under some circumstances. FossilOrigin-Name: e09a0c022903d88d5d6de34b2527565ef60c6bb049f2fb42f037e1520abf0f93 --- ext/session/session1.test | 6 +++-- ext/session/session9.test | 20 ++++++++++------ ext/session/sessionnoact.test | 44 ++++++++++++++++++++++++++++++++++- ext/session/sqlite3session.c | 4 ++-- manifest | 23 +++++++++--------- manifest.uuid | 2 +- test/fkey6.test | 27 +++++++++++++++++++++ 7 files changed, 101 insertions(+), 25 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index bcd7b03d5c..dfc1aa8957 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -204,7 +204,9 @@ proc do_conflict_test {tn args} { foreach t $O(-tables) { S attach $t } execsql $O(-sql) set ::xConflict [list] - sqlite3changeset_apply db2 [S changeset] xConflict + catch { + sqlite3changeset_apply db2 [S changeset] xConflict + } set conflicts [list] foreach c $O(-conflicts) { @@ -283,7 +285,7 @@ do_conflict_test $tn.3.2.3 -tables t2 -sql { {FOREIGN_KEY 1} } do_execsql_test $tn.3.2.4 "SELECT * FROM t2" {} -do_db2_test $tn.3.2.5 "SELECT * FROM t2" {4 five} +do_db2_test $tn.3.2.5 "SELECT * FROM t2" {1 one 2 two 4 five} # Test UPDATE changesets. # diff --git a/ext/session/session9.test b/ext/session/session9.test index ebb88ffade..6b7d1648b2 100644 --- a/ext/session/session9.test +++ b/ext/session/session9.test @@ -80,8 +80,10 @@ foreach {tn delrow trans conflictargs conflictret} { 8 3 1 {FOREIGN_KEY 1} ABORT } { - set A(OMIT) {0 {}} - set A(ABORT) {1 SQLITE_CONSTRAINT} + set A(OMIT,0) {1 SQLITE_CONSTRAINT} + set A(OMIT,1) {0 {}} + set A(ABORT,0) {1 SQLITE_CONSTRAINT} + set A(ABORT,1) {1 SQLITE_CONSTRAINT} do_test 1.2.$tn.1 { populate_db execsql { DELETE FROM p1 WHERE a=($delrow+0) } @@ -89,20 +91,24 @@ foreach {tn delrow trans conflictargs conflictret} { set ::xConflict [list] list [catch {sqlite3changeset_apply db $::cc xConflict} msg] $msg - } $A($conflictret) + } $A($conflictret,$trans) do_test 1.2.$tn.2 { set ::xConflict } $conflictargs - set A(OMIT) {1 1} - set A(ABORT) {0 0} + set A(OMIT,0) {0 0} + set A(OMIT,1) {1 1} + set A(ABORT,0) {0 0} + set A(ABORT,1) {0 0} + do_test 1.2.$tn.3 { execsql { SELECT count(*) FROM c1 UNION ALL SELECT count(*) FROM c2 } - } $A($conflictret) + } $A($conflictret,$trans) do_test 1.2.$tn.4 { expr ![sqlite3_get_autocommit db] } $trans do_test 1.2.$tn.5 { - if { $trans } { execsql COMMIT } + if { $trans && $conflictret=="ABORT" } { execsql COMMIT } } {} + catchsql ROLLBACK } #-------------------------------------------------------------------- diff --git a/ext/session/sessionnoact.test b/ext/session/sessionnoact.test index aa1cde4749..f605e6108e 100644 --- a/ext/session/sessionnoact.test +++ b/ext/session/sessionnoact.test @@ -82,7 +82,6 @@ do_execsql_test 1.5 { UPDATE p1 SET c=12345 WHERE a = 45; } -breakpoint sqlite3changeset_apply_v2 -noaction db $C conflict do_execsql_test 1.6 { SELECT * FROM c1 @@ -108,4 +107,47 @@ do_execsql_test 1.8 { PRAGMA foreign_key_check } +#------------------------------------------------------------------------- +# Check that a changeset that causes an FK violation may not be applied, +# even if SQLITE_CHANGESETAPPLY_FKNOACTION is specified. +# +reset_db +do_execsql_test 2.0 { + CREATE TABLE p1(a INTEGER PRIMARY KEY, b, c UNIQUE); + INSERT INTO p1 VALUES(1, 1, 'one'); + INSERT INTO p1 VALUES(2, 2, 'two'); + + CREATE TABLE c1(x REFERENCES p1(c) ON DELETE CASCADE); + INSERT INTO c1 VALUES('two'); +} + +db_save + +set C [changeset_from_sql { + DELETE FROM p1 WHERE a=2; +}] + +db_restore_and_reopen + +do_test 2.1 { + sqlite3changeset_apply_v2 -noaction db $C conflict +} {} +do_execsql_test 2.2 { + SELECT * FROM p1 +} {1 1 one} + +db_restore_and_reopen +db eval { PRAGMA foreign_keys = 1 } + +do_test 2.3 { + list [catch { sqlite3changeset_apply_v2 -noaction db $C conflict } msg] $msg +} {1 SQLITE_CONSTRAINT} +do_execsql_test 2.4 { + SELECT * FROM p1; +} {1 1 one 2 2 two} +do_execsql_test 2.5 { + SELECT * FROM c1; +} {two} + finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index f2eb942e68..a3f132add8 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -5283,12 +5283,12 @@ static int sessionChangesetApply( } } } - sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); - }else{ + } + if( rc!=SQLITE_OK ){ sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); } diff --git a/manifest b/manifest index 3cdc3c3865..1063bced5f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sdocument\sdescribing\stest\sprocedures\sfor\sthe\sTCL\sextension\sbuild\nprocess.\s\sUpdate\sthe\sWindows\smakefile\sso\sthat\sit\sbuilds\sthe\sTCL\sextensions\nsuccessfully\swith\sa\sdefault\sinstallation\sof\sTcl8.6. -D 2025-01-04T15:52:40.069 +C Fix\sa\sproblem\sin\sthe\ssessions\sextension\sallowing\schangesets\scontaining\sforeign\skey\sviolations\sto\sbe\scommitted\sunder\ssome\scircumstances. +D 2025-01-04T16:30:05.359 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -576,14 +576,14 @@ F ext/rtree/visual01.txt e9c2564083bcd30ec51b07f881bffbf0e12b50a3f6fced0c222c5c1 F ext/session/changeset.c 7a1e6a14c7e92d36ca177e92e88b5281acd709f3b726298dc34ec0fb58869cb5 F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8fac9cd8b0b24aa F ext/session/changesetfuzz1.test 15b629004e58d5ffcc852e6842a603775bb64b1ce51254831f3d12b113b616cd -F ext/session/session1.test e94f764fbfb672147c0ef7026b195988133b371dc8cf9e52423eba6cad69717e +F ext/session/session1.test 8d0509cd3fcfdee6a33422d5fe5c95a9770d62a0b8588adb0177ecdf79b2c345 F ext/session/session2.test ee83bb973b9ce17ccce4db931cdcdae65eb40bbb22089b2fe6aa4f6be3b9303f F ext/session/session3.test 2cc1629cfb880243aec1a7251145e07b78411d851b39b2aa1390704550db8e6a F ext/session/session4.test 823f6f018fcbb8dacf61e2960f8b3b848d492b094f8b495eae1d9407d9ab7219 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 35279f2ec45448cd2e24a61688219dc6cf7871757716063acf4a8b5455e1e926 F ext/session/session8.test 326f3273abf9d5d2d7d559eee8f5994c4ea74a5d935562454605e6607ee29904 -F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 +F ext/session/session9.test be090b1420f3824a573da9e56ff542b1e1c2a4f772118e9ab2f75774e66d25d0 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test c4fb7f8a688787111606e123a555f18ee04f65bb9f2a4bb2aa71d55ce4e6d02c F ext/session/sessionC.test f8a5508bc059ae646e5ec9bdbca66ad24bc92fe99fda5790ac57e1f59fce2fdf @@ -606,7 +606,7 @@ F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576d F ext/session/sessionfault3.test ce0b5d182133935c224d72507dbf1c5be1a1febf7e85d0b0fbd6d2f724b32b96 F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 -F ext/session/sessionnoact.test 2563dff62a2a80dc7c88002241b2fd1578c3e5438735e180fb7e941ebbc66214 +F ext/session/sessionnoact.test 1ea34324b7be2fa9d63870d44969e6bb5290a6d1603ddfd4151c51df73fad291 F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7 F ext/session/sessionnoop2.test de4672dce88464396ec9f30ed08c6c01643a69c53ae540fadbbf6d30642d64e8 F ext/session/sessionrebase.test 702378bdcb5062f1106e74457beca8797d09c113a81768734a58b197b5b334e2 @@ -614,7 +614,7 @@ F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795 F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc -F ext/session/sqlite3session.c 3d0a7f0f7a1c946e01818c716a55a40ae30542a29a9045cb05daf7fb658cdafa +F ext/session/sqlite3session.c d6f5e3e83b9b0bbc4a8db4837284f0ecc6af5321d4c8e7136380b456b278c46a F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b F ext/session/test_session.c aa29abdcc9011ac02f4fa38e8ede226106eaeee7c3ea7d8b2b999a124e0c368c F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c @@ -1153,7 +1153,7 @@ F test/fkey2.test 1063d65e5923c054cfb8f0555a92a3ae0fa8c067275a33ee1715bd856cdb30 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 6727452e163a427147e84e739da18713da553d79f9783559b04fdcd36d5c7421 -F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0 +F test/fkey6.test bdb9c808349a149575b87cf4bfd82d4c81612f0c4d954d27b3f42f043a385396 F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d031 F test/fkey8.test 51deda7f1a1448bca95875e4a6e1a3a75b4bd7215e924e845bd60de60e4d84bf F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 @@ -2205,9 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9ee57a30a49d9813bf2669a5d8346f7e018e3fbf1792739951311a8d3a249d45 0c2cdc632f26d6acac2d508def4ecfcc97462ebcddc20c84f8847e02e42b3a1d -R c39856b8b1c55486d94efa9f4d6e65f7 -T +closed 0c2cdc632f26d6acac2d508def4ecfcc97462ebcddc20c84f8847e02e42b3a1d -U drh -Z 0b107a7817bd289dd55ee148db24c6d9 +P 3263db9249444203b7a9a9f2b0be309c74944315dde7ed192366b709fff93f1b +R dd67c57d38ae3918a7498e739dc242d4 +U dan +Z 0beeea9f83c0978752782d269e0f987a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f286bc29e1..613d99cd96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3263db9249444203b7a9a9f2b0be309c74944315dde7ed192366b709fff93f1b +e09a0c022903d88d5d6de34b2527565ef60c6bb049f2fb42f037e1520abf0f93 diff --git a/test/fkey6.test b/test/fkey6.test index b658f20fea..8658759523 100644 --- a/test/fkey6.test +++ b/test/fkey6.test @@ -225,5 +225,32 @@ do_execsql_test 3.3.4 { SELECT * FROM p2; } {0 one 1 deleted!} +#------------------------------------------------------------------------- +# Verify that, even with "PRAGMA defer_foreign_keys", a transaction cannot +# be committed if there are outstanding foreign key violations. +# +reset_db +do_execsql_test 4.0 { + CREATE TABLE p1(a INTEGER PRIMARY KEY, b UNIQUE); + CREATE TABLE c1(x REFERENCES p1(b)); + + INSERT INTO p1 VALUES(1, 'one'), (2, 'two'), (3, 'three'); + INSERT INTO c1 VALUES('two'); + + PRAGMA foreign_keys = 1; + PRAGMA defer_foreign_keys = 1; +} + +do_execsql_test 4.1 { + BEGIN; + DELETE FROM p1 WHERE a=2; +} + +do_catchsql_test 4.2 { + COMMIT; +} {1 {FOREIGN KEY constraint failed}} + + + finish_test From 1388a716908e2ca8beffe7a7abc8e3321800d7ea Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 4 Jan 2025 19:50:44 +0000 Subject: [PATCH 487/522] Allow the 2nd argument to ".param set" to use previously bound parameters, as suggested by [forum:/forumpost/823e1bd746|forum post 823e1bd746]. FossilOrigin-Name: 13a35ad792dc0afe1f7b60230aef392ae01e702972b963d732e332f21848f38b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1063bced5f..cc01879f7d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\ssessions\sextension\sallowing\schangesets\scontaining\sforeign\skey\sviolations\sto\sbe\scommitted\sunder\ssome\scircumstances. -D 2025-01-04T16:30:05.359 +C Allow\sthe\s2nd\sargument\sto\s".param\sset"\sto\suse\spreviously\sbound\sparameters,\nas\ssuggested\sby\s[forum:/forumpost/823e1bd746|forum\spost\s823e1bd746]. +D 2025-01-04T19:50:44.608 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -779,7 +779,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 83e88fbb36f89b6703b348777491619554f0fd6f917c9fdf51e4c2e9cda6c04e -F src/shell.c.in ee54de10e9bd5572f689a6bc0c8e6fa58a8870e1670978ded44412d2715fd908 +F src/shell.c.in a9c0f8066eac40f1f97b8554bb0462b07263d5c02380cc1ef74734c5d1c67637 F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3263db9249444203b7a9a9f2b0be309c74944315dde7ed192366b709fff93f1b -R dd67c57d38ae3918a7498e739dc242d4 -U dan -Z 0beeea9f83c0978752782d269e0f987a +P e09a0c022903d88d5d6de34b2527565ef60c6bb049f2fb42f037e1520abf0f93 +R 364f6f3884762438edb0a3db4be13b55 +U drh +Z 24b57e7db6ae465e4c0bb8fa905414ba # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 613d99cd96..c7e903bba5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e09a0c022903d88d5d6de34b2527565ef60c6bb049f2fb42f037e1520abf0f93 +13a35ad792dc0afe1f7b60230aef392ae01e702972b963d732e332f21848f38b diff --git a/src/shell.c.in b/src/shell.c.in index cad8c92c57..27028ccb0f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -10237,6 +10237,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; } } + bind_prepared_stmt(p, pStmt); sqlite3_step(pStmt); sqlite3_finalize(pStmt); }else From 1c1b3a0f2db572bff16f66fcb07fd990b0425552 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 4 Jan 2025 20:13:54 +0000 Subject: [PATCH 488/522] Show the values of $(JIM_TCLSH) and $(VISUALSTUDIOVERSION) in the output of "nmake tcl-env". FossilOrigin-Name: 4270abc071ced9e7ec1fed3c387262cc1912e321e37e45e547a1088dbb022702 --- Makefile.msc | 2 ++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 7ebfcc8a32..a1c6ea8e18 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2796,6 +2796,8 @@ tcl-env: @echo LIBTCL = $(LIBTCL) @echo LIBTCLSTUB = $(LIBTCLSTUB) @echo TCLSH_CMD = $(TCLSH_CMD) + @echo JIM_TCLSH = $(JIM_TCLSH) + @echo VISUALSTUDIOVERSION = $(VISUALSTUDIOVERSION) LSMDIR=$(TOP)\ext\lsm1 !INCLUDE $(LSMDIR)\Makefile.msc diff --git a/manifest b/manifest index cc01879f7d..01871cbabd 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Allow\sthe\s2nd\sargument\sto\s".param\sset"\sto\suse\spreviously\sbound\sparameters,\nas\ssuggested\sby\s[forum:/forumpost/823e1bd746|forum\spost\s823e1bd746]. -D 2025-01-04T19:50:44.608 +C Show\sthe\svalues\sof\s$(JIM_TCLSH)\sand\s$(VISUALSTUDIOVERSION)\sin\sthe\s\noutput\sof\s"nmake\stcl-env". +D 2025-01-04T20:13:54.343 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in ad349acf91b3569033439fe498fa197aa530cafaa01362eb7daad2f84e43d265 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc a62f84e521a23168c61018420c6844a9fbb424950010dc6a3e084ffd8618312e +F Makefile.msc fd49fbfca5077436a4e7e9f38ec0f1ed900c3e5dc627a8ee00ff15d18649c00c F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e09a0c022903d88d5d6de34b2527565ef60c6bb049f2fb42f037e1520abf0f93 -R 364f6f3884762438edb0a3db4be13b55 +P 13a35ad792dc0afe1f7b60230aef392ae01e702972b963d732e332f21848f38b +R b249c902701d086f7fc1e9c45b94a036 U drh -Z 24b57e7db6ae465e4c0bb8fa905414ba +Z aade41f2b6bccecf69fadf6f2f547775 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c7e903bba5..3e076d8a56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -13a35ad792dc0afe1f7b60230aef392ae01e702972b963d732e332f21848f38b +4270abc071ced9e7ec1fed3c387262cc1912e321e37e45e547a1088dbb022702 From 1e03bd8a89e57c465a1975c0a17408448cc56985 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 4 Jan 2025 20:50:21 +0000 Subject: [PATCH 489/522] Improvements to testing and validation of the SQLite TCL extension. FossilOrigin-Name: 9d7597cad4a167aef7688e85513d8695e8d919e41f5cd44909aefee5ddf13345 --- Makefile.msc | 3 +++ doc/tcl-extension-testing.md | 16 ++++++++++------ main.mk | 7 +++++++ manifest | 18 +++++++++--------- manifest.uuid | 2 +- tool/buildtclext.tcl | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 16 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index a1c6ea8e18..5d3d4c01d0 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1894,6 +1894,9 @@ tclextension-uninstall: tclextension-list: $(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --info +tclextension-verify: sqlite3.h + $(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --version-check + # <> diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index 0b81b922c9..10c57b7c36 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -46,16 +46,18 @@
      • `./configure --with-tclsh=$TCLTD/tcl86/bin/tclsh8.6`
      • `make tclextension-install`
        ↑ Verify extension installed at $TCLTD/tcl86/lib/tcl8.6/sqlite3.* +
      • `make tclextension-verify`
      • `fossil clean -x`
      • `./configure --with-tclsh=$TCLTD/tcl90/bin/tclsh9.0`
      • `make tclextension-install`
        ↑ Verify extension installed at $TCLTD/tcl90/lib/sqlite3.* +
      • `make tclextension-verify` -### 1.4 Testing the extension +### 1.4 Additional sanity tests
          -
        1. +
        2. `$TCLTD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain`
          ↑ Verify thousands of lines of output with no errors
        3. `$TCLTD/tcl90/bin/tclsh9.0 test/testrunner.tcl release --explain`
          @@ -65,7 +67,7 @@ ### 1.5 Cleanup
            -
          1. `rm -rf $TCLTD` +
          2. `rm -rf $TCLTD`
          ## 2.0 Testing On Windows @@ -130,18 +132,20 @@
        4. `set TCLSH_CMD=%TCLTD%\tcl86\bin\tclsh86t.exe`
        5. `nmake /f Makefile.msc tclextension-install`
          ↑ Verify extension installed at %TCLTD%\\tcl86\\lib\\tcl8.6\\sqlite3.* +
        6. `nmake /f Makefile.msc tclextension-verify`
        7. `fossil clean -x`
        8. `set TCLDIR=%TCLTD%\tcl90`
        9. `set PATH=%TCLTD%\tcl90\bin;%ORIGINALPATH%`
        10. `set TCLSH_CMD=%TCLTD%\tcl90\bin\tclsh90.exe`
        11. `nmake /f Makefile.msc tclextension-install`
          ↑ Verify extension installed at %TCLTD%\\tcl90\\lib\\sqlite3.* +
        12. `nmake /f Makefile.msc tclextension-verify`
        -### 2.4 Testing on Windows +### 2.4 Additional sanity tests for Windows
          -
        1. +
        2. `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%`
        3. `tclsh86t test/testrunner.tcl release --explain`
          ↑ Verify thousands of lines of output with no errors @@ -153,5 +157,5 @@ ### 2.5 Cleanup
            -
          1. `rm -rf %TCLTD%` +
          2. `rm -rf %TCLTD%`
          diff --git a/main.mk b/main.mk index 660cf54bd3..28c4245aab 100644 --- a/main.mk +++ b/main.mk @@ -1574,6 +1574,13 @@ tclextension-uninstall: tclextension-list: $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info +# Verify that the SQLite TCL extension that is loaded by default +# in $(TCLSH_CMD) is the same as the version of SQLite for the +# current source tree +# +tclextension-verify: sqlite3.h + $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --version-check + # # FTS5 things # diff --git a/manifest b/manifest index 01871cbabd..28f03fcd38 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Show\sthe\svalues\sof\s$(JIM_TCLSH)\sand\s$(VISUALSTUDIOVERSION)\sin\sthe\s\noutput\sof\s"nmake\stcl-env". -D 2025-01-04T20:13:54.343 +C Improvements\sto\stesting\sand\svalidation\sof\sthe\sSQLite\sTCL\sextension. +D 2025-01-04T20:50:21.155 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in ad349acf91b3569033439fe498fa197aa530cafaa01362eb7daad2f84e43d265 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc fd49fbfca5077436a4e7e9f38ec0f1ed900c3e5dc627a8ee00ff15d18649c00c +F Makefile.msc 9180dae8de9534393c8a7c7d3b660deb6de5d29910471991738eed1b19c1aaa1 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md 1c7225115cede8dadd8fb173d5a1ada31d0ac566d53dcbec2013bbf97464933d +F doc/tcl-extension-testing.md ab39979265fd0e0aa1d31dfb9d468761470d8d84a285d49f11b3ed748224e2f4 F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -700,7 +700,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk fde6ef9167ab1972f6273c0cc06a7d2d776f562d06f44f4987868335910f3803 +F main.mk 566aff71e11c52e10f81548e60f79c48cc267cb4b9971e71720047105da4304b F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2110,7 +2110,7 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e045 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x F tool/build-shell.sh 369c4b171cc877ad974fef691e4da782b4c1e99fe8f4361316c735f64d49280f -F tool/buildtclext.tcl 5e1f1aa843e635c8b7480c7d1ec1f149a5e52136ae2fca1226304053a1a60587 +F tool/buildtclext.tcl e82120d672b34b507e1d9cb220ce18c5c36c3ee0ff0328e35f1806ce74ed2266 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 13a35ad792dc0afe1f7b60230aef392ae01e702972b963d732e332f21848f38b -R b249c902701d086f7fc1e9c45b94a036 +P 4270abc071ced9e7ec1fed3c387262cc1912e321e37e45e547a1088dbb022702 +R e76bc68f8d16f2d1c5c9148746df5950 U drh -Z aade41f2b6bccecf69fadf6f2f547775 +Z 3470080ccfb271429f7dd29c45e9a752 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3e076d8a56..8f0477bff4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4270abc071ced9e7ec1fed3c387262cc1912e321e37e45e547a1088dbb022702 +9d7597cad4a167aef7688e85513d8695e8d919e41f5cd44909aefee5ddf13345 diff --git a/tool/buildtclext.tcl b/tool/buildtclext.tcl index c74540c9ea..26f9b6dcc9 100644 --- a/tool/buildtclext.tcl +++ b/tool/buildtclext.tcl @@ -15,6 +15,7 @@ Options: --info Show info on existing SQLite TCL extension installs --install-only Install an extension previously build --uninstall Uninstall the extension + --version-check Check extension version against this source tree --destdir DIR Installation root (used by "make install DESTDIR=...") Other options are retained and passed through into the compiler.} @@ -24,6 +25,7 @@ set build 1 set install 1 set uninstall 0 set infoonly 0 +set versioncheck 0 set CC {} set OPTS {} set DESTDIR ""; # --destdir "$(DESTDIR)" @@ -36,11 +38,18 @@ for {set ii 0} {$ii<[llength $argv]} {incr ii} { } elseif {$a0=="--uninstall"} { set build 0 set install 0 + set versioncheck 0 set uninstall 1 } elseif {$a0=="--info"} { set build 0 set install 0 + set versioncheck 0 set infoonly 1 + } elseif {$a0=="--version-check"} { + set build 0 + set install 0 + set infoonly 0 + set versioncheck 1 } elseif {$a0=="--cc" && $ii+1<[llength $argv]} { incr ii set CC [lindex $argv $ii] @@ -156,6 +165,33 @@ if {$tcl_platform(platform)=="windows"} { set CMD [subst $cmd] } +# Check the SQLite TCL extension that is loaded by default by this running +# TCL interpreter to see if it has the same SQLITE_SOURCE_ID as the source +# code in the directory holding this script. +# +if {$versioncheck} { + if {[catch {package require sqlite3} msg]} { + puts stderr "No SQLite TCL extension available: $msg" + exit 1 + } + sqlite3 db :memory: + set extvers [db one {SELECT sqlite_source_id()}] + db close + set fd [open sqlite3.h rb] + set sqlite3h [read $fd] + close $fd + regexp {#define SQLITE_SOURCE_ID +"([^"]+)"} $sqlite3h all srcvers + set srcvers [string range $srcvers 0 78] + set extvers [string range $extvers 0 78] + if {$srcvers==$extvers} { + puts "source code and extension versions aligned:\n$extvers" + exit 0 + } + puts stderr "source code and extension versions differ" + puts stderr "source: $srcvers\nextension: $extvers" + exit 1 +} + # Show information about prior installs # if {$infoonly} { From 8b53358f8f2179e920bbe58d2e8f257d50dcfaac Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 5 Jan 2025 11:19:32 +0000 Subject: [PATCH 490/522] Improvements to TCL extension test procedure description. Improvements to the tclextension-list and tclextension-verify makefile targets to suppress unnecessary output. FossilOrigin-Name: 3e92fea09af13259d61afd2953fe5f3fc16e3cedfef09e350903aa5299b8e469 --- Makefile.msc | 4 ++-- doc/tcl-extension-testing.md | 37 ++++++++++++++++++++++++------------ main.mk | 4 ++-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 5d3d4c01d0..33c5ef107e 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1892,10 +1892,10 @@ tclextension-uninstall: $(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --uninstall tclextension-list: - $(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --info + @ $(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --info tclextension-verify: sqlite3.h - $(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --version-check + @ $(TCLSH_CMD) $(TOP)\tool\buildtclext.tcl --version-check # <> diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index 10c57b7c36..4835fe1be9 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -1,9 +1,22 @@ # Test Procedures For The SQLite TCL Extension +## 1.0 Background -## 1.0 Testing On Unix-like Systems (Including Mac) +The SQLite TCL extension logic (in the +"[tclsqlite.c](/file/src/tclsqlite3.c)" source +file) is statically linked into "textfixture" executable +which is the program used to do more of the testing +associated with "make test", "make devtest", and/or +"make releasetest". So the functionality of the SQLite +TCL extension is thoroughly vetted during normal testing. The +procedures below are designed to test the loadable extension +aspect of the SQLite TCL extension, and in particular to verify +that the "make tclextension-install" build target works and that +an ordinary tclsh can subsequently run "package require sqlite3". -### 1.1 Setup +## 2.0 Testing On Unix-like Systems (Including Mac) + +### 2.1 Setup
          1. @@ -21,7 +34,7 @@ of the TCL libraries and the SQLite TCL Extensions.
          -### 1.2 Building the TCL libraries and tclsh executables +### 2.2 Building the TCL libraries and tclsh executables
          1. `mkdir $TCLTD $TCLTD/tcl86 $TCLTD/tcl90` @@ -38,7 +51,7 @@
          2. `make install`
          -### 1.3 Building the SQLite TCL extension +### 2.3 Building the SQLite TCL extension
          1. `cd $SRCCO` @@ -54,7 +67,7 @@
          2. `make tclextension-verify`
          -### 1.4 Additional sanity tests +### 2.4 Additional sanity tests
          1. @@ -64,15 +77,15 @@ ↑ Verify thousands of lines of output with no errors
          -### 1.5 Cleanup +### 2.5 Cleanup
          1. `rm -rf $TCLTD`
          -## 2.0 Testing On Windows +## 3.0 Testing On Windows -### 2.1 Setup for Windows +### 3.1 Setup for Windows
          1. @@ -97,7 +110,7 @@ ↑ remember the original %PATH% value
          -### 2.2 Building the TCL libraries and tclsh.exe executables on Windows +### 3.2 Building the TCL libraries and tclsh.exe executables on Windows
          1. `mkdir %TCLTD% %TCLTD%\tcl86 %TCLTD%\tcl90` @@ -122,7 +135,7 @@
          2. `nmake /f makefile.vc install`
          -### 2.3 Building the SQLite TCL extension on Windows +### 3.3 Building the SQLite TCL extension on Windows
          1. `cd %SRCCO%` @@ -142,7 +155,7 @@
          2. `nmake /f Makefile.msc tclextension-verify`
          -### 2.4 Additional sanity tests for Windows +### 3.4 Additional sanity tests for Windows
          1. @@ -154,7 +167,7 @@ ↑ Verify thousands of lines of output with no errors
          -### 2.5 Cleanup +### 3.5 Cleanup
          1. `rm -rf %TCLTD%` diff --git a/main.mk b/main.mk index 28c4245aab..a22b0dfcdf 100644 --- a/main.mk +++ b/main.mk @@ -1572,14 +1572,14 @@ tclextension-uninstall: # by $TCLSH_CMD, including prior versions. # tclextension-list: - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info + @ $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info # Verify that the SQLite TCL extension that is loaded by default # in $(TCLSH_CMD) is the same as the version of SQLite for the # current source tree # tclextension-verify: sqlite3.h - $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --version-check + @ $(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --version-check # # FTS5 things diff --git a/manifest b/manifest index 28f03fcd38..57402835e3 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Improvements\sto\stesting\sand\svalidation\sof\sthe\sSQLite\sTCL\sextension. -D 2025-01-04T20:50:21.155 +C Improvements\sto\sTCL\sextension\stest\sprocedure\sdescription.\s\sImprovements\sto\nthe\stclextension-list\sand\stclextension-verify\smakefile\stargets\sto\ssuppress\nunnecessary\soutput. +D 2025-01-05T11:19:32.428 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in ad349acf91b3569033439fe498fa197aa530cafaa01362eb7daad2f84e43d265 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc 9180dae8de9534393c8a7c7d3b660deb6de5d29910471991738eed1b19c1aaa1 +F Makefile.msc 39785ec45f9ae0311e49094eff2ee079562246fed6be3b9f632a99d4df20056a F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 F VERSION 8dc0c3df15fd5ff0622f88fc483533fce990b1cbb2f5fb9fdfb4dbd71eef2889 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md ab39979265fd0e0aa1d31dfb9d468761470d8d84a285d49f11b3ed748224e2f4 +F doc/tcl-extension-testing.md 2d9c2b443ff978c679266cc77c505bc750ad41cad95c7ff57bcd261894db7685 F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -700,7 +700,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 566aff71e11c52e10f81548e60f79c48cc267cb4b9971e71720047105da4304b +F main.mk fe86d83158b547e02f8d08aa6af2130540746a4a61de7c61ea8b9d09eb06acd4 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4270abc071ced9e7ec1fed3c387262cc1912e321e37e45e547a1088dbb022702 -R e76bc68f8d16f2d1c5c9148746df5950 +P 9d7597cad4a167aef7688e85513d8695e8d919e41f5cd44909aefee5ddf13345 +R dea89f80d3d0e645bc0886ea1ea08414 U drh -Z 3470080ccfb271429f7dd29c45e9a752 +Z 5cb00fd50654015e2128f97c99b05bfe # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8f0477bff4..cd948c9ac2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d7597cad4a167aef7688e85513d8695e8d919e41f5cd44909aefee5ddf13345 +3e92fea09af13259d61afd2953fe5f3fc16e3cedfef09e350903aa5299b8e469 From 85900c04b01f28ae8b3b352dc58c124d32dbf7d9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 5 Jan 2025 11:40:15 +0000 Subject: [PATCH 491/522] Fix typo in the tcl-extension-testing.md document. FossilOrigin-Name: 28150c615cb601dfc9e4f660627228d6a8a715d64c65f7bc77931c9daf8a0dd7 --- doc/tcl-extension-testing.md | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index 4835fe1be9..3371d514bb 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -3,7 +3,7 @@ ## 1.0 Background The SQLite TCL extension logic (in the -"[tclsqlite.c](/file/src/tclsqlite3.c)" source +"[tclsqlite.c](/file/src/tclsqlite.c)" source file) is statically linked into "textfixture" executable which is the program used to do more of the testing associated with "make test", "make devtest", and/or diff --git a/manifest b/manifest index 57402835e3..ae7e6830ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sTCL\sextension\stest\sprocedure\sdescription.\s\sImprovements\sto\nthe\stclextension-list\sand\stclextension-verify\smakefile\stargets\sto\ssuppress\nunnecessary\soutput. -D 2025-01-05T11:19:32.428 +C Fix\stypo\sin\sthe\stcl-extension-testing.md\sdocument. +D 2025-01-05T11:40:15.277 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md 2d9c2b443ff978c679266cc77c505bc750ad41cad95c7ff57bcd261894db7685 +F doc/tcl-extension-testing.md 97f90ebaac1569c77395f715a4074ddf8b40984d1dae3af7ab693ec256e43853 F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9d7597cad4a167aef7688e85513d8695e8d919e41f5cd44909aefee5ddf13345 -R dea89f80d3d0e645bc0886ea1ea08414 +P 3e92fea09af13259d61afd2953fe5f3fc16e3cedfef09e350903aa5299b8e469 +R 62604835e027bab1689bab4a8c0e956a U drh -Z 5cb00fd50654015e2128f97c99b05bfe +Z adbf7e41d03db62cbc628242472f462e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cd948c9ac2..63309c3c39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e92fea09af13259d61afd2953fe5f3fc16e3cedfef09e350903aa5299b8e469 +28150c615cb601dfc9e4f660627228d6a8a715d64c65f7bc77931c9daf8a0dd7 From 15e388d91057ca381510ace3e094210b33626452 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 5 Jan 2025 17:16:33 +0000 Subject: [PATCH 492/522] Refactor the TCL extension test procedure to deal with TCL8.6 and TCL9.0 separately, to simplify the procedures and reduce cognative stress on the tester. FossilOrigin-Name: 5281536327d244ba9507548f7ed607e86e59b98a003e63f6da767471411c8ffc --- doc/tcl-extension-testing.md | 104 +++++++++++++++++------------------ manifest | 12 ++-- manifest.uuid | 2 +- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index 3371d514bb..65baa15469 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -34,53 +34,56 @@ an ordinary tclsh can subsequently run "package require sqlite3". of the TCL libraries and the SQLite TCL Extensions.
          -### 2.2 Building the TCL libraries and tclsh executables +### 2.2 Testing TCL 8.6 on unix
            -
          1. `mkdir $TCLTD $TCLTD/tcl86 $TCLTD/tcl90` +
          2. `mkdir $TCLTD/tcl86`
          3. `cd $TCLCO/unix`
          4. `fossil up core-8-6-16`
            ↑ Or some other version of Tcl8.6.
          5. `fossil clean -x`
          6. `./configure --prefix=$TCLTD/tcl86`
          7. `make install` +
          8. `cd $SRCCO` +
          9. `fossil clean -x` +
          10. `./configure --with-tclsh=$TCLTD/tcl86/bin/tclsh8.6` +
          11. `make tclextension-install`
            + ↑ Verify extension installed at $TCLTD/tcl86/lib/tcl8.6/sqlite3.* +
          12. `makek tclextension-list`
            + ↑ Verify TCL extension correctly installed. +
          13. `make tclextension-verify`
            + ↑ Verify that the correct version is installed. +
          14. `$TCLTD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain`
            + ↑ Verify thousands of lines of output with no errors. Or + consider running "devtest" without --explain instead of "release". +
          + +### 2.3 Testing TCL 9.0 on unix + +
            +
          1. `mkdir $TCLTD/tcl90`
          2. `fossil up core-9-0-0`
            ↑ Or some other version of Tcl9
          3. `fossil clean -x`
          4. `./configure --prefix=$TCLTD/tcl90`
          5. `make install` -
          - -### 2.3 Building the SQLite TCL extension - -
            -
          1. `cd $SRCCO` -
          2. `fossil clean -x` -
          3. `./configure --with-tclsh=$TCLTD/tcl86/bin/tclsh8.6` -
          4. `make tclextension-install`
            - ↑ Verify extension installed at $TCLTD/tcl86/lib/tcl8.6/sqlite3.* -
          5. `make tclextension-verify` +
          6. `cd $SRCCO`
          7. `fossil clean -x`
          8. `./configure --with-tclsh=$TCLTD/tcl90/bin/tclsh9.0`
          9. `make tclextension-install`
            ↑ Verify extension installed at $TCLTD/tcl90/lib/sqlite3.* +
          10. `makek tclextension-list`
            + ↑ Verify TCL extension correctly installed.
          11. `make tclextension-verify` -
          - -### 2.4 Additional sanity tests - -
            -
          1. - `$TCLTD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain`
            - ↑ Verify thousands of lines of output with no errors
          2. `$TCLTD/tcl90/bin/tclsh9.0 test/testrunner.tcl release --explain`
            - ↑ Verify thousands of lines of output with no errors + ↑ Verify thousands of lines of output with no errors. Or + consider running "devtest" without --explain instead of "release".
          -### 2.5 Cleanup +### 2.4 Cleanup
            -
          1. `rm -rf $TCLTD` +
          2. `rm -rf $TCLTD`
          ## 3.0 Testing On Windows @@ -110,10 +113,10 @@ an ordinary tclsh can subsequently run "package require sqlite3". ↑ remember the original %PATH% value
        -### 3.2 Building the TCL libraries and tclsh.exe executables on Windows +### 3.2 Testing TCL 8.6 on Windows
          -
        1. `mkdir %TCLTD% %TCLTD%\tcl86 %TCLTD%\tcl90` +
        2. `mkdir %TCLTD%\tcl86`
        3. `cd %TCLCO%\win`
        4. `fossil up core-8-6-16`
          ↑ Or some other version of Tcl8.6. @@ -124,6 +127,24 @@ an ordinary tclsh can subsequently run "package require sqlite3". using separate invocations of "nmake" or tclsh86t.exe won't be installed.
        5. `nmake /f makefile.vc install` +
        6. `cd %SRCCO%` +
        7. `fossil clean -x` +
        8. `set TCLDIR=%TCLTD%\tcl86` +
        9. `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%` +
        10. `set TCLSH_CMD=%TCLTD%\tcl86\bin\tclsh86t.exe` +
        11. `nmake /f Makefile.msc tclextension-install`
          + ↑ Verify extension installed at %TCLTD%\\tcl86\\lib\\tcl8.6\\sqlite3.* +
        12. `nmake /f Makefile.msc tclextension-verify` +
        13. `tclsh86t test/testrunner.tcl release --explain`
          + ↑ Verify thousands of lines of output with no errors. Or + consider running "devtest" without --explain instead of "release". +
        + +### 3.3 Testing TCL 9.0 on Windows + +
          +
        1. `mkdir %TCLTD%\tcl90` +
        2. `cd %TCLCO%\win`
        3. `fossil up core-9-0-0`
          ↑ Or some other version of Tcl9
        4. `fossil clean -x` @@ -133,19 +154,7 @@ an ordinary tclsh can subsequently run "package require sqlite3". using separate invocations of "nmake" or tclsh90.exe won't be installed.
        5. `nmake /f makefile.vc install` -
        - -### 3.3 Building the SQLite TCL extension on Windows - -
          -
        1. `cd %SRCCO%` -
        2. `fossil clean -x` -
        3. `set TCLDIR=%TCLTD%\tcl86` -
        4. `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%` -
        5. `set TCLSH_CMD=%TCLTD%\tcl86\bin\tclsh86t.exe` -
        6. `nmake /f Makefile.msc tclextension-install`
          - ↑ Verify extension installed at %TCLTD%\\tcl86\\lib\\tcl8.6\\sqlite3.* -
        7. `nmake /f Makefile.msc tclextension-verify` +
        8. `cd %SRCCO%`
        9. `fossil clean -x`
        10. `set TCLDIR=%TCLTD%\tcl90`
        11. `set PATH=%TCLTD%\tcl90\bin;%ORIGINALPATH%` @@ -153,22 +162,13 @@ an ordinary tclsh can subsequently run "package require sqlite3".
        12. `nmake /f Makefile.msc tclextension-install`
          ↑ Verify extension installed at %TCLTD%\\tcl90\\lib\\sqlite3.*
        13. `nmake /f Makefile.msc tclextension-verify` -
        - -### 3.4 Additional sanity tests for Windows - -
          -
        1. - `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%` -
        2. `tclsh86t test/testrunner.tcl release --explain`
          - ↑ Verify thousands of lines of output with no errors -
        3. `set PATH=%TCLTD%\tcl90\bin;%ORIGINALPATH%`
        4. `tclsh90 test/testrunner.tcl release --explain`
          - ↑ Verify thousands of lines of output with no errors + ↑ Verify thousands of lines of output with no errors. Or + consider running "devtest" without --explain instead of "release".
        -### 3.5 Cleanup +### 3.4 Cleanup
          -
        1. `rm -rf %TCLTD%` +
        2. `rm -rf %TCLTD%`
        diff --git a/manifest b/manifest index ae7e6830ec..06e0e02351 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\stcl-extension-testing.md\sdocument. -D 2025-01-05T11:40:15.277 +C Refactor\sthe\sTCL\sextension\stest\sprocedure\sto\sdeal\swith\sTCL8.6\sand\sTCL9.0\nseparately,\sto\ssimplify\sthe\sprocedures\sand\sreduce\scognative\sstress\son\sthe\ntester. +D 2025-01-05T17:16:33.231 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md 97f90ebaac1569c77395f715a4074ddf8b40984d1dae3af7ab693ec256e43853 +F doc/tcl-extension-testing.md 37722ac070d15ed687fbde2c444b97fd1b423b631a89897142f708594aafba47 F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3e92fea09af13259d61afd2953fe5f3fc16e3cedfef09e350903aa5299b8e469 -R 62604835e027bab1689bab4a8c0e956a +P 28150c615cb601dfc9e4f660627228d6a8a715d64c65f7bc77931c9daf8a0dd7 +R 866ce61f7bd1663ef897c7b2791f707c U drh -Z adbf7e41d03db62cbc628242472f462e +Z c10b13ae5e892d2f5ddbaa1f9222567d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 63309c3c39..f10a9cf7e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28150c615cb601dfc9e4f660627228d6a8a715d64c65f7bc77931c9daf8a0dd7 +5281536327d244ba9507548f7ed607e86e59b98a003e63f6da767471411c8ffc From f19d7b4de163f56f4cbe7298e3b347e0caefa540 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 5 Jan 2025 19:58:30 +0000 Subject: [PATCH 493/522] Further refactoring of the TCL extension test procedure document, for improved clarity and usability. FossilOrigin-Name: bcdaef434142973a0805117495e561b2dcd1ec1465cacc9b944a3707291afc0d --- doc/tcl-extension-testing.md | 121 ++++++++++++++++++----------------- manifest | 12 ++-- manifest.uuid | 2 +- 3 files changed, 68 insertions(+), 67 deletions(-) diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index 65baa15469..ec624ceb5b 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -5,7 +5,7 @@ The SQLite TCL extension logic (in the "[tclsqlite.c](/file/src/tclsqlite.c)" source file) is statically linked into "textfixture" executable -which is the program used to do more of the testing +which is the program used to do most of the testing associated with "make test", "make devtest", and/or "make releasetest". So the functionality of the SQLite TCL extension is thoroughly vetted during normal testing. The @@ -21,39 +21,39 @@ an ordinary tclsh can subsequently run "package require sqlite3".
        1. [Fossil](https://fossil-scm.org/) installed. -
        2. - A Fossil check-out of the TCL source tree. Let the directory - of this check-out be called **$TCLCO** (mnemonic: "TCL Check-Out"). -
        3. - A Fossil check-out of the SQLite source tree. Let the directory - of this check-out be called **$SRCCO** (mnemonic: "SouRCe Check-Out"). -
        4. - Let **$TCLTD** (mnemonic: "TCL Test Directory") be the name of a directory - that does not exist at the start of the test, and which will be - deleted at the end of the test, that will contain the test builds - of the TCL libraries and the SQLite TCL Extensions. +
        5. Check out source code and set environment variables: +
            +
          1. **TCLSOURCE** → + The top-level directory of a Fossil check-out of the TCL source tree. +
          2. **SQLITESOURCE** → + A Fossil check-out of the SQLite source tree. +
          3. **TCLBUILD** → + A directory that does not exist at the start of the test and which + will be deleted at the end of the test, and that will contain the + test builds of the TCL libraries and the SQLite TCL Extensions. +
        ### 2.2 Testing TCL 8.6 on unix
          -
        1. `mkdir $TCLTD/tcl86` -
        2. `cd $TCLCO/unix` +
        3. `mkdir -p $TCLBUILD/tcl86` +
        4. `cd $TCLSOURCE/unix`
        5. `fossil up core-8-6-16`
          ↑ Or some other version of Tcl8.6.
        6. `fossil clean -x` -
        7. `./configure --prefix=$TCLTD/tcl86` +
        8. `./configure --prefix=$TCLBUILD/tcl86`
        9. `make install` -
        10. `cd $SRCCO` +
        11. `cd $SQLITESOURCE`
        12. `fossil clean -x` -
        13. `./configure --with-tclsh=$TCLTD/tcl86/bin/tclsh8.6` +
        14. `./configure --with-tclsh=$TCLBUILD/tcl86/bin/tclsh8.6`
        15. `make tclextension-install`
          - ↑ Verify extension installed at $TCLTD/tcl86/lib/tcl8.6/sqlite3.* -
        16. `makek tclextension-list`
          + ↑ Verify extension installed at $TCLBUILD/tcl86/lib/tcl8.6/sqlite3.* +
        17. `make tclextension-list`
          ↑ Verify TCL extension correctly installed.
        18. `make tclextension-verify`
          ↑ Verify that the correct version is installed. -
        19. `$TCLTD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain`
          +
        20. `$TCLBUILD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain`
          ↑ Verify thousands of lines of output with no errors. Or consider running "devtest" without --explain instead of "release".
        @@ -61,21 +61,21 @@ an ordinary tclsh can subsequently run "package require sqlite3". ### 2.3 Testing TCL 9.0 on unix
          -
        1. `mkdir $TCLTD/tcl90` +
        2. `mkdir -p $TCLBUILD/tcl90`
        3. `fossil up core-9-0-0`
          ↑ Or some other version of Tcl9
        4. `fossil clean -x` -
        5. `./configure --prefix=$TCLTD/tcl90` +
        6. `./configure --prefix=$TCLBUILD/tcl90`
        7. `make install` -
        8. `cd $SRCCO` +
        9. `cd $SQLITESOURCE`
        10. `fossil clean -x` -
        11. `./configure --with-tclsh=$TCLTD/tcl90/bin/tclsh9.0` +
        12. `./configure --with-tclsh=$TCLBUILD/tcl90/bin/tclsh9.0`
        13. `make tclextension-install`
          - ↑ Verify extension installed at $TCLTD/tcl90/lib/sqlite3.* -
        14. `makek tclextension-list`
          + ↑ Verify extension installed at $TCLBUILD/tcl90/lib/sqlite3.* +
        15. `make tclextension-list`
          ↑ Verify TCL extension correctly installed.
        16. `make tclextension-verify` -
        17. `$TCLTD/tcl90/bin/tclsh9.0 test/testrunner.tcl release --explain`
          +
        18. `$TCLBUILD/tcl90/bin/tclsh9.0 test/testrunner.tcl release --explain`
          ↑ Verify thousands of lines of output with no errors. Or consider running "devtest" without --explain instead of "release".
        @@ -83,7 +83,7 @@ an ordinary tclsh can subsequently run "package require sqlite3". ### 2.4 Cleanup
          -
        1. `rm -rf $TCLTD` +
        2. `rm -rf $TCLBUILD`
        ## 3.0 Testing On Windows @@ -93,47 +93,48 @@ an ordinary tclsh can subsequently run "package require sqlite3".
        1. [Fossil](https://fossil-scm.org/) installed. -
        2. - A Fossil check-out of the TCL source tree. Let the directory - of this check-out be called **%TCLCO%** (mnemonic: "TCL Check-Out"). -
        3. - A Fossil check-out of the SQLite source tree. Let the directory - of this check-out be called **%SRCCO%** (mnemonic: "SouRCe Check-Out"). -
        4. - Let **%TCLTD%** (mnemonic: "TCL Test Directory") be the name of a directory - that does not exist at the start of the test, and which will be - deleted at the end of the test, that will contain the test builds - of the TCL libraries and the SQLite TCL Extensions.
        5. Unix-like command-line tools installed. Example: [unxutils](https://unxutils.sourceforge.net/)
        6. [Visual Studio](https://visualstudio.microsoft.com/vs/community/) installed. VS2015 or later required. -
        7. `set ORIGINALPATH=%PATH%`
          - ↑ remember the original %PATH% value +
        8. Check out source code and set environment variables. +
            +
          1. **TCLSOURCE** → + The top-level directory of a Fossil check-out of the TCL source tree. +
          2. **SQLITESOURCE** → + A Fossil check-out of the SQLite source tree. +
          3. **TCLBUILD** → + A directory that does not exist at the start of the test and which + will be deleted at the end of the test, and that will contain the + test builds of the TCL libraries and the SQLite TCL Extensions. +
          4. **ORIGINALPATH** → + The original value of %PATH%. In other words, set as follows: + `set ORIGINALPATH %PATH%` +
        ### 3.2 Testing TCL 8.6 on Windows
          -
        1. `mkdir %TCLTD%\tcl86` -
        2. `cd %TCLCO%\win` +
        3. `mkdir %TCLBUILD%\tcl86` +
        4. `cd %TCLSOURCE%\win`
        5. `fossil up core-8-6-16`
          ↑ Or some other version of Tcl8.6.
        6. `fossil clean -x` -
        7. `set INSTALLDIR=%TCLTD%\tcl86` +
        8. `set INSTALLDIR=%TCLBUILD%\tcl86`
        9. `nmake /f makefile.vc release`
          ⇅ You *must* invoke the "release" and "install" targets - using separate invocations of "nmake" or tclsh86t.exe won't be + using separate "nmake" commands or tclsh86t.exe won't be installed.
        10. `nmake /f makefile.vc install` -
        11. `cd %SRCCO%` +
        12. `cd %SQLITESOURCE%`
        13. `fossil clean -x` -
        14. `set TCLDIR=%TCLTD%\tcl86` -
        15. `set PATH=%TCLTD%\tcl86\bin;%ORIGINALPATH%` -
        16. `set TCLSH_CMD=%TCLTD%\tcl86\bin\tclsh86t.exe` +
        17. `set TCLDIR=%TCLBUILD%\tcl86` +
        18. `set PATH=%TCLBUILD%\tcl86\bin;%ORIGINALPATH%` +
        19. `set TCLSH_CMD=%TCLBUILD%\tcl86\bin\tclsh86t.exe`
        20. `nmake /f Makefile.msc tclextension-install`
          - ↑ Verify extension installed at %TCLTD%\\tcl86\\lib\\tcl8.6\\sqlite3.* + ↑ Verify extension installed at %TCLBUILD%\\tcl86\\lib\\tcl8.6\\sqlite3.*
        21. `nmake /f Makefile.msc tclextension-verify`
        22. `tclsh86t test/testrunner.tcl release --explain`
          ↑ Verify thousands of lines of output with no errors. Or @@ -143,24 +144,24 @@ an ordinary tclsh can subsequently run "package require sqlite3". ### 3.3 Testing TCL 9.0 on Windows
            -
          1. `mkdir %TCLTD%\tcl90` -
          2. `cd %TCLCO%\win` +
          3. `mkdir %TCLBUILD%\tcl90` +
          4. `cd %TCLSOURCE%\win`
          5. `fossil up core-9-0-0`
            ↑ Or some other version of Tcl9
          6. `fossil clean -x` -
          7. `set INSTALLDIR=%TCLTD%\tcl90` +
          8. `set INSTALLDIR=%TCLBUILD%\tcl90`
          9. `nmake /f makefile.vc release`
            ⇅ You *must* invoke the "release" and "install" targets - using separate invocations of "nmake" or tclsh90.exe won't be + using separate "nmake" commands or tclsh90.exe won't be installed.
          10. `nmake /f makefile.vc install` -
          11. `cd %SRCCO%` +
          12. `cd %SQLITESOURCE%`
          13. `fossil clean -x` -
          14. `set TCLDIR=%TCLTD%\tcl90` -
          15. `set PATH=%TCLTD%\tcl90\bin;%ORIGINALPATH%` -
          16. `set TCLSH_CMD=%TCLTD%\tcl90\bin\tclsh90.exe` +
          17. `set TCLDIR=%TCLBUILD%\tcl90` +
          18. `set PATH=%TCLBUILD%\tcl90\bin;%ORIGINALPATH%` +
          19. `set TCLSH_CMD=%TCLBUILD%\tcl90\bin\tclsh90.exe`
          20. `nmake /f Makefile.msc tclextension-install`
            - ↑ Verify extension installed at %TCLTD%\\tcl90\\lib\\sqlite3.* + ↑ Verify extension installed at %TCLBUILD%\\tcl90\\lib\\sqlite3.*
          21. `nmake /f Makefile.msc tclextension-verify`
          22. `tclsh90 test/testrunner.tcl release --explain`
            ↑ Verify thousands of lines of output with no errors. Or @@ -170,5 +171,5 @@ an ordinary tclsh can subsequently run "package require sqlite3". ### 3.4 Cleanup
              -
            1. `rm -rf %TCLTD%` +
            2. `rm -rf %TCLBUILD%`
            diff --git a/manifest b/manifest index 06e0e02351..73825f1a17 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sTCL\sextension\stest\sprocedure\sto\sdeal\swith\sTCL8.6\sand\sTCL9.0\nseparately,\sto\ssimplify\sthe\sprocedures\sand\sreduce\scognative\sstress\son\sthe\ntester. -D 2025-01-05T17:16:33.231 +C Further\srefactoring\sof\sthe\sTCL\sextension\stest\sprocedure\sdocument,\sfor\nimproved\sclarity\sand\susability. +D 2025-01-05T19:58:30.967 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md 37722ac070d15ed687fbde2c444b97fd1b423b631a89897142f708594aafba47 +F doc/tcl-extension-testing.md fca7b123e6f6c94f87c5e9285342fa08d17f118d47bea22c0b045485755fe9c3 F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 28150c615cb601dfc9e4f660627228d6a8a715d64c65f7bc77931c9daf8a0dd7 -R 866ce61f7bd1663ef897c7b2791f707c +P 5281536327d244ba9507548f7ed607e86e59b98a003e63f6da767471411c8ffc +R 789a42abc3bc046ab3689d41ea48cbbd U drh -Z c10b13ae5e892d2f5ddbaa1f9222567d +Z a57fb295edbde74d3aaadaf4afebbd36 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f10a9cf7e3..1a4dca11c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5281536327d244ba9507548f7ed607e86e59b98a003e63f6da767471411c8ffc +bcdaef434142973a0805117495e561b2dcd1ec1465cacc9b944a3707291afc0d From cee8b04d33e78b2227fdb6007b9991f998469a7d Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 6 Jan 2025 17:01:35 +0000 Subject: [PATCH 494/522] Add test case for using both SQLITE_CHANGESETAPPLY_IGNORENOOP and SQLITE_CHANGESETAPPLY_FKNOACTION. FossilOrigin-Name: b1cc53fa3fb2ac3abeadd3282d8751f4d533315754159f16ca7f7f300ccdd8c8 --- ext/session/sessionnoact.test | 15 +++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ext/session/sessionnoact.test b/ext/session/sessionnoact.test index f605e6108e..e447bc8a16 100644 --- a/ext/session/sessionnoact.test +++ b/ext/session/sessionnoact.test @@ -149,5 +149,20 @@ do_execsql_test 2.5 { SELECT * FROM c1; } {two} +db_restore_and_reopen +db eval { PRAGMA foreign_keys = 1 } + +do_test 2.6 { + list [catch { + sqlite3changeset_apply_v2 -ignorenoop -noaction db $C conflict + } msg] $msg +} {1 SQLITE_CONSTRAINT} +do_execsql_test 2.7 { + SELECT * FROM p1; +} {1 1 one 2 2 two} +do_execsql_test 2.8 { + SELECT * FROM c1; +} {two} + finish_test diff --git a/manifest b/manifest index 73825f1a17..cedab9b504 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\srefactoring\sof\sthe\sTCL\sextension\stest\sprocedure\sdocument,\sfor\nimproved\sclarity\sand\susability. -D 2025-01-05T19:58:30.967 +C Add\stest\scase\sfor\susing\sboth\sSQLITE_CHANGESETAPPLY_IGNORENOOP\sand\sSQLITE_CHANGESETAPPLY_FKNOACTION. +D 2025-01-06T17:01:35.295 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -606,7 +606,7 @@ F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576d F ext/session/sessionfault3.test ce0b5d182133935c224d72507dbf1c5be1a1febf7e85d0b0fbd6d2f724b32b96 F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 -F ext/session/sessionnoact.test 1ea34324b7be2fa9d63870d44969e6bb5290a6d1603ddfd4151c51df73fad291 +F ext/session/sessionnoact.test 0f552bd318b764bbc5b2cd6f3518435254a1c830fdaa5aab9c688f507ebc301e F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7 F ext/session/sessionnoop2.test de4672dce88464396ec9f30ed08c6c01643a69c53ae540fadbbf6d30642d64e8 F ext/session/sessionrebase.test 702378bdcb5062f1106e74457beca8797d09c113a81768734a58b197b5b334e2 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5281536327d244ba9507548f7ed607e86e59b98a003e63f6da767471411c8ffc -R 789a42abc3bc046ab3689d41ea48cbbd -U drh -Z a57fb295edbde74d3aaadaf4afebbd36 +P bcdaef434142973a0805117495e561b2dcd1ec1465cacc9b944a3707291afc0d +R 39da0f1150c2b7d20d41e16df982bdbc +U dan +Z 0e33be44116920d8dfb3948dc71a5c16 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1a4dca11c7..5d5632f5c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bcdaef434142973a0805117495e561b2dcd1ec1465cacc9b944a3707291afc0d +b1cc53fa3fb2ac3abeadd3282d8751f4d533315754159f16ca7f7f300ccdd8c8 From a5dbae3781a21ea91c210c41402e1213b97df649 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 6 Jan 2025 18:32:53 +0000 Subject: [PATCH 495/522] Fix a minor problem with the sqlite3_get_table_printf() test interface. No core changes. FossilOrigin-Name: a0df29c7a3eb4f558aba00598d827643830591def3101a4d5464543527b8d13c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test1.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index cedab9b504..dfe068dcb6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sfor\susing\sboth\sSQLITE_CHANGESETAPPLY_IGNORENOOP\sand\sSQLITE_CHANGESETAPPLY_FKNOACTION. -D 2025-01-06T17:01:35.295 +C Fix\sa\sminor\sproblem\swith\sthe\ssqlite3_get_table_printf()\stest\sinterface.\nNo\score\schanges. +D 2025-01-06T18:32:53.875 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -789,7 +789,7 @@ F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 90441d3cc16f966a23499d9096a3d2d971e5e8fddb4d1413b096b79c2b2cff07 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 -F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8 +F src/test1.c 7f5579f2786c11cf4391ec2abb7b5b5b234ca1408599d7a0d6dd32360e5f58d8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bcdaef434142973a0805117495e561b2dcd1ec1465cacc9b944a3707291afc0d -R 39da0f1150c2b7d20d41e16df982bdbc -U dan -Z 0e33be44116920d8dfb3948dc71a5c16 +P b1cc53fa3fb2ac3abeadd3282d8751f4d533315754159f16ca7f7f300ccdd8c8 +R b841ee7b12f689b8a9384b533ea34d09 +U drh +Z b3de29be7899c08cf5113466b37b5222 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5d5632f5c9..c9d8176551 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1cc53fa3fb2ac3abeadd3282d8751f4d533315754159f16ca7f7f300ccdd8c8 +a0df29c7a3eb4f558aba00598d827643830591def3101a4d5464543527b8d13c diff --git a/src/test1.c b/src/test1.c index cf5d484e9e..a1a96d2b3c 100644 --- a/src/test1.c +++ b/src/test1.c @@ -600,6 +600,7 @@ static int SQLITE_TCLAPI test_get_table_printf( } sqlite3_free(zSql); sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc); + Tcl_ResetResult(interp); Tcl_AppendElement(interp, zBuf); if( rc==SQLITE_OK ){ if( argc==4 ){ From 885f546f97374e9aaabb202bb4935bee56081ad5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 6 Jan 2025 21:36:16 +0000 Subject: [PATCH 496/522] Fix a problem with tool/mksqlite3h.tcl that prevents it from running out of a read-only check-out. FossilOrigin-Name: cb54f0063edd284996b225183b8e35d71ffcd3c0fb4f56a0e316181f1a186d46 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/mksqlite3h.tcl | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index dfe068dcb6..466d999e03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sminor\sproblem\swith\sthe\ssqlite3_get_table_printf()\stest\sinterface.\nNo\score\schanges. -D 2025-01-06T18:32:53.875 +C Fix\sa\sproblem\swith\stool/mksqlite3h.tcl\sthat\sprevents\sit\sfrom\srunning\sout\sof\na\sread-only\scheck-out. +D 2025-01-06T21:36:16.287 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2154,7 +2154,7 @@ F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b0 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f F tool/mksqlite3c.tcl 9e88a30981280e33489fe4782f4ab1e5349ba1866603fba7f1a948d5599b9124 -F tool/mksqlite3h.tcl 7a4648fef5efb33308d575c7775eb242855d71d5bf89065df3f006b9a634a0a1 +F tool/mksqlite3h.tcl 5a8d23f35462bfcf74324a19465abd0ad6717b92a404d177160963c292df5d04 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mksrczip.tcl 81efd9974dbb36005383f2cd655520057a2ae5aa85ac2441a80c7c28f803ac52 F tool/mktoolzip.tcl 34b4e92be544f820e2cc26f143f7d5aec511e826ec394cc82969a5dcf7c7a27c @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b1cc53fa3fb2ac3abeadd3282d8751f4d533315754159f16ca7f7f300ccdd8c8 -R b841ee7b12f689b8a9384b533ea34d09 +P a0df29c7a3eb4f558aba00598d827643830591def3101a4d5464543527b8d13c +R a69cbcd64a4b6b9f51efe8537d38ddcf U drh -Z b3de29be7899c08cf5113466b37b5222 +Z c3ef709b705fad2b3868091e66557171 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c9d8176551..eb6e9849fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0df29c7a3eb4f558aba00598d827643830591def3101a4d5464543527b8d13c +cb54f0063edd284996b225183b8e35d71ffcd3c0fb4f56a0e316181f1a186d46 diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index c242005a07..b409d306b2 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -62,7 +62,7 @@ set nVersion [eval format "%d%03d%03d" [split $zVersion .]] # set PWD [pwd] cd $TOP -set tmpfile tmp-[clock millisec]-[expr {int(rand()*100000000000)}].txt +set tmpfile $PWD/tmp-[clock millisec]-[expr {int(rand()*100000000000)}].txt exec $PWD/mksourceid manifest > $tmpfile set fd [open $tmpfile rb] set zSourceId [string trim [read $fd]] From fbbe26282092d2d1cb980cad9a90aa73748fd16b Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 6 Jan 2025 23:33:45 +0000 Subject: [PATCH 497/522] Enhance the makefile to make it easier to build from a read-only source tree. FossilOrigin-Name: f99a70eca2fd8a54be3a6629dabd62efc623488706eed5e5a1bd0be577ac1acb --- main.mk | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index a22b0dfcdf..a0b08e5773 100644 --- a/main.mk +++ b/main.mk @@ -1043,9 +1043,9 @@ T.link.tcl = $(T.tcl.env.source); $(T.link) rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc - rm tsrc/sqlite.h.in tsrc/parse.y + rm -f tsrc/sqlite.h.in tsrc/parse.y $(B.tclsh) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new - mv vdbe.new tsrc/vdbe.c + mv -f vdbe.new tsrc/vdbe.c cp fts5.c fts5.h tsrc touch .target_source diff --git a/manifest b/manifest index 466d999e03..877d0877f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\stool/mksqlite3h.tcl\sthat\sprevents\sit\sfrom\srunning\sout\sof\na\sread-only\scheck-out. -D 2025-01-06T21:36:16.287 +C Enhance\sthe\smakefile\sto\smake\sit\seasier\sto\sbuild\sfrom\sa\sread-only\ssource\stree. +D 2025-01-06T23:33:45.755 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -700,7 +700,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk fe86d83158b547e02f8d08aa6af2130540746a4a61de7c61ea8b9d09eb06acd4 +F main.mk 0b62344246f8a3e920edb8a52b0c3296dde829d7eb450f67b89c63d79536de85 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a0df29c7a3eb4f558aba00598d827643830591def3101a4d5464543527b8d13c -R a69cbcd64a4b6b9f51efe8537d38ddcf +P cb54f0063edd284996b225183b8e35d71ffcd3c0fb4f56a0e316181f1a186d46 +R 5feebefef2332c303303ce808be74cd6 U drh -Z c3ef709b705fad2b3868091e66557171 +Z 96dcc4cb8c6c1962175be17c438abbe8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eb6e9849fd..80e347be0c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb54f0063edd284996b225183b8e35d71ffcd3c0fb4f56a0e316181f1a186d46 +f99a70eca2fd8a54be3a6629dabd62efc623488706eed5e5a1bd0be577ac1acb From 4a6896379f8e45b04804e2606fa12371f02b1151 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Jan 2025 00:17:54 +0000 Subject: [PATCH 498/522] Minor fixes to tclsqlite.c to promote portability. FossilOrigin-Name: dd934f032fa6fc790a951006512e3ed76a5f2930858932918eafdbe3ceec4620 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 877d0877f2..c1482a11b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\smakefile\sto\smake\sit\seasier\sto\sbuild\sfrom\sa\sread-only\ssource\stree. -D 2025-01-06T23:33:45.755 +C Minor\sfixes\sto\stclsqlite.c\sto\spromote\sportability. +D 2025-01-07T00:17:54.439 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -787,7 +787,7 @@ F src/sqliteInt.h 3f20dfb5ae54e787b2643edc0b5bae0cecddfb89988e28afdc3c0b05892e25 F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 90441d3cc16f966a23499d9096a3d2d971e5e8fddb4d1413b096b79c2b2cff07 +F src/tclsqlite.c ada7d3ffeabcec94776693c841dae28cdee93a256989ce024c8227134d733958 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 7f5579f2786c11cf4391ec2abb7b5b5b234ca1408599d7a0d6dd32360e5f58d8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cb54f0063edd284996b225183b8e35d71ffcd3c0fb4f56a0e316181f1a186d46 -R 5feebefef2332c303303ce808be74cd6 +P f99a70eca2fd8a54be3a6629dabd62efc623488706eed5e5a1bd0be577ac1acb +R 5a83df004b6c0337f81b894fe038a2a2 U drh -Z 96dcc4cb8c6c1962175be17c438abbe8 +Z 202998befd372783ac123e095ab97a9d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 80e347be0c..070063b5ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f99a70eca2fd8a54be3a6629dabd62efc623488706eed5e5a1bd0be577ac1acb +dd934f032fa6fc790a951006512e3ed76a5f2930858932918eafdbe3ceec4620 diff --git a/src/tclsqlite.c b/src/tclsqlite.c index f0b5c3e814..ea9d468a99 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -341,7 +341,7 @@ static int SQLITE_TCLAPI incrblobInput( */ static int SQLITE_TCLAPI incrblobOutput( ClientData instanceData, - CONST char *buf, + const char *buf, int toWrite, int *errorCodePtr ){ @@ -1843,7 +1843,8 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){ ** are 8.6 or newer, the code still tests the Tcl version at runtime. ** This allows stubs-enabled builds to be used with older Tcl libraries. */ -#if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6) +#if TCL_MAJOR_VERSION>8 || !defined(TCL_MINOR_VERSION) \ + || TCL_MAJOR_VERSION>=6 # define SQLITE_TCL_NRE 1 static int DbUseNre(void){ int major, minor; From e53393250ae446f97d3d8ad37ffa1a25d857b7fb Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Jan 2025 11:54:43 +0000 Subject: [PATCH 499/522] Fix a typo in the previous check-in. FossilOrigin-Name: 7d41885e85b0e2ef28bac34d663af07c35b21ee3e8b14481d2371f623bce681d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c1482a11b0..ecfcaef04e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sfixes\sto\stclsqlite.c\sto\spromote\sportability. -D 2025-01-07T00:17:54.439 +C Fix\sa\stypo\sin\sthe\sprevious\scheck-in. +D 2025-01-07T11:54:43.065 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -787,7 +787,7 @@ F src/sqliteInt.h 3f20dfb5ae54e787b2643edc0b5bae0cecddfb89988e28afdc3c0b05892e25 F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c ada7d3ffeabcec94776693c841dae28cdee93a256989ce024c8227134d733958 +F src/tclsqlite.c 9004ed7a517e106087f70d2ec54a2a6819e55765151fa53d0d2cd408e698f99e F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 7f5579f2786c11cf4391ec2abb7b5b5b234ca1408599d7a0d6dd32360e5f58d8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f99a70eca2fd8a54be3a6629dabd62efc623488706eed5e5a1bd0be577ac1acb -R 5a83df004b6c0337f81b894fe038a2a2 +P dd934f032fa6fc790a951006512e3ed76a5f2930858932918eafdbe3ceec4620 +R 1ccf02cc09665431fcc21407330e398e U drh -Z 202998befd372783ac123e095ab97a9d +Z c9e32c83a7281ddac240e198b5bce057 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 070063b5ed..c4fbf1e0c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd934f032fa6fc790a951006512e3ed76a5f2930858932918eafdbe3ceec4620 +7d41885e85b0e2ef28bac34d663af07c35b21ee3e8b14481d2371f623bce681d diff --git a/src/tclsqlite.c b/src/tclsqlite.c index ea9d468a99..21437909ba 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1844,7 +1844,7 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){ ** This allows stubs-enabled builds to be used with older Tcl libraries. */ #if TCL_MAJOR_VERSION>8 || !defined(TCL_MINOR_VERSION) \ - || TCL_MAJOR_VERSION>=6 + || TCL_MINOR_VERSION>=6 # define SQLITE_TCL_NRE 1 static int DbUseNre(void){ int major, minor; From 4717d573e44db999b305902a68c4bd83bd14f713 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Jan 2025 12:14:32 +0000 Subject: [PATCH 500/522] Make the TCL extension aware of the booleanString type within TCL. FossilOrigin-Name: 14b38ae6ab86a314a63ca9513850b43fcc670864f94d03a2706eff469980da88 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ecfcaef04e..8e3fb1f0fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\sprevious\scheck-in. -D 2025-01-07T11:54:43.065 +C Make\sthe\sTCL\sextension\saware\sof\sthe\sbooleanString\stype\swithin\sTCL. +D 2025-01-07T12:14:32.905 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -787,7 +787,7 @@ F src/sqliteInt.h 3f20dfb5ae54e787b2643edc0b5bae0cecddfb89988e28afdc3c0b05892e25 F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 9004ed7a517e106087f70d2ec54a2a6819e55765151fa53d0d2cd408e698f99e +F src/tclsqlite.c 6e25a72d3f3769f779b05b2c618ae0388639d8e27d6434c2ff3926f3267342fe F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 7f5579f2786c11cf4391ec2abb7b5b5b234ca1408599d7a0d6dd32360e5f58d8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P dd934f032fa6fc790a951006512e3ed76a5f2930858932918eafdbe3ceec4620 -R 1ccf02cc09665431fcc21407330e398e +P 7d41885e85b0e2ef28bac34d663af07c35b21ee3e8b14481d2371f623bce681d +R 7defba456aa3fec0b02242de054d2a9a U drh -Z c9e32c83a7281ddac240e198b5bce057 +Z 915ad0926614914c31505681a5658ee7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c4fbf1e0c3..4f85e88e04 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d41885e85b0e2ef28bac34d663af07c35b21ee3e8b14481d2371f623bce681d +14b38ae6ab86a314a63ca9513850b43fcc670864f94d03a2706eff469980da88 diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 21437909ba..344b3e07c7 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1098,6 +1098,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ ** has no string representation. */ eType = SQLITE_BLOB; }else if( (c=='b' && strcmp(zType,"boolean")==0) + || (c=='b' && strcmp(zType,"booleanString")==0 && pVar->bytes==0) || (c=='w' && strcmp(zType,"wideInt")==0) || (c=='i' && strcmp(zType,"int")==0) ){ @@ -1505,7 +1506,9 @@ static int dbPrepareAndBind( sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); pPreStmt->apParm[iParm++] = pVar; - }else if( c=='b' && strcmp(zType,"boolean")==0 ){ + }else if( (c=='b' && strcmp(zType,"boolean")==0) + || (c=='b' && strcmp(zType,"booleanString")==0 + && pVar->bytes==0) ){ int nn; Tcl_GetIntFromObj(interp, pVar, &nn); sqlite3_bind_int(pStmt, i, nn); From 311990d74ed31b3622000d5e1ca85f31be6a0af7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Jan 2025 14:55:49 +0000 Subject: [PATCH 501/522] Enhancements to the Tcl SQLite extension testing procedures so that they install a full-featured SQLite and so that Tcl is build statically so that there is no need to worry with LD_LIBRARY_PATH. FossilOrigin-Name: c8972e652ebe62a8583904b5bc1d96b2d598222c037a714c8ff114ca84b52c7a --- doc/tcl-extension-testing.md | 12 ++++++++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index ec624ceb5b..dfe47922e0 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -42,11 +42,13 @@ an ordinary tclsh can subsequently run "package require sqlite3".
          23. `fossil up core-8-6-16`
            ↑ Or some other version of Tcl8.6.
          24. `fossil clean -x` -
          25. `./configure --prefix=$TCLBUILD/tcl86` +
          26. `./configure --prefix=$TCLBUILD/tcl86 --disable-shared`
            + ↑ The --disable-shared is to avoid the need to set LD_LIBRARY_PATH + when using this Tcl build.
          27. `make install`
          28. `cd $SQLITESOURCE`
          29. `fossil clean -x` -
          30. `./configure --with-tclsh=$TCLBUILD/tcl86/bin/tclsh8.6` +
          31. `./configure --with-tclsh=$TCLBUILD/tcl86/bin/tclsh8.6 --all`
          32. `make tclextension-install`
            ↑ Verify extension installed at $TCLBUILD/tcl86/lib/tcl8.6/sqlite3.*
          33. `make tclextension-list`
            @@ -65,11 +67,13 @@ an ordinary tclsh can subsequently run "package require sqlite3".
          34. `fossil up core-9-0-0`
            ↑ Or some other version of Tcl9
          35. `fossil clean -x` -
          36. `./configure --prefix=$TCLBUILD/tcl90` +
          37. `./configure --prefix=$TCLBUILD/tcl90 --disable-shared` + ↑ The --disable-shared is to avoid the need to set LD_LIBRARY_PATH + when using this Tcl build.
          38. `make install`
          39. `cd $SQLITESOURCE`
          40. `fossil clean -x` -
          41. `./configure --with-tclsh=$TCLBUILD/tcl90/bin/tclsh9.0` +
          42. `./configure --with-tclsh=$TCLBUILD/tcl90/bin/tclsh9.0 --all`
          43. `make tclextension-install`
            ↑ Verify extension installed at $TCLBUILD/tcl90/lib/sqlite3.*
          44. `make tclextension-list`
            diff --git a/manifest b/manifest index 8e3fb1f0fe..c5215c7f12 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sTCL\sextension\saware\sof\sthe\sbooleanString\stype\swithin\sTCL. -D 2025-01-07T12:14:32.905 +C Enhancements\sto\sthe\sTcl\sSQLite\sextension\stesting\sprocedures\sso\sthat\sthey\ninstall\sa\sfull-featured\sSQLite\sand\sso\sthat\sTcl\sis\sbuild\sstatically\sso\sthat\nthere\sis\sno\sneed\sto\sworry\swith\sLD_LIBRARY_PATH. +D 2025-01-07T14:55:49.344 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md fca7b123e6f6c94f87c5e9285342fa08d17f118d47bea22c0b045485755fe9c3 +F doc/tcl-extension-testing.md 059992abc132fcec1a0c811b7d0f8c4fb08763e9833247b60b411e60a7e6128d F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7d41885e85b0e2ef28bac34d663af07c35b21ee3e8b14481d2371f623bce681d -R 7defba456aa3fec0b02242de054d2a9a +P 14b38ae6ab86a314a63ca9513850b43fcc670864f94d03a2706eff469980da88 +R 811d0a9276e161f39f1993aa5a481734 U drh -Z 915ad0926614914c31505681a5658ee7 +Z c4fb188a31a7551b0e4fe1e776f9db48 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4f85e88e04..3d4d8f52f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14b38ae6ab86a314a63ca9513850b43fcc670864f94d03a2706eff469980da88 +c8972e652ebe62a8583904b5bc1d96b2d598222c037a714c8ff114ca84b52c7a From 4a833113706cc8a26f749f837e6492ac2ea79c6a Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Jan 2025 15:00:00 +0000 Subject: [PATCH 502/522] Typo in the previous check-in. FossilOrigin-Name: 5872d7a0a7d4959562e1218bbba1115df8b292d980234273d0d38749edf19822 --- doc/tcl-extension-testing.md | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index dfe47922e0..e2edf2ef1c 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -67,7 +67,7 @@ an ordinary tclsh can subsequently run "package require sqlite3".
          45. `fossil up core-9-0-0`
            ↑ Or some other version of Tcl9
          46. `fossil clean -x` -
          47. `./configure --prefix=$TCLBUILD/tcl90 --disable-shared` +
          48. `./configure --prefix=$TCLBUILD/tcl90 --disable-shared`
            ↑ The --disable-shared is to avoid the need to set LD_LIBRARY_PATH when using this Tcl build.
          49. `make install` diff --git a/manifest b/manifest index c5215c7f12..732add5baf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\sthe\sTcl\sSQLite\sextension\stesting\sprocedures\sso\sthat\sthey\ninstall\sa\sfull-featured\sSQLite\sand\sso\sthat\sTcl\sis\sbuild\sstatically\sso\sthat\nthere\sis\sno\sneed\sto\sworry\swith\sLD_LIBRARY_PATH. -D 2025-01-07T14:55:49.344 +C Typo\sin\sthe\sprevious\scheck-in. +D 2025-01-07T15:00:00.521 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md 059992abc132fcec1a0c811b7d0f8c4fb08763e9833247b60b411e60a7e6128d +F doc/tcl-extension-testing.md b6e9180a86aa65b53b5ced9c88b22e369e31fb779011c94435b6368d9e18d43d F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 14b38ae6ab86a314a63ca9513850b43fcc670864f94d03a2706eff469980da88 -R 811d0a9276e161f39f1993aa5a481734 +P c8972e652ebe62a8583904b5bc1d96b2d598222c037a714c8ff114ca84b52c7a +R 48f035d8ef2866d48331e5816d8b1a78 U drh -Z c4fb188a31a7551b0e4fe1e776f9db48 +Z 152a8e1b3ff1b7672d585ac11e0307c5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3d4d8f52f4..895b83beaa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8972e652ebe62a8583904b5bc1d96b2d598222c037a714c8ff114ca84b52c7a +5872d7a0a7d4959562e1218bbba1115df8b292d980234273d0d38749edf19822 From ece17299582b7766d26422e91019fcc535ca93c9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Jan 2025 15:39:57 +0000 Subject: [PATCH 503/522] Fix a memory error in test logic introduced by [8704034254938662]. FossilOrigin-Name: 8a56e98d257e280d308b9fdc26e17e202f00a70fb9a780e30924e87a189fc7f4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test1.c | 6 +++++- test/pragma4.test | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 732add5baf..ba5fcdfbf6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Typo\sin\sthe\sprevious\scheck-in. -D 2025-01-07T15:00:00.521 +C Fix\sa\smemory\serror\sin\stest\slogic\sintroduced\sby\s[8704034254938662]. +D 2025-01-07T15:39:57.880 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -789,7 +789,7 @@ F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 6e25a72d3f3769f779b05b2c618ae0388639d8e27d6434c2ff3926f3267342fe F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 -F src/test1.c 7f5579f2786c11cf4391ec2abb7b5b5b234ca1408599d7a0d6dd32360e5f58d8 +F src/test1.c 07c9b523f90b96f6e9a701476602fa1f82075da19955823316b3fe13eaaa52cc F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d @@ -1533,7 +1533,7 @@ F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b76 F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 92a46bbea12322dd94a404f49edcfbfc913a2c98115f0d030a7459bb4712ef31 -F test/pragma4.test 336b99c2a9fd35af3cc6da94f794b4cba09bbdb18f0ecbd3f734bb6bb8e1c15c +F test/pragma4.test 396ef9bff1fb966d41721545ad4b12bfc26aae315f5fe51d9b917828d49e6f8e F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d9102 F test/pragma6.test c5ec577ba087954b4dfa619a3cbe97b155b60a0af487527abe89b10fc17e6512 F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c8972e652ebe62a8583904b5bc1d96b2d598222c037a714c8ff114ca84b52c7a -R 48f035d8ef2866d48331e5816d8b1a78 +P 5872d7a0a7d4959562e1218bbba1115df8b292d980234273d0d38749edf19822 +R 2dc5969771af2d8527fa6ca2001dd4f3 U drh -Z 152a8e1b3ff1b7672d585ac11e0307c5 +Z 0fbc54108ea801128f403bfa92cfd727 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 895b83beaa..77e363b6bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5872d7a0a7d4959562e1218bbba1115df8b292d980234273d0d38749edf19822 +8a56e98d257e280d308b9fdc26e17e202f00a70fb9a780e30924e87a189fc7f4 diff --git a/src/test1.c b/src/test1.c index a1a96d2b3c..4212c73232 100644 --- a/src/test1.c +++ b/src/test1.c @@ -7553,6 +7553,10 @@ static int SQLITE_TCLAPI test_wal_autocheckpoint( /* ** tclcmd: test_sqlite3_log ?SCRIPT? +** +** Caution: If you register a log callback, you must deregister it (by +** invoking test_sqlite3_log with no arguments) prior to closing the +** Tcl interpreter or else a memory error will occur. */ static struct LogCallback { Tcl_Interp *pInterp; @@ -7584,7 +7588,7 @@ static int SQLITE_TCLAPI test_sqlite3_log( logcallback.pInterp = 0; sqlite3_config(SQLITE_CONFIG_LOG, (void*)0, (void*)0); } - if( objc>1 ){ + if( objc>1 && Tcl_GetString(objv[1])[0]!=0 ){ logcallback.pObj = objv[1]; Tcl_IncrRefCount(logcallback.pObj); logcallback.pInterp = interp; diff --git a/test/pragma4.test b/test/pragma4.test index 0466960cab..2ba87c0c60 100644 --- a/test/pragma4.test +++ b/test/pragma4.test @@ -301,7 +301,7 @@ ifcapable vtab { do_test 6.3 { set ::log } {} - test_sqlite3_log {} + test_sqlite3_log } # 2024-05-08 https://sqlite.org/forum/forumpost/cf29a33e94 From fd11e5c082e98d865c46a4a0d1069f55a484537f Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Jan 2025 16:36:47 +0000 Subject: [PATCH 504/522] Improvements to [14b38ae6ab86a314] so that the Tcl interface is better able to work with boolean values in both Tcl86 and Tcl90. FossilOrigin-Name: 4e85343d6107a46682b549667410c296d7f4d17e3ac04ded7357afcbbfbe3e6d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index ba5fcdfbf6..bceb3b8591 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smemory\serror\sin\stest\slogic\sintroduced\sby\s[8704034254938662]. -D 2025-01-07T15:39:57.880 +C Improvements\sto\s[14b38ae6ab86a314]\sso\sthat\sthe\sTcl\sinterface\sis\sbetter\sable\nto\swork\swith\sboolean\svalues\sin\sboth\sTcl86\sand\sTcl90. +D 2025-01-07T16:36:47.331 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -787,7 +787,7 @@ F src/sqliteInt.h 3f20dfb5ae54e787b2643edc0b5bae0cecddfb89988e28afdc3c0b05892e25 F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 6e25a72d3f3769f779b05b2c618ae0388639d8e27d6434c2ff3926f3267342fe +F src/tclsqlite.c c6b9d3a0b1100e1e028460c418c41ca180dac5958e96bef79f6799b552522a37 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 07c9b523f90b96f6e9a701476602fa1f82075da19955823316b3fe13eaaa52cc F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5872d7a0a7d4959562e1218bbba1115df8b292d980234273d0d38749edf19822 -R 2dc5969771af2d8527fa6ca2001dd4f3 +P 8a56e98d257e280d308b9fdc26e17e202f00a70fb9a780e30924e87a189fc7f4 +R 9f37d9e0a5a710d92c078118174ed306 U drh -Z 0fbc54108ea801128f403bfa92cfd727 +Z 1267df4caaf383b5de45df3c7a06eba4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 77e363b6bd..f17f9bb53b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a56e98d257e280d308b9fdc26e17e202f00a70fb9a780e30924e87a189fc7f4 +4e85343d6107a46682b549667410c296d7f4d17e3ac04ded7357afcbbfbe3e6d diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 344b3e07c7..598c9355ff 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1097,8 +1097,8 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ /* Only return a BLOB type if the Tcl variable is a bytearray and ** has no string representation. */ eType = SQLITE_BLOB; - }else if( (c=='b' && strcmp(zType,"boolean")==0) - || (c=='b' && strcmp(zType,"booleanString")==0 && pVar->bytes==0) + }else if( (c=='b' && pVar->bytes==0 && strcmp(zType,"boolean")==0 ) + || (c=='b' && pVar->bytes==0 && strcmp(zType,"booleanString")==0 ) || (c=='w' && strcmp(zType,"wideInt")==0) || (c=='i' && strcmp(zType,"int")==0) ){ @@ -1506,11 +1506,12 @@ static int dbPrepareAndBind( sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); pPreStmt->apParm[iParm++] = pVar; - }else if( (c=='b' && strcmp(zType,"boolean")==0) - || (c=='b' && strcmp(zType,"booleanString")==0 - && pVar->bytes==0) ){ + }else if( c=='b' && pVar->bytes==0 + && (strcmp(zType,"booleanString")==0 + || strcmp(zType,"boolean")==0) + ){ int nn; - Tcl_GetIntFromObj(interp, pVar, &nn); + Tcl_GetBooleanFromObj(interp, pVar, &nn); sqlite3_bind_int(pStmt, i, nn); }else if( c=='d' && strcmp(zType,"double")==0 ){ double r; From 6962f3d8144a4aba8f19961381593f20874f5776 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 7 Jan 2025 18:50:19 +0000 Subject: [PATCH 505/522] Further refinement to the Tcl extension testing procedure. FossilOrigin-Name: 32b8b078d16b8931afa56e587cf840412c65b68da0bc6fd6280ac773295116cf --- doc/tcl-extension-testing.md | 17 ++++++++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index e2edf2ef1c..c82d336a25 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -14,6 +14,18 @@ aspect of the SQLite TCL extension, and in particular to verify that the "make tclextension-install" build target works and that an ordinary tclsh can subsequently run "package require sqlite3". +This procedure can also be used as a template for how to set up +a local TCL+SQLite development environment. In other words, it +can be be used as a guide on how to compile per-user copies of +Tcl that are used to develop, test, and debug SQLite. In that +case, perhaps make minor changes to the procedure such as: + + * Make TCLBUILD directory is permanent. + * Enable debugging symbols on the Tcl library build. + * Reduce the optimization level to -O0 for easier debugging. + * Also compile "wish" to go with each "tclsh". + + ## 2.0 Testing On Unix-like Systems (Including Mac) ### 2.1 Setup @@ -71,6 +83,9 @@ an ordinary tclsh can subsequently run "package require sqlite3". ↑ The --disable-shared is to avoid the need to set LD_LIBRARY_PATH when using this Tcl build.
          50. `make install` +
          51. `cp -r ../library $TCLBUILD/tcl90/lib/tcl9.0`
            + ↑ The Tcl library is not installed in the expected place by + "make install" in Tcl9.0. This step is not required when building Tcl8.6.
          52. `cd $SQLITESOURCE`
          53. `fossil clean -x`
          54. `./configure --with-tclsh=$TCLBUILD/tcl90/bin/tclsh9.0 --all` @@ -87,7 +102,7 @@ an ordinary tclsh can subsequently run "package require sqlite3". ### 2.4 Cleanup
              -
            1. `rm -rf $TCLBUILD` +
            2. `rm -rf $TCLBUILD`
            ## 3.0 Testing On Windows diff --git a/manifest b/manifest index bceb3b8591..ea9d0e4fd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\s[14b38ae6ab86a314]\sso\sthat\sthe\sTcl\sinterface\sis\sbetter\sable\nto\swork\swith\sboolean\svalues\sin\sboth\sTcl86\sand\sTcl90. -D 2025-01-07T16:36:47.331 +C Further\srefinement\sto\sthe\sTcl\sextension\stesting\sprocedure. +D 2025-01-07T18:50:19.567 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md b6e9180a86aa65b53b5ced9c88b22e369e31fb779011c94435b6368d9e18d43d +F doc/tcl-extension-testing.md 4c0f45c9d9923b120573a006f71f1558a18aecc71bd66e5b1a182c49a2ee8c65 F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8a56e98d257e280d308b9fdc26e17e202f00a70fb9a780e30924e87a189fc7f4 -R 9f37d9e0a5a710d92c078118174ed306 +P 4e85343d6107a46682b549667410c296d7f4d17e3ac04ded7357afcbbfbe3e6d +R 28cb3fd95e62d91bdc02718299c22dad U drh -Z 1267df4caaf383b5de45df3c7a06eba4 +Z 6cf3497825f1341be717f1a079f18695 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f17f9bb53b..cf808db214 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e85343d6107a46682b549667410c296d7f4d17e3ac04ded7357afcbbfbe3e6d +32b8b078d16b8931afa56e587cf840412c65b68da0bc6fd6280ac773295116cf From 45d19952c394d32e67789929242185a57f4390a7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 8 Jan 2025 12:25:33 +0000 Subject: [PATCH 506/522] In the doc/tcl-extension-testing.md document, provide enhanced explanation for why the tcl library needs to be copied into the install directory. FossilOrigin-Name: cff70c859fff37f886fd622b7335a73836ff8cf15e6cb7aabcff449a7e427fa8 --- doc/tcl-extension-testing.md | 10 ++++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index c82d336a25..e5ae6dc731 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -84,8 +84,14 @@ case, perhaps make minor changes to the procedure such as: when using this Tcl build.
          55. `make install`
          56. `cp -r ../library $TCLBUILD/tcl90/lib/tcl9.0`
            - ↑ The Tcl library is not installed in the expected place by - "make install" in Tcl9.0. This step is not required when building Tcl8.6. + ↑ The Tcl library is not installed by "make install" for Tcl9.0 unless + you also include the --disable-zipfs to ./configure. But if you do that + then the generated tclsh9.0 is no longer stand-alone. On the other hand, + if you don't install the Tcl library, other programs like testfixture + won't be able to find the Tcl library and hence won't work. This + extra installation step resolves the dilemma. + This step is not required when building Tcl8.6, which lacks support for + zipfs and hence always installs its Tcl library.
          57. `cd $SQLITESOURCE`
          58. `fossil clean -x`
          59. `./configure --with-tclsh=$TCLBUILD/tcl90/bin/tclsh9.0 --all` diff --git a/manifest b/manifest index ea9d0e4fd4..4fea8ee35a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\srefinement\sto\sthe\sTcl\sextension\stesting\sprocedure. -D 2025-01-07T18:50:19.567 +C In\sthe\sdoc/tcl-extension-testing.md\sdocument,\sprovide\senhanced\sexplanation\sfor\nwhy\sthe\stcl\slibrary\sneeds\sto\sbe\scopied\sinto\sthe\sinstall\sdirectory. +D 2025-01-08T12:25:33.217 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -61,7 +61,7 @@ F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347b F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md 4c0f45c9d9923b120573a006f71f1558a18aecc71bd66e5b1a182c49a2ee8c65 +F doc/tcl-extension-testing.md 45dfc22b414d0b928f9c45aef2c8ae0a2f1d31b38c5582fe6283258a86d7e45f F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4e85343d6107a46682b549667410c296d7f4d17e3ac04ded7357afcbbfbe3e6d -R 28cb3fd95e62d91bdc02718299c22dad +P 32b8b078d16b8931afa56e587cf840412c65b68da0bc6fd6280ac773295116cf +R 52cb466101bde28f58c7d46df96d4072 U drh -Z 6cf3497825f1341be717f1a079f18695 +Z cbebb7dddd96cd0f0ae4da260aa15c99 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cf808db214..0080029df3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32b8b078d16b8931afa56e587cf840412c65b68da0bc6fd6280ac773295116cf +cff70c859fff37f886fd622b7335a73836ff8cf15e6cb7aabcff449a7e427fa8 From af8af121ab77bb761ccd975d97d216c932a9ba08 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 8 Jan 2025 12:51:28 +0000 Subject: [PATCH 507/522] Cross-link and otherwise improve the various how-to-compile documents. No code changes. FossilOrigin-Name: 5e6ede92afae77ce6023f3b294dc565651631c7976d898d800988f1b3ff2e83f --- doc/compile-for-unix.md | 6 +++++- doc/compile-for-windows.md | 10 ++++++---- doc/tcl-extension-testing.md | 8 ++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/doc/compile-for-unix.md b/doc/compile-for-unix.md index 7e3784d695..ce76b97bae 100644 --- a/doc/compile-for-unix.md +++ b/doc/compile-for-unix.md @@ -4,6 +4,8 @@ Here are step-by-step instructions on how to build SQLite from canonical source on any modern machine that isn't Windows. These notes are tested (on 2024-10-11) on Ubuntu and on MacOS, but they are general and should work on most any modern unix platform. +See the companion document ([](./compile-for-windows.md>)) for +guidance on building for Windows. 1. Install a C-compiler. GCC or Clang both work fine. If you are reading this document, you've probably already done that. @@ -12,6 +14,8 @@ are general and should work on most any modern unix platform. we'll do a private install in the $HOME/local directory, but you can make adjustments to install TCL wherever you like. This document assumes you are working with TCL version 9.0. + See also the [](./tcl-extension-testing.md) document that contains + more details on compiling Tcl for use with SQLite.
            1. Get the TCL source archive, perhaps from @@ -45,7 +49,7 @@ are general and should work on most any modern unix platform.
            2. `make sqldiff`
            3. `make sqlite3_rsync`
      -

      None of the targets above require TCL. TCL is only needed +

      None of the targets above require TCL. TCL is needed for the following targets:

      • `make tclextension-install` diff --git a/doc/compile-for-windows.md b/doc/compile-for-windows.md index 5cecfbf547..717569dd78 100644 --- a/doc/compile-for-windows.md +++ b/doc/compile-for-windows.md @@ -1,7 +1,9 @@ # Notes On Compiling SQLite On Windows 11 -Here are step-by-step instructions on how to build SQLite from -canonical source on a new Windows 11 PC, as of 2024-10-09: +Below are step-by-step instructions on how to build SQLite from +canonical source on a new Windows 11 PC, as of 2024-10-09. +See [](./compile-for-unix.md) for a similar guide for unix-like +systems, including MacOS. 1. Install Microsoft Visual Studio. The free "community edition" will work fine. Do a standard install for C++ development. @@ -33,8 +35,8 @@ canonical source on a new Windows 11 PC, as of 2024-10-09: "tclsh90.exe" command-line tool as part of the build process, and the "tcl90.lib" and "tclstub.lib" libraries in order to run tests. This document assumes you are working with TCL version 9.0. - See versions of this document from prior to 2024-10-10 for - instructions on how to build using TCL version 8.6. + See [](./tcl-extension-testing.md#windows) for guidance on how + to compile TCL version 8.6 for use with SQLite.
        1. Get the TCL source archive, perhaps from diff --git a/doc/tcl-extension-testing.md b/doc/tcl-extension-testing.md index e5ae6dc731..df5f6537ba 100644 --- a/doc/tcl-extension-testing.md +++ b/doc/tcl-extension-testing.md @@ -26,8 +26,12 @@ case, perhaps make minor changes to the procedure such as: * Also compile "wish" to go with each "tclsh". + ## 2.0 Testing On Unix-like Systems (Including Mac) +See also the [](./compile-for-unix.md) document which provides another +perspective on how to compile SQLite on unix-like systems. + ### 2.1 Setup
            @@ -111,8 +115,12 @@ case, perhaps make minor changes to the procedure such as:
          1. `rm -rf $TCLBUILD`
          + ## 3.0 Testing On Windows +See also the [](./compile-for-windows.md) document which provides another +perspective on how to compile SQLite on Windows. + ### 3.1 Setup for Windows
            diff --git a/manifest b/manifest index 4fea8ee35a..a8b5736857 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sdoc/tcl-extension-testing.md\sdocument,\sprovide\senhanced\sexplanation\sfor\nwhy\sthe\stcl\slibrary\sneeds\sto\sbe\scopied\sinto\sthe\sinstall\sdirectory. -D 2025-01-08T12:25:33.217 +C Cross-link\sand\sotherwise\simprove\sthe\svarious\show-to-compile\sdocuments.\nNo\scode\schanges. +D 2025-01-08T12:51:28.347 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -55,13 +55,13 @@ F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd -F doc/compile-for-unix.md 7d6a5770611ea0643de456b385581923dac7c0a7c3758825dda810d12fc3e5b2 -F doc/compile-for-windows.md 791f1754fcd669b0a8fdcdc0fdd56eff8c148add7457e8bf4863b46829966fc1 +F doc/compile-for-unix.md c9dce1ddd4bf0d25efccc5c63eb047e78c01ce06a6ff29c73e0a8af4a0f4adbc +F doc/compile-for-windows.md 31cddda1d5f34027f1f2b7484d580e7558f22a9875884805b6fdc84d56cab848 F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 -F doc/tcl-extension-testing.md 45dfc22b414d0b928f9c45aef2c8ae0a2f1d31b38c5582fe6283258a86d7e45f +F doc/tcl-extension-testing.md 864875c3b672db79e7d42348dd726f9a4fbd852b1d8e5efcf09fe3d1ff6bf2a2 F doc/testrunner.md 15583cf8c7d8a1c3378fd5d4319ca769a14c4d950a5df9b015d01d5be290dc69 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 32b8b078d16b8931afa56e587cf840412c65b68da0bc6fd6280ac773295116cf -R 52cb466101bde28f58c7d46df96d4072 +P cff70c859fff37f886fd622b7335a73836ff8cf15e6cb7aabcff449a7e427fa8 +R 9e488272febec3d17c3861ccb9f3e0b0 U drh -Z cbebb7dddd96cd0f0ae4da260aa15c99 +Z 5539a934602dd195ca384aa9f37e29a3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0080029df3..d3b8030481 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cff70c859fff37f886fd622b7335a73836ff8cf15e6cb7aabcff449a7e427fa8 +5e6ede92afae77ce6023f3b294dc565651631c7976d898d800988f1b3ff2e83f From ad460db7eb21cbcdd4f509653f86acbcf43029dc Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 8 Jan 2025 15:54:44 +0000 Subject: [PATCH 508/522] Fix a crash in fts5 that could occur if shadow tables are modified or removed. FossilOrigin-Name: c0b691095ae72fc07530777ef6d23688fb4196ce2e0feff14fc3c597c572252d --- ext/fts5/fts5_index.c | 6 +- ext/fts5/fts5_storage.c | 5 + ext/fts5/test/fts5circref.test | 2 +- ext/fts5/test/fts5corrupt3.test | 233 +++++++++++++++++++++++++++++++ ext/fts5/test/fts5savepoint.test | 2 +- manifest | 22 +-- manifest.uuid | 2 +- 7 files changed, 257 insertions(+), 15 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 242258af70..2e512fd215 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -891,9 +891,13 @@ static int fts5IndexPrepareStmt( ){ if( p->rc==SQLITE_OK ){ if( zSql ){ - p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, + int rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB, ppStmt, 0); + /* If this prepare() call fails with SQLITE_ERROR, then one of the + ** %_idx or %_data tables has been removed or modified. Call this + ** corruption. */ + p->rc = (rc==SQLITE_ERROR ? SQLITE_CORRUPT : rc); }else{ p->rc = SQLITE_NOMEM; } diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 31f5fc5dc3..2b43016bef 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -205,6 +205,11 @@ static int fts5StorageGetStmt( if( rc!=SQLITE_OK && pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); } + if( rc==SQLITE_ERROR && eStmt>FTS5_STMT_LOOKUP2 && eStmt Date: Wed, 8 Jan 2025 20:43:03 +0000 Subject: [PATCH 509/522] Fix another assert() failure in fts5. FossilOrigin-Name: 6da37893f5b5729ea5fd632e8d98789e867488a67501d4a4dad92f8e7cb6bda0 --- ext/fts5/fts5_main.c | 3 +- ext/fts5/test/fts5corrupt5.test | 235 ++++++++++++++++++++++++++++++++ manifest | 14 +- manifest.uuid | 2 +- 4 files changed, 245 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 876420f24d..474f7441e9 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -1913,7 +1913,7 @@ static int fts5UpdateMethod( ); assert( pTab->p.pConfig->pzErrmsg==0 ); if( pConfig->pgsz==0 ){ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie); if( rc!=SQLITE_OK ) return rc; } @@ -2126,6 +2126,7 @@ static int fts5RollbackMethod(sqlite3_vtab *pVtab){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0); rc = sqlite3Fts5StorageRollback(pTab->pStorage); + pTab->p.pConfig->pgsz = 0; return rc; } diff --git a/ext/fts5/test/fts5corrupt5.test b/ext/fts5/test/fts5corrupt5.test index 19f0538418..ddb22f870d 100644 --- a/ext/fts5/test/fts5corrupt5.test +++ b/ext/fts5/test/fts5corrupt5.test @@ -1451,6 +1451,241 @@ do_catchsql_test 9.2 { DELETE FROM t1; } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 10.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 32768 pagesize 4096 filename crash-b06f016068bcea.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........ +| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................ +| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 +| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............ +| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. +| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! +| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont +| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR +| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c +| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG +| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i.... +| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt +| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB +| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi +| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P +| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid +| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT +| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t +| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da +| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE +| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT +| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................ +| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... +| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... +| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160 +| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4. +| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5..... +| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000... +| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary.. +| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp +| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d +| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat........... +| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e +| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... +| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................ +| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................ +| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ +| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension.. +| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... +| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5....... +| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc......... +| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........ +| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........ +| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... +| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max........... +| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... +| 3648: 73 79 73 35 16 02 03 01 02 02 03 01 03 01 06 6e sys5...........n +| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase........... +| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................ +| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... +| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree......... +| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............ +| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 03 57 34 56 ..threadsafe.W4V +| 3840: 94 64 91 46 85 84 04 76 74 61 62 07 02 04 01 02 .d.F...vtab..... +| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... +| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 10 02 ................ +| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 3936: 01 02 01 06 01 01 10 01 06 01 01 02 01 06 01 01 ................ +| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ +| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G.......... +| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 4 offset 12288 +| 0: 0a 00 00 00 01 0f fa 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 24 0c 0a 00 0f d8 0f af 0f 86 0f 74 ....$..........t +| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./.......... +| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$...... +| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb .......h.O.5.... +| 64: 0c da 0c b9 0c 99 0c 00 00 00 00 00 00 00 00 00 ................ +| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 31 46 45 3d ..%..THREADS1FE= +| 3152: 30 58 52 64 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRdRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 +| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE. +| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4b 45 20 4d 45 4d 53 59 53 35 58 42 49 NABKE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 42 60 2d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 B`-EMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 46 ....)..ENABLE MF +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 4e 41 BLE GEOPOLYXBINA +| 3616: 52 59 1a 11 05 00 39 0f 19 45 4e 41 42 4c 45 2e RY....9..ENABLE. +| 3632: 41 40 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 40 A@GEOPOLYXNOCAS@ +| 3648: 4f 4c 59 58 55 09 10 05 00 29 0f 17 45 4e 41 42 OLYXU....)..ENAB +| 3664: 4c 45 20 47 45 4f 52 54 52 49 4d 17 0f 05 00 23 LE GEORTRIM....# +| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE... +| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 24 15 48 4e 4f 43 41 53 45 1d TAT VT$.HNOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4. +| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM +| page 6 offset 20480 +| 0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0 ....$........... +| 16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f b0 0f a8 0f a0 ................ +| 32: 1f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60 .........x.p.h.` +| 48: 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 0f 28 0f 20 .X.P.H.@.8.0.(. +| 64: 0f 18 0f 10 0f 08 0f 00 0e f8 0e f0 0e e8 00 00 ................ +| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... +| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... +| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . .............. +| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ +| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ +| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................ +| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ +| 3920: 06 15 f3 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ +| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ +| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ +| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ +| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ +| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................ +| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ +| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ +| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................ +| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ +| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ +| page 7 offset 24576 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| page 8 offset 28672 +| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f 00 00 00 00 00 ................ +| 4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 67 72 .........+integr +| 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb +| 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 00 00 00 00 uild....opti.... +| end crash-b06f016068bcea.db +.testctrl prng_seed 1 db +.testctrl internal_functions +.testctrl json_selfcheck on +}]} {} + +do_execsql_test 10.1 { + UPDATE t1 SET b=quote(zeroblob(current_date)) WHERE t1 MATCH 't*'; +} + +do_catchsql_test 10.2 { + BEGIN; + INSERT INTO t1(t1,rank) VALUES('secure-delete',1); + REPLACE INTO t1(b,a,rowid) VALUES(1,2,3); +} {0 {}} + +do_catchsql_test 10.3 { + COMMIT +} {1 {database disk image is malformed}} + +do_catchsql_test 10.4 { + REPLACE INTO t1(b,a,rowid) VALUES(1,2,3); +} {1 {database disk image is malformed}} + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index 57eca29cdb..c848e6661b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sin\sfts5\sthat\scould\soccur\sif\sshadow\stables\sare\smodified\sor\sremoved. -D 2025-01-08T15:54:44.349 +C Fix\sanother\sassert()\sfailure\sin\sfts5. +D 2025-01-08T20:43:03.635 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -113,7 +113,7 @@ F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773 F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 F ext/fts5/fts5_index.c 1a450035b9e06cc82fcd75f71d6ed9028a78bd56101dcb0c813346e1e91c722a -F ext/fts5/fts5_main.c 72527efa1d634054b93a21eafe854763cbc5c270e8a4ab99bbb589557b818482 +F ext/fts5/fts5_main.c 9ba1871ee99c415756346ea515d0fd31162d599b9b39a29a5b5a265509f136e3 F ext/fts5/fts5_storage.c 1ad05dab4830a4e2eaf2900bb143477f93bc17437093582f36f4b818809e88d8 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -163,7 +163,7 @@ F ext/fts5/test/fts5corrupt.test 6485f721b88ba355ca5d701e7ee87a4efa3ea578d8e6adb F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4 F ext/fts5/test/fts5corrupt3.test 3420ad30bf9e9bbdbd43b3224c582431744899530a65b11b60ddacdf14200e19 F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733 -F ext/fts5/test/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76 +F ext/fts5/test/fts5corrupt5.test b1199f316976dc0396caac59655f489576b7dd29c2520799af19ce3386ef6562 F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06 F ext/fts5/test/fts5corrupt7.test 4e830875c33b9ea3c4cf1ba71e692b63893cbb4faae8c69b1071889dc26e211c F ext/fts5/test/fts5corrupt8.test b81d802e41631e98100f49a1aadeeffef860e30a62d6ed7d743c2797c477239e @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5e6ede92afae77ce6023f3b294dc565651631c7976d898d800988f1b3ff2e83f -R aaf463096c33b6880c3455de8eba69af +P c0b691095ae72fc07530777ef6d23688fb4196ce2e0feff14fc3c597c572252d +R 25cf4f6dfa19d9549598c6fb3f0ef39b U dan -Z ae39e4a53d5583331f681da82808c46e +Z af424067c12fe68ac83a2d82b8d3d4b3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e3d479fb61..c25464140b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0b691095ae72fc07530777ef6d23688fb4196ce2e0feff14fc3c597c572252d +6da37893f5b5729ea5fd632e8d98789e867488a67501d4a4dad92f8e7cb6bda0 From b1cbae8bd62a1d920a91ad820841b50008130310 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 Jan 2025 14:10:25 +0000 Subject: [PATCH 510/522] When removing an fts5 in secure-delete mode, defer setting the table version to SECUREDELETE until flushing data to disk. This prevents problems that can occur if there is a rollback or statement rollback operation. FossilOrigin-Name: c359e555ceafcaab2ae38074bc4f57cccdc5bc6080d17f82290c09b9e5dd80c2 --- ext/fts5/fts5_index.c | 18 +++ ext/fts5/fts5_main.c | 19 --- ext/fts5/test/fts5corrupt5.test | 232 ++++++++++++++++++++++++++++++++ ext/fts5/test/fts5version.test | 2 +- manifest | 18 +-- manifest.uuid | 2 +- 6 files changed, 261 insertions(+), 30 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 2e512fd215..a8ac98b699 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5477,6 +5477,24 @@ static void fts5FlushSecureDelete( const int f = FTS5INDEX_QUERY_SKIPHASH; Fts5Iter *pIter = 0; /* Used to find term instance */ + /* If the version number has not been set to SECUREDELETE, do so now. */ + if( p->pConfig->iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ + Fts5Config *pConfig = p->pConfig; + sqlite3_stmt *pStmt = 0; + fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf( + "REPLACE INTO %Q.'%q_config' VALUES ('version', %d)", + pConfig->zDb, pConfig->zName, FTS5_CURRENT_VERSION_SECUREDELETE + )); + if( p->rc==SQLITE_OK ){ + int rc; + sqlite3_step(pStmt); + rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK ) p->rc = rc; + pConfig->iCookie++; + pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; + } + } + fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); if( fts5MultiIterEof(p, pIter)==0 ){ i64 iThis = fts5MultiIterRowid(pIter); diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 474f7441e9..9f504bb3a3 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -1901,7 +1901,6 @@ static int fts5UpdateMethod( Fts5Config *pConfig = pTab->p.pConfig; int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ - int bUpdateOrDelete = 0; /* A transaction must be open when this is called. */ assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); @@ -1938,7 +1937,6 @@ static int fts5UpdateMethod( rc = SQLITE_ERROR; }else{ rc = fts5SpecialDelete(pTab, apVal); - bUpdateOrDelete = 1; } }else{ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); @@ -1975,7 +1973,6 @@ static int fts5UpdateMethod( }else{ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0); - bUpdateOrDelete = 1; } } @@ -2003,7 +2000,6 @@ static int fts5UpdateMethod( if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); - bUpdateOrDelete = 1; } fts5StorageInsert(&rc, pTab, apVal, pRowid); } @@ -2057,23 +2053,8 @@ static int fts5UpdateMethod( rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); fts5StorageInsert(&rc, pTab, apVal, pRowid); } - bUpdateOrDelete = 1; sqlite3Fts5StorageReleaseDeleteRow(pStorage); } - - } - } - - if( rc==SQLITE_OK - && bUpdateOrDelete - && pConfig->bSecureDelete - && pConfig->iVersion==FTS5_CURRENT_VERSION - ){ - rc = sqlite3Fts5StorageConfigValue( - pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE - ); - if( rc==SQLITE_OK ){ - pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; } } diff --git a/ext/fts5/test/fts5corrupt5.test b/ext/fts5/test/fts5corrupt5.test index ddb22f870d..6a70fc7e44 100644 --- a/ext/fts5/test/fts5corrupt5.test +++ b/ext/fts5/test/fts5corrupt5.test @@ -1686,6 +1686,238 @@ do_catchsql_test 10.4 { REPLACE INTO t1(b,a,rowid) VALUES(1,2,3); } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 11.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 32768 pagesize 4096 filename crash-3d05232c78871b.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........ +| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................ +| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 +| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............ +| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. +| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! +| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont +| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR +| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c +| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG +| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i.... +| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt +| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB +| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi +| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P +| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid +| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT +| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t +| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da +| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE +| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT +| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................ +| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... +| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... +| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160 +| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4. +| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5..... +| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000... +| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary.. +| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp +| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d +| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat........... +| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e +| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... +| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................ +| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................ +| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ +| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension.. +| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... +| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5....... +| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc......... +| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........ +| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........ +| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... +| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max........... +| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... +| 3648: 73 79 73 35 16 02 03 01 02 02 03 01 03 01 06 6e sys5...........n +| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase........... +| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................ +| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... +| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree......... +| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............ +| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 03 57 34 56 ..threadsafe.W4V +| 3840: 94 64 91 46 85 84 04 76 74 61 62 07 02 04 01 02 .d.F...vtab..... +| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... +| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 10 02 ................ +| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 3936: 01 02 01 06 01 01 10 01 06 01 01 02 01 06 01 01 ................ +| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ +| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G.......... +| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 4 offset 12288 +| 0: 0a 00 00 00 01 0f fa 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 24 0c 0a 00 0f d8 0f af 0f 86 0f 74 ....$..........t +| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./.......... +| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$...... +| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb .......h.O.5.... +| 64: 0c da 0c b9 0c 99 0c 00 00 00 00 00 00 00 00 00 ................ +| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 31 46 45 3d ..%..THREADS1FE= +| 3152: 30 58 52 64 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRdRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 +| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE. +| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4b 45 20 4d 45 4d 53 59 53 35 58 42 49 NABKE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 42 60 2d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 B`-EMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 46 ....)..ENABLE MF +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 4e 41 BLE GEOPOLYXBINA +| 3616: 52 59 1a 11 05 00 39 0f 19 45 4e 41 42 4c 45 2e RY....9..ENABLE. +| 3632: 41 40 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 40 A@GEOPOLYXNOCAS@ +| 3648: 4f 4c 59 58 55 09 10 05 00 29 0f 17 45 4e 41 42 OLYXU....)..ENAB +| 3664: 4c 45 20 47 45 4f 52 54 52 49 4d 17 0f 05 00 23 LE GEORTRIM....# +| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE... +| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 24 15 48 4e 4f 43 41 53 45 1d TAT VT$.HNOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4. +| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM +| page 6 offset 20480 +| 0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0 ....$........... +| 16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f b0 0f a8 0f a0 ................ +| 32: 1f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60 .........x.p.h.` +| 48: 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 0f 28 0f 20 .X.P.H.@.8.0.(. +| 64: 0f 18 0f 10 0f 08 0f 00 0e f8 0e f0 0e e8 00 00 ................ +| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... +| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... +| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . .............. +| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ +| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ +| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................ +| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ +| 3920: 06 15 f3 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ +| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ +| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ +| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ +| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ +| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................ +| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ +| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ +| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................ +| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ +| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ +| page 7 offset 24576 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| page 8 offset 28672 +| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f 00 00 00 00 00 ................ +| 4048: 00 00 00 00 00 00 11 03 02 2b 69 6e 74 65 67 72 .........+integr +| 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb +| 4080: 75 69 6c 64 0a 01 02 1d 6f 00 00 00 00 00 00 00 uild....o....... +| end crash-3d05232c78871b.db +}]} {} + +do_execsql_test 11.1 { + UPDATE t1 SET b=quote(zeroblob('2025-01-09')) WHERE t1 MATCH 't*'; + INSERT INTO t1(t1,rank) VALUES('secure-delete',1); +} + +do_catchsql_test 11.2 { + BEGIN; + REPLACE INTO t1(rowid,b,a,rowid) VALUES(x'44023b9eb002d28b0ee90c',1,2,3); + PRAGMA writable_schema=RESET; + INSERT INTO t1(t1) SELECT x FROM t2; + ROLLBACK; +} {1 {database disk image is malformed}} + +do_catchsql_test 11.3 { + REPLACE INTO t1(rowid,b,a,rowid) VALUES(x'44023b9eb002d28b0ee90c',1,2,3); +} {1 {database disk image is malformed}} + + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/ext/fts5/test/fts5version.test b/ext/fts5/test/fts5version.test index a92c0dc9f4..58dd9fe14e 100644 --- a/ext/fts5/test/fts5version.test +++ b/ext/fts5/test/fts5version.test @@ -112,7 +112,7 @@ do_execsql_test 2.1 { do_execsql_test 2.2 { SELECT v FROM xyz_config WHERE k='version'; -} {5} +} {4} do_execsql_test 2.3 { ROLLBACK TO one; diff --git a/manifest b/manifest index c848e6661b..6eb5459a34 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sassert()\sfailure\sin\sfts5. -D 2025-01-08T20:43:03.635 +C When\sremoving\san\sfts5\sin\ssecure-delete\smode,\sdefer\ssetting\sthe\stable\sversion\sto\sSECUREDELETE\suntil\sflushing\sdata\sto\sdisk.\sThis\sprevents\sproblems\sthat\scan\soccur\sif\sthere\sis\sa\srollback\sor\sstatement\srollback\soperation. +D 2025-01-09T14:10:25.673 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -112,8 +112,8 @@ F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70 F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 F ext/fts5/fts5_expr.c 69b8d976058512c07dfe86e229521b7a871768157bd1607cedf1a5038dfd72c9 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c 1a450035b9e06cc82fcd75f71d6ed9028a78bd56101dcb0c813346e1e91c722a -F ext/fts5/fts5_main.c 9ba1871ee99c415756346ea515d0fd31162d599b9b39a29a5b5a265509f136e3 +F ext/fts5/fts5_index.c f1f6da5938af616e0a5e54f0423a3134df95b9f17ac1c6ebf2e2e8132bbc75b9 +F ext/fts5/fts5_main.c 9a1daef7247f9b8a50b4159323e340efa6b0e4bea4fcd83580480f94d4f2c888 F ext/fts5/fts5_storage.c 1ad05dab4830a4e2eaf2900bb143477f93bc17437093582f36f4b818809e88d8 F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -163,7 +163,7 @@ F ext/fts5/test/fts5corrupt.test 6485f721b88ba355ca5d701e7ee87a4efa3ea578d8e6adb F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4 F ext/fts5/test/fts5corrupt3.test 3420ad30bf9e9bbdbd43b3224c582431744899530a65b11b60ddacdf14200e19 F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733 -F ext/fts5/test/fts5corrupt5.test b1199f316976dc0396caac59655f489576b7dd29c2520799af19ce3386ef6562 +F ext/fts5/test/fts5corrupt5.test bcf0801b0c991eadae3cb8e978e82b4bf01412cb4df41874a90d5aa279c7cc96 F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06 F ext/fts5/test/fts5corrupt7.test 4e830875c33b9ea3c4cf1ba71e692b63893cbb4faae8c69b1071889dc26e211c F ext/fts5/test/fts5corrupt8.test b81d802e41631e98100f49a1aadeeffef860e30a62d6ed7d743c2797c477239e @@ -264,7 +264,7 @@ F ext/fts5/test/fts5unindexed.test 168838d2c385e131120bbf5b516d2432a5fabc4caa225 F ext/fts5/test/fts5unindexed2.test 516236eceaac05ace322290a0d3705b4c4ffe4760d8eb9d014d9d27d56dfcc02 F ext/fts5/test/fts5update.test b8affd796e45c94a4d19ad5c26606ea06065a0f162a9562d9f005b5a80ccf0bc F ext/fts5/test/fts5update2.test c5baa76799ac605ebb8e5e21035db2014b396cef25c903eb96ba39b1d6f9f046 -F ext/fts5/test/fts5version.test c22d163c17e60a99f022cbc52de5a48bb7f84deaa00fe15e9bc4c3aa1996204e +F ext/fts5/test/fts5version.test 44ab35566267b7618c090443de2d9ad84f633df5d20bf72e9bad199ae5fced84 F ext/fts5/test/fts5vocab.test 2a2bdb60d0998fa3124d541b6d30b019504918dc43a6584645b63a24be72f992 F ext/fts5/test/fts5vocab2.test bbba149c254375d00055930c1a501c9a51e80b0d20bf7b98f3e9fa3b03786373 F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c0b691095ae72fc07530777ef6d23688fb4196ce2e0feff14fc3c597c572252d -R 25cf4f6dfa19d9549598c6fb3f0ef39b +P 6da37893f5b5729ea5fd632e8d98789e867488a67501d4a4dad92f8e7cb6bda0 +R 659181897535bd26e43a32e9be047282 U dan -Z af424067c12fe68ac83a2d82b8d3d4b3 +Z a32ef00755f10bd4444e41dd1939dfc6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c25464140b..30a1951bd1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6da37893f5b5729ea5fd632e8d98789e867488a67501d4a4dad92f8e7cb6bda0 +c359e555ceafcaab2ae38074bc4f57cccdc5bc6080d17f82290c09b9e5dd80c2 From 35ac4c868572c57b12e7f034b299a632e2151ca0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 9 Jan 2025 19:57:44 +0000 Subject: [PATCH 511/522] Update the makefile so that it puts the amalgamation files in a subdirectory in the amalgamation-zip. [forum:/forumpost/b8dd1941e1|Forum post b8dd1941e1]. FossilOrigin-Name: cef8e88bedf01dc47012ef1cb878b22117c9966e615edf5a69704486f9cfa56c --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/mkamalzip.tcl | 12 ++++++++++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6eb5459a34..defee4b6a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sremoving\san\sfts5\sin\ssecure-delete\smode,\sdefer\ssetting\sthe\stable\sversion\sto\sSECUREDELETE\suntil\sflushing\sdata\sto\sdisk.\sThis\sprevents\sproblems\sthat\scan\soccur\sif\sthere\sis\sa\srollback\sor\sstatement\srollback\soperation. -D 2025-01-09T14:10:25.673 +C Update\sthe\smakefile\sso\sthat\sit\sputs\sthe\samalgamation\sfiles\sin\sa\ssubdirectory\nin\sthe\samalgamation-zip.\n[forum:/forumpost/b8dd1941e1|Forum\spost\sb8dd1941e1]. +D 2025-01-09T19:57:44.593 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2139,7 +2139,7 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 -F tool/mkamalzip.tcl 8a1b21fb6a7f990eb9625e08daa2dd0e03cb551bccc69ccd1cdd5bd975e8177a +F tool/mkamalzip.tcl 8aa5ebe7973c8b8774062d34e15fea9815c4cc2ceea3a9b184695f005910876a F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a F tool/mkccode.tcl 210159febe0ef0ecbc53c79833500663ceaba0115b2b374405818dc835b5f84b x F tool/mkctimec.tcl ef6a67ec82e5b6fc19152a4c79f237227b18bf67ff16d155bac7adb94355d9cf x @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6da37893f5b5729ea5fd632e8d98789e867488a67501d4a4dad92f8e7cb6bda0 -R 659181897535bd26e43a32e9be047282 -U dan -Z a32ef00755f10bd4444e41dd1939dfc6 +P c359e555ceafcaab2ae38074bc4f57cccdc5bc6080d17f82290c09b9e5dd80c2 +R 4acc7fa1125cb682f7786bdefbb3cacb +U drh +Z 1b3035dddd40c2669ae993db009fbd5c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 30a1951bd1..afb4e5caa1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c359e555ceafcaab2ae38074bc4f57cccdc5bc6080d17f82290c09b9e5dd80c2 +cef8e88bedf01dc47012ef1cb878b22117c9966e615edf5a69704486f9cfa56c diff --git a/tool/mkamalzip.tcl b/tool/mkamalzip.tcl index a7c6587566..92feb4122e 100644 --- a/tool/mkamalzip.tcl +++ b/tool/mkamalzip.tcl @@ -9,7 +9,15 @@ set vers [read $fd] close $fd scan $vers %d.%d.%d major minor patch set numvers [format {3%02d%02d00} $minor $patch] -set cmd "zip sqlite-amalgamation-$numvers.zip\ - sqlite3.c sqlite3.h shell.c sqlite3ext.h" +set dir sqlite-amalgamation-$numvers +file delete -force $dir +file mkdir $dir +set filelist {sqlite3.c sqlite3.h shell.c sqlite3ext.h} +foreach f $filelist { + file copy $f $dir/$f +} +set cmd "zip -r $dir.zip $dir" puts $cmd +file delete -force $dir.zip exec {*}$cmd +file delete -force $dir From c1f914dbc986e7e9ef6643eb02e03ec5cb55c3d0 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 11 Jan 2025 09:02:55 +0000 Subject: [PATCH 512/522] Fix an age-old bug in the lower-level wasm/js helper bits which was (A) caused removal of customized WASM func/argument conversion to siltently fail and (B) triggered a warning in the closure toolchain. Reported in [jaccwabyt ticket c5c296e85a7c01360820|https://fossil.wanderinghorse.net/r/jaccwabyt/info/c5c296e85a7c01360820]. FossilOrigin-Name: 99917a5bb04b5ad6ace95baf86d91e6ce098f9d3001de1a29d3d0b0b817acdce --- ext/wasm/common/whwasmutil.js | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js index 25400d48e3..8fe4a990b6 100644 --- a/ext/wasm/common/whwasmutil.js +++ b/ext/wasm/common/whwasmutil.js @@ -2055,7 +2055,7 @@ globalThis.WhWasmUtilInstaller = function(target){ if(1===argc) return xcvPart.get(typeName); else if(2===argc){ if(!adapter){ - delete xcvPart.get(typeName); + xcvPart.delete(typeName); return func; }else if(!(adapter instanceof Function)){ toss(modeName,"requires a function argument."); diff --git a/manifest b/manifest index defee4b6a3..d41be8009b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\smakefile\sso\sthat\sit\sputs\sthe\samalgamation\sfiles\sin\sa\ssubdirectory\nin\sthe\samalgamation-zip.\n[forum:/forumpost/b8dd1941e1|Forum\spost\sb8dd1941e1]. -D 2025-01-09T19:57:44.593 +C Fix\san\sage-old\sbug\sin\sthe\slower-level\swasm/js\shelper\sbits\swhich\swas\s(A)\scaused\sremoval\sof\scustomized\sWASM\sfunc/argument\sconversion\sto\ssiltently\sfail\sand\s(B)\striggered\sa\swarning\sin\sthe\sclosure\stoolchain.\sReported\sin\s[jaccwabyt\sticket\sc5c296e85a7c01360820|https://fossil.wanderinghorse.net/r/jaccwabyt/info/c5c296e85a7c01360820]. +D 2025-01-11T09:02:55.088 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -658,7 +658,7 @@ F ext/wasm/c-pp.c 6d131069644964223305582a80973477fa8b06b57306781690d7874ebd3a4f F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f -F ext/wasm/common/whwasmutil.js 6181f8cd958700f3723350bd4d76c7cc797db331a9aa14b25b42d121f12d6fee +F ext/wasm/common/whwasmutil.js d76c69617e95d85ffc9996f7d9d7481df6976dcbd860ecd82bd8c075e3a101ae F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 F ext/wasm/demo-123.js c7b3cca50c55841c381a9ca4f9396e5bbdc6114273d0b10a43e378e32e7be5bf @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c359e555ceafcaab2ae38074bc4f57cccdc5bc6080d17f82290c09b9e5dd80c2 -R 4acc7fa1125cb682f7786bdefbb3cacb -U drh -Z 1b3035dddd40c2669ae993db009fbd5c +P cef8e88bedf01dc47012ef1cb878b22117c9966e615edf5a69704486f9cfa56c +R 2966a1ed8608823769a5c4d3eb2bc028 +U stephan +Z 02b31671f60b5e3785eaa517886d85b1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index afb4e5caa1..a540ad80d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cef8e88bedf01dc47012ef1cb878b22117c9966e615edf5a69704486f9cfa56c +99917a5bb04b5ad6ace95baf86d91e6ce098f9d3001de1a29d3d0b0b817acdce From 27661f24cd6fc71387af5a48caf3fc38dffe1b14 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 11 Jan 2025 13:59:42 +0000 Subject: [PATCH 513/522] Fix harmless scan-build warnings. FossilOrigin-Name: b93af6feb7c0c3af30a47810a7c0e77ce41c386fac164c64bb5871a6c153db7e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 1 + src/shell.c.in | 1 + 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d41be8009b..6f043074b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sage-old\sbug\sin\sthe\slower-level\swasm/js\shelper\sbits\swhich\swas\s(A)\scaused\sremoval\sof\scustomized\sWASM\sfunc/argument\sconversion\sto\ssiltently\sfail\sand\s(B)\striggered\sa\swarning\sin\sthe\sclosure\stoolchain.\sReported\sin\s[jaccwabyt\sticket\sc5c296e85a7c01360820|https://fossil.wanderinghorse.net/r/jaccwabyt/info/c5c296e85a7c01360820]. -D 2025-01-11T09:02:55.088 +C Fix\sharmless\sscan-build\swarnings. +D 2025-01-11T13:59:42.950 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -728,7 +728,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c e90410e5d4c0217dfddc4184a81e38ec4903c25d4ec0f201060a0e54e7c2099f F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c 3329173aacc6c37da3971b6253827799b32e301673be00126df8271bf018e15f +F src/expr.c bc600813682b849ef180fffd26fbb36397016366ac1246aa3d3d58f9a31f88f8 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 89b733a5f513c4bc06b7271384363d5693d62782de8295bc87b97d79862c9714 @@ -779,7 +779,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 83e88fbb36f89b6703b348777491619554f0fd6f917c9fdf51e4c2e9cda6c04e -F src/shell.c.in a9c0f8066eac40f1f97b8554bb0462b07263d5c02380cc1ef74734c5d1c67637 +F src/shell.c.in d6d1901fda17a7ab5443e6a6fbc3ca523c01c85058cf0d3ce2e2e5c2e898915e F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cef8e88bedf01dc47012ef1cb878b22117c9966e615edf5a69704486f9cfa56c -R 2966a1ed8608823769a5c4d3eb2bc028 -U stephan -Z 02b31671f60b5e3785eaa517886d85b1 +P 99917a5bb04b5ad6ace95baf86d91e6ce098f9d3001de1a29d3d0b0b817acdce +R 4a4f027b9e85dc62acdf46f689ae54cd +U drh +Z a5dd0b9f1006749b9a2e9efcfdf75968 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a540ad80d9..034199fd7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99917a5bb04b5ad6ace95baf86d91e6ce098f9d3001de1a29d3d0b0b817acdce +b93af6feb7c0c3af30a47810a7c0e77ce41c386fac164c64bb5871a6c153db7e diff --git a/src/expr.c b/src/expr.c index 86c966683c..8c118d0779 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3285,6 +3285,7 @@ int sqlite3FindInIndex( if( aiMap ) aiMap[i] = j; } + assert( nExproutCount = 2; }else{ From 4b5e8c926ac48d83f70ae9fc1db8a6a9f6b73454 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 11 Jan 2025 14:43:47 +0000 Subject: [PATCH 514/522] Better job at suppressing harmless scan-build warnings. This time testing and working. FossilOrigin-Name: c847973947de67579fab78a65ecfc90bf59fd5db0b7fa7a9c1abb1fc92213d01 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- src/shell.c.in | 4 +++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6f043074b9..cf63954c97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\sscan-build\swarnings. -D 2025-01-11T13:59:42.950 +C Better\sjob\sat\ssuppressing\sharmless\sscan-build\swarnings.\s\sThis\stime\stesting\nand\sworking. +D 2025-01-11T14:43:47.901 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -728,7 +728,7 @@ F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a F src/dbpage.c e90410e5d4c0217dfddc4184a81e38ec4903c25d4ec0f201060a0e54e7c2099f F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c bc600813682b849ef180fffd26fbb36397016366ac1246aa3d3d58f9a31f88f8 +F src/expr.c 30a407765d4e4b592f9f958085fb4e8336e54fa46a70ade7f5a67111bc191563 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 89b733a5f513c4bc06b7271384363d5693d62782de8295bc87b97d79862c9714 @@ -779,7 +779,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 83e88fbb36f89b6703b348777491619554f0fd6f917c9fdf51e4c2e9cda6c04e -F src/shell.c.in d6d1901fda17a7ab5443e6a6fbc3ca523c01c85058cf0d3ce2e2e5c2e898915e +F src/shell.c.in aca84434e73942aaaefdba3790fd147c75f73f7c6908959cf2d5cd6a53e8ee76 F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 99917a5bb04b5ad6ace95baf86d91e6ce098f9d3001de1a29d3d0b0b817acdce -R 4a4f027b9e85dc62acdf46f689ae54cd +P b93af6feb7c0c3af30a47810a7c0e77ce41c386fac164c64bb5871a6c153db7e +R ae54af26d9f89a39f6b222b17c0e4b08 U drh -Z a5dd0b9f1006749b9a2e9efcfdf75968 +Z 623dab57f8e4a45135026255ca9de26f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 034199fd7d..16c5fbe1c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b93af6feb7c0c3af30a47810a7c0e77ce41c386fac164c64bb5871a6c153db7e +c847973947de67579fab78a65ecfc90bf59fd5db0b7fa7a9c1abb1fc92213d01 diff --git a/src/expr.c b/src/expr.c index 8c118d0779..ca5b9092e7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3285,7 +3285,7 @@ int sqlite3FindInIndex( if( aiMap ) aiMap[i] = j; } - assert( nExpr0 && nExpr Date: Sat, 11 Jan 2025 16:28:41 +0000 Subject: [PATCH 515/522] Fix harmless "implicit fall through" warnings that suddenly appeared when I upgraded to gcc-13. FossilOrigin-Name: 3e2875dac27de1525d9c78f38ac5f1fc12fec7e1b43dbdf47798b128fae49084 --- ext/misc/base64.c | 9 ++++++--- ext/misc/base85.c | 4 ++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 6 +++--- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/ext/misc/base64.c b/ext/misc/base64.c index bc7a976abc..b8147707f9 100644 --- a/ext/misc/base64.c +++ b/ext/misc/base64.c @@ -175,15 +175,15 @@ static u8* fromBase64( char *pIn, int ncIn, u8 *pOut ){ case ND: /* Treat dark non-digits as pad, but they terminate decode too. */ ncIn = 0; - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ case WS: /* Treat whitespace as pad and terminate this group.*/ nti = nac; - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ case PC: bdp = 0; --nbo; - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ default: /* bdp is the digit value. */ qv = qv<<6 | bdp; break; @@ -192,10 +192,13 @@ static u8* fromBase64( char *pIn, int ncIn, u8 *pOut ){ switch( nbo ){ case 3: pOut[2] = (qv) & 0xff; + deliberate_fall_through; /* FALLTHRU */ case 2: pOut[1] = (qv>>8) & 0xff; + deliberate_fall_through; /* FALLTHRU */ case 1: pOut[0] = (qv>>16) & 0xff; + deliberate_fall_through; /* FALLTHRU */ } pOut += nbo; } diff --git a/ext/misc/base85.c b/ext/misc/base85.c index e7ef0a04c9..eaf1732c46 100644 --- a/ext/misc/base85.c +++ b/ext/misc/base85.c @@ -232,12 +232,16 @@ static u8* fromBase85( char *pIn, int ncIn, u8 *pOut ){ switch( nbo ){ case 4: *pOut++ = (qv >> 24)&0xff; + /* FALLTHRU */ case 3: *pOut++ = (qv >> 16)&0xff; + /* FALLTHRU */ case 2: *pOut++ = (qv >> 8)&0xff; + /* FALLTHRU */ case 1: *pOut++ = qv&0xff; + /* FALLTHRU */ case 0: break; } diff --git a/manifest b/manifest index cf63954c97..ba912442f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Better\sjob\sat\ssuppressing\sharmless\sscan-build\swarnings.\s\sThis\stime\stesting\nand\sworking. -D 2025-01-11T14:43:47.901 +C Fix\sharmless\s"implicit\sfall\sthrough"\swarnings\sthat\ssuddenly\sappeared\swhen\nI\supgraded\sto\sgcc-13. +D 2025-01-11T16:28:41.860 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -400,8 +400,8 @@ F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f23 F ext/misc/amatch.c 5001711cbecdd57b288cb613386789f3034e5beb58fbe0c79f2b3d643ffd4e03 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824 -F ext/misc/base64.c a71b131e50300c654a66c469a25b62874481f3d1cb3beb56aca9a68edd812e0d -F ext/misc/base85.c 073054111988db593ef5fdb87ab8c459df1ea0c3aaaddf0f5bfa3d72b7e6280a +F ext/misc/base64.c 95abb0547cb1799d9851f3357c8d7fc3c09a95c63c8772aa3acd5f65f12050f6 +F ext/misc/base85.c a70c885c5c9350261ea6e7b166038eab21a09cf4fceae856ce41fae9c2213b60 F ext/misc/basexx.c 89ad6b76558efbceb627afd5e2ef1d84b2e96d9aaf9b7ecb20e3d00b51be6fcf F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a F ext/misc/btreeinfo.c cb952620eedf5c0b7625b678f0f08e54d2ec0011d4e50efda5ebdc97f3df7d04 @@ -779,7 +779,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 83e88fbb36f89b6703b348777491619554f0fd6f917c9fdf51e4c2e9cda6c04e -F src/shell.c.in aca84434e73942aaaefdba3790fd147c75f73f7c6908959cf2d5cd6a53e8ee76 +F src/shell.c.in beb370609906092a6810fcd9ea76737be2c91694445061c2eb05c4c0a3753de4 F src/sqlite.h.in 6afbcaae44140216704a6c82e4c4ea4118c46d5f6573d6c5fa4fc901ed9d369e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b93af6feb7c0c3af30a47810a7c0e77ce41c386fac164c64bb5871a6c153db7e -R ae54af26d9f89a39f6b222b17c0e4b08 +P c847973947de67579fab78a65ecfc90bf59fd5db0b7fa7a9c1abb1fc92213d01 +R 21473fba427f7d039b2fd83376887456 U drh -Z 623dab57f8e4a45135026255ca9de26f +Z b74c42c31ff873968b8ed05fb8e82534 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 16c5fbe1c6..899a15f66c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c847973947de67579fab78a65ecfc90bf59fd5db0b7fa7a9c1abb1fc92213d01 +3e2875dac27de1525d9c78f38ac5f1fc12fec7e1b43dbdf47798b128fae49084 diff --git a/src/shell.c.in b/src/shell.c.in index db0604eb18..17054a961c 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7337,7 +7337,7 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){ break; case AR_SWITCH_APPEND: pAr->bAppend = 1; - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ case AR_SWITCH_FILE: pAr->zFile = zArg; break; @@ -12029,7 +12029,7 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, break; case '[': cin = ']'; - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ case '`': case '\'': case '"': cWait = cin; qss = QSS_HasDark | cWait; @@ -12064,7 +12064,7 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, ++zLine; continue; } - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ case ']': CONTINUE_PROMPT_AWAITC(pst, 0); qss = QSS_SETV(qss, 0); From 43afab28a09659f7869661a8e56f21865af2414d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 13 Jan 2025 11:28:34 +0000 Subject: [PATCH 516/522] GCC 13 has become more quite pedantic about the signature of functions matching the type of pointers through which the functions are called. Make adjustments to extension functions and test procedures to work around this. No changes to the core. FossilOrigin-Name: ed83b79100b4345235aec990303c4526874f0c2f8701160c4639a80633ebaf70 --- ext/misc/closure.c | 7 ++++++- ext/misc/regexp.c | 3 ++- ext/session/test_session.c | 3 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/test1.c | 12 ++++++++---- src/test_intarray.c | 3 ++- src/test_malloc.c | 6 ++++-- 8 files changed, 34 insertions(+), 24 deletions(-) diff --git a/ext/misc/closure.c b/ext/misc/closure.c index 79a5a21d1e..267ae1c424 100644 --- a/ext/misc/closure.c +++ b/ext/misc/closure.c @@ -588,12 +588,17 @@ static int closureOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ return SQLITE_OK; } +/* +** Wrapper around sqlite3_free +*/ +static void closureMemFree(closure_avl *p){ sqlite3_free(p); } + /* ** Free up all the memory allocated by a cursor. Set it rLimit to 0 ** to indicate that it is at EOF. */ static void closureClearCursor(closure_cursor *pCur){ - closureAvlDestroy(pCur->pClosure, (void(*)(closure_avl*))sqlite3_free); + closureAvlDestroy(pCur->pClosure, closureMemFree); sqlite3_free(pCur->zTableName); sqlite3_free(pCur->zIdColumn); sqlite3_free(pCur->zParentColumn); diff --git a/ext/misc/regexp.c b/ext/misc/regexp.c index a50008ca35..71c7ea4c22 100644 --- a/ext/misc/regexp.c +++ b/ext/misc/regexp.c @@ -656,7 +656,8 @@ static const char *re_subcompile_string(ReCompiled *p){ ** regular expression. Applications should invoke this routine once ** for every call to re_compile() to avoid memory leaks. */ -static void re_free(ReCompiled *pRe){ +static void re_free(void *p){ + ReCompiled *pRe = (ReCompiled*)p; if( pRe ){ sqlite3_free(pRe->aOp); sqlite3_free(pRe->aArg); diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 29aeadf537..41d6aaa109 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -719,7 +719,6 @@ static int replace_handler( const char *zTab; /* Name of table conflict is on */ int nCol; /* Number of columns in table zTab */ int i; - int x = 0; sqlite3changeset_op(pIter, &zTab, &nCol, &op, 0); @@ -728,7 +727,6 @@ static int replace_handler( sqlite3_value *pVal; sqlite3changeset_old(pIter, i, &pVal); sqlite3_value_text16(pVal); - x++; } } @@ -737,7 +735,6 @@ static int replace_handler( sqlite3_value *pVal; sqlite3changeset_new(pIter, i, &pVal); sqlite3_value_text16(pVal); - x++; } } diff --git a/manifest b/manifest index ba912442f4..d079f815d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\s"implicit\sfall\sthrough"\swarnings\sthat\ssuddenly\sappeared\swhen\nI\supgraded\sto\sgcc-13. -D 2025-01-11T16:28:41.860 +C GCC\s13\shas\sbecome\smore\squite\spedantic\sabout\sthe\ssignature\sof\sfunctions\smatching\sthe\ntype\sof\spointers\sthrough\swhich\sthe\sfunctions\sare\scalled.\s\sMake\sadjustments\sto\nextension\sfunctions\sand\stest\sprocedures\sto\swork\saround\sthis.\s\sNo\schanges\sto\sthe\ncore. +D 2025-01-13T11:28:34.810 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -408,7 +408,7 @@ F ext/misc/btreeinfo.c cb952620eedf5c0b7625b678f0f08e54d2ec0011d4e50efda5ebdc97f F ext/misc/carray.c 34fac63770971611c5285de0a9f0ac67d504eaf66be891f637add9290f1c76a5 F ext/misc/carray.h 503209952ccf2431c7fd899ebb92bf46bf7635b38aace42ec8aa1b8d7b6e98a5 F ext/misc/cksumvfs.c 3a7931dd30667be6348af919f3f9e6188dfd7646b42af8e399a499b327f5bd63 -F ext/misc/closure.c 0e04f52d93e678dd6f950f195f365992edf3c380df246f3d80425cba4c13891e +F ext/misc/closure.c 87e0967772e0087e709887ce7ca9cf13aa32d2096e33b5d3382c8b8d477c6cb1 F ext/misc/completion.c cb978c88d5577821323617a8ea775ce1b920e02dcdb593858f02044a4d008eea F ext/misc/compress.c 2c79a74330e0e0ba6cb3f7397f8ba5af12d46377ef5d3ee075e12dd8a6ed57f0 F ext/misc/csv.c 575c2c05fba0a451586a4d42c2c81e711780c41e797126f198d8d9e0a308dcdb @@ -432,7 +432,7 @@ F ext/misc/percentile.c 82531c62cd015b9cdca95ad6bb10c3a907ceb570d21ebd4fb7d634c8 F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6 F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed -F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab84070963624047db +F ext/misc/regexp.c 388e7f237307c7dfbfb8dde44e097946f6c437801d63f0d7ad63f3320d4e61cc F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 @@ -616,7 +616,7 @@ F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc F ext/session/sqlite3session.c d6f5e3e83b9b0bbc4a8db4837284f0ecc6af5321d4c8e7136380b456b278c46a F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b -F ext/session/test_session.c aa29abdcc9011ac02f4fa38e8ede226106eaeee7c3ea7d8b2b999a124e0c368c +F ext/session/test_session.c 12e0a2c15fd60f92da4bb29c697c9177ff0c0dbcdc5129a54c47e999f147937a F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c F ext/wasm/GNUmakefile 311aa0d5edc7006409962cc77cc26560d92f9be69c2c4302e8bbc68189fd02db F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 @@ -789,7 +789,7 @@ F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c c6b9d3a0b1100e1e028460c418c41ca180dac5958e96bef79f6799b552522a37 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 -F src/test1.c 07c9b523f90b96f6e9a701476602fa1f82075da19955823316b3fe13eaaa52cc +F src/test1.c 9d2da51b4c33633e7370e4068af6d16d2c52b22a5810ec012ac32e77f8397b64 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d @@ -810,11 +810,11 @@ F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5 F src/test_func.c 858d4dddb7acf88222ebcba7cffb585f6dde83e4a15b838c0d05ccdf8d5219b9 F src/test_hexio.c 7449504e4bde876ba91b202617a9228c7c8c2e7bd8b957302f3803ac0e9e353c F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e -F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5 +F src/test_intarray.c 3fcf8ca7bb5c8776ea83f6aa9b66f8df0d1f37a99207b0097c8486f9c15cedbf F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293 F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f4e287 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c a0295e022103b14a1bc5e0660cc2af7fbec05e0d029098782e326e50612e69d9 +F src/test_malloc.c 4954125ee89aa51d9f641d5cb272cc93ca4cb03dcc7c9c941d70210354c69567 F src/test_md5.c 811a45330c9391933360f998156a8907ee29909c828ab83ac05d329942cbea8f F src/test_multiplex.c b99d7f43ec859e6b93a40aaa5455420b3ad133053cce3db739498d29ea30735f F src/test_multiplex.h f0ff5b6f4462bfd46dac165d6375b9530d08089b7bcbe75e88e0926110db5363 @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c847973947de67579fab78a65ecfc90bf59fd5db0b7fa7a9c1abb1fc92213d01 -R 21473fba427f7d039b2fd83376887456 +P 3e2875dac27de1525d9c78f38ac5f1fc12fec7e1b43dbdf47798b128fae49084 +R 6e0293de1d493e0b13b460e55a82a4db U drh -Z b74c42c31ff873968b8ed05fb8e82534 +Z 4c81104bb07f42df2245a2e0f81e374f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 899a15f66c..d415ffab2c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e2875dac27de1525d9c78f38ac5f1fc12fec7e1b43dbdf47798b128fae49084 +ed83b79100b4345235aec990303c4526874f0c2f8701160c4639a80633ebaf70 diff --git a/src/test1.c b/src/test1.c index 4212c73232..c204335dcc 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5681,9 +5681,11 @@ static int SQLITE_TCLAPI test_stmt_utf8( sqlite3_stmt *pStmt; int col; const char *(*xFunc)(sqlite3_stmt*, int); + const unsigned char *(*xFuncU)(sqlite3_stmt*, int); const char *zRet; xFunc = (const char *(*)(sqlite3_stmt*, int))clientData; + xFuncU = (const unsigned char*(*)(sqlite3_stmt*,int))xFunc; if( objc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " STMT column", 0); @@ -5692,7 +5694,11 @@ static int SQLITE_TCLAPI test_stmt_utf8( if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; - zRet = xFunc(pStmt, col); + if( xFunc==sqlite3_column_name || xFunc==sqlite3_column_decltype ){ + zRet = xFunc(pStmt, col); + }else{ + zRet = (const char*)xFuncU(pStmt, col); + } if( zRet ){ Tcl_SetResult(interp, (char *)zRet, 0); } @@ -7562,7 +7568,7 @@ static struct LogCallback { Tcl_Interp *pInterp; Tcl_Obj *pObj; } logcallback = {0, 0}; -static void xLogcallback(void *unused, int err, char *zMsg){ +static void xLogcallback(void *unused, int err, const char *zMsg){ Tcl_Obj *pNew = Tcl_DuplicateObj(logcallback.pObj); Tcl_IncrRefCount(pNew); Tcl_ListObjAppendElement( @@ -8601,7 +8607,6 @@ static int SQLITE_TCLAPI test_decode_hexdb( const char *zIn = 0; unsigned char *a = 0; int n = 0; - int lineno = 0; int i, iNext; int iOffset = 0; int j, k; @@ -8613,7 +8618,6 @@ static int SQLITE_TCLAPI test_decode_hexdb( } zIn = Tcl_GetString(objv[1]); for(i=0; zIn[i]; i=iNext){ - lineno++; for(iNext=i; zIn[iNext] && zIn[iNext]!='\n'; iNext++){} if( zIn[iNext]=='\n' ) iNext++; while( zIn[i]==' ' || zIn[i]=='\t' ){ i++; } diff --git a/src/test_intarray.c b/src/test_intarray.c index 16c1df2e9c..9e4629467e 100644 --- a/src/test_intarray.c +++ b/src/test_intarray.c @@ -61,7 +61,8 @@ struct intarray_cursor { /* ** Free an sqlite3_intarray object. */ -static void intarrayFree(sqlite3_intarray *p){ +static void intarrayFree(void *pX){ + sqlite3_intarray *p = (sqlite3_intarray*)pX; if( p->xFree ){ p->xFree(p->a); } diff --git a/src/test_malloc.c b/src/test_malloc.c index 21faa0d291..8d6c4fa505 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -41,8 +41,9 @@ static struct MemFault { ** fire on any simulated malloc() failure. */ static void sqlite3Fault(void){ - static int cnt = 0; + static u64 cnt = 0; cnt++; + if( cnt>((u64)1<<63) ) abort(); } /* @@ -52,8 +53,9 @@ static void sqlite3Fault(void){ ** This routine only runs on the first such failure. */ static void sqlite3FirstFault(void){ - static int cnt2 = 0; + static u64 cnt2 = 0; cnt2++; + if( cnt2>((u64)1<<63) ) abort(); } /* From f1747f93e0f8df7984b595b91649c7789217fe59 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 13 Jan 2025 13:32:56 +0000 Subject: [PATCH 517/522] Remove a stray tab character from a comment. FossilOrigin-Name: 315079b150b47e013e2cde4985bc39d24e0f6f6c6e60f9383fb8ea4ea897c67a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d079f815d5..dfaaeb02a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C GCC\s13\shas\sbecome\smore\squite\spedantic\sabout\sthe\ssignature\sof\sfunctions\smatching\sthe\ntype\sof\spointers\sthrough\swhich\sthe\sfunctions\sare\scalled.\s\sMake\sadjustments\sto\nextension\sfunctions\sand\stest\sprocedures\sto\swork\saround\sthis.\s\sNo\schanges\sto\sthe\ncore. -D 2025-01-13T11:28:34.810 +C Remove\sa\sstray\stab\scharacter\sfrom\sa\scomment. +D 2025-01-13T13:32:56.652 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -862,7 +862,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4e6181d8780ab0af2e1388d0754cbe6f2f04593d2b1ab6c41699a89942fd8997 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 -F src/where.c d519bc93b4a05928f10ba4925b1afc77cbd71c1b1b5148583ab4868925c639fb +F src/where.c 604f17baed46f4997ffe79f25c07c4b51a4165a5938cc27fe165c7e1ca485d11 F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca F src/wherecode.c 0c3d3199a2b769a5e2bb70feb5003dc85b3d86842ecaf903a47f2b4205ca5dab F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f @@ -2205,8 +2205,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3e2875dac27de1525d9c78f38ac5f1fc12fec7e1b43dbdf47798b128fae49084 -R 6e0293de1d493e0b13b460e55a82a4db +P ed83b79100b4345235aec990303c4526874f0c2f8701160c4639a80633ebaf70 +R 0ed0cfcc7f2bc831da5d62a3490571ed U drh -Z 4c81104bb07f42df2245a2e0f81e374f +Z 2b06b025e298002c2c77b6953d35e566 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d415ffab2c..aeb488e3a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed83b79100b4345235aec990303c4526874f0c2f8701160c4639a80633ebaf70 +315079b150b47e013e2cde4985bc39d24e0f6f6c6e60f9383fb8ea4ea897c67a diff --git a/src/where.c b/src/where.c index 4325374bce..20b1c38c0c 100644 --- a/src/where.c +++ b/src/where.c @@ -862,7 +862,7 @@ static int constraintCompatibleWithOuterJoin( ** 3. If no disqualifying conditions above are found, return true. ** ** 2025-01-03: I experimented with a new rule that returns false if the -** the datatype of the column is "BOOLEAN". This did not improve +** the datatype of the column is "BOOLEAN". This did not improve ** performance on any queries at hand, but it did burn CPU cycles, so the ** idea was not committed. */ From 942c9587698715734715242737dba07ef296b0ef Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 14 Jan 2025 11:05:00 +0000 Subject: [PATCH 518/522] Version 3.48.0 FossilOrigin-Name: d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e84010 --- manifest | 11 +++++++---- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/manifest b/manifest index dfaaeb02a3..809b43bc20 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sstray\stab\scharacter\sfrom\sa\scomment. -D 2025-01-13T13:32:56.652 +C Version\s3.48.0 +D 2025-01-14T11:05:00.186 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -2205,8 +2205,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ed83b79100b4345235aec990303c4526874f0c2f8701160c4639a80633ebaf70 +P 315079b150b47e013e2cde4985bc39d24e0f6f6c6e60f9383fb8ea4ea897c67a R 0ed0cfcc7f2bc831da5d62a3490571ed +T +sym-major-relase * +T +sym-relase * +T +sym-version-3.48.0 * U drh -Z 2b06b025e298002c2c77b6953d35e566 +Z cc77aac977f98c5521d75f4212754ff8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index aeb488e3a7..582262f689 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -315079b150b47e013e2cde4985bc39d24e0f6f6c6e60f9383fb8ea4ea897c67a +d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e84010 From 097ec793e43cc28c22102c27c128e2bb67438512 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 28 May 2026 12:51:56 +0300 Subject: [PATCH 519/522] libsql-ffi: Bump bundled SQLite3MultipleCiphers from 1.8.1 to 2.0.2 The vendored copy at libsql-ffi/bundled/SQLite3MultipleCiphers/ was at upstream v1.8.1, which is based on SQLite ~3.44 and still ships the user- authentication extension. After the 3.48.0 merge (bcd6013d8a) the SQLite amalgamation no longer defines sqlite3_userauth / UAUTH_* (SQLite 3.48.0 removed the extension entirely), so sqlite3mc's userauth.c stopped compiling against it. This refreshes the vendored copy to upstream v2.0.2 (de01ff8 "Prepare release of version 2.0.2"), which is the sqlite3mc release that targets SQLite 3.48.0. The libsql-local patches are reapplied on top. == Broad upstream changelog 1.8.1 -> 2.0.2 == * Remove user authentication extension (d15fcab) - both userauth.c and sqlite3userauth.h deleted; sqlite3mc.{c,h} now unconditionally `#undef SQLITE_USER_AUTHENTICATION`; CMakeLists.txt drops the SQLITE_USER_AUTHENTICATION option and the userauth public header. This is the change that unblocks the 3.48.0 amalgamation. * Add AEGIS cipher (src/aegis/ tree, src/cipher_aegis.c, AEGIS added to the CODEC_TYPE enum in CMakeLists.txt). * Vendor argon2 in-tree (src/argon2/). * Android compile flags: -march=armv8-a+crypto for arm64-v8a, -mvaes for x86_64. * Drop SQLITE3MC_USE_RANDOM_FILL_MEMORY option. * Adjust includes / preprocessor symbols to be amalgamation-friendly (3739865, b2253ef, c95b4e8). * AES hardware detection adjustments (398558f). * Codec initialization fix (d9767c6, the 2.0.2-final commit). * General cleanup of AEGIS / ARM / AltiVec variants (51f8e00, 5577826). * Bumped cmake_minimum_required to 3.24.0 in the upstream file; libsql patches it back to 3.18.0 (kept for broader CI compatibility). == Reapplied libsql-local patches == src/cipher_config.c sqlite3mcFileControlPragma -> libsql_extra_pragma (different signature, no SQLITE_NOTFOUND fallthrough check; called directly from libsql's patched sqlite3.c). src/cipher_wxaes256.c Added libsql_generate_aes256_key() helper (padded-password SHA-256 iteration). src/codec_algos.c Added libsql_generate_initial_vector() wrapper. src/codecext.c Forward-decl libsql_db_has_codec(); after sqlite3mcSetIsEncrypted(), update cached db->aDb[].hasCodec / pPager->hasCodec. src/sqlite3mc.c #include "sqlite3.c" instead of upstream's "sqlite3patched.c" (libsql uses the unpatched amalgamation directly). src/sqlite3mc_vfs.c sqlite3mcPagerCodec -> libsql_pager_codec_impl (takes libsql_pghdr*, returns int rc, writes data via out-param). sqlite3mcPagerHasCodec -> libsql_db_has_codec (takes sqlite3_vfs* + zFilename instead of PagerMC*; called at connection-open time so the hasCodec check can be cached). CMakeLists.txt cmake_minimum_required 3.24 -> 3.18. Add LIBSQL_ENABLE_WASM_RUNTIME option. Add libsql-specific compile defs in SQLITE3MC_BASE_DEFINITIONS: LIBSQL_ENABLE_WASM_RUNTIME, LIBSQL_EXTRA_PRAGMAS, LIBSQL_CUSTOM_PAGER_CODEC, LIBSQL_ENCRYPTION, SQLITE_ENABLE_{DBSTAT,DBPAGE,STMT}VTAB=1, SQLITE_DEFAULT_FOREIGN_KEYS=1, HAVE_CIPHER_AES_256_CBC=1 with all other ciphers forced =0. Skip -msse4.2 -maes on aarch64/arm64/armv7/arm (Linux/Darwin block, GNU else-branch, and an added Clang block that also excludes CMAKE_ANDROID_ARCH_ABI arm variants). == Out of scope (separate commit) == The regenerated SQLite amalgamation (libsql-ffi/bundled/src/sqlite3.{c,h}, libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.{c,h}) and the regenerated bindgen files (libsql-ffi/bundled/bindings/{bindgen, session_bindgen}.rs) will be committed separately as the "update bundled SQLite to 3.48.0" step. With this commit in place, `./scripts/update-sqlite-bundle.sh` and `cargo build --features multiple-ciphers` succeed. --- .../SQLite3MultipleCiphers/CHANGELOG.md | 124 +- .../SQLite3MultipleCiphers/CMakeLists.txt | 30 +- .../bundled/SQLite3MultipleCiphers/LICENSE | 2 +- .../SQLite3MultipleCiphers/Makefile.am | 21 +- .../SQLite3MultipleCiphers/configure.ac | 21 +- .../SQLite3MultipleCiphers/premake5.lua | 36 +- .../bundled/SQLite3MultipleCiphers/readme.md | 6 +- .../src/aegis/aegis128l/aegis128l.c | 299 + .../src/aegis/aegis128l/aegis128l_aesni.c | 110 + .../src/aegis/aegis128l/aegis128l_aesni.h | 16 + .../src/aegis/aegis128l/aegis128l_altivec.c | 106 + .../src/aegis/aegis128l/aegis128l_altivec.h | 16 + .../src/aegis/aegis128l/aegis128l_armcrypto.c | 120 + .../src/aegis/aegis128l/aegis128l_armcrypto.h | 16 + .../src/aegis/aegis128l/aegis128l_common.h | 726 + .../src/aegis/aegis128l/aegis128l_soft.c | 96 + .../src/aegis/aegis128l/aegis128l_soft.h | 16 + .../src/aegis/aegis128l/implementations.h | 50 + .../src/aegis/aegis128x2/aegis128x2.c | 303 + .../src/aegis/aegis128x2/aegis128x2_aesni.c | 116 + .../src/aegis/aegis128x2/aegis128x2_aesni.h | 16 + .../src/aegis/aegis128x2/aegis128x2_altivec.c | 111 + .../src/aegis/aegis128x2/aegis128x2_altivec.h | 16 + .../aegis/aegis128x2/aegis128x2_armcrypto.c | 125 + .../aegis/aegis128x2/aegis128x2_armcrypto.h | 16 + .../src/aegis/aegis128x2/aegis128x2_avx2.c | 113 + .../src/aegis/aegis128x2/aegis128x2_avx2.h | 18 + .../src/aegis/aegis128x2/aegis128x2_common.h | 833 + .../src/aegis/aegis128x2/aegis128x2_soft.c | 100 + .../src/aegis/aegis128x2/aegis128x2_soft.h | 16 + .../src/aegis/aegis128x2/implementations.h | 50 + .../src/aegis/aegis128x4/aegis128x4.c | 309 + .../src/aegis/aegis128x4/aegis128x4_aesni.c | 125 + .../src/aegis/aegis128x4/aegis128x4_aesni.h | 16 + .../src/aegis/aegis128x4/aegis128x4_altivec.c | 119 + .../src/aegis/aegis128x4/aegis128x4_altivec.h | 16 + .../aegis/aegis128x4/aegis128x4_armcrypto.c | 133 + .../aegis/aegis128x4/aegis128x4_armcrypto.h | 16 + .../src/aegis/aegis128x4/aegis128x4_avx2.c | 119 + .../src/aegis/aegis128x4/aegis128x4_avx2.h | 18 + .../src/aegis/aegis128x4/aegis128x4_avx512.c | 119 + .../src/aegis/aegis128x4/aegis128x4_avx512.h | 18 + .../src/aegis/aegis128x4/aegis128x4_common.h | 847 + .../src/aegis/aegis128x4/aegis128x4_soft.c | 108 + .../src/aegis/aegis128x4/aegis128x4_soft.h | 16 + .../src/aegis/aegis128x4/implementations.h | 50 + .../src/aegis/aegis256/aegis256.c | 296 + .../src/aegis/aegis256/aegis256_aesni.c | 106 + .../src/aegis/aegis256/aegis256_aesni.h | 16 + .../src/aegis/aegis256/aegis256_altivec.c | 104 + .../src/aegis/aegis256/aegis256_altivec.h | 16 + .../src/aegis/aegis256/aegis256_armcrypto.c | 118 + .../src/aegis/aegis256/aegis256_armcrypto.h | 16 + .../src/aegis/aegis256/aegis256_common.h | 712 + .../src/aegis/aegis256/aegis256_soft.c | 91 + .../src/aegis/aegis256/aegis256_soft.h | 16 + .../src/aegis/aegis256/implementations.h | 50 + .../src/aegis/aegis256x2/aegis256x2.c | 303 + .../src/aegis/aegis256x2/aegis256x2_aesni.c | 111 + .../src/aegis/aegis256x2/aegis256x2_aesni.h | 16 + .../src/aegis/aegis256x2/aegis256x2_altivec.c | 110 + .../src/aegis/aegis256x2/aegis256x2_altivec.h | 16 + .../aegis/aegis256x2/aegis256x2_armcrypto.c | 123 + .../aegis/aegis256x2/aegis256x2_armcrypto.h | 16 + .../src/aegis/aegis256x2/aegis256x2_avx2.c | 108 + .../src/aegis/aegis256x2/aegis256x2_avx2.h | 18 + .../src/aegis/aegis256x2/aegis256x2_common.h | 829 + .../src/aegis/aegis256x2/aegis256x2_soft.c | 95 + .../src/aegis/aegis256x2/aegis256x2_soft.h | 16 + .../src/aegis/aegis256x2/implementations.h | 50 + .../src/aegis/aegis256x4/aegis256x4.c | 308 + .../src/aegis/aegis256x4/aegis256x4_aesni.c | 120 + .../src/aegis/aegis256x4/aegis256x4_aesni.h | 16 + .../src/aegis/aegis256x4/aegis256x4_altivec.c | 117 + .../src/aegis/aegis256x4/aegis256x4_altivec.h | 16 + .../aegis/aegis256x4/aegis256x4_armcrypto.c | 131 + .../aegis/aegis256x4/aegis256x4_armcrypto.h | 16 + .../src/aegis/aegis256x4/aegis256x4_avx2.c | 114 + .../src/aegis/aegis256x4/aegis256x4_avx2.h | 18 + .../src/aegis/aegis256x4/aegis256x4_avx512.c | 114 + .../src/aegis/aegis256x4/aegis256x4_avx512.h | 18 + .../src/aegis/aegis256x4/aegis256x4_common.h | 848 + .../src/aegis/aegis256x4/aegis256x4_soft.c | 104 + .../src/aegis/aegis256x4/aegis256x4_soft.h | 16 + .../src/aegis/aegis256x4/implementations.h | 50 + .../src/aegis/common/aeshardware.h | 98 + .../src/aegis/common/common.c | 93 + .../src/aegis/common/common.h | 161 + .../src/aegis/common/cpu.c | 351 + .../src/aegis/common/cpu.h | 40 + .../src/aegis/common/func_names_define.h | 36 + .../src/aegis/common/func_names_undefine.h | 40 + .../src/aegis/common/func_table.h | 21 + .../src/aegis/common/softaes.c | 347 + .../src/aegis/common/softaes.h | 73 + .../src/aegis/common/type_names_undefine.h | 21 + .../src/aegis/include/aegis.h | 80 + .../src/aegis/include/aegis128l.h | 371 + .../src/aegis/include/aegis128x2.h | 370 + .../src/aegis/include/aegis128x4.h | 371 + .../src/aegis/include/aegis256.h | 370 + .../src/aegis/include/aegis256x2.h | 370 + .../src/aegis/include/aegis256x4.h | 370 + .../src/aegis/libaegis.c | 86 + .../SQLite3MultipleCiphers/src/aes_hardware.c | 48 +- .../src/argon2/include/argon2.h | 445 + .../src/argon2/libargon2.c | 26 + .../src/argon2/src/argon2.c | 452 + .../src/argon2/src/bench.c | 111 + .../src/argon2/src/blake2/blake2-impl.h | 157 + .../src/argon2/src/blake2/blake2.h | 89 + .../src/argon2/src/blake2/blake2b.c | 397 + .../src/argon2/src/blake2/blamka-round-opt.h | 471 + .../src/argon2/src/blake2/blamka-round-ref.h | 56 + .../src/argon2/src/core.c | 667 + .../src/argon2/src/core.h | 243 + .../src/argon2/src/encoding.c | 468 + .../src/argon2/src/encoding.h | 61 + .../src/argon2/src/genkat.c | 213 + .../src/argon2/src/genkat.h | 51 + .../src/argon2/src/opt.c | 283 + .../src/argon2/src/ref.c | 195 + .../src/argon2/src/run.c | 337 + .../src/argon2/src/test.c | 289 + .../src/argon2/src/thread.c | 60 + .../src/argon2/src/thread.h | 70 + .../SQLite3MultipleCiphers/src/ascon/aead.c | 4 +- .../src/ascon/crypto_aead.h | 6 + .../src/ascon/crypto_hash.h | 5 + .../src/ascon/crypto_pbkdf2.h | 5 + .../SQLite3MultipleCiphers/src/ascon/hash.c | 1 + .../SQLite3MultipleCiphers/src/ascon/pbkdf2.c | 13 +- .../SQLite3MultipleCiphers/src/ascon/prolog.h | 2 +- .../SQLite3MultipleCiphers/src/ascon/word.h | 14 +- .../SQLite3MultipleCiphers/src/carray.c | 28 +- .../src/chacha20poly1305.c | 6 +- .../SQLite3MultipleCiphers/src/cipher_aegis.c | 507 + .../SQLite3MultipleCiphers/src/cipher_ascon.c | 11 +- .../src/cipher_chacha20.c | 14 +- .../src/cipher_common.c | 67 +- .../src/cipher_common.h | 4 + .../src/cipher_config.c | 108 +- .../src/cipher_config.h | 2 +- .../src/cipher_sds_rc4.c | 4 +- .../src/cipher_sqlcipher.c | 68 +- .../src/cipher_wxaes128.c | 4 +- .../src/cipher_wxaes256.c | 4 +- .../SQLite3MultipleCiphers/src/codec_algos.c | 4 +- .../SQLite3MultipleCiphers/src/codecext.c | 83 +- .../SQLite3MultipleCiphers/src/compress.c | 12 +- .../bundled/SQLite3MultipleCiphers/src/csv.c | 26 +- .../src/extensionfunctions.c | 96 +- .../SQLite3MultipleCiphers/src/fastpbkdf2.c | 4 + .../SQLite3MultipleCiphers/src/fastpbkdf2.h | 8 + .../SQLite3MultipleCiphers/src/fileio.c | 50 +- .../bundled/SQLite3MultipleCiphers/src/md5.c | 32 +- .../src/memory_secure.c | 37 - .../SQLite3MultipleCiphers/src/miniz.c | 160 +- .../SQLite3MultipleCiphers/src/miniz.h | 24 +- .../SQLite3MultipleCiphers/src/mystdint.h | 2 +- .../SQLite3MultipleCiphers/src/regexp.c | 21 +- .../SQLite3MultipleCiphers/src/rekeyvacuum.c | 25 +- .../SQLite3MultipleCiphers/src/rijndael.c | 132 +- .../SQLite3MultipleCiphers/src/rijndael.h | 44 +- .../SQLite3MultipleCiphers/src/series.c | 267 +- .../bundled/SQLite3MultipleCiphers/src/sha1.c | 8 +- .../bundled/SQLite3MultipleCiphers/src/sha1.h | 12 +- .../bundled/SQLite3MultipleCiphers/src/sha2.c | 31 +- .../bundled/SQLite3MultipleCiphers/src/sha2.h | 56 +- .../SQLite3MultipleCiphers/src/shathree.c | 236 +- .../SQLite3MultipleCiphers/src/shell.c | 8624 ++++-- .../SQLite3MultipleCiphers/src/sqlar.c | 18 +- .../SQLite3MultipleCiphers/src/sqlite3mc.c | 151 +- .../SQLite3MultipleCiphers/src/sqlite3mc.def | 4 - .../SQLite3MultipleCiphers/src/sqlite3mc.h | 13 +- .../SQLite3MultipleCiphers/src/sqlite3mc.rc | 2 +- .../src/sqlite3mc_config.h | 27 +- .../src/sqlite3mc_shell.rc | 2 +- .../src/sqlite3mc_version.h | 10 +- .../src/sqlite3mc_vfs.c | 89 +- .../src/sqlite3mc_vfs.h | 1 + .../src/sqlite3patched.c | 25622 ++++++++++------ .../src/sqlite3userauth.h | 96 - .../SQLite3MultipleCiphers/src/tclsqlite.c | 209 +- .../SQLite3MultipleCiphers/src/userauth.c | 359 - .../bundled/SQLite3MultipleCiphers/src/uuid.c | 7 +- .../bundled/SQLite3MultipleCiphers/src/vsv.c | 7 +- .../SQLite3MultipleCiphers/src/zipfile.c | 91 +- 188 files changed, 45228 insertions(+), 12240 deletions(-) create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_aesni.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_aesni.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_altivec.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_altivec.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_armcrypto.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_armcrypto.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_common.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_soft.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_soft.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/implementations.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_aesni.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_aesni.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_altivec.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_altivec.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_armcrypto.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_armcrypto.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_avx2.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_avx2.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_common.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_soft.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_soft.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/implementations.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_aesni.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_aesni.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_altivec.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_altivec.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_armcrypto.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_armcrypto.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx2.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx2.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx512.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx512.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_common.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_soft.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_soft.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/implementations.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_aesni.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_aesni.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_altivec.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_altivec.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_armcrypto.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_armcrypto.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_common.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_soft.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_soft.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/implementations.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_aesni.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_aesni.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_altivec.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_altivec.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_armcrypto.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_armcrypto.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_avx2.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_avx2.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_common.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_soft.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_soft.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/implementations.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_aesni.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_aesni.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_altivec.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_altivec.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_armcrypto.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_armcrypto.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx2.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx2.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx512.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx512.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_common.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_soft.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_soft.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/implementations.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/aeshardware.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/common.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/common.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/cpu.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/cpu.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_names_define.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_names_undefine.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_table.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/softaes.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/softaes.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/type_names_undefine.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128l.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128x2.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128x4.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256x2.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256x4.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/libaegis.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/include/argon2.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/libargon2.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/argon2.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/bench.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2-impl.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2b.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blamka-round-opt.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blamka-round-ref.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/core.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/core.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/encoding.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/encoding.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/genkat.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/genkat.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/opt.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/ref.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/run.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/test.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/thread.c create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/thread.h create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_aegis.c delete mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3userauth.h delete mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/src/userauth.c diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/CHANGELOG.md b/libsql-ffi/bundled/SQLite3MultipleCiphers/CHANGELOG.md index 748450afae..deb396c2d2 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/CHANGELOG.md +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/CHANGELOG.md @@ -7,6 +7,115 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.0.2] - 2025-01-15 + +### Changed + +- Based on SQLite version 3.48.0 + +## [2.0.1] - 2025-01-06 + +### Fixed + +- Fixed issue [#186](../../issues/186)) - crashes due to _illegal instruction_ exception on some Linux systems +- Fixed issue [#185](../../issues/185)) - missing header file and include path in CMake build file + +## [2.0.0] - 2024-12-31 + +### Added + +- Added new cipher scheme AEGIS + +### Changed + +- Removed User Authentication extension +- Cleaned up some extensions to use SQLITE_API + +### Fixed + +- Fixed undefined behavior related to function pointer cast + +## [1.9.2] - 2024-12-08 + +### Changed + +- Based on SQLite version 3.47.2 + +### Fixed + +- Fixed issue with page size change request for encrypted databases + +## [1.9.1] - 2024-11-26 + +### Changed + +- Based on SQLite version 3.47.1 +- Remove need to specify AES hw compile time options + +## [1.9.0] - 2024-10-22 + +### Changed + +- Based on SQLite version 3.47.0 +- Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes) + +### Fixed + +- Using differing KDF and HMAC algorithms resulted in databases incompatible with the original SQLCipher library. Setting the parameter `hmac_algorithm_compat` to 0 restores the (incompatible) behaviour. + +## [1.8.7] - 2024-08-14 + +### Changed + +- Based on SQLite version 3.46.1 + +## [1.8.6] - 2024-06-14 + +### Changed + +- Removed extern keyword in function declarations +- Cleaned up white space +- Added SQLITE_PRIVATE for several internal functions +- The cipher configuration parameter `legacy_page_size` now accepts only valid page sizes +- The cipher configuration parameter `plaintext_header_size` now accepts only values that are multiples of 16 + +### Fixed + +- Fixed issue [#156](../../issues/156)) - corrupted database if MMAP_SIZE > 0 was used +- Fixed issue [#158](../../issues/158)) - add check to verify compatibility of source and target database in backup operation +- Fixed issue [#160](../../issues/160)) - fix accessing memory out of array bounds +- Fixed issue [#162](../../issues/162)) - fix loading/storing misaligned data +- Fixed issue [#164](../../issues/164)) - fix return of error messages from rekey +- Fixed issue [#165](../../issues/165)) - fix rekey function by enforcing page size and number of reserved bytes per page +- Fixed issue [#166](../../issues/166)) - missing attribute SQLITE_PRIVATE for several internal functions +- Fixed issue [#167](../../issues/167)) - improve VFS error reporting +- Fixed issue [#168](../../issues/168)) - add check for encryption support + +## [1.8.5] - 2024-05-24 + +### Changed + +- Based on SQLite version 3.46.0 + +## [1.8.4] - 2024-03-14 + +### Changed + +- Based on SQLite version 3.45.2 +- Disable user authentication extension by default + +## [1.8.3] - 2024-01-31 + +### Changed + +- Based on SQLite version 3.45.1 + +## [1.8.2] - 2024-01-16 + +### Changed + +- Based on SQLite version 3.45.0 + ## [1.8.1] - 2023-12-02 ### Changed @@ -469,7 +578,20 @@ The following ciphers are supported: - AES 256 Bit CBC - SHA1/SHA256/SHA512 HMAC ([SQLCipher](https://www.zetetic.net/sqlcipher/), database versions 1, 2, 3, and 4) - RC4 - No HMAC ([System.Data.SQLite](http://system.data.sqlite.org)) -[Unreleased]: ../../compare/v1.8.0...HEAD +[Unreleased]: ../../compare/v2.0.2...HEAD +[2.0.2]: ../../compare/v2.0.1...v2.0.2 +[2.0.1]: ../../compare/v2.0.0...v2.0.1 +[2.0.0]: ../../compare/v1.9.2...v2.0.0 +[1.9.2]: ../../compare/v1.9.1...v1.9.2 +[1.9.1]: ../../compare/v1.9.0...v1.9.1 +[1.9.0]: ../../compare/v1.8.7...v1.9.0 +[1.8.7]: ../../compare/v1.8.6...v1.8.7 +[1.8.6]: ../../compare/v1.8.5...v1.8.6 +[1.8.5]: ../../compare/v1.8.4...v1.8.5 +[1.8.4]: ../../compare/v1.8.3...v1.8.4 +[1.8.3]: ../../compare/v1.8.2...v1.8.3 +[1.8.2]: ../../compare/v1.8.1...v1.8.2 +[1.8.1]: ../../compare/v1.8.0...v1.8.1 [1.8.0]: ../../compare/v1.7.4...v1.8.0 [1.7.4]: ../../compare/v1.7.3...v1.7.4 [1.7.3]: ../../compare/v1.7.2...v1.7.3 diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/CMakeLists.txt b/libsql-ffi/bundled/SQLite3MultipleCiphers/CMakeLists.txt index e178589249..b517dc82ec 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/CMakeLists.txt +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/CMakeLists.txt @@ -32,7 +32,6 @@ OPTION(SQLITE_ENABLE_JSON1 "Enable extension 'json1'" ON) OPTION(SQLITE_ENABLE_RTREE "Enable extension 'rtree'" ON) OPTION(SQLITE_ENABLE_UUID "Enable extension 'uuid'" ON) OPTION(SQLITE_USE_URI "Enable the URI filename process logic" ON) -OPTION(SQLITE_USER_AUTHENTICATION "Enable extension 'user authentication'" ON) OPTION(SQLITE_ENABLE_PREUPDATE_HOOK "Enable preupdate hooks" OFF) OPTION(SQLITE_ENABLE_SESSION "Enable session extension" OFF) OPTION(SQLITE_SHELL_IS_UTF8 "Shell command line arguments in UTF-8 encoding" ON) @@ -64,7 +63,6 @@ OPTION(SQLITE3MC_USE_SQLCIPHER_LEGACY "Use sqlcipher legacy mode as default" OFF # Additional memory security (filling freed memory allocations with zeros or random data) OPTION(SQLITE3MC_SECURE_MEMORY "Enable pragma to secure freed memory" OFF) -OPTION(SQLITE3MC_USE_RANDOM_FILL_MEMORY "Fill freed memory with random data" OFF) # Omit AES hardware support OPTION(SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT "Omit AES hardware support" OFF) @@ -84,7 +82,7 @@ set(SQLITE_THREADSAFE 1 CACHE STRING "Set threading mode (0 = single-threaded, 1 set_property(CACHE SQLITE_THREADSAFE PROPERTY STRINGS 0 1 2) set(CODEC_TYPE CHACHA20 CACHE STRING "Set default codec type") -set_property(CACHE CODEC_TYPE PROPERTY STRINGS AES128 AES256 CHACHA20 SQLCIPHER RC4 ASCON128) +set_property(CACHE CODEC_TYPE PROPERTY STRINGS AES128 AES256 CHACHA20 SQLCIPHER RC4 ASCON128 AEGIS) if(SQLITE_ENABLE_COMPRESS OR SQLITE_ENABLE_SQLAR OR SQLITE_ENABLE_ZIPFILE) if(NOT SQLITE3MC_USE_MINIZ) @@ -98,7 +96,6 @@ set(SQLITE3MC_BASE_DEFINITIONS CODEC_TYPE=CODEC_TYPE_${CODEC_TYPE} SQLITE_DQS=${SQLITE_DQS} SQLITE_MAX_ATTACHED=${SQLITE_MAX_ATTACHED} - $<$:SQLITE_USER_AUTHENTICATION=1> $<$:SQLITE_ENABLE_DEBUG=1> SQLITE_THREADSAFE=${SQLITE_THREADSAFE} $<$:SQLITE_SOUNDEX=1> @@ -116,7 +113,6 @@ set(SQLITE3MC_BASE_DEFINITIONS $<$:SQLITE_ENABLE_UUID=1> SQLITE_TEMP_STORE=2 $<$:SQLITE_USE_URI=1> - $<$:SQLITE_USER_AUTHENTICATION=1> $<$:SQLITE_ENABLE_PREUPDATE_HOOK=1> $<$:SQLITE_ENABLE_SESSION=1> $<$:SQLITE3MC_USE_MINIZ=1> @@ -133,9 +129,9 @@ set(SQLITE3MC_BASE_DEFINITIONS HAVE_CIPHER_AES_128_CBC=0 HAVE_CIPHER_AES_256_CBC=1 - HAVE_CIPHER_CHACHA20=0 - HAVE_CIPHER_SQLCIPHER=0 - HAVE_CIPHER_RC4=0 + HAVE_CIPHER_CHACHA20=0 + HAVE_CIPHER_SQLCIPHER=0 + HAVE_CIPHER_RC4=0 HAVE_CIPHER_ASCON128=0 # $<$:SQLITE_USE_TCL=1> ) @@ -182,12 +178,6 @@ if(SQLITE3MC_SECURE_MEMORY) SQLITE3MC_SECURE_MEMORY=1 ) endif() -if(SQLITE3MC_USE_RANDOM_FILL_MEMORY) - set(SQLITE3MC_BASE_DEFINITIONS - ${SQLITE3MC_BASE_DEFINITIONS} - SQLITE3MC_USE_RANDOM_FILL_MEMORY=1 - ) -endif() if(SQLITE3MC_USE_MINIZ OR _SQLITE3MC_REQUIRE_ZLIB) if(_SQLITE3MC_REQUIRE_ZLIB) @@ -234,7 +224,6 @@ set(SQLITE3MC_PUBLIC_HEADERS src/sqlite3mc.h src/sqlite3mc_version.h src/sqlite3mc_vfs.h - src/sqlite3userauth.h ) set(SQLITE3MC_BASE_SRCS @@ -260,6 +249,8 @@ set(SQLITE3MC_SHELL_SRCS set(SQLITE3MC_INCLUDEDIRS src + src/aegis/include + src/argon2/include ) set(SQLITE3MC_LINK_LIBRARIES ) @@ -299,6 +290,14 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux" list(APPEND SQLITE3MC_LINK_LIBRARIES "-framework Security") endif() set(SHARED_LIB_EXPORT_DEFINITION "__attribute__((visibility(\"default\")))") +elseif (CMAKE_SYSTEM_NAME STREQUAL "Android") + if (ANDROID_ABI STREQUAL "arm64-v8a") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto") + elseif (ANDROID_ABI STREQUAL "x86_64") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mvaes") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mvaes") + endif() else() if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT ( CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" @@ -323,6 +322,7 @@ if (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT ( set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -maes -Wno-error=incompatible-function-pointer-types") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 -maes") endif() + set(_LIB_DIFINITIONS _LIB ) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/LICENSE b/libsql-ffi/bundled/SQLite3MultipleCiphers/LICENSE index 3317557506..074d3c71ac 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/LICENSE +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019-2020 Ulrich Telle +Copyright (c) 2019-2024 Ulrich Telle Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/Makefile.am b/libsql-ffi/bundled/SQLite3MultipleCiphers/Makefile.am index 900cac9cd6..127b38f8e6 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/Makefile.am +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/Makefile.am @@ -1,14 +1,14 @@ # Process this file with automake to create Makefile.in for sqlite3mc library # -# Copyright (C) 2019-2023 Ulrich Telle +# Copyright (C) 2019-2024 Ulrich Telle # # This file is covered by the same licence as the entire SQLite3 Multiple Ciphers package. -if HOST_X86 -X86_FLAGS = -msse4.2 -maes -else +#if HOST_X86 +#X86_FLAGS = -msse4.2 -maes +#else X86_FLAGS = -endif +#endif if HOST_ARM #ARM_FLAGS = -march=native @@ -21,10 +21,10 @@ ACLOCAL_AMFLAGS = -I admin/m4 # Flags used for compiling all the targets and linking all the executables # (libraries use LIBADD which is set for lib@SQLITE3MC_LIBNAME@.la only). -AM_CXXFLAGS = -I$(top_srcdir)/src -AM_CFLAGS = -I$(top_srcdir)/src +AM_CXXFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/aegis/include -I$(top_srcdir)/src/argon2/include +AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/aegis/include -I$(top_srcdir)/src/argon2/include -AM_CFLAGS += -std=c99 -DSQLITE_THREADSAFE=1 -DSQLITE_DQS=0 -DSQLITE_MAX_ATTACHED=10 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_CORE=1 -DSQLITE_ENABLE_EXTFUNC=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DSQLITE_ENABLE_CSV=1 -DSQLITE_ENABLE_SHA3=1 -DSQLITE_ENABLE_CARRAY=1 -DSQLITE_ENABLE_FILEIO=1 -DSQLITE_ENABLE_SERIES=1 -DSQLITE_ENABLE_UUID=1 -DSQLITE_ENABLE_REGEXP=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_USE_URI=1 -DSQLITE_USER_AUTHENTICATION=1 $(X86_FLAGS) $(ARM_FLAGS) +AM_CFLAGS += -std=c99 -DSQLITE_THREADSAFE=1 -DSQLITE_DQS=0 -DSQLITE_MAX_ATTACHED=10 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_CORE=1 -DSQLITE_ENABLE_EXTFUNC=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DSQLITE_ENABLE_CSV=1 -DSQLITE_ENABLE_SHA3=1 -DSQLITE_ENABLE_CARRAY=1 -DSQLITE_ENABLE_FILEIO=1 -DSQLITE_ENABLE_SERIES=1 -DSQLITE_ENABLE_UUID=1 -DSQLITE_ENABLE_REGEXP=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_USE_URI=1 -DSQLITE_USER_AUTHENTICATION=0 $(X86_FLAGS) $(ARM_FLAGS) if HOST_WINDOWS AM_CFLAGS += -DSQLITE_API=__declspec\(dllexport\) @@ -79,7 +79,6 @@ endif includemc_HEADERS = \ src/sqlite3.h \ - src/sqlite3userauth.h \ src/sqlite3ext.h \ src/sqlite3mc_version.h \ src/sqlite3mc_vfs.h \ @@ -111,7 +110,6 @@ noinst_HEADERS = \ src/sqlite3.c \ src/sqlite3mc_vfs.c \ src/test_windirent.c \ - src/userauth.c \ src/uuid.c \ src/cipher_common.h \ src/fastpbkdf2.h \ @@ -120,7 +118,6 @@ noinst_HEADERS = \ src/sha1.h \ src/sha2.h \ src/sqlite3mc_vfs.h \ - src/sqlite3userauth.h \ src/test_windirent.h lib@SQLITE3MC_LIBNAME@_la_LDFLAGS = -no-undefined $(AM_LDFLAGS) @@ -138,7 +135,7 @@ sqlite3shell_SOURCES = \ src/sqlite3mc.c \ src/shell.c -sqlite3shell_CFLAGS = -I$(top_srcdir)/src -std=c99 -D_GNU_SOURCE -DSQLITE_THREADSAFE=1 -DSQLITE_DQS=0 -DSQLITE_MAX_ATTACHED=10 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_CORE=1 -DSQLITE_ENABLE_EXTFUNC=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DSQLITE_ENABLE_CSV=1 -DSQLITE_ENABLE_CARRAY=1 -DSQLITE_ENABLE_UUID=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_USE_URI=1 -DSQLITE_USER_AUTHENTICATION=1 -DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_STMTVTAB=1 -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1 $(X86_FLAGS) $(ARM_FLAGS) +sqlite3shell_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/aegis/include -I$(top_srcdir)/src/argon2/include -std=c99 -D_GNU_SOURCE -DSQLITE_THREADSAFE=1 -DSQLITE_DQS=0 -DSQLITE_MAX_ATTACHED=10 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_CORE=1 -DSQLITE_ENABLE_EXTFUNC=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DSQLITE_ENABLE_CSV=1 -DSQLITE_ENABLE_CARRAY=1 -DSQLITE_ENABLE_UUID=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_USE_URI=1 -DSQLITE_USER_AUTHENTICATION=0 -DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_STMTVTAB=1 -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1 $(X86_FLAGS) $(ARM_FLAGS) if HOST_WINDOWS sqlite3shell_LDADD = diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/configure.ac b/libsql-ffi/bundled/SQLite3MultipleCiphers/configure.ac index 355f6b5786..7a61ced266 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/configure.ac +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/configure.ac @@ -1,10 +1,10 @@ dnl Process this script with autoconf to create configure for sqlite3mc library dnl -dnl Copyright (C) 2019-2023 Ulrich Telle +dnl Copyright (C) 2019-2025 Ulrich Telle dnl dnl This file is covered by the same licence as the entire SQLite3 Multiple Ciphers package. -AC_INIT([sqlite3mc], [1.8.1], [ulrich@telle-online.de]) +AC_INIT([sqlite3mc], [2.0.2], [ulrich@telle-online.de]) dnl This is the version tested with, might work with earlier ones. AC_PREREQ([2.69]) @@ -95,6 +95,15 @@ AC_ARG_WITH([ascon128], AS_IF([test "x$with_ascon128" = xno], [AC_DEFINE([HAVE_CIPHER_ASCON128], [0], [Define if you have Ascon-128 disabled])]) +AC_ARG_WITH([aegis], + [AS_HELP_STRING([--without-aegis], + [Disable support for AEGIS Encryption])], + [], + [with_aegis=yes]) + +AS_IF([test "x$with_aegis" = xno], + [AC_DEFINE([HAVE_CIPHER_AEGIS], [0], [Define if you have AEGIS disabled])]) + dnl Enable cipher codec AC_ARG_ENABLE(codec, @@ -104,7 +113,8 @@ AC_ARG_ENABLE(codec, chacha20 [default]: ChaCha20-Poly1305 Encryption sqlcipher: SQLCipher Encryption rc4: System.Data.SQLite RC4 Encryption - ascon128: Ascon-128 Encryption], + ascon128: Ascon-128 Encryption + aegis: AEGIS Encryption], [if test "x$enableval" = "xaes128" && test "x$with_aes128cbc" = xyes ; then codec_type=CODEC_TYPE_AES128 elif test "x$enableval" = "xaes256" && test "x$with_aes256cbc" = xyes ; then @@ -117,6 +127,8 @@ AC_ARG_ENABLE(codec, codec_type=CODEC_TYPE_RC4 elif test "x$enableval" = "xascon128" && test "x$with_ascon128" = xyes ; then codec_type=CODEC_TYPE_ASCON128 + elif test "x$enableval" = "xaegis" && test "x$with_aegis" = xyes ; then + codec_type=CODEC_TYPE_AEGIS else echo echo "Error!" @@ -131,7 +143,8 @@ AS_IF([test "x$with_aes128cbc" = xno && test "x$with_chacha20" = xno && test "x$with_sqlcipher" = xno && test "x$with_rc4" = xno && - test "x$with_ascon128" = xno], + test "x$with_ascon128" = xno && + test "x$with_aegis" = xno], [AC_DEFINE([SQLITE_HAS_CODEC], [0], [All ciphers disabled so encryption is disabled])]) dnl Check for zlib diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/premake5.lua b/libsql-ffi/bundled/SQLite3MultipleCiphers/premake5.lua index b304564412..3e82964ef0 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/premake5.lua +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/premake5.lua @@ -39,7 +39,7 @@ project "sqlite3mc_lib" end else toolset("gcc") - buildoptions { "-msse4.2", "-maes" } +-- buildoptions { "-msse4.2", "-maes" } -- buildoptions { "-march=native" } end makesettings { "include config.gcc" } @@ -51,7 +51,7 @@ project "sqlite3mc_lib" } characterset ("Unicode") staticruntime "On" - includedirs { "src" } + includedirs { "src", "src/aegis/include", "src/argon2/include" } location( BUILDDIR ) targetname "sqlite3mc" @@ -92,10 +92,9 @@ project "sqlite3mc_lib" -- "SQLITE_ENABLE_SQLAR=1" -- "SQLITE_ENABLE_ZIPFILE=1" "SQLITE3MC_SECURE_MEMORY=$(SQLITE3MC_SECURE_MEMORY)", --- "SQLITE3MC_USE_RANDOM_FILL_MEMORY=$(SQLITE3MC_USE_RANDOM_FILL_MEMORY)", "SQLITE_TEMP_STORE=2", "SQLITE_USE_URI=1", - "SQLITE_USER_AUTHENTICATION=1", + "SQLITE_USER_AUTHENTICATION=0", -- Compatibility with official SQLite3 shell "SQLITE_ENABLE_DBPAGE_VTAB=1", "SQLITE_ENABLE_DBSTAT_VTAB=1", @@ -136,7 +135,7 @@ project "sqlite3mc_dll" end else toolset("gcc") - buildoptions { "-msse4.2", "-maes" } +-- buildoptions { "-msse4.2", "-maes" } -- buildoptions { "-march=native" } end makesettings { "include config.gcc" } @@ -149,7 +148,7 @@ project "sqlite3mc_dll" } characterset ("Unicode") staticruntime "On" - includedirs { "src" } + includedirs { "src", "src/aegis/include", "src/argon2/include" } location( BUILDDIR ) targetname "sqlite3mc" @@ -190,10 +189,9 @@ project "sqlite3mc_dll" -- "SQLITE_ENABLE_SQLAR=1" -- "SQLITE_ENABLE_ZIPFILE=1" "SQLITE3MC_SECURE_MEMORY=$(SQLITE3MC_SECURE_MEMORY)", --- "SQLITE3MC_USE_RANDOM_FILL_MEMORY=$(SQLITE3MC_USE_RANDOM_FILL_MEMORY)", "SQLITE_TEMP_STORE=2", "SQLITE_USE_URI=1", - "SQLITE_USER_AUTHENTICATION=1" + "SQLITE_USER_AUTHENTICATION=0" } -- Intermediate directory @@ -229,7 +227,7 @@ project "sqlite3mc_shell" end else toolset("gcc") - buildoptions { "-msse4.2", "-maes" } +-- buildoptions { "-msse4.2", "-maes" } -- buildoptions { "-march=native" } end makesettings { "include config.gcc" } @@ -251,7 +249,7 @@ project "sqlite3mc_shell" "SQLITE_SHELL_IS_UTF8=1", "SQLITE_ENABLE_SESSION=1", "SQLITE_ENABLE_DBPAGE_VTAB=1", - "SQLITE_USER_AUTHENTICATION=1" + "SQLITE_USER_AUTHENTICATION=0" } -- Intermediate directory @@ -288,7 +286,7 @@ project "sqlite3mc_libicu" end else toolset("gcc") - buildoptions { "-msse4.2", "-maes" } +-- buildoptions { "-msse4.2", "-maes" } -- buildoptions { "-march=native" } end makesettings { "include config.gcc" } @@ -300,7 +298,7 @@ project "sqlite3mc_libicu" } characterset ("Unicode") staticruntime "On" - includedirs { "src", "$(LIBICU_PATH)/include" } + includedirs { "src", "src/aegis/include", "src/argon2/include", "$(LIBICU_PATH)/include" } location( BUILDDIR ) targetname "sqlite3mc_icu" @@ -342,10 +340,9 @@ project "sqlite3mc_libicu" -- "SQLITE_ENABLE_SQLAR=1" -- "SQLITE_ENABLE_ZIPFILE=1" "SQLITE3MC_SECURE_MEMORY=$(SQLITE3MC_SECURE_MEMORY)", --- "SQLITE3MC_USE_RANDOM_FILL_MEMORY=$(SQLITE3MC_USE_RANDOM_FILL_MEMORY)", "SQLITE_TEMP_STORE=2", "SQLITE_USE_URI=1", - "SQLITE_USER_AUTHENTICATION=1", + "SQLITE_USER_AUTHENTICATION=0", -- Compatibility with official SQLite3 shell "SQLITE_ENABLE_DBPAGE_VTAB=1", "SQLITE_ENABLE_DBSTAT_VTAB=1", @@ -386,7 +383,7 @@ project "sqlite3mc_dllicu" end else toolset("gcc") - buildoptions { "-msse4.2", "-maes" } +-- buildoptions { "-msse4.2", "-maes" } -- buildoptions { "-march=native" } end makesettings { "include config.gcc" } @@ -399,7 +396,7 @@ project "sqlite3mc_dllicu" } characterset ("Unicode") staticruntime "On" - includedirs { "src", "$(LIBICU_PATH)/include" } + includedirs { "src", "src/aegis/include", "src/argon2/include", "$(LIBICU_PATH)/include" } filter { "platforms:Win32" } libdirs { "$(LIBICU_PATH)/lib" } @@ -453,10 +450,9 @@ project "sqlite3mc_dllicu" -- "SQLITE_ENABLE_SQLAR=1" -- "SQLITE_ENABLE_ZIPFILE=1" "SQLITE3MC_SECURE_MEMORY=$(SQLITE3MC_SECURE_MEMORY)", --- "SQLITE3MC_USE_RANDOM_FILL_MEMORY=$(SQLITE3MC_USE_RANDOM_FILL_MEMORY)", "SQLITE_TEMP_STORE=2", "SQLITE_USE_URI=1", - "SQLITE_USER_AUTHENTICATION=1" + "SQLITE_USER_AUTHENTICATION=0" } -- Intermediate directory @@ -492,7 +488,7 @@ project "sqlite3mc_shellicu" end else toolset("gcc") - buildoptions { "-msse4.2", "-maes" } +-- buildoptions { "-msse4.2", "-maes" } -- buildoptions { "-march=native" } end makesettings { "include config.gcc" } @@ -526,7 +522,7 @@ project "sqlite3mc_shellicu" "SQLITE_SHELL_IS_UTF8=1", "SQLITE_ENABLE_SESSION=1", "SQLITE_ENABLE_DBPAGE_VTAB=1", - "SQLITE_USER_AUTHENTICATION=1" + "SQLITE_USER_AUTHENTICATION=0" } -- Intermediate directory diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/readme.md b/libsql-ffi/bundled/SQLite3MultipleCiphers/readme.md index 1ab5f9d684..40bb85ca36 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/readme.md +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/readme.md @@ -10,10 +10,8 @@ The code was mainly developed under Windows, but was tested under Linux as well. ## Version information -* 1.8.1 - *December 2023* - - Based on SQLite version 3.44.2 - - Fixed issue #133 - missing API symbols - - Applied several modifications to improve support for [SQLite3 WASM](https://sqlite.org/wasm/) +* 2.0.2 - *January 2025* + - Based on SQLite version 3.48.0 For further version information please consult the [CHANGELOG](CHANGELOG.md). diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l.c new file mode 100644 index 0000000000..4a9d75bb5e --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l.c @@ -0,0 +1,299 @@ +/* +** Name: aegis128l.c +** Purpose: Implementation of AEGIS-128L +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" +#include "../include/aegis128l.h" +#if 0 +#include "aegis128l_aesni.h" +#include "aegis128l_altivec.h" +#include "aegis128l_armcrypto.h" +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NONE +#include "aegis128l_soft.h" +static const aegis128l_implementation *implementation_128l = &aegis128l_soft_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON +static const aegis128l_implementation *implementation_128l = &aegis128l_armcrypto_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +static const aegis128l_implementation *implementation_128l = &aegis128l_aesni_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC +static const aegis128l_implementation *implementation_128l = &aegis128l_altivec_implementation; +#else +#error "Unsupported architecture" +#endif + +AEGIS_API +size_t +aegis128l_keybytes(void) +{ + return aegis128l_KEYBYTES; +} + +AEGIS_API +size_t +aegis128l_npubbytes(void) +{ + return aegis128l_NPUBBYTES; +} + +AEGIS_API +size_t +aegis128l_abytes_min(void) +{ + return aegis128l_ABYTES_MIN; +} + +AEGIS_API +size_t +aegis128l_abytes_max(void) +{ + return aegis128l_ABYTES_MAX; +} + +AEGIS_API +size_t +aegis128l_tailbytes_max(void) +{ + return aegis128l_TAILBYTES_MAX; +} + +AEGIS_API +int +aegis128l_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128l->encrypt_detached(c, mac, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128l_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128l->decrypt_detached(m, c, clen, mac, maclen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128l_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + return aegis128l_encrypt_detached(c, c + mlen, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128l_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + int ret = -1; + + if (clen >= maclen) { + ret = aegis128l_decrypt_detached(m, c, clen - maclen, c + clen - maclen, maclen, ad, adlen, + npub, k); + } + return ret; +} + +#ifndef AEGIS_OMIT_INCREMENTAL + +AEGIS_API +void +aegis128l_state_init(aegis128l_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + memset(st_, 0, sizeof *st_); + implementation_128l->state_init(st_, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128l_state_encrypt_update(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + return implementation_128l->state_encrypt_update(st_, c, clen_max, written, m, mlen); +} + +AEGIS_API +int +aegis128l_state_encrypt_detached_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128l->state_encrypt_detached_final(st_, c, clen_max, written, mac, maclen); +} + +AEGIS_API +int +aegis128l_state_encrypt_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128l->state_encrypt_final(st_, c, clen_max, written, maclen); +} + +AEGIS_API +int +aegis128l_state_decrypt_detached_update(aegis128l_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) +{ + return implementation_128l->state_decrypt_detached_update(st_, m, mlen_max, written, c, clen); +} + +AEGIS_API +int +aegis128l_state_decrypt_detached_final(aegis128l_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128l->state_decrypt_detached_final(st_, m, mlen_max, written, mac, maclen); +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +AEGIS_API +void +aegis128l_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + implementation_128l->stream(out, len, npub, k); +} + +AEGIS_API +void +aegis128l_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_128l->encrypt_unauthenticated(c, m, mlen, npub, k); +} + +AEGIS_API +void +aegis128l_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_128l->decrypt_unauthenticated(m, c, clen, npub, k); +} + +#ifndef AEGIS_OMIT_MAC_API + +AEGIS_API +void +aegis128l_mac_init(aegis128l_mac_state *st_, const uint8_t *k, const uint8_t *npub) +{ +#if 0 + memset(st_, 0, sizeof *st_); +#endif + implementation_128l->state_mac_init(st_, npub, k); +} + +AEGIS_API +int +aegis128l_mac_update(aegis128l_mac_state *st_, const uint8_t *m, size_t mlen) +{ + return implementation_128l->state_mac_update(st_, m, mlen); +} + +AEGIS_API +int +aegis128l_mac_final(aegis128l_mac_state *st_, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128l->state_mac_final(st_, mac, maclen); +} + +AEGIS_API +int +aegis128l_mac_verify(aegis128l_mac_state *st_, const uint8_t *mac, size_t maclen) +{ + uint8_t expected_mac[32]; + + switch (maclen) { + case 16: + implementation_128l->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_16(expected_mac, mac); + case 32: + implementation_128l->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_32(expected_mac, mac); + default: + errno = EINVAL; + return -1; + } +} + +AEGIS_API +void +aegis128l_mac_reset(aegis128l_mac_state *st_) +{ + implementation_128l->state_mac_reset(st_); +} + +AEGIS_API +void +aegis128l_mac_state_clone(aegis128l_mac_state *dst, const aegis128l_mac_state *src) +{ + implementation_128l->state_mac_clone(dst, src); +} + +#endif /* AEGIS_OMIT_MAC_API */ + +AEGIS_PRIVATE +int +aegis128l_pick_best_implementation(void) +{ + implementation_128l = &aegis128l_soft_implementation; + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + if (aegis_runtime_has_armcrypto()) { + implementation_128l = &aegis128l_armcrypto_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI + if (aegis_runtime_has_aesni() && aegis_runtime_has_avx()) { + implementation_128l = &aegis128l_aesni_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC + if (aegis_runtime_has_altivec()) { + implementation_128l = &aegis128l_altivec_implementation; + return 0; + } +#endif + + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_aesni.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_aesni.c new file mode 100644 index 0000000000..650c42aeaa --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_aesni.c @@ -0,0 +1,110 @@ +/* +** Name: aegis128l_aesni.c +** Purpose: Implementation of AEGIS-128L - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128l.h" +#include "aegis128l_aesni.h" + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("aes,avx") +#endif + +#include +#include + +#define AES_BLOCK_LENGTH 16 + +typedef __m128i aegis128l_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128l_aes_block_t +#define AEGIS_BLOCKS aegis128l_blocks +#define AEGIS_STATE _aegis128l_state +#define AEGIS_MAC_STATE _aegis128l_mac_state + +#define AEGIS_FUNC_PREFIX aegis128l_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm_xor_si128(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm_and_si128(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return _mm_loadu_si128((const AEGIS_AES_BLOCK_T *) (const void *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return _mm_set_epi64x((long long) a, (long long) b); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm_storeu_si128((AEGIS_AES_BLOCK_T *) (void *) a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm_aesenc_si128(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128l_common.h" + +struct aegis128l_implementation aegis128l_aesni_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_aesni.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_aesni.h new file mode 100644 index 0000000000..c47b999901 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_aesni.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128l_aesni.h +** Purpose: Header for implementation structure of AEGIS-128L - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128L_AESNI_H +#define AEGIS128L_AESNI_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128l_implementation aegis128l_aesni_implementation; + +#endif /* AEGIS128L_AESNI_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_altivec.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_altivec.c new file mode 100644 index 0000000000..4beed1fc1f --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_altivec.c @@ -0,0 +1,106 @@ +/* +** Name: aegis128l_altivec.c +** Purpose: Implementation of AEGIS-128L - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__ALTIVEC__) && defined(__CRYPTO__) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128l.h" +#include "aegis128l_altivec.h" + +#include + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("altivec,crypto"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("altivec,crypto") +#endif + +#define AES_BLOCK_LENGTH 16 + +typedef vector unsigned char aegis128l_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128l_aes_block_t +#define AEGIS_BLOCKS aegis128l_blocks +#define AEGIS_STATE _aegis128l_state +#define AEGIS_MAC_STATE _aegis128l_mac_state + +#define AEGIS_FUNC_PREFIX aegis128l_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return vec_xor(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return vec_and(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return vec_xl_be(0, (const unsigned char *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return (AEGIS_AES_BLOCK_T) vec_revb(vec_insert(a, vec_promote((unsigned long long) b, 1), 0)); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vec_xst_be(b, 0, (unsigned char *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) vec_cipher_be(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(state[3], state[4]), d2); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d1); +} + +#include "aegis128l_common.h" + +struct aegis128l_implementation aegis128l_altivec_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_altivec.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_altivec.h new file mode 100644 index 0000000000..2a76d0b9a4 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_altivec.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128l_altivec.h +** Purpose: Header for implementation structure of AEGIS-128L - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128L_ALTIVEC_H +#define AEGIS128L_ALTIVEC_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128l_implementation aegis128l_altivec_implementation; + +#endif /* AEGIS128L_ALTIVEC_H */ \ No newline at end of file diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_armcrypto.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_armcrypto.c new file mode 100644 index 0000000000..2dde33fe90 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_armcrypto.c @@ -0,0 +1,120 @@ +/* +** Name: aegis128l_armcrypto.c +** Purpose: Implementation of AEGIS-128L - ARM-Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include "../common/aeshardware.h" + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128l.h" +#include "aegis128l_armcrypto.h" + +#ifndef __ARM_FEATURE_CRYPTO +# define __ARM_FEATURE_CRYPTO 1 +#endif +#ifndef __ARM_FEATURE_AES +# define __ARM_FEATURE_AES 1 +#endif + +#ifdef USE_ARM64_NEON_H +#include +#else +#include +#endif + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("neon,crypto,aes"))), \ + apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("+simd+crypto") +#endif + +#define AES_BLOCK_LENGTH 16 + +typedef uint8x16_t aegis128l_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128l_aes_block_t +#define AEGIS_BLOCKS aegis128l_blocks +#define AEGIS_STATE _aegis128l_state +#define AEGIS_MAC_STATE _aegis128l_mac_state + +#define AEGIS_FUNC_PREFIX aegis128l_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return veorq_u8(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return vandq_u8(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return vld1q_u8(a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return vreinterpretq_u8_u64(vsetq_lane_u64(a, vmovq_n_u64(b), 1)); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vst1q_u8(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return veorq_u8(vaesmcq_u8(vaeseq_u8(a, vmovq_n_u8(0))), b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(state[3], state[4]), d2); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d1); +} + +#include "aegis128l_common.h" + +struct aegis128l_implementation aegis128l_armcrypto_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_armcrypto.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_armcrypto.h new file mode 100644 index 0000000000..cb0744a429 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_armcrypto.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128l_armcrypto.h +** Purpose: Header for implementation structure of AEGIS-128L - ARM Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128L_ARMCRYPTO_H +#define AEGIS128L_ARMCRYPTO_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128l_implementation aegis128l_armcrypto_implementation; + +#endif /* AEGIS128L_ARMCRYPTO_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_common.h new file mode 100644 index 0000000000..d4af7e9fdc --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_common.h @@ -0,0 +1,726 @@ +/* +** Name: aegis128l_common.h +** Purpose: Common implementation for AEGIS-128L +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#define AEGIS_RATE 32 +#define AEGIS_ALIGNMENT 32 + +typedef AEGIS_AES_BLOCK_T AEGIS_BLOCKS[8]; + +#define AEGIS_init AEGIS_FUNC(init) +#define AEGIS_mac AEGIS_FUNC(mac) +#define AEGIS_absorb AEGIS_FUNC(absorb) +#define AEGIS_enc AEGIS_FUNC(enc) +#define AEGIS_dec AEGIS_FUNC(dec) +#define AEGIS_declast AEGIS_FUNC(declast) + +static void +AEGIS_init(const uint8_t *key, const uint8_t *nonce, AEGIS_AES_BLOCK_T *const state) +{ + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) + const uint8_t c0_[AES_BLOCK_LENGTH] = { 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, + 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }; + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) + const uint8_t c1_[AES_BLOCK_LENGTH] = { 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, + 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }; + + const AEGIS_AES_BLOCK_T c0 = AEGIS_AES_BLOCK_LOAD(c0_); + const AEGIS_AES_BLOCK_T c1 = AEGIS_AES_BLOCK_LOAD(c1_); + AEGIS_AES_BLOCK_T k; + AEGIS_AES_BLOCK_T n; + int i; + + k = AEGIS_AES_BLOCK_LOAD(key); + n = AEGIS_AES_BLOCK_LOAD(nonce); + + state[0] = AEGIS_AES_BLOCK_XOR(k, n); + state[1] = c1; + state[2] = c0; + state[3] = c1; + state[4] = AEGIS_AES_BLOCK_XOR(k, n); + state[5] = AEGIS_AES_BLOCK_XOR(k, c0); + state[6] = AEGIS_AES_BLOCK_XOR(k, c1); + state[7] = AEGIS_AES_BLOCK_XOR(k, c0); + for (i = 0; i < 10; i++) { + AEGIS_update(state, n, k); + } +} + +static void +AEGIS_mac(uint8_t *mac, size_t maclen, uint64_t adlen, uint64_t mlen, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T tmp; + int i; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(mlen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } + + if (maclen == 16) { + tmp = AEGIS_AES_BLOCK_XOR(state[6], AEGIS_AES_BLOCK_XOR(state[5], state[4])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac, tmp); + } else if (maclen == 32) { + tmp = AEGIS_AES_BLOCK_XOR(state[3], state[2]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac, tmp); + tmp = AEGIS_AES_BLOCK_XOR(state[7], state[6]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[5], state[4])); + AEGIS_AES_BLOCK_STORE(mac + 16, tmp); + } else { + memset(mac, 0, maclen); + } +} + +static inline void +AEGIS_absorb(const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_enc(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + AEGIS_AES_BLOCK_T tmp0, tmp1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + tmp0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + tmp0 = AEGIS_AES_BLOCK_XOR(tmp0, state[1]); + tmp1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + tmp1 = AEGIS_AES_BLOCK_XOR(tmp1, state[2]); + tmp0 = AEGIS_AES_BLOCK_XOR(tmp0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + tmp1 = AEGIS_AES_BLOCK_XOR(tmp1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(dst, tmp0); + AEGIS_AES_BLOCK_STORE(dst + AES_BLOCK_LENGTH, tmp1); + + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_dec(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[1]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[2]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(dst, msg0); + AEGIS_AES_BLOCK_STORE(dst + AES_BLOCK_LENGTH, msg1); + + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_declast(uint8_t *const dst, const uint8_t *const src, size_t len, + AEGIS_AES_BLOCK_T *const state) +{ + uint8_t pad[AEGIS_RATE]; + AEGIS_AES_BLOCK_T msg0, msg1; + + memset(pad, 0, sizeof pad); + memcpy(pad, src, len); + + msg0 = AEGIS_AES_BLOCK_LOAD(pad); + msg1 = AEGIS_AES_BLOCK_LOAD(pad + AES_BLOCK_LENGTH); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[1]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[2]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(pad, msg0); + AEGIS_AES_BLOCK_STORE(pad + AES_BLOCK_LENGTH, msg1); + + memset(pad + len, 0, sizeof pad - len); + memcpy(dst, pad, len); + + msg0 = AEGIS_AES_BLOCK_LOAD(pad); + msg1 = AEGIS_AES_BLOCK_LOAD(pad + AES_BLOCK_LENGTH); + + AEGIS_update(state, msg0, msg1); +} + +static int +AEGIS_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } + + AEGIS_mac(mac, maclen, adlen, mlen, state); + + return 0; +} + +static int +AEGIS_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, size_t maclen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + const size_t mlen = clen; + size_t i; + int ret; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + if (m != NULL) { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + } else { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, state); + } + } + if (mlen % AEGIS_RATE) { + if (m != NULL) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } else { + AEGIS_declast(dst, c + i, mlen % AEGIS_RATE, state); + } + } + + COMPILER_ASSERT(sizeof computed_mac >= 32); + AEGIS_mac(computed_mac, maclen, adlen, mlen, state); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret != 0 && m != NULL) { + memset(m, 0, mlen); + } + return ret; +} + +static void +AEGIS_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + memset(src, 0, sizeof src); + if (npub == NULL) { + npub = src; + } + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= len; i += AEGIS_RATE) { + AEGIS_enc(out + i, src, state); + } + if (len % AEGIS_RATE) { + AEGIS_enc(dst, src, state); + memcpy(out + i, dst, len % AEGIS_RATE); + } +} + +static void +AEGIS_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } +} + +static void +AEGIS_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + const size_t mlen = clen; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + if (mlen % AEGIS_RATE) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } +} + +typedef struct AEGIS_STATE { + AEGIS_BLOCKS blocks; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + uint64_t mlen; + size_t pos; +} AEGIS_STATE; + +typedef struct AEGIS_MAC_STATE { + AEGIS_BLOCKS blocks; + AEGIS_BLOCKS blocks0; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + size_t pos; +} AEGIS_MAC_STATE; + +#ifndef AEGIS_OMIT_INCREMENTAL + +static void +AEGIS_state_init(aegis128l_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->mlen = 0; + st->pos = 0; + + memcpy(blocks, st->blocks, sizeof blocks); + + AEGIS_init(k, npub, blocks); + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (adlen % AEGIS_RATE) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(st->buf, blocks); + } + st->adlen = adlen; + + memcpy(st->blocks, blocks, sizeof blocks); +} + +static int +AEGIS_state_encrypt_update(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += mlen; + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = mlen < available ? mlen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, m + i, n); + m += n; + mlen -= n; + st->pos += n; + } + if (st->pos == sizeof st->buf) { + if (clen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + clen_max -= AEGIS_RATE; + AEGIS_enc(c, st->buf, blocks); + *written += AEGIS_RATE; + c += AEGIS_RATE; + st->pos = 0; + } else { + return 0; + } + } + if (clen_max < (mlen & ~(size_t) (AEGIS_RATE - 1))) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, blocks); + } + *written += i; + left = mlen % AEGIS_RATE; + if (left != 0) { + memcpy(st->buf, m + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_detached_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written, + uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(mac, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos + maclen) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(c + st->pos, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos + maclen; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_update(aegis128l_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *c, size_t clen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += clen; + + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = clen < available ? clen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, c, n); + c += n; + clen -= n; + st->pos += n; + } + if (st->pos < (sizeof st->buf)) { + return 0; + } + st->pos = 0; + if (m != NULL) { + if (mlen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + mlen_max -= AEGIS_RATE; + AEGIS_dec(m, st->buf, blocks); + m += AEGIS_RATE; + } else { + AEGIS_dec(dst, st->buf, blocks); + } + *written += AEGIS_RATE; + } + if (m != NULL) { + if (mlen_max < (clen % AEGIS_RATE)) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, blocks); + } + } else { + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, blocks); + } + } + *written += i; + left = clen % AEGIS_RATE; + if (left) { + memcpy(st->buf, c + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_final(aegis128l_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + int ret; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (st->pos != 0) { + if (m != NULL) { + if (mlen_max < st->pos) { + errno = ERANGE; + return -1; + } + AEGIS_declast(m, st->buf, st->pos, blocks); + } else { + AEGIS_declast(dst, st->buf, st->pos, blocks); + } + } + AEGIS_mac(computed_mac, maclen, st->adlen, st->mlen, blocks); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret == 0) { + *written = st->pos; + } else { + memset(m, 0, st->pos); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return ret; +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +#ifndef AEGIS_OMIT_MAC_API + +static void +AEGIS_state_mac_init(aegis128l_mac_state *st_, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->pos = 0; + + memcpy(blocks, st->blocks, sizeof blocks); + + AEGIS_init(k, npub, blocks); + + memcpy(st->blocks0, blocks, sizeof blocks); + memcpy(st->blocks, blocks, sizeof blocks); + st->adlen = 0; +} + +static int +AEGIS_state_mac_update(aegis128l_mac_state *st_, const uint8_t *ad, size_t adlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + st->adlen += adlen; + if (left != 0) { + if (left + adlen < AEGIS_RATE) { + memcpy(st->buf + left, ad, adlen); + return 0; + } + memcpy(st->buf + left, ad, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + ad += AEGIS_RATE - left; + adlen -= AEGIS_RATE - left; + } + for (i = 0; i + AEGIS_RATE * 2 <= adlen; i += AEGIS_RATE * 2) { + AEGIS_AES_BLOCK_T msg0, msg1, msg2, msg3; + + msg0 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 0); + msg1 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 1); + msg2 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 2); + msg3 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 3); + COMPILER_ASSERT(AES_BLOCK_LENGTH * 4 == AEGIS_RATE * 2); + + AEGIS_update(blocks, msg0, msg1); + AEGIS_update(blocks, msg2, msg3); + } + for (; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (i < adlen) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen - i); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_mac_final(aegis128l_mac_state *st_, uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + if (left != 0) { + memset(st->buf + left, 0, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + } + AEGIS_mac(mac, maclen, st->adlen, maclen, blocks); + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static void +AEGIS_state_mac_reset(aegis128l_mac_state *st_) +{ + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + st->adlen = 0; + st->pos = 0; + memcpy(st->blocks, st->blocks0, sizeof(AEGIS_BLOCKS)); +} + +static void +AEGIS_state_mac_clone(aegis128l_mac_state *dst, const aegis128l_mac_state *src) +{ + AEGIS_MAC_STATE *const dst_ = + (AEGIS_MAC_STATE *) ((((uintptr_t) &dst->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + const AEGIS_MAC_STATE *const src_ = + (const AEGIS_MAC_STATE *) ((((uintptr_t) &src->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + *dst_ = *src_; +} + +#endif /* AEGIS_OMIT_MAC_API */ + +#undef AEGIS_RATE +#undef AEGIS_ALIGNMENT + +#undef AEGIS_init +#undef AEGIS_mac +#undef AEGIS_absorb +#undef AEGIS_enc +#undef AEGIS_dec +#undef AEGIS_declast diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_soft.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_soft.c new file mode 100644 index 0000000000..ac31461533 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_soft.c @@ -0,0 +1,96 @@ +/* +** Name: aegis128l_soft.c +** Purpose: Implementation of AEGIS-128L - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" + +#include "../common/softaes.h" +#include "aegis128l.h" +#include "aegis128l_soft.h" + +#define AES_BLOCK_LENGTH 16 + +typedef SoftAesBlock aegis128l_soft_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128l_soft_aes_block_t +#define AEGIS_BLOCKS aegis128l_soft_blocks +#define AEGIS_STATE _aegis128l_soft_state +#define AEGIS_MAC_STATE _aegis128l_soft_mac_state + +#define AEGIS_FUNC_PREFIX aegis128l_soft_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return softaes_block_xor(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return softaes_block_and(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return softaes_block_load(a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return softaes_block_load64x2(a, b); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + softaes_block_store(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return softaes_block_encrypt(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128l_common.h" + +struct aegis128l_implementation aegis128l_soft_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_soft.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_soft.h new file mode 100644 index 0000000000..a6576b0b0e --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/aegis128l_soft.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128l_soft.h +** Purpose: Header for implementation structure of AEGIS-128L - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128L_SOFT_H +#define AEGIS128L_SOFT_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128l_implementation aegis128l_soft_implementation; + +#endif /* AEGIS128L_SOFT_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/implementations.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/implementations.h new file mode 100644 index 0000000000..63c03b7056 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128l/implementations.h @@ -0,0 +1,50 @@ +/* +** Name: implementations.h +** Purpose: Header for implementation structure of AEGIS-128L +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128L_IMPLEMENTATIONS_H +#define AEGIS128L_IMPLEMENTATIONS_H + +#include +#include + +#include "aegis128l.h" + +typedef struct aegis128l_implementation { + int (*encrypt_detached)(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k); + int (*decrypt_detached)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + void (*stream)(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + void (*encrypt_unauthenticated)(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k); + void (*decrypt_unauthenticated)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k); +#ifndef AEGIS_OMIT_INCREMENTAL + void (*state_init)(aegis128l_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + int (*state_encrypt_update)(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen); + int (*state_encrypt_detached_final)(aegis128l_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + int (*state_encrypt_final)(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen); + int (*state_decrypt_detached_update)(aegis128l_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen); + int (*state_decrypt_detached_final)(aegis128l_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen); +#endif /* AEGIS_OMIT_INCREMENTAL */ +#ifndef AEGIS_OMIT_MAC_API + void (*state_mac_init)(aegis128l_mac_state *st_, const uint8_t *npub, const uint8_t *k); + int (*state_mac_update)(aegis128l_mac_state *st_, const uint8_t *ad, size_t adlen); + int (*state_mac_final)(aegis128l_mac_state *st_, uint8_t *mac, size_t maclen); + void (*state_mac_reset)(aegis128l_mac_state *st); + void (*state_mac_clone)(aegis128l_mac_state *dst, const aegis128l_mac_state *src); +#endif /* AEGIS_OMIT_MAC_API */ +} aegis128l_implementation; + +#endif /* AEGIS128L_IMPLEMENTATIONS_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2.c new file mode 100644 index 0000000000..dc2f878c3a --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2.c @@ -0,0 +1,303 @@ +/* +** Name: aegis128x2.c +** Purpose: Implementation of AEGIS-128x2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" +#include "../include/aegis128x2.h" +#if 0 +#include "aegis128x2_aesni.h" +#include "aegis128x2_altivec.h" +#include "aegis128x2_armcrypto.h" +#include "aegis128x2_avx2.h" +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NONE +#include "aegis128x2_soft.h" +static const aegis128x2_implementation* implementation_128x2 = &aegis128x2_soft_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON +static const aegis128x2_implementation* implementation_128x2 = &aegis128x2_armcrypto_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +static const aegis128x2_implementation* implementation_128x2 = &aegis128x2_aesni_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC +static const aegis128x2_implementation* implementation_128x2 = &aegis128x2_altivec_implementation; +#else +#error "Unsupported architecture" +#endif + +AEGIS_API +size_t +aegis128x2_keybytes(void) +{ + return aegis128x2_KEYBYTES; +} + +AEGIS_API +size_t +aegis128x2_npubbytes(void) +{ + return aegis128x2_NPUBBYTES; +} + +AEGIS_API +size_t +aegis128x2_abytes_min(void) +{ + return aegis128x2_ABYTES_MIN; +} + +AEGIS_API +size_t +aegis128x2_abytes_max(void) +{ + return aegis128x2_ABYTES_MAX; +} + +AEGIS_API +size_t +aegis128x2_tailbytes_max(void) +{ + return aegis128x2_TAILBYTES_MAX; +} + +AEGIS_API +int +aegis128x2_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x2->encrypt_detached(c, mac, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128x2_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x2->decrypt_detached(m, c, clen, mac, maclen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128x2_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + return aegis128x2_encrypt_detached(c, c + mlen, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128x2_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + int ret = -1; + + if (clen >= maclen) { + ret = aegis128x2_decrypt_detached(m, c, clen - maclen, c + clen - maclen, maclen, ad, adlen, + npub, k); + } + return ret; +} + +#ifndef AEGIS_OMIT_INCREMENTAL + +AEGIS_API +void +aegis128x2_state_init(aegis128x2_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + memset(st_, 0, sizeof *st_); + implementation_128x2->state_init(st_, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128x2_state_encrypt_update(aegis128x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + return implementation_128x2->state_encrypt_update(st_, c, clen_max, written, m, mlen); +} + +AEGIS_API +int +aegis128x2_state_encrypt_detached_final(aegis128x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x2->state_encrypt_detached_final(st_, c, clen_max, written, mac, maclen); +} + +AEGIS_API +int +aegis128x2_state_encrypt_final(aegis128x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x2->state_encrypt_final(st_, c, clen_max, written, maclen); +} + +AEGIS_API +int +aegis128x2_state_decrypt_detached_update(aegis128x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) +{ + return implementation_128x2->state_decrypt_detached_update(st_, m, mlen_max, written, c, clen); +} + +AEGIS_API +int +aegis128x2_state_decrypt_detached_final(aegis128x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x2->state_decrypt_detached_final(st_, m, mlen_max, written, mac, maclen); +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +AEGIS_API +void +aegis128x2_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + implementation_128x2->stream(out, len, npub, k); +} + +AEGIS_API +void +aegis128x2_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_128x2->encrypt_unauthenticated(c, m, mlen, npub, k); +} + +AEGIS_API +void +aegis128x2_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_128x2->decrypt_unauthenticated(m, c, clen, npub, k); +} + +#ifndef AEGIS_OMIT_MAC_API + +AEGIS_API +void +aegis128x2_mac_init(aegis128x2_mac_state *st_, const uint8_t *k, const uint8_t *npub) +{ + implementation_128x2->state_mac_init(st_, npub, k); +} + +AEGIS_API +int +aegis128x2_mac_update(aegis128x2_mac_state *st_, const uint8_t *m, size_t mlen) +{ + return implementation_128x2->state_mac_update(st_, m, mlen); +} + +AEGIS_API +int +aegis128x2_mac_final(aegis128x2_mac_state *st_, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x2->state_mac_final(st_, mac, maclen); +} + +AEGIS_API +int +aegis128x2_mac_verify(aegis128x2_mac_state *st_, const uint8_t *mac, size_t maclen) +{ + uint8_t expected_mac[32]; + + switch (maclen) { + case 16: + implementation_128x2->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_16(expected_mac, mac); + case 32: + implementation_128x2->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_32(expected_mac, mac); + default: + errno = EINVAL; + return -1; + } +} + +AEGIS_API +void +aegis128x2_mac_reset(aegis128x2_mac_state *st_) +{ + implementation_128x2->state_mac_reset(st_); +} + +AEGIS_API +void +aegis128x2_mac_state_clone(aegis128x2_mac_state *dst, const aegis128x2_mac_state *src) +{ + implementation_128x2->state_mac_clone(dst, src); +} + +#endif /* AEGIS_OMIT_MAC_API */ + +AEGIS_PRIVATE +int +aegis128x2_pick_best_implementation(void) +{ + implementation_128x2 = &aegis128x2_soft_implementation; + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + if (aegis_runtime_has_armcrypto()) { + implementation_128x2 = &aegis128x2_armcrypto_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +# ifdef HAVE_VAESINTRIN_H + if (aegis_runtime_has_vaes() && aegis_runtime_has_avx2()) { + implementation_128x2 = &aegis128x2_avx2_implementation; + return 0; + } +# endif + if (aegis_runtime_has_aesni() && aegis_runtime_has_avx()) { + implementation_128x2 = &aegis128x2_aesni_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC + if (aegis_runtime_has_altivec()) { + implementation_128x2 = &aegis128x2_altivec_implementation; + return 0; + } +#endif + + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_aesni.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_aesni.c new file mode 100644 index 0000000000..930c8dd886 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_aesni.c @@ -0,0 +1,116 @@ +/* +** Name: aegis128x2_aesni.c +** Purpose: Implementation of AEGIS-128x2 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x2.h" +#include "aegis128x2_aesni.h" + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("aes,avx") +#endif + +#include +#include + +#define AES_BLOCK_LENGTH 32 + +typedef struct { + __m128i b0; + __m128i b1; +} aegis128x2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x2_aes_block_t +#define AEGIS_BLOCKS aegis128x2_blocks +#define AEGIS_STATE _aegis128x2_state +#define AEGIS_MAC_STATE _aegis128x2_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_xor_si128(a.b0, b.b0), _mm_xor_si128(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_and_si128(a.b0, b.b0), _mm_and_si128(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { _mm_loadu_si128((const __m128i *) (const void *) a), + _mm_loadu_si128((const __m128i *) (const void *) (a + 16)) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const __m128i t = _mm_set_epi64x((long long) a, (long long) b); + return (AEGIS_AES_BLOCK_T) { t, t }; +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm_storeu_si128((__m128i *) (void *) a, b.b0); + _mm_storeu_si128((__m128i *) (void *) (a + 16), b.b1); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_aesenc_si128(a.b0, b.b0), _mm_aesenc_si128(a.b1, b.b1) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128x2_common.h" + +struct aegis128x2_implementation aegis128x2_aesni_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_aesni.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_aesni.h new file mode 100644 index 0000000000..60295f8832 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_aesni.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128x2_aesni.h +** Purpose: Header for implementation structure of AEGIS-128x2 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X2_AESNI_H +#define AEGIS128X2_AESNI_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128x2_implementation aegis128x2_aesni_implementation; + +#endif /* AEGIS128X2_AESNI_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_altivec.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_altivec.c new file mode 100644 index 0000000000..7ed1b21fa8 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_altivec.c @@ -0,0 +1,111 @@ +/* +** Name: aegis128x2_altivec.c +** Purpose: Implementation of AEGIS-128x2 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__ALTIVEC__) && defined(__CRYPTO__) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x2.h" +#include "aegis128x2_altivec.h" + +#include + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("altivec,crypto"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("altivec,crypto") +#endif + +#define AES_BLOCK_LENGTH 32 + +typedef struct { + vector unsigned char b0; + vector unsigned char b1; +} aegis128x2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x2_aes_block_t +#define AEGIS_BLOCKS aegis128x2_blocks +#define AEGIS_STATE _aegis128x2_state +#define AEGIS_MAC_STATE _aegis128x2_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_xor(a.b0, b.b0), vec_xor(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_and(a.b0, b.b0), vec_and(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { vec_xl_be(0, a), vec_xl_be(0, a + 16) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const vector unsigned char t = + (vector unsigned char) vec_revb(vec_insert(a, vec_promote((unsigned long long) (b), 1), 0)); + return (AEGIS_AES_BLOCK_T) { t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vec_xst_be(b.b0, 0, a); + vec_xst_be(b.b1, 0, a + 16); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_cipher_be(a.b0, b.b0), vec_cipher_be(a.b1, b.b1) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(state[3], state[4]), d2); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d1); +} + +#include "aegis128x2_common.h" + +struct aegis128x2_implementation aegis128x2_altivec_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_altivec.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_altivec.h new file mode 100644 index 0000000000..237ef47b1d --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_altivec.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128x2_altivec.h +** Purpose: Header for implementation structure of AEGIS-128x2 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X2_ALTIVEC_H +#define AEGIS128X2_ALTIVEC_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128x2_implementation aegis128x2_altivec_implementation; + +#endif /* AEGIS128X2_ALTIVEC_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_armcrypto.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_armcrypto.c new file mode 100644 index 0000000000..441bbf9e8c --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_armcrypto.c @@ -0,0 +1,125 @@ +/* +** Name: aegis128x2_armcrypto.c +** Purpose: Implementation of AEGIS-128x2 - ARM-Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include "../common/aeshardware.h" + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x2.h" +#include "aegis128x2_armcrypto.h" + +#ifndef __ARM_FEATURE_CRYPTO +# define __ARM_FEATURE_CRYPTO 1 +#endif +#ifndef __ARM_FEATURE_AES +# define __ARM_FEATURE_AES 1 +#endif + +#ifdef USE_ARM64_NEON_H +#include +#else +#include +#endif + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("neon,crypto,aes"))), \ + apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("+simd+crypto") +#endif + +#define AES_BLOCK_LENGTH 32 + +typedef struct { + uint8x16_t b0; + uint8x16_t b1; +} aegis128x2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x2_aes_block_t +#define AEGIS_BLOCKS aegis128x2_blocks +#define AEGIS_STATE _aegis128x2_state +#define AEGIS_MAC_STATE _aegis128x2_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { veorq_u8(a.b0, b.b0), veorq_u8(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vandq_u8(a.b0, b.b0), vandq_u8(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { vld1q_u8(a), vld1q_u8(a + 16) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const uint8x16_t t = vreinterpretq_u8_u64(vsetq_lane_u64((a), vmovq_n_u64(b), 1)); + return (AEGIS_AES_BLOCK_T) { t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vst1q_u8(a, b.b0); + vst1q_u8(a + 16, b.b1); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { veorq_u8(vaesmcq_u8(vaeseq_u8((a.b0), vmovq_n_u8(0))), (b.b0)), + veorq_u8(vaesmcq_u8(vaeseq_u8((a.b1), vmovq_n_u8(0))), (b.b1)) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(state[3], state[4]), d2); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d1); +} + +#include "aegis128x2_common.h" + +struct aegis128x2_implementation aegis128x2_armcrypto_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_armcrypto.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_armcrypto.h new file mode 100644 index 0000000000..f2faad47bc --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_armcrypto.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128x2_armcrypto.h +** Purpose: Header for implementation structure of AEGIS-128x2 - ARM Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X2_ARMCRYPTO_H +#define AEGIS128X2_ARMCRYPTO_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128x2_implementation aegis128x2_armcrypto_implementation; + +#endif /* AEGIS128X2_ARMCRYPTO_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_avx2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_avx2.c new file mode 100644 index 0000000000..f6652c5c9b --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_avx2.c @@ -0,0 +1,113 @@ +/* +** Name: aegis128x2_avx2.c +** Purpose: Implementation of AEGIS-128x2 - AES-NI AVX2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x2.h" +#include "aegis128x2_avx2.h" + +#ifdef HAVE_VAESINTRIN_H + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("vaes,avx2"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("vaes,avx2") +#endif + +#include + +#define AES_BLOCK_LENGTH 32 + +typedef __m256i aegis128x2_avx2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x2_avx2_aes_block_t +#define AEGIS_BLOCKS aegis128x2_avx2_blocks +#define AEGIS_STATE _aegis128x2_avx2_state +#define AEGIS_MAC_STATE _aegis128x2_avx2_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x2_avx2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm256_xor_si256(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm256_and_si256(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return _mm256_loadu_si256((const AEGIS_AES_BLOCK_T *) (const void *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return _mm256_broadcastsi128_si256(_mm_set_epi64x(a, b)); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm256_storeu_si256((AEGIS_AES_BLOCK_T *) (void *) a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm256_aesenc_epi128(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128x2_common.h" + +struct aegis128x2_implementation aegis128x2_avx2_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif /* HAVE_VAESINTRIN_H */ + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_avx2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_avx2.h new file mode 100644 index 0000000000..10f6a71618 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_avx2.h @@ -0,0 +1,18 @@ +/* +** Name: aegis128x2_avx2.h +** Purpose: Header for implementation structure of AEGIS-128x2 - AES-NI AVX2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X2_AVX2_H +#define AEGIS128X2_AVX2_H + +#include "../common/common.h" +#include "implementations.h" + +#ifdef HAVE_VAESINTRIN_H +extern struct aegis128x2_implementation aegis128x2_avx2_implementation; +#endif + +#endif /* AEGIS128X2_AVX2_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_common.h new file mode 100644 index 0000000000..7be2cba57b --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_common.h @@ -0,0 +1,833 @@ +/* +** Name: aegis128x2_common.h +** Purpose: Common implementation for AEGIS-128x2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#define AEGIS_RATE 64 +#define AEGIS_ALIGNMENT 64 + +typedef AEGIS_AES_BLOCK_T AEGIS_BLOCKS[8]; + +#define AEGIS_init AEGIS_FUNC(init) +#define AEGIS_mac AEGIS_FUNC(mac) +#define AEGIS_mac_nr AEGIS_FUNC(mac_nr) +#define AEGIS_absorb AEGIS_FUNC(absorb) +#define AEGIS_enc AEGIS_FUNC(enc) +#define AEGIS_dec AEGIS_FUNC(dec) +#define AEGIS_declast AEGIS_FUNC(declast) + +static void +AEGIS_init(const uint8_t *key, const uint8_t *nonce, AEGIS_AES_BLOCK_T *const state) +{ + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) const uint8_t c0_[AES_BLOCK_LENGTH] = { + 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, + 0x59, 0x90, 0xe9, 0x79, 0x62, 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, + 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62, + }; + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) const uint8_t c1_[AES_BLOCK_LENGTH] = { + 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, + 0x42, 0x73, 0xb5, 0x28, 0xdd, 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, + 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd, + }; + + const AEGIS_AES_BLOCK_T c0 = AEGIS_AES_BLOCK_LOAD(c0_); + const AEGIS_AES_BLOCK_T c1 = AEGIS_AES_BLOCK_LOAD(c1_); + uint8_t tmp[2 * 16]; + uint8_t context_bytes[AES_BLOCK_LENGTH]; + AEGIS_AES_BLOCK_T context; + AEGIS_AES_BLOCK_T k; + AEGIS_AES_BLOCK_T n; + int i; + + memcpy(tmp, key, 16); + memcpy(tmp + 16, key, 16); + k = AEGIS_AES_BLOCK_LOAD(tmp); + + memcpy(tmp, nonce, 16); + memcpy(tmp + 16, nonce, 16); + n = AEGIS_AES_BLOCK_LOAD(tmp); + + memset(context_bytes, 0, sizeof context_bytes); + context_bytes[0 * 16] = 0x00; + context_bytes[0 * 16 + 1] = 0x01; + context_bytes[1 * 16] = 0x01; + context_bytes[1 * 16 + 1] = 0x01; + context = AEGIS_AES_BLOCK_LOAD(context_bytes); + + state[0] = AEGIS_AES_BLOCK_XOR(k, n); + state[1] = c1; + state[2] = c0; + state[3] = c1; + state[4] = AEGIS_AES_BLOCK_XOR(k, n); + state[5] = AEGIS_AES_BLOCK_XOR(k, c0); + state[6] = AEGIS_AES_BLOCK_XOR(k, c1); + state[7] = AEGIS_AES_BLOCK_XOR(k, c0); + for (i = 0; i < 10; i++) { + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[7] = AEGIS_AES_BLOCK_XOR(state[7], context); + AEGIS_update(state, n, k); + } +} + +static void +AEGIS_mac(uint8_t *mac, size_t maclen, uint64_t adlen, uint64_t mlen, AEGIS_AES_BLOCK_T *const state) +{ + uint8_t mac_multi_0[AES_BLOCK_LENGTH]; + uint8_t mac_multi_1[AES_BLOCK_LENGTH]; + AEGIS_AES_BLOCK_T tmp; + int i; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(mlen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } + + if (maclen == 16) { + tmp = AEGIS_AES_BLOCK_XOR(state[6], AEGIS_AES_BLOCK_XOR(state[5], state[4])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac_multi_0, tmp); + for (i = 0; i < 16; i++) { + mac[i] = mac_multi_0[i] ^ mac_multi_0[1 * 16 + i]; + } + } else if (maclen == 32) { + tmp = AEGIS_AES_BLOCK_XOR(state[3], state[2]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac_multi_0, tmp); + for (i = 0; i < 16; i++) { + mac[i] = mac_multi_0[i] ^ mac_multi_0[1 * 16 + i]; + } + + tmp = AEGIS_AES_BLOCK_XOR(state[7], state[6]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[5], state[4])); + AEGIS_AES_BLOCK_STORE(mac_multi_1, tmp); + for (i = 0; i < 16; i++) { + mac[i + 16] = mac_multi_1[i] ^ mac_multi_1[1 * 16 + i]; + } + } else { + memset(mac, 0, maclen); + } +} + +static inline void +AEGIS_absorb(const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_enc(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + AEGIS_AES_BLOCK_T tmp0, tmp1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + tmp0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + tmp0 = AEGIS_AES_BLOCK_XOR(tmp0, state[1]); + tmp1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + tmp1 = AEGIS_AES_BLOCK_XOR(tmp1, state[2]); + tmp0 = AEGIS_AES_BLOCK_XOR(tmp0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + tmp1 = AEGIS_AES_BLOCK_XOR(tmp1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(dst, tmp0); + AEGIS_AES_BLOCK_STORE(dst + AES_BLOCK_LENGTH, tmp1); + + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_dec(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[1]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[2]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(dst, msg0); + AEGIS_AES_BLOCK_STORE(dst + AES_BLOCK_LENGTH, msg1); + + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_declast(uint8_t *const dst, const uint8_t *const src, size_t len, + AEGIS_AES_BLOCK_T *const state) +{ + uint8_t pad[AEGIS_RATE]; + AEGIS_AES_BLOCK_T msg0, msg1; + + memset(pad, 0, sizeof pad); + memcpy(pad, src, len); + + msg0 = AEGIS_AES_BLOCK_LOAD(pad); + msg1 = AEGIS_AES_BLOCK_LOAD(pad + AES_BLOCK_LENGTH); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[1]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[2]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(pad, msg0); + AEGIS_AES_BLOCK_STORE(pad + AES_BLOCK_LENGTH, msg1); + + memset(pad + len, 0, sizeof pad - len); + memcpy(dst, pad, len); + + msg0 = AEGIS_AES_BLOCK_LOAD(pad); + msg1 = AEGIS_AES_BLOCK_LOAD(pad + AES_BLOCK_LENGTH); + + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_mac_nr(uint8_t *mac, size_t maclen, uint64_t adlen, AEGIS_AES_BLOCK_T*state) +{ + uint8_t t[2 * AES_BLOCK_LENGTH]; + uint8_t r[AEGIS_RATE]; + AEGIS_AES_BLOCK_T tmp; + int i; + const int d = AES_BLOCK_LENGTH / 16; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } + + memset(r, 0, sizeof r); + if (maclen == 16) { +#if AES_BLOCK_LENGTH > 16 + tmp = AEGIS_AES_BLOCK_XOR(state[6], AEGIS_AES_BLOCK_XOR(state[5], state[4])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + for (i = 0; i < d / 2; i++) { + memcpy(r, t + i * 32, 32); + AEGIS_absorb(r, state); + } + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, d); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } +#endif + tmp = AEGIS_AES_BLOCK_XOR(state[6], AEGIS_AES_BLOCK_XOR(state[5], state[4])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac, t, 16); + } else if (maclen == 32) { +#if AES_BLOCK_LENGTH > 16 + tmp = AEGIS_AES_BLOCK_XOR(state[3], state[2]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + tmp = AEGIS_AES_BLOCK_XOR(state[7], state[6]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[5], state[4])); + AEGIS_AES_BLOCK_STORE(t + AES_BLOCK_LENGTH, tmp); + for (i = 1; i < d; i++) { + memcpy(r, t + i * 16, 16); + memcpy(r + 16, t + AES_BLOCK_LENGTH + i * 16, 16); + AEGIS_absorb(r, state); + } + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, d); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } +#endif + tmp = AEGIS_AES_BLOCK_XOR(state[3], state[2]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac, t, 16); + tmp = AEGIS_AES_BLOCK_XOR(state[7], state[6]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[5], state[4])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac + 16, t, 16); + } else { + memset(mac, 0, maclen); + } +} + +static int +AEGIS_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } + + AEGIS_mac(mac, maclen, adlen, mlen, state); + + return 0; +} + +static int +AEGIS_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, size_t maclen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + const size_t mlen = clen; + size_t i; + int ret; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + if (m != NULL) { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + } else { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, state); + } + } + if (mlen % AEGIS_RATE) { + if (m != NULL) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } else { + AEGIS_declast(dst, c + i, mlen % AEGIS_RATE, state); + } + } + + COMPILER_ASSERT(sizeof computed_mac >= 32); + AEGIS_mac(computed_mac, maclen, adlen, mlen, state); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret != 0 && m != NULL) { + memset(m, 0, mlen); + } + return ret; +} + +static void +AEGIS_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + memset(src, 0, sizeof src); + if (npub == NULL) { + npub = src; + } + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= len; i += AEGIS_RATE) { + AEGIS_enc(out + i, src, state); + } + if (len % AEGIS_RATE) { + AEGIS_enc(dst, src, state); + memcpy(out + i, dst, len % AEGIS_RATE); + } +} + +static void +AEGIS_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } +} + +static void +AEGIS_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + const size_t mlen = clen; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + if (mlen % AEGIS_RATE) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } +} + +typedef struct AEGIS_STATE { + AEGIS_BLOCKS blocks; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + uint64_t mlen; + size_t pos; +} AEGIS_STATE; + +typedef struct AEGIS_MAC_STATE { + AEGIS_BLOCKS blocks; + AEGIS_BLOCKS blocks0; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + size_t pos; +} AEGIS_MAC_STATE; + +#ifndef AEGIS_OMIT_INCREMENTAL + +static void +AEGIS_state_init(aegis128x2_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + + memcpy(blocks, st->blocks, sizeof blocks); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->mlen = 0; + st->pos = 0; + + AEGIS_init(k, npub, blocks); + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (adlen % AEGIS_RATE) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(st->buf, blocks); + } + st->adlen = adlen; + + memcpy(st->blocks, blocks, sizeof blocks); +} + +static int +AEGIS_state_encrypt_update(aegis128x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += mlen; + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = mlen < available ? mlen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, m + i, n); + m += n; + mlen -= n; + st->pos += n; + } + if (st->pos == sizeof st->buf) { + if (clen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + clen_max -= AEGIS_RATE; + AEGIS_enc(c, st->buf, blocks); + *written += AEGIS_RATE; + c += AEGIS_RATE; + st->pos = 0; + } else { + return 0; + } + } + if (clen_max < (mlen & ~(size_t) (AEGIS_RATE - 1))) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, blocks); + } + *written += i; + left = mlen % AEGIS_RATE; + if (left != 0) { + memcpy(st->buf, m + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_detached_final(aegis128x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(mac, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_final(aegis128x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos + maclen) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(c + st->pos, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos + maclen; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_update(aegis128x2_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *c, size_t clen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += clen; + + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = clen < available ? clen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, c, n); + c += n; + clen -= n; + st->pos += n; + } + if (st->pos < (sizeof st->buf)) { + return 0; + } + st->pos = 0; + if (m != NULL) { + if (mlen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + mlen_max -= AEGIS_RATE; + AEGIS_dec(m, st->buf, blocks); + m += AEGIS_RATE; + } else { + AEGIS_dec(dst, st->buf, blocks); + } + *written += AEGIS_RATE; + } + + if (m != NULL) { + if (mlen_max < (clen % AEGIS_RATE)) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, blocks); + } + } else { + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, blocks); + } + } + *written += i; + left = clen % AEGIS_RATE; + if (left) { + memcpy(st->buf, c + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_final(aegis128x2_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + int ret; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (st->pos != 0) { + if (m != NULL) { + if (mlen_max < st->pos) { + errno = ERANGE; + return -1; + } + AEGIS_declast(m, st->buf, st->pos, blocks); + } else { + AEGIS_declast(dst, st->buf, st->pos, blocks); + } + } + AEGIS_mac(computed_mac, maclen, st->adlen, st->mlen, blocks); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret == 0) { + *written = st->pos; + } else { + memset(m, 0, st->pos); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return ret; +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +#ifndef AEGIS_OMIT_MAC_API + +static void +AEGIS_state_mac_init(aegis128x2_mac_state *st_, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->pos = 0; + + memcpy(blocks, st->blocks, sizeof blocks); + + AEGIS_init(k, npub, blocks); + + memcpy(st->blocks0, blocks, sizeof blocks); + memcpy(st->blocks, blocks, sizeof blocks); + st->adlen = 0; +} + +static int +AEGIS_state_mac_update(aegis128x2_mac_state *st_, const uint8_t *ad, size_t adlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + st->adlen += adlen; + if (left != 0) { + if (left + adlen < AEGIS_RATE) { + memcpy(st->buf + left, ad, adlen); + return 0; + } + memcpy(st->buf + left, ad, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + ad += AEGIS_RATE - left; + adlen -= AEGIS_RATE - left; + } + for (i = 0; i + AEGIS_RATE * 2 <= adlen; i += AEGIS_RATE * 2) { + AEGIS_AES_BLOCK_T msg0, msg1, msg2, msg3; + + msg0 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 0); + msg1 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 1); + msg2 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 2); + msg3 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 3); + COMPILER_ASSERT(AES_BLOCK_LENGTH * 4 == AEGIS_RATE * 2); + + AEGIS_update(blocks, msg0, msg1); + AEGIS_update(blocks, msg2, msg3); + } + for (; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (i < adlen) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen - i); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_mac_final(aegis128x2_mac_state *st_, uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + if (left != 0) { + memset(st->buf + left, 0, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + } + AEGIS_mac_nr(mac, maclen, st->adlen, blocks); + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static void +AEGIS_state_mac_reset(aegis128x2_mac_state *st_) +{ + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + st->adlen = 0; + st->pos = 0; + memcpy(st->blocks, st->blocks0, sizeof(AEGIS_BLOCKS)); + +} + +static void +AEGIS_state_mac_clone(aegis128x2_mac_state *dst, const aegis128x2_mac_state *src) +{ + AEGIS_MAC_STATE *const dst_ = + (AEGIS_MAC_STATE *) ((((uintptr_t) &dst->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + const AEGIS_MAC_STATE*const src_ = + (const AEGIS_MAC_STATE*) ((((uintptr_t) &src->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + *dst_ = *src_; +} + +#endif /* AEGIS_OMIT_MAC_API */ + +#undef AEGIS_RATE +#undef AEGIS_ALIGNMENT + +#undef AEGIS_init +#undef AEGIS_mac +#undef AEGIS_mac_nr +#undef AEGIS_absorb +#undef AEGIS_enc +#undef AEGIS_dec +#undef AEGIS_declast diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_soft.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_soft.c new file mode 100644 index 0000000000..c7fb213b16 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_soft.c @@ -0,0 +1,100 @@ +/* +** Name: aegis128x2_soft.c +** Purpose: Implementation of AEGIS-128x2 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" + +#include "../common/softaes.h" +#include "aegis128x2.h" +#include "aegis128x2_soft.h" + +#define AES_BLOCK_LENGTH 32 + +typedef struct { + SoftAesBlock b0; + SoftAesBlock b1; +} aegis128x2_soft_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x2_soft_aes_block_t +#define AEGIS_BLOCKS aegis128x2_soft_blocks +#define AEGIS_STATE _aegis128x2_soft_state +#define AEGIS_MAC_STATE _aegis128x2_soft_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x2_soft_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_xor(a.b0, b.b0), softaes_block_xor(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_and(a.b0, b.b0), softaes_block_and(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_load(a), softaes_block_load(a + 16) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const SoftAesBlock t = softaes_block_load64x2(a, b); + return (AEGIS_AES_BLOCK_T) { t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + softaes_block_store(a, b.b0); + softaes_block_store(a + 16, b.b1); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_encrypt(a.b0, b.b0), softaes_block_encrypt(a.b1, b.b1) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128x2_common.h" + +struct aegis128x2_implementation aegis128x2_soft_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_soft.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_soft.h new file mode 100644 index 0000000000..ed9ea12cab --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/aegis128x2_soft.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128x2_soft.h +** Purpose: Header for implementation structure of AEGIS-128x2 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X2_SOFT_H +#define AEGIS128X2_SOFT_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128x2_implementation aegis128x2_soft_implementation; + +#endif /* AEGIS128X2_SOFT_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/implementations.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/implementations.h new file mode 100644 index 0000000000..846394ab43 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x2/implementations.h @@ -0,0 +1,50 @@ +/* +** Name: implementations.h +** Purpose: Header for implementation structure of AEGIS-128x2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X2_IMPLEMENTATIONS_H +#define AEGIS128X2_IMPLEMENTATIONS_H + +#include +#include + +#include "aegis128x2.h" + +typedef struct aegis128x2_implementation { + int (*encrypt_detached)(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k); + int (*decrypt_detached)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + void (*stream)(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + void (*encrypt_unauthenticated)(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k); + void (*decrypt_unauthenticated)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k); +#ifndef AEGIS_OMIT_INCREMENTAL + void (*state_init)(aegis128x2_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + int (*state_encrypt_update)(aegis128x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen); + int (*state_encrypt_detached_final)(aegis128x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + int (*state_encrypt_final)(aegis128x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen); + int (*state_decrypt_detached_update)(aegis128x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen); + int (*state_decrypt_detached_final)(aegis128x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen); +#endif /* AEGIS_OMIT_INCREMENTAL */ +#ifndef AEGIS_OMIT_MAC_API + void (*state_mac_init)(aegis128x2_mac_state *st_, const uint8_t *npub, const uint8_t *k); + int (*state_mac_update)(aegis128x2_mac_state *st_, const uint8_t *ad, size_t adlen); + int (*state_mac_final)(aegis128x2_mac_state *st_, uint8_t *mac, size_t maclen); + void (*state_mac_reset)(aegis128x2_mac_state *st); + void (*state_mac_clone)(aegis128x2_mac_state *dst, const aegis128x2_mac_state *src); +#endif /* AEGIS_OMIT_MAC_API */ +} aegis128x2_implementation; + +#endif /* AEGIS128X2_IMPLEMENTATIONS_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4.c new file mode 100644 index 0000000000..4407317148 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4.c @@ -0,0 +1,309 @@ +/* +** Name: aegis128x4.c +** Purpose: Implementation of AEGIS-128x4 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" +#include "../include/aegis128x4.h" + +#if 0 +#include "aegis128x4_aesni.h" +#include "aegis128x4_altivec.h" +#include "aegis128x4_armcrypto.h" +#include "aegis128x4_avx2.h" +#include "aegis128x4_avx512.h" +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NONE +#include "aegis128x4_soft.h" +static const aegis128x4_implementation* implementation_128x4 = &aegis128x4_soft_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON +static const aegis128x4_implementation* implementation_128x4 = &aegis128x4_armcrypto_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +static const aegis128x4_implementation* implementation_128x4 = &aegis128x4_aesni_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC +static const aegis128x4_implementation* implementation_128x4 = &aegis128x4_altivec_implementation; +#else +#error "Unsupported architecture" +#endif + +AEGIS_API +size_t +aegis128x4_keybytes(void) +{ + return aegis128x4_KEYBYTES; +} + +AEGIS_API +size_t +aegis128x4_npubbytes(void) +{ + return aegis128x4_NPUBBYTES; +} + +AEGIS_API +size_t +aegis128x4_abytes_min(void) +{ + return aegis128x4_ABYTES_MIN; +} + +AEGIS_API +size_t +aegis128x4_abytes_max(void) +{ + return aegis128x4_ABYTES_MAX; +} + +AEGIS_API +size_t +aegis128x4_tailbytes_max(void) +{ + return aegis128x4_TAILBYTES_MAX; +} + +AEGIS_API +int +aegis128x4_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x4->encrypt_detached(c, mac, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128x4_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x4->decrypt_detached(m, c, clen, mac, maclen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128x4_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + return aegis128x4_encrypt_detached(c, c + mlen, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128x4_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + int ret = -1; + + if (clen >= maclen) { + ret = aegis128x4_decrypt_detached(m, c, clen - maclen, c + clen - maclen, maclen, ad, adlen, + npub, k); + } + return ret; +} + +#ifndef AEGIS_OMIT_INCREMENTAL + +AEGIS_API +void +aegis128x4_state_init(aegis128x4_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + memset(st_, 0, sizeof *st_); + implementation_128x4->state_init(st_, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis128x4_state_encrypt_update(aegis128x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + return implementation_128x4->state_encrypt_update(st_, c, clen_max, written, m, mlen); +} + +AEGIS_API +int +aegis128x4_state_encrypt_detached_final(aegis128x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x4->state_encrypt_detached_final(st_, c, clen_max, written, mac, maclen); +} + +AEGIS_API +int +aegis128x4_state_encrypt_final(aegis128x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x4->state_encrypt_final(st_, c, clen_max, written, maclen); +} + +AEGIS_API +int +aegis128x4_state_decrypt_detached_update(aegis128x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) +{ + return implementation_128x4->state_decrypt_detached_update(st_, m, mlen_max, written, c, clen); +} + +AEGIS_API +int +aegis128x4_state_decrypt_detached_final(aegis128x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x4->state_decrypt_detached_final(st_, m, mlen_max, written, mac, maclen); +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +AEGIS_API +void +aegis128x4_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + implementation_128x4->stream(out, len, npub, k); +} + +AEGIS_API +void +aegis128x4_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_128x4->encrypt_unauthenticated(c, m, mlen, npub, k); +} + +AEGIS_API +void +aegis128x4_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_128x4->decrypt_unauthenticated(m, c, clen, npub, k); +} + +#ifndef AEGIS_OMIT_MAC_API + +AEGIS_API +void +aegis128x4_mac_init(aegis128x4_mac_state *st_, const uint8_t *k, const uint8_t *npub) +{ + implementation_128x4->state_mac_init(st_, npub, k); +} + +AEGIS_API +int +aegis128x4_mac_update(aegis128x4_mac_state *st_, const uint8_t *m, size_t mlen) +{ + return implementation_128x4->state_mac_update(st_, m, mlen); +} + +AEGIS_API +int +aegis128x4_mac_final(aegis128x4_mac_state *st_, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_128x4->state_mac_final(st_, mac, maclen); +} + +AEGIS_API +int +aegis128x4_mac_verify(aegis128x4_mac_state *st_, const uint8_t *mac, size_t maclen) +{ + uint8_t expected_mac[32]; + + switch (maclen) { + case 16: + implementation_128x4->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_16(expected_mac, mac); + case 32: + implementation_128x4->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_32(expected_mac, mac); + default: + errno = EINVAL; + return -1; + } +} + +AEGIS_API +void +aegis128x4_mac_reset(aegis128x4_mac_state *st_) +{ + implementation_128x4->state_mac_reset(st_); +} + +AEGIS_API +void +aegis128x4_mac_state_clone(aegis128x4_mac_state *dst, const aegis128x4_mac_state *src) +{ + implementation_128x4->state_mac_clone(dst, src); +} + +#endif /* AEGIS_OMIT_MAC_API */ + +AEGIS_PRIVATE +int +aegis128x4_pick_best_implementation(void) +{ + implementation_128x4 = &aegis128x4_soft_implementation; + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + if (aegis_runtime_has_armcrypto()) { + implementation_128x4 = &aegis128x4_armcrypto_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +# ifdef HAVE_VAESINTRIN_H + if (aegis_runtime_has_vaes() && aegis_runtime_has_avx512f()) { + implementation_128x4 = &aegis128x4_avx512_implementation; + return 0; + } + if (aegis_runtime_has_vaes() && aegis_runtime_has_avx2()) { + implementation_128x4 = &aegis128x4_avx2_implementation; + return 0; + } +# endif + if (aegis_runtime_has_aesni() && aegis_runtime_has_avx()) { + implementation_128x4 = &aegis128x4_aesni_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC + if (aegis_runtime_has_altivec()) { + implementation_128x4 = &aegis128x4_altivec_implementation; + return 0; + } +#endif + + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_aesni.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_aesni.c new file mode 100644 index 0000000000..6e327887fe --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_aesni.c @@ -0,0 +1,125 @@ +/* +** Name: aegis128x4_aesni.c +** Purpose: Implementation of AEGIS-128x4 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x4.h" +#include "aegis128x4_aesni.h" + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("aes,avx") +#endif + +#include +#include + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + __m128i b0; + __m128i b1; + __m128i b2; + __m128i b3; +} aegis128x4_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x4_aes_block_t +#define AEGIS_BLOCKS aegis128x4_blocks +#define AEGIS_STATE _aegis128x4_state +#define AEGIS_MAC_STATE _aegis128x4_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x4_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_xor_si128(a.b0, b.b0), _mm_xor_si128(a.b1, b.b1), + _mm_xor_si128(a.b2, b.b2), _mm_xor_si128(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_and_si128(a.b0, b.b0), _mm_and_si128(a.b1, b.b1), + _mm_and_si128(a.b2, b.b2), _mm_and_si128(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { _mm_loadu_si128((const __m128i *) (const void *) a), + _mm_loadu_si128((const __m128i *) (const void *) (a + 16)), + _mm_loadu_si128((const __m128i *) (const void *) (a + 32)), + _mm_loadu_si128((const __m128i *) (const void *) (a + 48)) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const __m128i t = _mm_set_epi64x((long long) a, (long long) b); + return (AEGIS_AES_BLOCK_T) { t, t, t, t }; +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm_storeu_si128((__m128i *) (void *) a, b.b0); + _mm_storeu_si128((__m128i *) (void *) (a + 16), b.b1); + _mm_storeu_si128((__m128i *) (void *) (a + 32), b.b2); + _mm_storeu_si128((__m128i *) (void *) (a + 48), b.b3); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_aesenc_si128(a.b0, b.b0), _mm_aesenc_si128(a.b1, b.b1), + _mm_aesenc_si128(a.b2, b.b2), _mm_aesenc_si128(a.b3, b.b3) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128x4_common.h" + +struct aegis128x4_implementation aegis128x4_aesni_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_aesni.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_aesni.h new file mode 100644 index 0000000000..087e91f0f3 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_aesni.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128x4_aesni.h +** Purpose: Header for implementation structure of AEGIS-128x4 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X4_AESNI_H +#define AEGIS128X4_AESNI_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128x4_implementation aegis128x4_aesni_implementation; + +#endif /* AEGIS128X4_AESNI_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_altivec.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_altivec.c new file mode 100644 index 0000000000..08d7a825f9 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_altivec.c @@ -0,0 +1,119 @@ +/* +** Name: aegis128x4_altivec.c +** Purpose: Implementation of AEGIS-128x4 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__ALTIVEC__) && defined(__CRYPTO__) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x4.h" +#include "aegis128x4_altivec.h" + +#include + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("altivec,crypto"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("altivec,crypto") +#endif + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + vector unsigned char b0; + vector unsigned char b1; + vector unsigned char b2; + vector unsigned char b3; +} aegis128x4_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x4_aes_block_t +#define AEGIS_BLOCKS aegis128x4_blocks +#define AEGIS_STATE _aegis128x4_state +#define AEGIS_MAC_STATE _aegis128x4_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x4_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_xor(a.b0, b.b0), vec_xor(a.b1, b.b1), + vec_xor(a.b2, b.b2), vec_xor(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_and(a.b0, b.b0), vec_and(a.b1, b.b1), + vec_and(a.b2, b.b2), vec_and(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { vec_xl_be(0, a), vec_xl_be(0, a + 16), + vec_xl_be(0, a + 32), vec_xl_be(0, a + 48) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const vector unsigned char t = + (vector unsigned char) vec_revb(vec_insert(a, vec_promote((unsigned long long) (b), 1), 0)); + return (AEGIS_AES_BLOCK_T) { t, t, t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vec_xst_be(b.b0, 0, a); + vec_xst_be(b.b1, 0, a + 16); + vec_xst_be(b.b2, 0, a + 32); + vec_xst_be(b.b3, 0, a + 48); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_cipher_be(a.b0, b.b0), vec_cipher_be(a.b1, b.b1), + vec_cipher_be(a.b2, b.b2), vec_cipher_be(a.b3, b.b3) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(state[3], state[4]), d2); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d1); +} + +#include "aegis128x4_common.h" + +struct aegis128x4_implementation aegis128x4_altivec_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_altivec.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_altivec.h new file mode 100644 index 0000000000..7aeb3e54b7 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_altivec.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128x4_altivec.h +** Purpose: Header for implementation structure of AEGIS-128x4 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X4_ALTIVEC_H +#define AEGIS128X4_ALTIVEC_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128x4_implementation aegis128x4_altivec_implementation; + +#endif /* AEGIS128X4_ALTIVEC_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_armcrypto.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_armcrypto.c new file mode 100644 index 0000000000..ef60de812c --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_armcrypto.c @@ -0,0 +1,133 @@ +/* +** Name: aegis128x4_armcrypto.c +** Purpose: Implementation of AEGIS-128x4 - ARM-Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include "../common/aeshardware.h" + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x4.h" +#include "aegis128x4_armcrypto.h" + +#ifndef __ARM_FEATURE_CRYPTO +# define __ARM_FEATURE_CRYPTO 1 +#endif +#ifndef __ARM_FEATURE_AES +# define __ARM_FEATURE_AES 1 +#endif + +#ifdef USE_ARM64_NEON_H +#include +#else +#include +#endif + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("neon,crypto,aes"))), \ + apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("+simd+crypto") +#endif + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + uint8x16_t b0; + uint8x16_t b1; + uint8x16_t b2; + uint8x16_t b3; +} aegis128x4_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x4_aes_block_t +#define AEGIS_BLOCKS aegis128x4_blocks +#define AEGIS_STATE _aegis128x4_state +#define AEGIS_MAC_STATE _aegis128x4_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x4_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { veorq_u8(a.b0, b.b0), veorq_u8(a.b1, b.b1), veorq_u8(a.b2, b.b2), + veorq_u8(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vandq_u8(a.b0, b.b0), vandq_u8(a.b1, b.b1), vandq_u8(a.b2, b.b2), + vandq_u8(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { vld1q_u8(a), vld1q_u8(a + 16), vld1q_u8(a + 32), vld1q_u8(a + 48) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const uint8x16_t t = vreinterpretq_u8_u64(vsetq_lane_u64((a), vmovq_n_u64(b), 1)); + return (AEGIS_AES_BLOCK_T) { t, t, t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vst1q_u8(a, b.b0); + vst1q_u8(a + 16, b.b1); + vst1q_u8(a + 32, b.b2); + vst1q_u8(a + 48, b.b3); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { veorq_u8(vaesmcq_u8(vaeseq_u8((a.b0), vmovq_n_u8(0))), (b.b0)), + veorq_u8(vaesmcq_u8(vaeseq_u8((a.b1), vmovq_n_u8(0))), (b.b1)), + veorq_u8(vaesmcq_u8(vaeseq_u8((a.b2), vmovq_n_u8(0))), (b.b2)), + veorq_u8(vaesmcq_u8(vaeseq_u8((a.b3), vmovq_n_u8(0))), (b.b3)) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(state[3], state[4]), d2); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d1); +} + +#include "aegis128x4_common.h" + +struct aegis128x4_implementation aegis128x4_armcrypto_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_armcrypto.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_armcrypto.h new file mode 100644 index 0000000000..43d2c1adc4 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_armcrypto.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128x4_armcrypto.h +** Purpose: Header for implementation structure of AEGIS-128x4 - ARM Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X4_ARMCRYPTO_H +#define AEGIS128X4_ARMCRYPTO_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128x4_implementation aegis128x4_armcrypto_implementation; + +#endif /* AEGIS128X4_ARMCRYPTO_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx2.c new file mode 100644 index 0000000000..13eb3a40bb --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx2.c @@ -0,0 +1,119 @@ +/* +** Name: aegis128x4_avx2.c +** Purpose: Implementation of AEGIS-128x4 - AES-NI AVX2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x4.h" +#include "aegis128x4_avx2.h" + +#ifdef HAVE_VAESINTRIN_H + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("vaes,avx2"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("vaes,avx2") +#endif + +#include + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + __m256i b0; + __m256i b1; +} aegis128x4_avx2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x4_avx2_aes_block_t +#define AEGIS_BLOCKS aegis128x4_avx2_blocks +#define AEGIS_STATE _aegis128x4_avx2_state +#define AEGIS_MAC_STATE _aegis128x4_avx2_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x4_avx2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm256_xor_si256(a.b0, b.b0), _mm256_xor_si256(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm256_and_si256(a.b0, b.b0), _mm256_and_si256(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { _mm256_loadu_si256((const __m256i *) (const void *) a), + _mm256_loadu_si256((const __m256i *) (const void *) (a + 32)) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const __m256i t = _mm256_broadcastsi128_si256(_mm_set_epi64x((long long) a, (long long) b)); + return (AEGIS_AES_BLOCK_T) { t, t }; +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm256_storeu_si256((__m256i *) (void *) a, b.b0); + _mm256_storeu_si256((__m256i *) (void *) (a + 32), b.b1); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm256_aesenc_epi128(a.b0, b.b0), _mm256_aesenc_epi128(a.b1, b.b1) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128x4_common.h" + +struct aegis128x4_implementation aegis128x4_avx2_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif /* HAVE_VAESINTRIN_H */ + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx2.h new file mode 100644 index 0000000000..25485d9944 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx2.h @@ -0,0 +1,18 @@ +/* +** Name: aegis128x4_avx2.h +** Purpose: Header for implementation structure of AEGIS-128x4 - AES-NI AVX2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X4_AVX2_H +#define AEGIS128X4_AVX2_H + +#include "../common/common.h" +#include "implementations.h" + +#ifdef HAVE_VAESINTRIN_H +extern struct aegis128x4_implementation aegis128x4_avx2_implementation; +#endif + +#endif /* AEGIS128X4_AVX2_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx512.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx512.c new file mode 100644 index 0000000000..513dbd33b5 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx512.c @@ -0,0 +1,119 @@ +/* +** Name: aegis128x4_avx512.c +** Purpose: Implementation of AEGIS-128x4 - AES-NI AVX512 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis128x4.h" +#include "aegis128x4_avx512.h" + +#ifdef HAVE_VAESINTRIN_H + +#ifdef __clang__ +# if __clang_major__ >= 18 +# pragma clang attribute push(__attribute__((target("vaes,avx512f,evex512"))), \ + apply_to = function) +# else +# pragma clang attribute push(__attribute__((target("vaes,avx512f"))), \ + apply_to = function) +# endif +#elif defined(__GNUC__) +# pragma GCC target("vaes,avx512f") +#endif + +#include + +#define AES_BLOCK_LENGTH 64 + +typedef __m512i aegis128x4_avx512_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x4_avx512_aes_block_t +#define AEGIS_BLOCKS aegis128x4_avx512_blocks +#define AEGIS_STATE _aegis128x4_avx512_state +#define AEGIS_MAC_STATE _aegis128x4_avx512_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x4_avx512_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm512_xor_si512(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm512_and_si512(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return _mm512_loadu_si512((const AEGIS_AES_BLOCK_T *) (const void *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return _mm512_broadcast_i32x4(_mm_set_epi64x(a, b)); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm512_storeu_si512((AEGIS_AES_BLOCK_T *) (void *) a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm512_aesenc_epi128(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128x4_common.h" + +struct aegis128x4_implementation aegis128x4_avx512_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif /* HAVE_VAESINTRIN_H */ + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx512.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx512.h new file mode 100644 index 0000000000..de73238cbc --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_avx512.h @@ -0,0 +1,18 @@ +/* +** Name: aegis128x4_avx512.h +** Purpose: Header for implementation structure of AEGIS-128x4 - AES-NI AVX512 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X4_AVX512_H +#define AEGIS128X4_AVX512_H + +#include "../common/common.h" +#include "implementations.h" + +#ifdef HAVE_VAESINTRIN_H +extern struct aegis128x4_implementation aegis128x4_avx512_implementation; +#endif + +#endif /* AEGIS128X4_AVX512_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_common.h new file mode 100644 index 0000000000..58c5ae22bd --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_common.h @@ -0,0 +1,847 @@ +/* +** Name: aegis128x4_common.h +** Purpose: Common implementation for AEGIS-128x4 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#define AEGIS_RATE 128 +#define AEGIS_ALIGNMENT 64 + +typedef AEGIS_AES_BLOCK_T AEGIS_BLOCKS[8]; + +#define AEGIS_init AEGIS_FUNC(init) +#define AEGIS_mac AEGIS_FUNC(mac) +#define AEGIS_mac_nr AEGIS_FUNC(mac_nr) +#define AEGIS_absorb AEGIS_FUNC(absorb) +#define AEGIS_enc AEGIS_FUNC(enc) +#define AEGIS_dec AEGIS_FUNC(dec) +#define AEGIS_declast AEGIS_FUNC(declast) + +static void +AEGIS_init(const uint8_t *key, const uint8_t *nonce, AEGIS_AES_BLOCK_T *const state) +{ + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) const uint8_t c0_[AES_BLOCK_LENGTH] = { + 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, + 0xe9, 0x79, 0x62, 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, + 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62, 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, + 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62, 0x00, 0x01, 0x01, 0x02, + 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62, + }; + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) const uint8_t c1_[AES_BLOCK_LENGTH] = { + 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, + 0xb5, 0x28, 0xdd, 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, + 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd, 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, + 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd, 0xdb, 0x3d, 0x18, 0x55, + 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd, + }; + + const AEGIS_AES_BLOCK_T c0 = AEGIS_AES_BLOCK_LOAD(c0_); + const AEGIS_AES_BLOCK_T c1 = AEGIS_AES_BLOCK_LOAD(c1_); + uint8_t tmp[4 * 16]; + uint8_t context_bytes[AES_BLOCK_LENGTH]; + AEGIS_AES_BLOCK_T context; + AEGIS_AES_BLOCK_T k; + AEGIS_AES_BLOCK_T n; + int i; + + memcpy(tmp, key, 16); + memcpy(tmp + 16, key, 16); + memcpy(tmp + 32, key, 16); + memcpy(tmp + 48, key, 16); + k = AEGIS_AES_BLOCK_LOAD(tmp); + + memcpy(tmp, nonce, 16); + memcpy(tmp + 16, nonce, 16); + memcpy(tmp + 32, nonce, 16); + memcpy(tmp + 48, nonce, 16); + n = AEGIS_AES_BLOCK_LOAD(tmp); + + memset(context_bytes, 0, sizeof context_bytes); + context_bytes[0 * 16] = 0x00; + context_bytes[0 * 16 + 1] = 0x03; + context_bytes[1 * 16] = 0x01; + context_bytes[1 * 16 + 1] = 0x03; + context_bytes[2 * 16] = 0x02; + context_bytes[2 * 16 + 1] = 0x03; + context_bytes[3 * 16] = 0x03; + context_bytes[3 * 16 + 1] = 0x03; + context = AEGIS_AES_BLOCK_LOAD(context_bytes); + + state[0] = AEGIS_AES_BLOCK_XOR(k, n); + state[1] = c1; + state[2] = c0; + state[3] = c1; + state[4] = AEGIS_AES_BLOCK_XOR(k, n); + state[5] = AEGIS_AES_BLOCK_XOR(k, c0); + state[6] = AEGIS_AES_BLOCK_XOR(k, c1); + state[7] = AEGIS_AES_BLOCK_XOR(k, c0); + for (i = 0; i < 10; i++) { + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[7] = AEGIS_AES_BLOCK_XOR(state[7], context); + AEGIS_update(state, n, k); + } +} + +static void +AEGIS_mac(uint8_t *mac, size_t maclen, uint64_t adlen, uint64_t mlen, AEGIS_AES_BLOCK_T *const state) +{ + uint8_t mac_multi_0[AES_BLOCK_LENGTH]; + uint8_t mac_multi_1[AES_BLOCK_LENGTH]; + AEGIS_AES_BLOCK_T tmp; + int i; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(mlen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } + + if (maclen == 16) { + tmp = AEGIS_AES_BLOCK_XOR(state[6], AEGIS_AES_BLOCK_XOR(state[5], state[4])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac_multi_0, tmp); + for (i = 0; i < 16; i++) { + mac[i] = mac_multi_0[i] ^ mac_multi_0[1 * 16 + i] ^ mac_multi_0[2 * 16 + i] ^ + mac_multi_0[3 * 16 + i]; + } + } else if (maclen == 32) { + tmp = AEGIS_AES_BLOCK_XOR(state[3], state[2]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac_multi_0, tmp); + for (i = 0; i < 16; i++) { + mac[i] = mac_multi_0[i] ^ mac_multi_0[1 * 16 + i] ^ mac_multi_0[2 * 16 + i] ^ + mac_multi_0[3 * 16 + i]; + } + + tmp = AEGIS_AES_BLOCK_XOR(state[7], state[6]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[5], state[4])); + AEGIS_AES_BLOCK_STORE(mac_multi_1, tmp); + for (i = 0; i < 16; i++) { + mac[i + 16] = mac_multi_1[i] ^ mac_multi_1[1 * 16 + i] ^ mac_multi_1[2 * 16 + i] ^ + mac_multi_1[3 * 16 + i]; + } + } else { + memset(mac, 0, maclen); + } +} + +static inline void +AEGIS_absorb(const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_enc(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + AEGIS_AES_BLOCK_T tmp0, tmp1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + tmp0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + tmp0 = AEGIS_AES_BLOCK_XOR(tmp0, state[1]); + tmp1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + tmp1 = AEGIS_AES_BLOCK_XOR(tmp1, state[2]); + tmp0 = AEGIS_AES_BLOCK_XOR(tmp0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + tmp1 = AEGIS_AES_BLOCK_XOR(tmp1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(dst, tmp0); + AEGIS_AES_BLOCK_STORE(dst + AES_BLOCK_LENGTH, tmp1); + + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_dec(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(src); + msg1 = AEGIS_AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[1]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[2]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(dst, msg0); + AEGIS_AES_BLOCK_STORE(dst + AES_BLOCK_LENGTH, msg1); + + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_declast(uint8_t *const dst, const uint8_t *const src, size_t len, + AEGIS_AES_BLOCK_T *const state) +{ + uint8_t pad[AEGIS_RATE]; + AEGIS_AES_BLOCK_T msg0, msg1; + + memset(pad, 0, sizeof pad); + memcpy(pad, src, len); + + msg0 = AEGIS_AES_BLOCK_LOAD(pad); + msg1 = AEGIS_AES_BLOCK_LOAD(pad + AES_BLOCK_LENGTH); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[6]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, state[1]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[5]); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, state[2]); + msg0 = AEGIS_AES_BLOCK_XOR(msg0, AEGIS_AES_BLOCK_AND(state[2], state[3])); + msg1 = AEGIS_AES_BLOCK_XOR(msg1, AEGIS_AES_BLOCK_AND(state[6], state[7])); + AEGIS_AES_BLOCK_STORE(pad, msg0); + AEGIS_AES_BLOCK_STORE(pad + AES_BLOCK_LENGTH, msg1); + + memset(pad + len, 0, sizeof pad - len); + memcpy(dst, pad, len); + + msg0 = AEGIS_AES_BLOCK_LOAD(pad); + msg1 = AEGIS_AES_BLOCK_LOAD(pad + AES_BLOCK_LENGTH); + + AEGIS_update(state, msg0, msg1); +} + +static void +AEGIS_mac_nr(uint8_t *mac, size_t maclen, uint64_t adlen, AEGIS_AES_BLOCK_T *state) +{ + uint8_t t[2 * AES_BLOCK_LENGTH]; + uint8_t r[AEGIS_RATE]; + AEGIS_AES_BLOCK_T tmp; + int i; + const int d = AES_BLOCK_LENGTH / 16; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } + + memset(r, 0, sizeof r); + if (maclen == 16) { +#if AES_BLOCK_LENGTH > 16 + tmp = AEGIS_AES_BLOCK_XOR(state[6], AEGIS_AES_BLOCK_XOR(state[5], state[4])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + for (i = 0; i < d / 2; i++) { + memcpy(r, t + i * 32, 32); + AEGIS_absorb(r, state); + } + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, d); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } +#endif + tmp = AEGIS_AES_BLOCK_XOR(state[6], AEGIS_AES_BLOCK_XOR(state[5], state[4])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac, t, 16); + } else if (maclen == 32) { +#if AES_BLOCK_LENGTH > 16 + tmp = AEGIS_AES_BLOCK_XOR(state[3], state[2]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + tmp = AEGIS_AES_BLOCK_XOR(state[7], state[6]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[5], state[4])); + AEGIS_AES_BLOCK_STORE(t + AES_BLOCK_LENGTH, tmp); + for (i = 1; i < d; i++) { + memcpy(r, t + i * 16, 16); + memcpy(r + 16, t + AES_BLOCK_LENGTH + i * 16, 16); + AEGIS_absorb(r, state); + } + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, d); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[2]); + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp, tmp); + } +#endif + tmp = AEGIS_AES_BLOCK_XOR(state[3], state[2]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac, t, 16); + tmp = AEGIS_AES_BLOCK_XOR(state[7], state[6]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[5], state[4])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac + 16, t, 16); + } else { + memset(mac, 0, maclen); + } +} + +static int +AEGIS_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } + + AEGIS_mac(mac, maclen, adlen, mlen, state); + + return 0; +} + +static int +AEGIS_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, size_t maclen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + const size_t mlen = clen; + size_t i; + int ret; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + if (m != NULL) { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + } else { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, state); + } + } + if (mlen % AEGIS_RATE) { + if (m != NULL) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } else { + AEGIS_declast(dst, c + i, mlen % AEGIS_RATE, state); + } + } + + COMPILER_ASSERT(sizeof computed_mac >= 32); + AEGIS_mac(computed_mac, maclen, adlen, mlen, state); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret != 0 && m != NULL) { + memset(m, 0, mlen); + } + return ret; +} + +static void +AEGIS_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + memset(src, 0, sizeof src); + if (npub == NULL) { + npub = src; + } + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= len; i += AEGIS_RATE) { + AEGIS_enc(out + i, src, state); + } + if (len % AEGIS_RATE) { + AEGIS_enc(dst, src, state); + memcpy(out + i, dst, len % AEGIS_RATE); + } +} + +static void +AEGIS_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } +} + +static void +AEGIS_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + const size_t mlen = clen; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + if (mlen % AEGIS_RATE) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } +} + +typedef struct AEGIS_STATE { + AEGIS_BLOCKS blocks; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + uint64_t mlen; + size_t pos; +} AEGIS_STATE; + +typedef struct AEGIS_MAC_STATE { + AEGIS_BLOCKS blocks; + AEGIS_BLOCKS blocks0; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + size_t pos; +} AEGIS_MAC_STATE; + +#ifndef AEGIS_OMIT_INCREMENTAL + +static void +AEGIS_state_init(aegis128x4_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + + memcpy(blocks, st->blocks, sizeof blocks); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->mlen = 0; + st->pos = 0; + + AEGIS_init(k, npub, blocks); + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (adlen % AEGIS_RATE) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(st->buf, blocks); + } + st->adlen = adlen; + + memcpy(st->blocks, blocks, sizeof blocks); +} + +static int +AEGIS_state_encrypt_update(aegis128x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += mlen; + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = mlen < available ? mlen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, m + i, n); + m += n; + mlen -= n; + st->pos += n; + } + if (st->pos == sizeof st->buf) { + if (clen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + clen_max -= AEGIS_RATE; + AEGIS_enc(c, st->buf, blocks); + *written += AEGIS_RATE; + c += AEGIS_RATE; + st->pos = 0; + } else { + return 0; + } + } + if (clen_max < (mlen & ~(size_t) (AEGIS_RATE - 1))) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, blocks); + } + *written += i; + left = mlen % AEGIS_RATE; + if (left != 0) { + memcpy(st->buf, m + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_detached_final(aegis128x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(mac, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_final(aegis128x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos + maclen) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(c + st->pos, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos + maclen; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_update(aegis128x4_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *c, size_t clen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += clen; + + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = clen < available ? clen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, c, n); + c += n; + clen -= n; + st->pos += n; + } + if (st->pos < (sizeof st->buf)) { + return 0; + } + st->pos = 0; + if (m != NULL) { + if (mlen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + mlen_max -= AEGIS_RATE; + AEGIS_dec(m, st->buf, blocks); + m += AEGIS_RATE; + } else { + AEGIS_dec(dst, st->buf, blocks); + } + *written += AEGIS_RATE; + } + + if (m != NULL) { + if (mlen_max < (clen % AEGIS_RATE)) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, blocks); + } + } else { + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, blocks); + } + } + *written += i; + left = clen % AEGIS_RATE; + if (left) { + memcpy(st->buf, c + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_final(aegis128x4_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + int ret; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (st->pos != 0) { + if (m != NULL) { + if (mlen_max < st->pos) { + errno = ERANGE; + return -1; + } + AEGIS_declast(m, st->buf, st->pos, blocks); + } else { + AEGIS_declast(dst, st->buf, st->pos, blocks); + } + } + AEGIS_mac(computed_mac, maclen, st->adlen, st->mlen, blocks); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret == 0) { + *written = st->pos; + } else { + memset(m, 0, st->pos); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return ret; +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +#ifndef AEGIS_OMIT_MAC_API + +static void +AEGIS_state_mac_init(aegis128x4_mac_state *st_, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->pos = 0; + + memcpy(blocks, st->blocks, sizeof blocks); + + AEGIS_init(k, npub, blocks); + + memcpy(st->blocks0, blocks, sizeof blocks); + memcpy(st->blocks, blocks, sizeof blocks); + st->adlen = 0; +} + +static int +AEGIS_state_mac_update(aegis128x4_mac_state *st_, const uint8_t *ad, size_t adlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + st->adlen += adlen; + if (left != 0) { + if (left + adlen < AEGIS_RATE) { + memcpy(st->buf + left, ad, adlen); + return 0; + } + memcpy(st->buf + left, ad, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + ad += AEGIS_RATE - left; + adlen -= AEGIS_RATE - left; + } + for (i = 0; i + AEGIS_RATE * 2 <= adlen; i += AEGIS_RATE * 2) { + AEGIS_AES_BLOCK_T msg0, msg1, msg2, msg3; + + msg0 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 0); + msg1 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 1); + msg2 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 2); + msg3 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 3); + COMPILER_ASSERT(AES_BLOCK_LENGTH * 4 == AEGIS_RATE * 2); + + AEGIS_update(blocks, msg0, msg1); + AEGIS_update(blocks, msg2, msg3); + } + for (; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (i < adlen) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen - i); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_mac_final(aegis128x4_mac_state *st_, uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + if (left != 0) { + memset(st->buf + left, 0, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + } + AEGIS_mac_nr(mac, maclen, st->adlen, blocks); + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static void +AEGIS_state_mac_reset(aegis128x4_mac_state *st_) +{ + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + st->adlen = 0; + st->pos = 0; + memcpy(st->blocks, st->blocks0, sizeof(AEGIS_BLOCKS)); +} + +static void +AEGIS_state_mac_clone(aegis128x4_mac_state *dst, const aegis128x4_mac_state *src) +{ + AEGIS_MAC_STATE *const dst_ = + (AEGIS_MAC_STATE *) ((((uintptr_t) &dst->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + const AEGIS_MAC_STATE *const src_ = + (const AEGIS_MAC_STATE *) ((((uintptr_t) &src->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + *dst_ = *src_; +} + +#endif /* AEGIS_OMIT_MAC_API */ + +#undef AEGIS_RATE +#undef AEGIS_ALIGNMENT + +#undef AEGIS_init +#undef AEGIS_mac +#undef AEGIS_mac_nr +#undef AEGIS_absorb +#undef AEGIS_enc +#undef AEGIS_dec +#undef AEGIS_declast diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_soft.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_soft.c new file mode 100644 index 0000000000..40a3ef1d66 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_soft.c @@ -0,0 +1,108 @@ +/* +** Name: aegis128x4_soft.c +** Purpose: Implementation of AEGIS-128x4 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" + +#include "../common/softaes.h" +#include "aegis128x4.h" +#include "aegis128x4_soft.h" + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + SoftAesBlock b0; + SoftAesBlock b1; + SoftAesBlock b2; + SoftAesBlock b3; +} aegis128x4_soft_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis128x4_soft_aes_block_t +#define AEGIS_BLOCKS aegis128x4_soft_blocks +#define AEGIS_STATE _aegis128x4_soft_state +#define AEGIS_MAC_STATE _aegis128x4_soft_mac_state + +#define AEGIS_FUNC_PREFIX aegis128x4_soft_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_xor(a.b0, b.b0), softaes_block_xor(a.b1, b.b1), + softaes_block_xor(a.b2, b.b2), softaes_block_xor(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_and(a.b0, b.b0), softaes_block_and(a.b1, b.b1), + softaes_block_and(a.b2, b.b2), softaes_block_and(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_load(a), softaes_block_load(a + 16), + softaes_block_load(a + 32), softaes_block_load(a + 48) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const SoftAesBlock t = softaes_block_load64x2(a, b); + return (AEGIS_AES_BLOCK_T) { t, t, t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + softaes_block_store(a, b.b0); + softaes_block_store(a + 16, b.b1); + softaes_block_store(a + 32, b.b2); + softaes_block_store(a + 48, b.b3); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_encrypt(a.b0, b.b0), softaes_block_encrypt(a.b1, b.b1), + softaes_block_encrypt(a.b2, b.b2), softaes_block_encrypt(a.b3, b.b3) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d1, const AEGIS_AES_BLOCK_T d2) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[7]; + state[7] = AEGIS_AES_ENC(state[6], state[7]); + state[6] = AEGIS_AES_ENC(state[5], state[6]); + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_ENC(tmp, state[0]); + + state[0] = AEGIS_AES_BLOCK_XOR(state[0], d1); + state[4] = AEGIS_AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128x4_common.h" + +struct aegis128x4_implementation aegis128x4_soft_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_soft.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_soft.h new file mode 100644 index 0000000000..882978123d --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/aegis128x4_soft.h @@ -0,0 +1,16 @@ +/* +** Name: aegis128x4_soft.h +** Purpose: Header for implementation structure of AEGIS-128x4 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X4_SOFT_H +#define AEGIS128X4_SOFT_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis128x4_implementation aegis128x4_soft_implementation; + +#endif /* AEGIS128X4_SOFT_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/implementations.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/implementations.h new file mode 100644 index 0000000000..24571934a7 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis128x4/implementations.h @@ -0,0 +1,50 @@ +/* +** Name: implementations.h +** Purpose: Header for implementation structure of AEGIS-128x4 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X4_IMPLEMENTATIONS_H +#define AEGIS128X4_IMPLEMENTATIONS_H + +#include +#include + +#include "aegis128x4.h" + +typedef struct aegis128x4_implementation { + int (*encrypt_detached)(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k); + int (*decrypt_detached)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + void (*stream)(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + void (*encrypt_unauthenticated)(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k); + void (*decrypt_unauthenticated)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k); +#ifndef AEGIS_OMIT_INCREMENTAL + void (*state_init)(aegis128x4_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + int (*state_encrypt_update)(aegis128x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen); + int (*state_encrypt_detached_final)(aegis128x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + int (*state_encrypt_final)(aegis128x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen); + int (*state_decrypt_detached_update)(aegis128x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen); + int (*state_decrypt_detached_final)(aegis128x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen); +#endif /* AEGIS_OMIT_INCREMENTAL */ +#ifndef AEGIS_OMIT_MAC_API + void (*state_mac_init)(aegis128x4_mac_state *st_, const uint8_t *npub, const uint8_t *k); + int (*state_mac_update)(aegis128x4_mac_state *st_, const uint8_t *ad, size_t adlen); + int (*state_mac_final)(aegis128x4_mac_state *st_, uint8_t *mac, size_t maclen); + void (*state_mac_reset)(aegis128x4_mac_state *st); + void (*state_mac_clone)(aegis128x4_mac_state *dst, const aegis128x4_mac_state *src); +#endif /* AEGIS_OMIT_MAC_API */ +} aegis128x4_implementation; + +#endif /* AEGIS128X4_IMPLEMENTATIONS_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256.c new file mode 100644 index 0000000000..6458bc8939 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256.c @@ -0,0 +1,296 @@ +/* +** Name: aegis256.c +** Purpose: Implementation of AEGIS-256 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" +#include "aegis256.h" +#if 0 +#include "aegis256_aesni.h" +#include "aegis256_altivec.h" +#include "aegis256_armcrypto.h" +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NONE +#include "aegis256_soft.h" +static const aegis256_implementation *implementation_256 = &aegis256_soft_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON +static const aegis256_implementation *implementation_256 = &aegis256_armcrypto_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +static const aegis256_implementation *implementation_256 = &aegis256_aesni_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC +static const aegis256_implementation *implementation_256 = &aegis256_altivec_implementation; +#else +#error "Unsupported architecture" +#endif + +AEGIS_API +size_t +aegis256_keybytes(void) +{ + return aegis256_KEYBYTES; +} + +AEGIS_API +size_t +aegis256_npubbytes(void) +{ + return aegis256_NPUBBYTES; +} + +AEGIS_API +size_t +aegis256_abytes_min(void) +{ + return aegis256_ABYTES_MIN; +} + +AEGIS_API +size_t +aegis256_abytes_max(void) +{ + return aegis256_ABYTES_MAX; +} + +AEGIS_API +size_t +aegis256_tailbytes_max(void) +{ + return aegis256_TAILBYTES_MAX; +} + +AEGIS_API +int +aegis256_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256->encrypt_detached(c, mac, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256->decrypt_detached(m, c, clen, mac, maclen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + return aegis256_encrypt_detached(c, c + mlen, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + int ret = -1; + + if (clen >= maclen) { + ret = aegis256_decrypt_detached(m, c, clen - maclen, c + clen - maclen, maclen, ad, adlen, + npub, k); + } + return ret; +} + +#ifndef AEGIS_OMIT_INCREMENTAL + +AEGIS_API +void +aegis256_state_init(aegis256_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + memset(st_, 0, sizeof *st_); + implementation_256->state_init(st_, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256_state_encrypt_update(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + return implementation_256->state_encrypt_update(st_, c, clen_max, written, m, mlen); +} + +AEGIS_API +int +aegis256_state_encrypt_detached_final(aegis256_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256->state_encrypt_detached_final(st_, c, clen_max, written, mac, maclen); +} + +AEGIS_API +int +aegis256_state_encrypt_final(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256->state_encrypt_final(st_, c, clen_max, written, maclen); +} + +AEGIS_API +int +aegis256_state_decrypt_detached_update(aegis256_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) +{ + return implementation_256->state_decrypt_detached_update(st_, m, mlen_max, written, c, clen); +} + +AEGIS_API +int +aegis256_state_decrypt_detached_final(aegis256_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256->state_decrypt_detached_final(st_, m, mlen_max, written, mac, maclen); +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +AEGIS_API +void +aegis256_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + implementation_256->stream(out, len, npub, k); +} + +AEGIS_API +void +aegis256_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_256->encrypt_unauthenticated(c, m, mlen, npub, k); +} + +AEGIS_API +void +aegis256_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_256->decrypt_unauthenticated(m, c, clen, npub, k); +} + +#ifndef AEGIS_OMIT_MAC_API + +AEGIS_API +void +aegis256_mac_init(aegis256_mac_state *st_, const uint8_t *k, const uint8_t *npub) +{ + implementation_256->state_mac_init(st_, npub, k); +} + +AEGIS_API +int +aegis256_mac_update(aegis256_mac_state *st_, const uint8_t *m, size_t mlen) +{ + return implementation_256->state_mac_update(st_, m, mlen); +} + +AEGIS_API +int +aegis256_mac_final(aegis256_mac_state *st_, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256->state_mac_final(st_, mac, maclen); +} + +AEGIS_API +int +aegis256_mac_verify(aegis256_mac_state *st_, const uint8_t *mac, size_t maclen) +{ + uint8_t expected_mac[32]; + + switch (maclen) { + case 16: + implementation_256->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_16(expected_mac, mac); + case 32: + implementation_256->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_32(expected_mac, mac); + default: + errno = EINVAL; + return -1; + } +} + +AEGIS_API +void +aegis256_mac_reset(aegis256_mac_state *st_) +{ + implementation_256->state_mac_reset(st_); +} + +AEGIS_API +void +aegis256_mac_state_clone(aegis256_mac_state *dst, const aegis256_mac_state *src) +{ + implementation_256->state_mac_clone(dst, src); +} + +#endif /* AEGIS_OMIT_MAC_API */ + +AEGIS_PRIVATE +int +aegis256_pick_best_implementation(void) +{ + implementation_256 = &aegis256_soft_implementation; + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + if (aegis_runtime_has_armcrypto()) { + implementation_256 = &aegis256_armcrypto_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI + if (aegis_runtime_has_aesni() && aegis_runtime_has_avx()) { + implementation_256 = &aegis256_aesni_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC + if (aegis_runtime_has_altivec()) { + implementation_256 = &aegis256_altivec_implementation; + return 0; + } +#endif + + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_aesni.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_aesni.c new file mode 100644 index 0000000000..bfd9f4f156 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_aesni.c @@ -0,0 +1,106 @@ +/* +** Name: aegis256_aesni.c +** Purpose: Implementation of AEGIS-256 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256.h" +#include "aegis256_aesni.h" + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("aes,avx") +#endif + +#include +#include + +#define AES_BLOCK_LENGTH 16 + +typedef __m128i aegis256_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256_aes_block_t +#define AEGIS_BLOCKS aegis256_blocks +#define AEGIS_STATE _aegis256_state +#define AEGIS_MAC_STATE _aegis256_mac_state + +#define AEGIS_FUNC_PREFIX aegis256_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm_xor_si128(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm_and_si128(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return _mm_loadu_si128((const AEGIS_AES_BLOCK_T *) (const void *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return _mm_set_epi64x((long long) a, (long long) b); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm_storeu_si128((AEGIS_AES_BLOCK_T *) (void *) a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm_aesenc_si128(a, b); +} + + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256_common.h" + +struct aegis256_implementation aegis256_aesni_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_aesni.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_aesni.h new file mode 100644 index 0000000000..8052159c94 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_aesni.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256_aesni.h +** Purpose: Header for implementation structure of AEGIS-256 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256_AESNI_H +#define AEGIS256_AESNI_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256_implementation aegis256_aesni_implementation; + +#endif /* AEGIS256_AESNI_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_altivec.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_altivec.c new file mode 100644 index 0000000000..aa20f50bd1 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_altivec.c @@ -0,0 +1,104 @@ +/* +** Name: aegis256_altivec.c +** Purpose: Implementation of AEGIS-256 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__ALTIVEC__) && defined(__CRYPTO__) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256.h" +#include "aegis256_altivec.h" + +#include + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("altivec,crypto"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("altivec,crypto") +#endif + +#define AES_BLOCK_LENGTH 16 + +typedef vector unsigned char aegis256_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256_aes_block_t +#define AEGIS_BLOCKS aegis256_blocks +#define AEGIS_STATE _aegis256_state +#define AEGIS_MAC_STATE _aegis256_mac_state + +#define AEGIS_FUNC_PREFIX aegis256_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return vec_xor(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return vec_and(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return vec_xl_be(0, (const unsigned char *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return (AEGIS_AES_BLOCK_T) vec_revb(vec_insert(a, vec_promote((unsigned long long) b, 1), 0)); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vec_xst_be(b, 0, (unsigned char *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) vec_cipher_be(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256_common.h" + +struct aegis256_implementation aegis256_altivec_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_altivec.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_altivec.h new file mode 100644 index 0000000000..fed2305ec6 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_altivec.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256_altivec.h +** Purpose: Header for implementation structure of AEGIS-256 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256_ALTIVEC_H +#define AEGIS256_ALTIVEC_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256_implementation aegis256_altivec_implementation; + +#endif /* AEGIS256_ALTIVEC_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_armcrypto.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_armcrypto.c new file mode 100644 index 0000000000..33d2d2cb01 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_armcrypto.c @@ -0,0 +1,118 @@ +/* +** Name: aegis256_armcrypto.c +** Purpose: Implementation of AEGIS-256 - ARM-Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include "../common/aeshardware.h" + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256.h" +#include "aegis256_armcrypto.h" + +#ifndef __ARM_FEATURE_CRYPTO +# define __ARM_FEATURE_CRYPTO 1 +#endif +#ifndef __ARM_FEATURE_AES +# define __ARM_FEATURE_AES 1 +#endif + +#ifdef USE_ARM64_NEON_H +#include +#else +#include +#endif + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("neon,crypto,aes"))), \ + apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("+simd+crypto") +#endif + +#define AES_BLOCK_LENGTH 16 + +typedef uint8x16_t aegis256_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256_aes_block_t +#define AEGIS_BLOCKS aegis256_blocks +#define AEGIS_STATE _aegis256_state +#define AEGIS_MAC_STATE _aegis256_mac_state + +#define AEGIS_FUNC_PREFIX aegis256_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return veorq_u8(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return vandq_u8(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return vld1q_u8(a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return vreinterpretq_u8_u64(vsetq_lane_u64(a, vmovq_n_u64(b), 1)); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vst1q_u8(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return veorq_u8(vaesmcq_u8(vaeseq_u8(a, vmovq_n_u8(0))), b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256_common.h" + +struct aegis256_implementation aegis256_armcrypto_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_armcrypto.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_armcrypto.h new file mode 100644 index 0000000000..0273bfe918 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_armcrypto.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256_armcrypto.h +** Purpose: Header for implementation structure of AEGIS-256 - ARM Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256_ARMCRYPTO_H +#define AEGIS256_ARMCRYPTO_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256_implementation aegis256_armcrypto_implementation; + +#endif /* AEGIS256_ARMCRYPTO_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_common.h new file mode 100644 index 0000000000..f35538e631 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_common.h @@ -0,0 +1,712 @@ +/* +** Name: aegis256_common.h +** Purpose: Common implementation for AEGIS-256 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#define AEGIS_RATE 16 +#define AEGIS_ALIGNMENT 16 + +typedef AEGIS_AES_BLOCK_T AEGIS_BLOCKS[6]; + +#define AEGIS_init AEGIS_FUNC(init) +#define AEGIS_mac AEGIS_FUNC(mac) +#define AEGIS_absorb AEGIS_FUNC(absorb) +#define AEGIS_enc AEGIS_FUNC(enc) +#define AEGIS_dec AEGIS_FUNC(dec) +#define AEGIS_declast AEGIS_FUNC(declast) + +static void +AEGIS_init(const uint8_t *key, const uint8_t *nonce, AEGIS_AES_BLOCK_T *const state) +{ + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) + const uint8_t c0_[AES_BLOCK_LENGTH] = { 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, + 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }; + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) + const uint8_t c1_[AES_BLOCK_LENGTH] = { 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, + 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }; + + const AEGIS_AES_BLOCK_T c0 = AEGIS_AES_BLOCK_LOAD(c0_); + const AEGIS_AES_BLOCK_T c1 = AEGIS_AES_BLOCK_LOAD(c1_); + const AEGIS_AES_BLOCK_T k0 = AEGIS_AES_BLOCK_LOAD(key); + const AEGIS_AES_BLOCK_T k1 = AEGIS_AES_BLOCK_LOAD(key + AES_BLOCK_LENGTH); + const AEGIS_AES_BLOCK_T n0 = AEGIS_AES_BLOCK_LOAD(nonce); + const AEGIS_AES_BLOCK_T n1 = AEGIS_AES_BLOCK_LOAD(nonce + AES_BLOCK_LENGTH); + const AEGIS_AES_BLOCK_T k0_n0 = AEGIS_AES_BLOCK_XOR(k0, n0); + const AEGIS_AES_BLOCK_T k1_n1 = AEGIS_AES_BLOCK_XOR(k1, n1); + int i; + + state[0] = k0_n0; + state[1] = k1_n1; + state[2] = c1; + state[3] = c0; + state[4] = AEGIS_AES_BLOCK_XOR(k0, c0); + state[5] = AEGIS_AES_BLOCK_XOR(k1, c1); + for (i = 0; i < 4; i++) { + AEGIS_update(state, k0); + AEGIS_update(state, k1); + AEGIS_update(state, k0_n0); + AEGIS_update(state, k1_n1); + } +} + +static void +AEGIS_mac(uint8_t *mac, size_t maclen, uint64_t adlen, uint64_t mlen, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T tmp; + int i; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(mlen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } + + if (maclen == 16) { + tmp = AEGIS_AES_BLOCK_XOR(state[5], state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac, tmp); + } else if (maclen == 32) { + tmp = AEGIS_AES_BLOCK_XOR(AEGIS_AES_BLOCK_XOR(state[2], state[1]), state[0]); + AEGIS_AES_BLOCK_STORE(mac, tmp); + tmp = AEGIS_AES_BLOCK_XOR(AEGIS_AES_BLOCK_XOR(state[5], state[4]), state[3]); + AEGIS_AES_BLOCK_STORE(mac + 16, tmp); + } else { + memset(mac, 0, maclen); + } +} + +static inline void +AEGIS_absorb(const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + + msg = AEGIS_AES_BLOCK_LOAD(src); + AEGIS_update(state, msg); +} + +static void +AEGIS_enc(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + AEGIS_AES_BLOCK_T tmp; + + msg = AEGIS_AES_BLOCK_LOAD(src); + tmp = AEGIS_AES_BLOCK_XOR(msg, state[5]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[1]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(dst, tmp); + + AEGIS_update(state, msg); +} + +static void +AEGIS_dec(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + + msg = AEGIS_AES_BLOCK_LOAD(src); + msg = AEGIS_AES_BLOCK_XOR(msg, state[5]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[4]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[1]); + msg = AEGIS_AES_BLOCK_XOR(msg, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(dst, msg); + + AEGIS_update(state, msg); +} + +static void +AEGIS_declast(uint8_t *const dst, const uint8_t *const src, size_t len, AEGIS_AES_BLOCK_T *const state) +{ + uint8_t pad[AEGIS_RATE]; + AEGIS_AES_BLOCK_T msg; + + memset(pad, 0, sizeof pad); + memcpy(pad, src, len); + + msg = AEGIS_AES_BLOCK_LOAD(pad); + msg = AEGIS_AES_BLOCK_XOR(msg, state[5]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[4]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[1]); + msg = AEGIS_AES_BLOCK_XOR(msg, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(pad, msg); + + memset(pad + len, 0, sizeof pad - len); + memcpy(dst, pad, len); + + msg = AEGIS_AES_BLOCK_LOAD(pad); + + AEGIS_update(state, msg); +} + +static int +AEGIS_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } + + AEGIS_mac(mac, maclen, adlen, mlen, state); + + return 0; +} + +static int +AEGIS_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, size_t maclen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + const size_t mlen = clen; + size_t i; + int ret; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + if (m != NULL) { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + } else { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, state); + } + } + if (mlen % AEGIS_RATE) { + if (m != NULL) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } else { + AEGIS_declast(dst, c + i, mlen % AEGIS_RATE, state); + } + } + + COMPILER_ASSERT(sizeof computed_mac >= 32); + AEGIS_mac(computed_mac, maclen, adlen, mlen, state); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret != 0 && m != NULL) { + memset(m, 0, mlen); + } + return ret; +} + +static void +AEGIS_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + memset(src, 0, sizeof src); + if (npub == NULL) { + npub = src; + } + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= len; i += AEGIS_RATE) { + AEGIS_enc(out + i, src, state); + } + if (len % AEGIS_RATE) { + AEGIS_enc(dst, src, state); + memcpy(out + i, dst, len % AEGIS_RATE); + } +} + +static void +AEGIS_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } +} + +static void +AEGIS_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + const size_t mlen = clen; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + if (mlen % AEGIS_RATE) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } +} + +typedef struct AEGIS_STATE { + AEGIS_BLOCKS blocks; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + uint64_t mlen; + size_t pos; +} AEGIS_STATE; + +typedef struct AEGIS_MAC_STATE { + AEGIS_BLOCKS blocks; + AEGIS_BLOCKS blocks0; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + size_t pos; +} AEGIS_MAC_STATE; + +#ifndef AEGIS_OMIT_INCREMENTAL + +static void +AEGIS_state_init(aegis256_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + + memcpy(blocks, st->blocks, sizeof blocks); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->mlen = 0; + st->pos = 0; + + AEGIS_init(k, npub, blocks); + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (adlen % AEGIS_RATE) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(st->buf, blocks); + } + st->adlen = adlen; + + memset(st->buf, 0, sizeof st->buf); + + memcpy(st->blocks, blocks, sizeof blocks); +} + +static int +AEGIS_state_encrypt_update(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += mlen; + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = mlen < available ? mlen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, m + i, n); + m += n; + mlen -= n; + st->pos += n; + } + if (st->pos == sizeof st->buf) { + if (clen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + clen_max -= AEGIS_RATE; + AEGIS_enc(c, st->buf, blocks); + *written += AEGIS_RATE; + c += AEGIS_RATE; + st->pos = 0; + } else { + return 0; + } + } + if (clen_max < (mlen & ~(size_t) (AEGIS_RATE - 1))) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, blocks); + } + *written += i; + left = mlen % AEGIS_RATE; + if (left != 0) { + memcpy(st->buf, m + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_detached_final(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(mac, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_final(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos + maclen) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(c + st->pos, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos + maclen; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_update(aegis256_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *c, size_t clen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += clen; + + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = clen < available ? clen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, c, n); + c += n; + clen -= n; + st->pos += n; + } + if (st->pos < (sizeof st->buf)) { + return 0; + } + st->pos = 0; + if (m != NULL) { + if (mlen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + mlen_max -= AEGIS_RATE; + AEGIS_dec(m, st->buf, blocks); + m += AEGIS_RATE; + } else { + AEGIS_dec(dst, st->buf, blocks); + } + *written += AEGIS_RATE; + } + + if (m != NULL) { + if (mlen_max < (clen % AEGIS_RATE)) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, blocks); + } + } else { + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, blocks); + } + } + *written += i; + left = clen % AEGIS_RATE; + if (left) { + memcpy(st->buf, c + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_final(aegis256_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + int ret; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (st->pos != 0) { + if (m != NULL) { + if (mlen_max < st->pos) { + errno = ERANGE; + return -1; + } + AEGIS_declast(m, st->buf, st->pos, blocks); + } else { + AEGIS_declast(dst, st->buf, st->pos, blocks); + } + } + AEGIS_mac(computed_mac, maclen, st->adlen, st->mlen, blocks); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret == 0) { + *written = st->pos; + } else { + memset(m, 0, st->pos); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return ret; +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +#ifndef AEGIS_OMIT_MAC_API + +static void +AEGIS_state_mac_init(aegis256_mac_state *st_, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->pos = 0; + + memcpy(blocks, st->blocks, sizeof blocks); + + AEGIS_init(k, npub, blocks); + + memcpy(st->blocks0, blocks, sizeof blocks); + memcpy(st->blocks, blocks, sizeof blocks); + st->adlen = 0; +} + +static int +AEGIS_state_mac_update(aegis256_mac_state *st_, const uint8_t *ad, size_t adlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + st->adlen += adlen; + if (left != 0) { + if (left + adlen < AEGIS_RATE) { + memcpy(st->buf + left, ad, adlen); + return 0; + } + memcpy(st->buf + left, ad, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + ad += AEGIS_RATE - left; + adlen -= AEGIS_RATE - left; + } + for (i = 0; i + AEGIS_RATE * 2 <= adlen; i += AEGIS_RATE * 2) { + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 0); + msg1 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 1); + COMPILER_ASSERT(AES_BLOCK_LENGTH * 2 == AEGIS_RATE * 2); + + AEGIS_update(blocks, msg0); + AEGIS_update(blocks, msg1); + } + for (; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (i < adlen) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen - i); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_mac_final(aegis256_mac_state *st_, uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + if (left != 0) { + memset(st->buf + left, 0, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + } + AEGIS_mac(mac, maclen, st->adlen, maclen, blocks); + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static void +AEGIS_state_mac_reset(aegis256_mac_state *st_) +{ + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + st->adlen = 0; + st->pos = 0; + memcpy(st->blocks, st->blocks0, sizeof(AEGIS_BLOCKS)); +} + +static void +AEGIS_state_mac_clone(aegis256_mac_state *dst, const aegis256_mac_state *src) +{ + AEGIS_MAC_STATE *const dst_ = + (AEGIS_MAC_STATE *) ((((uintptr_t) &dst->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + const AEGIS_MAC_STATE *const src_ = + (const AEGIS_MAC_STATE *) ((((uintptr_t) &src->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + *dst_ = *src_; +} + +#endif /* AEGIS_OMIT_MAC_API */ + +#undef AEGIS_RATE +#undef AEGIS_ALIGNMENT + +#undef AEGIS_init +#undef AEGIS_mac +#undef AEGIS_absorb +#undef AEGIS_enc +#undef AEGIS_dec +#undef AEGIS_declast diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_soft.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_soft.c new file mode 100644 index 0000000000..55729799a7 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_soft.c @@ -0,0 +1,91 @@ +/* +** Name: aegis256_soft.c +** Purpose: Implementation of AEGIS-256 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" + +#include "../common/softaes.h" +#include "aegis256.h" +#include "aegis256_soft.h" + +#define AES_BLOCK_LENGTH 16 + +typedef SoftAesBlock aegis256_soft_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256_soft_aes_block_t +#define AEGIS_BLOCKS aegis256_soft_blocks +#define AEGIS_STATE _aegis256_soft_state +#define AEGIS_MAC_STATE _aegis256_soft_mac_state + +#define AEGIS_FUNC_PREFIX aegis256_soft_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return softaes_block_xor(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return softaes_block_and(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return softaes_block_load(a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return softaes_block_load64x2(a, b); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + softaes_block_store(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return softaes_block_encrypt(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256_common.h" + +struct aegis256_implementation aegis256_soft_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_soft.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_soft.h new file mode 100644 index 0000000000..1c8302d9df --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/aegis256_soft.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256_soft.h +** Purpose: Header for implementation structure of AEGIS-256 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256_SOFT_H +#define AEGIS256_SOFT_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256_implementation aegis256_soft_implementation; + +#endif /* AEGIS256_SOFT_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/implementations.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/implementations.h new file mode 100644 index 0000000000..5be1388cdc --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256/implementations.h @@ -0,0 +1,50 @@ +/* +** Name: implementations.h +** Purpose: Header for implementation structure of AEGIS-256 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256_IMPLEMENTATIONS_H +#define AEGIS256_IMPLEMENTATIONS_H + +#include +#include + +#include "aegis256.h" + +typedef struct aegis256_implementation { + int (*encrypt_detached)(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k); + int (*decrypt_detached)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + void (*stream)(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + void (*encrypt_unauthenticated)(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k); + void (*decrypt_unauthenticated)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k); +#ifndef AEGIS_OMIT_INCREMENTAL + void (*state_init)(aegis256_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + int (*state_encrypt_update)(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen); + int (*state_encrypt_detached_final)(aegis256_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + int (*state_encrypt_final)(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen); + int (*state_decrypt_detached_update)(aegis256_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen); + int (*state_decrypt_detached_final)(aegis256_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen); +#endif /* AEGIS_OMIT_INCREMENTAL */ +#ifndef AEGIS_OMIT_MAC_API + void (*state_mac_init)(aegis256_mac_state *st_, const uint8_t *npub, const uint8_t *k); + int (*state_mac_update)(aegis256_mac_state *st_, const uint8_t *ad, size_t adlen); + int (*state_mac_final)(aegis256_mac_state *st_, uint8_t *mac, size_t maclen); + void (*state_mac_reset)(aegis256_mac_state *st); + void (*state_mac_clone)(aegis256_mac_state *dst, const aegis256_mac_state *src); +#endif /* AEGIS_OMIT_MAC_API */ +} aegis256_implementation; + +#endif /* AEGIS256_IMPLEMENTATIONS_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2.c new file mode 100644 index 0000000000..eb2a383851 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2.c @@ -0,0 +1,303 @@ +/* +** Name: aegis256x2.c +** Purpose: Implementation of AEGIS-256x2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" +#include "aegis256x2.h" +#if 0 +#include "aegis256x2_aesni.h" +#include "aegis256x2_altivec.h" +#include "aegis256x2_armcrypto.h" +#include "aegis256x2_avx2.h" +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NONE +#include "aegis256x2_soft.h" +static const aegis256x2_implementation *implementation_256x2 = &aegis256x2_soft_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON +static const aegis256x2_implementation *implementation_256x2 = &aegis256x2_armcrypto_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +static const aegis256x2_implementation *implementation_256x2 = &aegis256x2_aesni_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC +static const aegis256x2_implementation *implementation_256x2 = &aegis256x2_altivec_implementation; +#else +#error "Unsupported architecture" +#endif + +AEGIS_API +size_t +aegis256x2_keybytes(void) +{ + return aegis256x2_KEYBYTES; +} + +AEGIS_API +size_t +aegis256x2_npubbytes(void) +{ + return aegis256x2_NPUBBYTES; +} + +AEGIS_API +size_t +aegis256x2_abytes_min(void) +{ + return aegis256x2_ABYTES_MIN; +} + +AEGIS_API +size_t +aegis256x2_abytes_max(void) +{ + return aegis256x2_ABYTES_MAX; +} + +AEGIS_API +size_t +aegis256x2_tailbytes_max(void) +{ + return aegis256x2_TAILBYTES_MAX; +} + +AEGIS_API +int +aegis256x2_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x2->encrypt_detached(c, mac, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256x2_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x2->decrypt_detached(m, c, clen, mac, maclen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256x2_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + return aegis256x2_encrypt_detached(c, c + mlen, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256x2_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + int ret = -1; + + if (clen >= maclen) { + ret = aegis256x2_decrypt_detached(m, c, clen - maclen, c + clen - maclen, maclen, ad, adlen, + npub, k); + } + return ret; +} + +#ifndef AEGIS_OMIT_INCREMENTAL + +AEGIS_API +void +aegis256x2_state_init(aegis256x2_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + memset(st_, 0, sizeof *st_); + implementation_256x2->state_init(st_, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256x2_state_encrypt_update(aegis256x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + return implementation_256x2->state_encrypt_update(st_, c, clen_max, written, m, mlen); +} + +AEGIS_API +int +aegis256x2_state_encrypt_detached_final(aegis256x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x2->state_encrypt_detached_final(st_, c, clen_max, written, mac, maclen); +} + +AEGIS_API +int +aegis256x2_state_encrypt_final(aegis256x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x2->state_encrypt_final(st_, c, clen_max, written, maclen); +} + +AEGIS_API +int +aegis256x2_state_decrypt_detached_update(aegis256x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) +{ + return implementation_256x2->state_decrypt_detached_update(st_, m, mlen_max, written, c, clen); +} + +AEGIS_API +int +aegis256x2_state_decrypt_detached_final(aegis256x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x2->state_decrypt_detached_final(st_, m, mlen_max, written, mac, maclen); +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +AEGIS_API +void +aegis256x2_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + implementation_256x2->stream(out, len, npub, k); +} + +AEGIS_API +void +aegis256x2_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_256x2->encrypt_unauthenticated(c, m, mlen, npub, k); +} + +AEGIS_API +void +aegis256x2_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_256x2->decrypt_unauthenticated(m, c, clen, npub, k); +} + +#ifndef AEGIS_OMIT_MAC_API + +AEGIS_API +void +aegis256x2_mac_init(aegis256x2_mac_state *st_, const uint8_t *k, const uint8_t *npub) +{ + implementation_256x2->state_mac_init(st_, npub, k); +} + +AEGIS_API +int +aegis256x2_mac_update(aegis256x2_mac_state *st_, const uint8_t *m, size_t mlen) +{ + return implementation_256x2->state_mac_update(st_, m, mlen); +} + +AEGIS_API +int +aegis256x2_mac_final(aegis256x2_mac_state *st_, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x2->state_mac_final(st_, mac, maclen); +} + +AEGIS_API +int +aegis256x2_mac_verify(aegis256x2_mac_state *st_, const uint8_t *mac, size_t maclen) +{ + uint8_t expected_mac[32]; + + switch (maclen) { + case 16: + implementation_256x2->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_16(expected_mac, mac); + case 32: + implementation_256x2->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_32(expected_mac, mac); + default: + errno = EINVAL; + return -1; + } +} + +AEGIS_API +void +aegis256x2_mac_reset(aegis256x2_mac_state *st_) +{ + implementation_256x2->state_mac_reset(st_); +} + +AEGIS_API +void +aegis256x2_mac_state_clone(aegis256x2_mac_state *dst, const aegis256x2_mac_state *src) +{ + implementation_256x2->state_mac_clone(dst, src); +} + +#endif /* AEGIS_OMIT_MAC_API */ + +AEGIS_PRIVATE +int +aegis256x2_pick_best_implementation(void) +{ + implementation_256x2 = &aegis256x2_soft_implementation; + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + if (aegis_runtime_has_armcrypto()) { + implementation_256x2 = &aegis256x2_armcrypto_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +# ifdef HAVE_VAESINTRIN_H + if (aegis_runtime_has_vaes() && aegis_runtime_has_avx2()) { + implementation_256x2 = &aegis256x2_avx2_implementation; + return 0; + } +# endif + if (aegis_runtime_has_aesni() && aegis_runtime_has_avx()) { + implementation_256x2 = &aegis256x2_aesni_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC + if (aegis_runtime_has_altivec()) { + implementation_256x2 = &aegis256x2_altivec_implementation; + return 0; + } +#endif + + return 0; /* LCOV_EXCL_LINE */ +} \ No newline at end of file diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_aesni.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_aesni.c new file mode 100644 index 0000000000..88b00f38d7 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_aesni.c @@ -0,0 +1,111 @@ +/* +** Name: aegis256x2_aesni.c +** Purpose: Implementation of AEGIS-256x2 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x2.h" +#include "aegis256x2_aesni.h" + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("aes,avx") +#endif + +#include +#include + +#define AES_BLOCK_LENGTH 32 + +typedef struct { + __m128i b0; + __m128i b1; +} aegis256x2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x2_aes_block_t +#define AEGIS_BLOCKS aegis256x2_blocks +#define AEGIS_STATE _aegis256x2_state +#define AEGIS_MAC_STATE _aegis256x2_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_xor_si128(a.b0, b.b0), _mm_xor_si128(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_and_si128(a.b0, b.b0), _mm_and_si128(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { _mm_loadu_si128((const __m128i *) (const void *) a), + _mm_loadu_si128((const __m128i *) (const void *) (a + 16)) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const __m128i t = _mm_set_epi64x((long long) a, (long long) b); + return (AEGIS_AES_BLOCK_T) { t, t }; +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm_storeu_si128((__m128i *) (void *) a, b.b0); + _mm_storeu_si128((__m128i *) (void *) (a + 16), b.b1); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_aesenc_si128(a.b0, b.b0), _mm_aesenc_si128(a.b1, b.b1) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x2_common.h" + +struct aegis256x2_implementation aegis256x2_aesni_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_aesni.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_aesni.h new file mode 100644 index 0000000000..2ac90b391f --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_aesni.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256x2_aesni.h +** Purpose: Header for implementation structure of AEGIS-256x2 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X2_AESNI_H +#define AEGIS256X2_AESNI_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256x2_implementation aegis256x2_aesni_implementation; + +#endif /* AEGIS256X2_AESNI_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_altivec.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_altivec.c new file mode 100644 index 0000000000..1eba181980 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_altivec.c @@ -0,0 +1,110 @@ +/* +** Name: aegis256x2_altivec.c +** Purpose: Implementation of AEGIS-256x2 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__ALTIVEC__) && defined(__CRYPTO__) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x2.h" +#include "aegis256x2_altivec.h" + +#include + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("altivec,crypto"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("altivec,crypto") +#endif + +#define AES_BLOCK_LENGTH 32 + +typedef struct { + vector unsigned char b0; + vector unsigned char b1; +} aegis256x2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x2_aes_block_t +#define AEGIS_BLOCKS aegis256x2_blocks +#define AEGIS_STATE _aegis256x2_state +#define AEGIS_MAC_STATE _aegis256x2_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_xor(a.b0, b.b0), vec_xor(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_and(a.b0, b.b0), vec_and(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { vec_xl_be(0, a), vec_xl_be(0, a + 16) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const vector unsigned char t = + (vector unsigned char) vec_revb(vec_insert(a, vec_promote((unsigned long long) (b), 1), 0)); + return (AEGIS_AES_BLOCK_T) { t, t }; +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vec_xst_be(b.b0, 0, a); + vec_xst_be(b.b1, 0, a + 16); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_cipher_be(a.b0, b.b0), vec_cipher_be(a.b1, b.b1) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x2_common.h" + +struct aegis256x2_implementation aegis256x2_altivec_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_altivec.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_altivec.h new file mode 100644 index 0000000000..f8b0568edd --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_altivec.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256x2_altivec.h +** Purpose: Header for implementation structure of AEGIS-256x2 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X2_ALTIVEC_H +#define AEGIS256X2_ALTIVEC_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256x2_implementation aegis256x2_altivec_implementation; + +#endif /* AEGIS256X2_ALTIVEC_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_armcrypto.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_armcrypto.c new file mode 100644 index 0000000000..1c03883e9f --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_armcrypto.c @@ -0,0 +1,123 @@ +/* +** Name: aegis256x2_armcrypto.c +** Purpose: Implementation of AEGIS-256x2 - ARM-Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include "../common/aeshardware.h" + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x2.h" +#include "aegis256x2_armcrypto.h" + +#ifndef __ARM_FEATURE_CRYPTO +# define __ARM_FEATURE_CRYPTO 1 +#endif +#ifndef __ARM_FEATURE_AES +# define __ARM_FEATURE_AES 1 +#endif + +#ifdef USE_ARM64_NEON_H +#include +#else +#include +#endif + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("neon,crypto,aes"))), \ + apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("+simd+crypto") +#endif + +#define AES_BLOCK_LENGTH 32 + +typedef struct { + uint8x16_t b0; + uint8x16_t b1; +} aegis256x2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x2_aes_block_t +#define AEGIS_BLOCKS aegis256x2_blocks +#define AEGIS_STATE _aegis256x2_state +#define AEGIS_MAC_STATE _aegis256x2_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { veorq_u8(a.b0, b.b0), veorq_u8(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vandq_u8(a.b0, b.b0), vandq_u8(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { vld1q_u8(a), vld1q_u8(a + 16) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const uint8x16_t t = vreinterpretq_u8_u64(vsetq_lane_u64((a), vmovq_n_u64(b), 1)); + return (AEGIS_AES_BLOCK_T) { t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vst1q_u8(a, b.b0); + vst1q_u8(a + 16, b.b1); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { veorq_u8(vaesmcq_u8(vaeseq_u8((a.b0), vmovq_n_u8(0))), (b.b0)), + veorq_u8(vaesmcq_u8(vaeseq_u8((a.b1), vmovq_n_u8(0))), (b.b1)) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x2_common.h" + +struct aegis256x2_implementation aegis256x2_armcrypto_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_armcrypto.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_armcrypto.h new file mode 100644 index 0000000000..0e1c4ece58 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_armcrypto.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256x2_armcrypto.h +** Purpose: Header for implementation structure of AEGIS-256x2 - ARM Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X2_ARMCRYPTO_H +#define AEGIS256X2_ARMCRYPTO_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256x2_implementation aegis256x2_armcrypto_implementation; + +#endif /* AEGIS256X2_ARMCRYPTO_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_avx2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_avx2.c new file mode 100644 index 0000000000..76003cfcc5 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_avx2.c @@ -0,0 +1,108 @@ +/* +** Name: aegis256x2_avx2.c +** Purpose: Implementation of AEGIS-256x2 - AES-NI AVX2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x2.h" +#include "aegis256x2_avx2.h" + +#ifdef HAVE_VAESINTRIN_H + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("vaes,avx2"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("vaes,avx2") +#endif + +#include + +#define AES_BLOCK_LENGTH 32 + +typedef __m256i aegis256x2_avx2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x2_avx2_aes_block_t +#define AEGIS_BLOCKS aegis256x2_avx2_blocks +#define AEGIS_STATE _aegis256x2_avx2_state +#define AEGIS_MAC_STATE _aegis256x2_avx2_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x2_avx2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm256_xor_si256(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm256_and_si256(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return _mm256_loadu_si256((const AEGIS_AES_BLOCK_T *) (const void *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return _mm256_broadcastsi128_si256(_mm_set_epi64x(a, b)); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm256_storeu_si256((AEGIS_AES_BLOCK_T *) (void *) a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm256_aesenc_epi128(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x2_common.h" + +struct aegis256x2_implementation aegis256x2_avx2_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif /* HAVE_VAESINTRIN_H */ + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_avx2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_avx2.h new file mode 100644 index 0000000000..7df3413cd8 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_avx2.h @@ -0,0 +1,18 @@ +/* +** Name: aegis256x2_avx2.h +** Purpose: Header for implementation structure of AEGIS-256x2 - AES-NI AVX2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X2_AVX2_H +#define AEGIS256X2_AVX2_H + +#include "../common/common.h" +#include "implementations.h" + +#ifdef HAVE_VAESINTRIN_H +extern struct aegis256x2_implementation aegis256x2_avx2_implementation; +#endif + +#endif /* AEGIS256X2_AVX2_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_common.h new file mode 100644 index 0000000000..7f13488188 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_common.h @@ -0,0 +1,829 @@ +/* +** Name: aegis256x2_common.h +** Purpose: Common implementation for AEGIS-256x2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#define AEGIS_RATE 32 +#define AEGIS_ALIGNMENT 32 + +typedef AEGIS_AES_BLOCK_T AEGIS_BLOCKS[6]; + +#define AEGIS_init AEGIS_FUNC(init) +#define AEGIS_mac AEGIS_FUNC(mac) +#define AEGIS_mac_nr AEGIS_FUNC(mac_nr) +#define AEGIS_absorb AEGIS_FUNC(absorb) +#define AEGIS_enc AEGIS_FUNC(enc) +#define AEGIS_dec AEGIS_FUNC(dec) +#define AEGIS_declast AEGIS_FUNC(declast) + +static void +AEGIS_init(const uint8_t *key, const uint8_t *nonce, AEGIS_AES_BLOCK_T *const state) +{ + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) const uint8_t c0_[AES_BLOCK_LENGTH] = { + 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, + 0x59, 0x90, 0xe9, 0x79, 0x62, 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, + 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62, + }; + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) const uint8_t c1_[AES_BLOCK_LENGTH] = { + 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, + 0x42, 0x73, 0xb5, 0x28, 0xdd, 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, + 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd, + }; + + const AEGIS_AES_BLOCK_T c0 = AEGIS_AES_BLOCK_LOAD(c0_); + const AEGIS_AES_BLOCK_T c1 = AEGIS_AES_BLOCK_LOAD(c1_); + uint8_t tmp[2 * 16]; + uint8_t context_bytes[AES_BLOCK_LENGTH]; + AEGIS_AES_BLOCK_T context; + AEGIS_AES_BLOCK_T k0, k1; + AEGIS_AES_BLOCK_T n0, n1; + AEGIS_AES_BLOCK_T k0_n0, k1_n1; + int i; + + memcpy(tmp, key, 16); + memcpy(tmp + 16, key, 16); + k0 = AEGIS_AES_BLOCK_LOAD(tmp); + memcpy(tmp, key + 16, 16); + memcpy(tmp + 16, key + 16, 16); + k1 = AEGIS_AES_BLOCK_LOAD(tmp); + + memcpy(tmp, nonce, 16); + memcpy(tmp + 16, nonce, 16); + n0 = AEGIS_AES_BLOCK_LOAD(tmp); + memcpy(tmp, nonce + 16, 16); + memcpy(tmp + 16, nonce + 16, 16); + n1 = AEGIS_AES_BLOCK_LOAD(tmp); + + k0_n0 = AEGIS_AES_BLOCK_XOR(k0, n0); + k1_n1 = AEGIS_AES_BLOCK_XOR(k1, n1); + + memset(context_bytes, 0, sizeof context_bytes); + context_bytes[0 * 16] = 0x00; + context_bytes[0 * 16 + 1] = 0x01; + context_bytes[1 * 16] = 0x01; + context_bytes[1 * 16 + 1] = 0x01; + context = AEGIS_AES_BLOCK_LOAD(context_bytes); + + state[0] = k0_n0; + state[1] = k1_n1; + state[2] = c1; + state[3] = c0; + state[4] = AEGIS_AES_BLOCK_XOR(k0, c0); + state[5] = AEGIS_AES_BLOCK_XOR(k1, c1); + for (i = 0; i < 4; i++) { + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[5] = AEGIS_AES_BLOCK_XOR(state[5], context); + AEGIS_update(state, k0); + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[5] = AEGIS_AES_BLOCK_XOR(state[5], context); + AEGIS_update(state, k1); + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[5] = AEGIS_AES_BLOCK_XOR(state[5], context); + AEGIS_update(state, k0_n0); + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[5] = AEGIS_AES_BLOCK_XOR(state[5], context); + AEGIS_update(state, k1_n1); + } +} + +static void +AEGIS_mac(uint8_t *mac, size_t maclen, uint64_t adlen, uint64_t mlen, AEGIS_AES_BLOCK_T *const state) +{ + uint8_t mac_multi_0[AES_BLOCK_LENGTH]; + uint8_t mac_multi_1[AES_BLOCK_LENGTH]; + AEGIS_AES_BLOCK_T tmp; + int i; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(mlen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } + + if (maclen == 16) { + tmp = AEGIS_AES_BLOCK_XOR(state[5], state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac_multi_0, tmp); + for (i = 0; i < 16; i++) { + mac[i] = mac_multi_0[i] ^ mac_multi_0[1 * 16 + i]; + } + } else if (maclen == 32) { + tmp = AEGIS_AES_BLOCK_XOR(state[2], AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac_multi_0, tmp); + for (i = 0; i < 16; i++) { + mac[i] = mac_multi_0[i] ^ mac_multi_0[1 * 16 + i]; + } + + tmp = AEGIS_AES_BLOCK_XOR(state[5], AEGIS_AES_BLOCK_XOR(state[4], state[3])); + AEGIS_AES_BLOCK_STORE(mac_multi_1, tmp); + for (i = 0; i < 16; i++) { + mac[i + 16] = mac_multi_1[i] ^ mac_multi_1[1 * 16 + i]; + } + } else { + memset(mac, 0, maclen); + } +} + +static inline void +AEGIS_absorb(const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + + msg = AEGIS_AES_BLOCK_LOAD(src); + AEGIS_update(state, msg); +} + +static void +AEGIS_enc(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + AEGIS_AES_BLOCK_T tmp; + + msg = AEGIS_AES_BLOCK_LOAD(src); + tmp = AEGIS_AES_BLOCK_XOR(msg, state[5]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[1]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(dst, tmp); + + AEGIS_update(state, msg); +} + +static void +AEGIS_dec(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + + msg = AEGIS_AES_BLOCK_LOAD(src); + msg = AEGIS_AES_BLOCK_XOR(msg, state[5]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[4]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[1]); + msg = AEGIS_AES_BLOCK_XOR(msg, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(dst, msg); + + AEGIS_update(state, msg); +} + +static void +AEGIS_declast(uint8_t *const dst, const uint8_t *const src, size_t len, + AEGIS_AES_BLOCK_T *const state) +{ + uint8_t pad[AEGIS_RATE]; + AEGIS_AES_BLOCK_T msg; + + memset(pad, 0, sizeof pad); + memcpy(pad, src, len); + + msg = AEGIS_AES_BLOCK_LOAD(pad); + msg = AEGIS_AES_BLOCK_XOR(msg, state[5]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[4]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[1]); + msg = AEGIS_AES_BLOCK_XOR(msg, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(pad, msg); + + memset(pad + len, 0, sizeof pad - len); + memcpy(dst, pad, len); + + msg = AEGIS_AES_BLOCK_LOAD(pad); + + AEGIS_update(state, msg); +} + +static void +AEGIS_mac_nr(uint8_t *mac, size_t maclen, uint64_t adlen, AEGIS_AES_BLOCK_T *state) +{ + uint8_t t[2 * AES_BLOCK_LENGTH]; + uint8_t r[AEGIS_RATE]; + AEGIS_AES_BLOCK_T tmp; + int i; + const int d = AES_BLOCK_LENGTH / 16; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } + + memset(r, 0, sizeof r); + if (maclen == 16) { +#if AES_BLOCK_LENGTH > 16 + tmp = AEGIS_AES_BLOCK_XOR(state[5], state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + + for (i = 1; i < d; i++) { + memcpy(r, t + i * 16, 16); + AEGIS_absorb(r, state); + } + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, d); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } +#endif + tmp = AEGIS_AES_BLOCK_XOR(state[5], state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac, t, 16); + } else if (maclen == 32) { +#if AES_BLOCK_LENGTH > 16 + tmp = AEGIS_AES_BLOCK_XOR(state[2], AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + tmp = AEGIS_AES_BLOCK_XOR(state[5], AEGIS_AES_BLOCK_XOR(state[4], state[3])); + AEGIS_AES_BLOCK_STORE(t + AES_BLOCK_LENGTH, tmp); + for (i = 1; i < d; i++) { + memcpy(r, t + i * 16, 16); + AEGIS_absorb(r, state); + memcpy(r, t + AES_BLOCK_LENGTH + i * 16, 16); + AEGIS_absorb(r, state); + } + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, d); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } +#endif + tmp = AEGIS_AES_BLOCK_XOR(state[2], AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac, t, 16); + tmp = AEGIS_AES_BLOCK_XOR(state[5], AEGIS_AES_BLOCK_XOR(state[4], state[3])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac + 16, t, 16); + } else { + memset(mac, 0, maclen); + } +} + +static int +AEGIS_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } + + AEGIS_mac(mac, maclen, adlen, mlen, state); + + return 0; +} + +static int +AEGIS_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, size_t maclen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + const size_t mlen = clen; + size_t i; + int ret; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + if (m != NULL) { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + } else { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, state); + } + } + if (mlen % AEGIS_RATE) { + if (m != NULL) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } else { + AEGIS_declast(dst, c + i, mlen % AEGIS_RATE, state); + } + } + + COMPILER_ASSERT(sizeof computed_mac >= 32); + AEGIS_mac(computed_mac, maclen, adlen, mlen, state); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret != 0 && m != NULL) { + memset(m, 0, mlen); + } + return ret; +} + +static void +AEGIS_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + memset(src, 0, sizeof src); + if (npub == NULL) { + npub = src; + } + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= len; i += AEGIS_RATE) { + AEGIS_enc(out + i, src, state); + } + if (len % AEGIS_RATE) { + AEGIS_enc(dst, src, state); + memcpy(out + i, dst, len % AEGIS_RATE); + } +} + +static void +AEGIS_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } +} + +static void +AEGIS_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + const size_t mlen = clen; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + if (mlen % AEGIS_RATE) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } +} + +typedef struct AEGIS_STATE { + AEGIS_BLOCKS blocks; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + uint64_t mlen; + size_t pos; +} AEGIS_STATE; + +typedef struct AEGIS_MAC_STATE { + AEGIS_BLOCKS blocks; + AEGIS_BLOCKS blocks0; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + size_t pos; +} AEGIS_MAC_STATE; + +#ifndef AEGIS_OMIT_INCREMENTAL + +static void +AEGIS_state_init(aegis256x2_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + + memcpy(blocks, st->blocks, sizeof blocks); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->mlen = 0; + st->pos = 0; + + AEGIS_init(k, npub, blocks); + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (adlen % AEGIS_RATE) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(st->buf, blocks); + } + st->adlen = adlen; + + memcpy(st->blocks, blocks, sizeof blocks); +} + +static int +AEGIS_state_encrypt_update(aegis256x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += mlen; + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = mlen < available ? mlen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, m + i, n); + m += n; + mlen -= n; + st->pos += n; + } + if (st->pos == sizeof st->buf) { + if (clen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + clen_max -= AEGIS_RATE; + AEGIS_enc(c, st->buf, blocks); + *written += AEGIS_RATE; + c += AEGIS_RATE; + st->pos = 0; + } else { + return 0; + } + } + if (clen_max < (mlen & ~(size_t) (AEGIS_RATE - 1))) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, blocks); + } + *written += i; + left = mlen % AEGIS_RATE; + if (left != 0) { + memcpy(st->buf, m + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_detached_final(aegis256x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(mac, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_final(aegis256x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos + maclen) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(c + st->pos, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos + maclen; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_update(aegis256x2_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *c, size_t clen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += clen; + + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = clen < available ? clen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, c, n); + c += n; + clen -= n; + st->pos += n; + } + if (st->pos < (sizeof st->buf)) { + return 0; + } + st->pos = 0; + if (m != NULL) { + if (mlen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + mlen_max -= AEGIS_RATE; + AEGIS_dec(m, st->buf, blocks); + m += AEGIS_RATE; + } else { + AEGIS_dec(dst, st->buf, blocks); + } + *written += AEGIS_RATE; + } + + if (m != NULL) { + if (mlen_max < (clen % AEGIS_RATE)) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, blocks); + } + } else { + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, blocks); + } + } + *written += i; + left = clen % AEGIS_RATE; + if (left) { + memcpy(st->buf, c + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_final(aegis256x2_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + int ret; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (st->pos != 0) { + if (m != NULL) { + if (mlen_max < st->pos) { + errno = ERANGE; + return -1; + } + AEGIS_declast(m, st->buf, st->pos, blocks); + } else { + AEGIS_declast(dst, st->buf, st->pos, blocks); + } + } + AEGIS_mac(computed_mac, maclen, st->adlen, st->mlen, blocks); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret == 0) { + *written = st->pos; + } else { + memset(m, 0, st->pos); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return ret; +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +#ifndef AEGIS_OMIT_MAC_API + +static void +AEGIS_state_mac_init(aegis256x2_mac_state *st_, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->pos = 0; + + memcpy(blocks, st->blocks, sizeof blocks); + + AEGIS_init(k, npub, blocks); + + memcpy(st->blocks0, blocks, sizeof blocks); + memcpy(st->blocks, blocks, sizeof blocks); + st->adlen = 0; +} + +static int +AEGIS_state_mac_update(aegis256x2_mac_state *st_, const uint8_t *ad, size_t adlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + st->adlen += adlen; + if (left != 0) { + if (left + adlen < AEGIS_RATE) { + memcpy(st->buf + left, ad, adlen); + return 0; + } + memcpy(st->buf + left, ad, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + ad += AEGIS_RATE - left; + adlen -= AEGIS_RATE - left; + } + for (i = 0; i + AEGIS_RATE * 2 <= adlen; i += AEGIS_RATE * 2) { + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 0); + msg1 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 1); + COMPILER_ASSERT(AES_BLOCK_LENGTH * 2 == AEGIS_RATE * 2); + + AEGIS_update(blocks, msg0); + AEGIS_update(blocks, msg1); + } + for (; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (i < adlen) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen - i); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_mac_final(aegis256x2_mac_state *st_, uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + if (left != 0) { + memset(st->buf + left, 0, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + } + AEGIS_mac_nr(mac, maclen, st->adlen, blocks); + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static void +AEGIS_state_mac_reset(aegis256x2_mac_state *st_) +{ + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + st->adlen = 0; + st->pos = 0; + memcpy(st->blocks, st->blocks0, sizeof(AEGIS_BLOCKS)); +} + +static void +AEGIS_state_mac_clone(aegis256x2_mac_state *dst, const aegis256x2_mac_state *src) +{ + AEGIS_MAC_STATE *const dst_ = + (AEGIS_MAC_STATE *) ((((uintptr_t) &dst->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + const AEGIS_MAC_STATE *const src_ = + (const AEGIS_MAC_STATE *) ((((uintptr_t) &src->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + *dst_ = *src_; +} + +#endif /* AEGIS_OMIT_MAC_API */ + +#undef AEGIS_RATE +#undef AEGIS_ALIGNMENT + +#undef AEGIS_init +#undef AEGIS_mac +#undef AEGIS_mac_nr +#undef AEGIS_absorb +#undef AEGIS_enc +#undef AEGIS_dec +#undef AEGIS_declast diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_soft.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_soft.c new file mode 100644 index 0000000000..70ecea1f3d --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_soft.c @@ -0,0 +1,95 @@ +/* +** Name: aegis256x2_soft.c +** Purpose: Implementation of AEGIS-256x2 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" + +#include "../common/softaes.h" +#include "aegis256x2.h" +#include "aegis256x2_soft.h" + +#define AES_BLOCK_LENGTH 32 + +typedef struct { + SoftAesBlock b0; + SoftAesBlock b1; +} aegis256x2_soft_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x2_soft_aes_block_t +#define AEGIS_BLOCKS aegis256x2_soft_blocks +#define AEGIS_STATE _aegis256x2_soft_state +#define AEGIS_MAC_STATE _aegis256x2_soft_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x2_soft_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_xor(a.b0, b.b0), softaes_block_xor(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_and(a.b0, b.b0), softaes_block_and(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_load(a), softaes_block_load(a + 16) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const SoftAesBlock t = softaes_block_load64x2(a, b); + return (AEGIS_AES_BLOCK_T) { t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + softaes_block_store(a, b.b0); + softaes_block_store(a + 16, b.b1); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_encrypt(a.b0, b.b0), softaes_block_encrypt(a.b1, b.b1) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x2_common.h" + +struct aegis256x2_implementation aegis256x2_soft_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_soft.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_soft.h new file mode 100644 index 0000000000..9fd5beb6ba --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/aegis256x2_soft.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256x2_soft.h +** Purpose: Header for implementation structure of AEGIS-256x2 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X2_SOFT_H +#define AEGIS256X2_SOFT_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256x2_implementation aegis256x2_soft_implementation; + +#endif /* AEGIS256X2_SOFT_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/implementations.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/implementations.h new file mode 100644 index 0000000000..963485dba9 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x2/implementations.h @@ -0,0 +1,50 @@ +/* +** Name: implementations.h +** Purpose: Header for implementation structure of AEGIS-256x2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X2_IMPLEMENTATIONS_H +#define AEGIS256X2_IMPLEMENTATIONS_H + +#include +#include + +#include "aegis256x2.h" + +typedef struct aegis256x2_implementation { + int (*encrypt_detached)(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k); + int (*decrypt_detached)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + void (*stream)(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + void (*encrypt_unauthenticated)(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k); + void (*decrypt_unauthenticated)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k); +#ifndef AEGIS_OMIT_INCREMENTAL + void (*state_init)(aegis256x2_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + int (*state_encrypt_update)(aegis256x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen); + int (*state_encrypt_detached_final)(aegis256x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + int (*state_encrypt_final)(aegis256x2_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen); + int (*state_decrypt_detached_update)(aegis256x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen); + int (*state_decrypt_detached_final)(aegis256x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen); +#endif /* AEGIS_OMIT_INCREMENTAL */ +#ifndef AEGIS_OMIT_MAC_API + void (*state_mac_init)(aegis256x2_mac_state *st_, const uint8_t *npub, const uint8_t *k); + int (*state_mac_update)(aegis256x2_mac_state *st_, const uint8_t *ad, size_t adlen); + int (*state_mac_final)(aegis256x2_mac_state *st_, uint8_t *mac, size_t maclen); + void (*state_mac_reset)(aegis256x2_mac_state *st); + void (*state_mac_clone)(aegis256x2_mac_state *dst, const aegis256x2_mac_state *src); +#endif /* AEGIS_OMIT_MAC_API */ +} aegis256x2_implementation; + +#endif /* AEGIS256X2_IMPLEMENTATIONS_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4.c new file mode 100644 index 0000000000..0a00c924cd --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4.c @@ -0,0 +1,308 @@ +/* +** Name: aegis256x4.c +** Purpose: Implementation of AEGIS-256x4 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" +#include "aegis256x4.h" +#if 0 +#include "aegis256x4_aesni.h" +#include "aegis256x4_altivec.h" +#include "aegis256x4_armcrypto.h" +#include "aegis256x4_avx2.h" +#include "aegis256x4_avx512.h" +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NONE +#include "aegis256x4_soft.h" +static const aegis256x4_implementation *implementation_256x4 = &aegis256x4_soft_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON +static const aegis256x4_implementation *implementation_256x4 = &aegis256x4_armcrypto_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +static const aegis256x4_implementation *implementation_256x4 = &aegis256x4_aesni_implementation; +#elif HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC +static const aegis256x4_implementation *implementation_256x4 = &aegis256x4_altivec_implementation; +#else +#error "Unsupported architecture" +#endif + +AEGIS_API +size_t +aegis256x4_keybytes(void) +{ + return aegis256x4_KEYBYTES; +} + +AEGIS_API +size_t +aegis256x4_npubbytes(void) +{ + return aegis256x4_NPUBBYTES; +} + +AEGIS_API +size_t +aegis256x4_abytes_min(void) +{ + return aegis256x4_ABYTES_MIN; +} + +AEGIS_API +size_t +aegis256x4_abytes_max(void) +{ + return aegis256x4_ABYTES_MAX; +} + +AEGIS_API +size_t +aegis256x4_tailbytes_max(void) +{ + return aegis256x4_TAILBYTES_MAX; +} + +AEGIS_API +int +aegis256x4_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x4->encrypt_detached(c, mac, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256x4_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x4->decrypt_detached(m, c, clen, mac, maclen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256x4_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + return aegis256x4_encrypt_detached(c, c + mlen, maclen, m, mlen, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256x4_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + int ret = -1; + + if (clen >= maclen) { + ret = aegis256x4_decrypt_detached(m, c, clen - maclen, c + clen - maclen, maclen, ad, adlen, + npub, k); + } + return ret; +} + +#ifndef AEGIS_OMIT_INCREMENTAL + +AEGIS_API +void +aegis256x4_state_init(aegis256x4_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + memset(st_, 0, sizeof *st_); + implementation_256x4->state_init(st_, ad, adlen, npub, k); +} + +AEGIS_API +int +aegis256x4_state_encrypt_update(aegis256x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + return implementation_256x4->state_encrypt_update(st_, c, clen_max, written, m, mlen); +} + +AEGIS_API +int +aegis256x4_state_encrypt_detached_final(aegis256x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x4->state_encrypt_detached_final(st_, c, clen_max, written, mac, maclen); +} + +AEGIS_API +int +aegis256x4_state_encrypt_final(aegis256x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x4->state_encrypt_final(st_, c, clen_max, written, maclen); +} + +AEGIS_API +int +aegis256x4_state_decrypt_detached_update(aegis256x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) +{ + return implementation_256x4->state_decrypt_detached_update(st_, m, mlen_max, written, c, clen); +} + +AEGIS_API +int +aegis256x4_state_decrypt_detached_final(aegis256x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x4->state_decrypt_detached_final(st_, m, mlen_max, written, mac, maclen); +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +AEGIS_API +void +aegis256x4_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + implementation_256x4->stream(out, len, npub, k); +} + +AEGIS_API +void +aegis256x4_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_256x4->encrypt_unauthenticated(c, m, mlen, npub, k); +} + +AEGIS_API +void +aegis256x4_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + implementation_256x4->decrypt_unauthenticated(m, c, clen, npub, k); +} + +#ifndef AEGIS_OMIT_MAC_API + +AEGIS_API +void +aegis256x4_mac_init(aegis256x4_mac_state *st_, const uint8_t *k, const uint8_t *npub) +{ + implementation_256x4->state_mac_init(st_, npub, k); +} + +AEGIS_API +int +aegis256x4_mac_update(aegis256x4_mac_state *st_, const uint8_t *m, size_t mlen) +{ + return implementation_256x4->state_mac_update(st_, m, mlen); +} + +AEGIS_API +int +aegis256x4_mac_final(aegis256x4_mac_state *st_, uint8_t *mac, size_t maclen) +{ + if (maclen != 16 && maclen != 32) { + errno = EINVAL; + return -1; + } + return implementation_256x4->state_mac_final(st_, mac, maclen); +} + +AEGIS_API +int +aegis256x4_mac_verify(aegis256x4_mac_state *st_, const uint8_t *mac, size_t maclen) +{ + uint8_t expected_mac[32]; + + switch (maclen) { + case 16: + implementation_256x4->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_16(expected_mac, mac); + case 32: + implementation_256x4->state_mac_final(st_, expected_mac, maclen); + return aegis_verify_32(expected_mac, mac); + default: + errno = EINVAL; + return -1; + } +} + +AEGIS_API +void +aegis256x4_mac_reset(aegis256x4_mac_state *st_) +{ + implementation_256x4->state_mac_reset(st_); +} + +AEGIS_API +void +aegis256x4_mac_state_clone(aegis256x4_mac_state *dst, const aegis256x4_mac_state *src) +{ + implementation_256x4->state_mac_clone(dst, src); +} + +#endif /* AEGIS_OMIT_MAC_API */ + +AEGIS_PRIVATE +int +aegis256x4_pick_best_implementation(void) +{ + implementation_256x4 = &aegis256x4_soft_implementation; + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + if (aegis_runtime_has_armcrypto()) { + implementation_256x4 = &aegis256x4_armcrypto_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +# ifdef HAVE_VAESINTRIN_H + if (aegis_runtime_has_vaes() && aegis_runtime_has_avx512f()) { + implementation_256x4 = &aegis256x4_avx512_implementation; + return 0; + } + if (aegis_runtime_has_vaes() && aegis_runtime_has_avx2()) { + implementation_256x4 = &aegis256x4_avx2_implementation; + return 0; + } +# endif + if (aegis_runtime_has_aesni() && aegis_runtime_has_avx()) { + implementation_256x4 = &aegis256x4_aesni_implementation; + return 0; + } +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_ALTIVEC + if (aegis_runtime_has_altivec()) { + implementation_256x4 = &aegis256x4_altivec_implementation; + return 0; + } +#endif + + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_aesni.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_aesni.c new file mode 100644 index 0000000000..8938dc24ed --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_aesni.c @@ -0,0 +1,120 @@ +/* +** Name: aegis256x4_aesni.c +** Purpose: Implementation of AEGIS-256x4 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x4.h" +#include "aegis256x4_aesni.h" + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("aes,avx") +#endif + +#include +#include + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + __m128i b0; + __m128i b1; + __m128i b2; + __m128i b3; +} aegis256x4_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x4_aes_block_t +#define AEGIS_BLOCKS aegis256x4_blocks +#define AEGIS_STATE _aegis256x4_state +#define AEGIS_MAC_STATE _aegis256x4_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x4_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_xor_si128(a.b0, b.b0), _mm_xor_si128(a.b1, b.b1), + _mm_xor_si128(a.b2, b.b2), _mm_xor_si128(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_and_si128(a.b0, b.b0), _mm_and_si128(a.b1, b.b1), + _mm_and_si128(a.b2, b.b2), _mm_and_si128(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { _mm_loadu_si128((const __m128i *) (const void *) a), + _mm_loadu_si128((const __m128i *) (const void *) (a + 16)), + _mm_loadu_si128((const __m128i *) (const void *) (a + 32)), + _mm_loadu_si128((const __m128i *) (const void *) (a + 48)) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const __m128i t = _mm_set_epi64x((long long) a, (long long) b); + return (AEGIS_AES_BLOCK_T) { t, t, t, t }; +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm_storeu_si128((__m128i *) (void *) a, b.b0); + _mm_storeu_si128((__m128i *) (void *) (a + 16), b.b1); + _mm_storeu_si128((__m128i *) (void *) (a + 32), b.b2); + _mm_storeu_si128((__m128i *) (void *) (a + 48), b.b3); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm_aesenc_si128(a.b0, b.b0), _mm_aesenc_si128(a.b1, b.b1), + _mm_aesenc_si128(a.b2, b.b2), _mm_aesenc_si128(a.b3, b.b3) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x4_common.h" + +struct aegis256x4_implementation aegis256x4_aesni_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_aesni.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_aesni.h new file mode 100644 index 0000000000..93a38b33e4 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_aesni.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256x4_aesni.h +** Purpose: Header for implementation structure of AEGIS-256x4 - AES-NI +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X4_AESNI_H +#define AEGIS256X4_AESNI_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256x4_implementation aegis256x4_aesni_implementation; + +#endif /* AEGIS256X4_AESNI_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_altivec.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_altivec.c new file mode 100644 index 0000000000..95230749f4 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_altivec.c @@ -0,0 +1,117 @@ +/* +** Name: aegis256x4_altivec.c +** Purpose: Implementation of AEGIS-256x4 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__ALTIVEC__) && defined(__CRYPTO__) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x4.h" +#include "aegis256x4_altivec.h" + +#include + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("altivec,crypto"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("altivec,crypto") +#endif + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + vector unsigned char b0; + vector unsigned char b1; + vector unsigned char b2; + vector unsigned char b3; +} aegis256x4_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x4_aes_block_t +#define AEGIS_BLOCKS aegis256x4_blocks +#define AEGIS_STATE _aegis256x4_state +#define AEGIS_MAC_STATE _aegis256x4_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x4_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_xor(a.b0, b.b0), vec_xor(a.b1, b.b1), vec_xor(a.b2, b.b2), + vec_xor(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_and(a.b0, b.b0), vec_and(a.b1, b.b1), vec_and(a.b2, b.b2), + vec_and(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { vec_xl_be(0, a), vec_xl_be(0, a + 16), vec_xl_be(0, a + 32), + vec_xl_be(0, a + 48) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const vector unsigned char t = + (vector unsigned char) vec_revb(vec_insert(a, vec_promote((unsigned long long) (b), 1), 0)); + return (AEGIS_AES_BLOCK_T) { t, t, t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vec_xst_be(b.b0, 0, a); + vec_xst_be(b.b1, 0, a + 16); + vec_xst_be(b.b2, 0, a + 32); + vec_xst_be(b.b3, 0, a + 48); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vec_cipher_be(a.b0, b.b0), vec_cipher_be(a.b1, b.b1), + vec_cipher_be(a.b2, b.b2), vec_cipher_be(a.b3, b.b3) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x4_common.h" + +struct aegis256x4_implementation aegis256x4_altivec_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_altivec.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_altivec.h new file mode 100644 index 0000000000..5449248b0a --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_altivec.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256x4_altivec.h +** Purpose: Header for implementation structure of AEGIS-256x4 - AltiVec +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X4_ALTIVEC_H +#define AEGIS256X4_ALTIVEC_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256x4_implementation aegis256x4_altivec_implementation; + +#endif /* AEGIS256X4_ALTIVEC_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_armcrypto.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_armcrypto.c new file mode 100644 index 0000000000..79a0e7ffe5 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_armcrypto.c @@ -0,0 +1,131 @@ +/* +** Name: aegis256x4_armcrypto.c +** Purpose: Implementation of AEGIS-256x4 - ARM-Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include "../common/aeshardware.h" + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NEON + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x4.h" +#include "aegis256x4_armcrypto.h" + +#ifndef __ARM_FEATURE_CRYPTO +# define __ARM_FEATURE_CRYPTO 1 +#endif +#ifndef __ARM_FEATURE_AES +# define __ARM_FEATURE_AES 1 +#endif + +#ifdef USE_ARM64_NEON_H +#include +#else +#include +#endif + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("neon,crypto,aes"))), \ + apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("+simd+crypto") +#endif + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + uint8x16_t b0; + uint8x16_t b1; + uint8x16_t b2; + uint8x16_t b3; +} aegis256x4_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x4_aes_block_t +#define AEGIS_BLOCKS aegis256x4_blocks +#define AEGIS_STATE _aegis256x4_state +#define AEGIS_MAC_STATE _aegis256x4_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x4_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { veorq_u8(a.b0, b.b0), veorq_u8(a.b1, b.b1), veorq_u8(a.b2, b.b2), + veorq_u8(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { vandq_u8(a.b0, b.b0), vandq_u8(a.b1, b.b1), vandq_u8(a.b2, b.b2), + vandq_u8(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { vld1q_u8(a), vld1q_u8(a + 16), vld1q_u8(a + 32), vld1q_u8(a + 48) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const uint8x16_t t = vreinterpretq_u8_u64(vsetq_lane_u64((a), vmovq_n_u64(b), 1)); + return (AEGIS_AES_BLOCK_T) { t, t, t, t }; +} +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + vst1q_u8(a, b.b0); + vst1q_u8(a + 16, b.b1); + vst1q_u8(a + 32, b.b2); + vst1q_u8(a + 48, b.b3); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { veorq_u8(vaesmcq_u8(vaeseq_u8((a.b0), vmovq_n_u8(0))), (b.b0)), + veorq_u8(vaesmcq_u8(vaeseq_u8((a.b1), vmovq_n_u8(0))), (b.b1)), + veorq_u8(vaesmcq_u8(vaeseq_u8((a.b2), vmovq_n_u8(0))), (b.b2)), + veorq_u8(vaesmcq_u8(vaeseq_u8((a.b3), vmovq_n_u8(0))), (b.b3)) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x4_common.h" + +struct aegis256x4_implementation aegis256x4_armcrypto_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_armcrypto.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_armcrypto.h new file mode 100644 index 0000000000..0009d14e03 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_armcrypto.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256x4_armcrypto.h +** Purpose: Header for implementation structure of AEGIS-256x4 - ARM Crypto +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X4_ARMCRYPTO_H +#define AEGIS256X4_ARMCRYPTO_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256x4_implementation aegis256x4_armcrypto_implementation; + +#endif /* AEGIS256X4_ARMCRYPTO_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx2.c new file mode 100644 index 0000000000..ea560b59a3 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx2.c @@ -0,0 +1,114 @@ +/* +** Name: aegis256x4_avx2.c +** Purpose: Implementation of AEGIS-256x4 - AES-NI AVX2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x4.h" +#include "aegis256x4_avx2.h" + +#ifdef HAVE_VAESINTRIN_H + +#ifdef __clang__ +# pragma clang attribute push(__attribute__((target("vaes,avx2"))), apply_to = function) +#elif defined(__GNUC__) +# pragma GCC target("vaes,avx2") +#endif + +#include + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + __m256i b0; + __m256i b1; +} aegis256_avx2_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256_avx2_aes_block_t +#define AEGIS_BLOCKS aegis256x4_avx2_blocks +#define AEGIS_STATE _aegis256x4_avx2_state +#define AEGIS_MAC_STATE _aegis256x4_avx2_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x4_avx2_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm256_xor_si256(a.b0, b.b0), _mm256_xor_si256(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm256_and_si256(a.b0, b.b0), _mm256_and_si256(a.b1, b.b1) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { _mm256_loadu_si256((const __m256i *) (const void *) a), + _mm256_loadu_si256((const __m256i *) (const void *) (a + 32)) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const __m256i t = _mm256_broadcastsi128_si256(_mm_set_epi64x((long long) a, (long long) b)); + return (AEGIS_AES_BLOCK_T) { t, t }; +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm256_storeu_si256((__m256i *) (void *) a, b.b0); + _mm256_storeu_si256((__m256i *) (void *) (a + 32), b.b1); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { _mm256_aesenc_epi128(a.b0, b.b0), _mm256_aesenc_epi128(a.b1, b.b1) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x4_common.h" + +struct aegis256x4_implementation aegis256x4_avx2_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif /* HAVE_VAESINTRIN_H */ + +#endif \ No newline at end of file diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx2.h new file mode 100644 index 0000000000..2256e38d78 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx2.h @@ -0,0 +1,18 @@ +/* +** Name: aegis256x4_avx2.h +** Purpose: Header for implementation structure of AEGIS-256x4 - AES-NI AVX2 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X4_AVX2_H +#define AEGIS256X4_AVX2_H + +#include "../common/common.h" +#include "implementations.h" + +#ifdef HAVE_VAESINTRIN_H +extern struct aegis256x4_implementation aegis256x4_avx2_implementation; +#endif + +#endif /* AEGIS256X4_AVX2_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx512.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx512.c new file mode 100644 index 0000000000..5bfa21c4df --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx512.c @@ -0,0 +1,114 @@ +/* +** Name: aegis256x4_avx512.c +** Purpose: Implementation of AEGIS-256x4 - AES-NI AVX512 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "aegis256x4.h" +#include "aegis256x4_avx512.h" + +#ifdef HAVE_VAESINTRIN_H + +#ifdef __clang__ +# if __clang_major__ >= 18 +# pragma clang attribute push(__attribute__((target("vaes,avx512f,evex512"))), \ + apply_to = function) +# else +# pragma clang attribute push(__attribute__((target("vaes,avx512f"))), \ + apply_to = function) +# endif +#elif defined(__GNUC__) +# pragma GCC target("vaes,avx512f") +#endif + +#include + +#define AES_BLOCK_LENGTH 64 + +typedef __m512i aegis256_avx512_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256_avx512_aes_block_t +#define AEGIS_BLOCKS aegis256x4_avx512_blocks +#define AEGIS_STATE _aegis256x4_avx512_state +#define AEGIS_MAC_STATE _aegis256x4_avx512_mac_state + +#define AEGIS_FUNC_PREFIX aegis256_avx512_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm512_xor_si512(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm512_and_si512(a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return _mm512_loadu_si512((const AEGIS_AES_BLOCK_T *) (const void *) a); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + return _mm512_broadcast_i32x4(_mm_set_epi64x(a, b)); +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + _mm512_storeu_si512((AEGIS_AES_BLOCK_T *) (void *) a, b); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return _mm512_aesenc_epi128(a, b); +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x4_common.h" + +struct aegis256x4_implementation aegis256x4_avx512_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif /* HAVE_VAESINTRIN_H */ + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx512.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx512.h new file mode 100644 index 0000000000..6dc70f300f --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_avx512.h @@ -0,0 +1,18 @@ +/* +** Name: aegis256x4_avx512.h +** Purpose: Header for implementation structure of AEGIS-256x4 - AES-NI AVX512 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X4_AVX512_H +#define AEGIS256X4_AVX512_H + +#include "../common/common.h" +#include "implementations.h" + +#ifdef HAVE_VAESINTRIN_H +extern struct aegis256x4_implementation aegis256x4_avx512_implementation; +#endif + +#endif /* AEGIS256X4_AVX512_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_common.h new file mode 100644 index 0000000000..89f2ff5f6c --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_common.h @@ -0,0 +1,848 @@ +/* +** Name: aegis256x4_common.h +** Purpose: Common implementation for AEGIS-256 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#define AEGIS_RATE 64 +#define AEGIS_ALIGNMENT 64 + +typedef AEGIS_AES_BLOCK_T AEGIS_BLOCKS[6]; + +#define AEGIS_init AEGIS_FUNC(init) +#define AEGIS_mac AEGIS_FUNC(mac) +#define AEGIS_mac_nr AEGIS_FUNC(mac_nr) +#define AEGIS_absorb AEGIS_FUNC(absorb) +#define AEGIS_enc AEGIS_FUNC(enc) +#define AEGIS_dec AEGIS_FUNC(dec) +#define AEGIS_declast AEGIS_FUNC(declast) + +static void +AEGIS_init(const uint8_t *key, const uint8_t *nonce, AEGIS_AES_BLOCK_T *const state) +{ + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) const uint8_t c0_[AES_BLOCK_LENGTH] = { + 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, + 0xe9, 0x79, 0x62, 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, + 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62, 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, + 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62, 0x00, 0x01, 0x01, 0x02, + 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62, + }; + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) const uint8_t c1_[AES_BLOCK_LENGTH] = { + 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, + 0xb5, 0x28, 0xdd, 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, + 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd, 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, + 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd, 0xdb, 0x3d, 0x18, 0x55, + 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd, + }; + + const AEGIS_AES_BLOCK_T c0 = AEGIS_AES_BLOCK_LOAD(c0_); + const AEGIS_AES_BLOCK_T c1 = AEGIS_AES_BLOCK_LOAD(c1_); + uint8_t tmp[4 * 16]; + uint8_t context_bytes[AES_BLOCK_LENGTH]; + AEGIS_AES_BLOCK_T context; + AEGIS_AES_BLOCK_T k0, k1; + AEGIS_AES_BLOCK_T n0, n1; + AEGIS_AES_BLOCK_T k0_n0, k1_n1; + int i; + + memcpy(tmp, key, 16); + memcpy(tmp + 16, key, 16); + memcpy(tmp + 32, key, 16); + memcpy(tmp + 48, key, 16); + k0 = AEGIS_AES_BLOCK_LOAD(tmp); + memcpy(tmp, key + 16, 16); + memcpy(tmp + 16, key + 16, 16); + memcpy(tmp + 32, key + 16, 16); + memcpy(tmp + 48, key + 16, 16); + k1 = AEGIS_AES_BLOCK_LOAD(tmp); + + memcpy(tmp, nonce, 16); + memcpy(tmp + 16, nonce, 16); + memcpy(tmp + 32, nonce, 16); + memcpy(tmp + 48, nonce, 16); + n0 = AEGIS_AES_BLOCK_LOAD(tmp); + memcpy(tmp, nonce + 16, 16); + memcpy(tmp + 16, nonce + 16, 16); + memcpy(tmp + 32, nonce + 16, 16); + memcpy(tmp + 48, nonce + 16, 16); + n1 = AEGIS_AES_BLOCK_LOAD(tmp); + + k0_n0 = AEGIS_AES_BLOCK_XOR(k0, n0); + k1_n1 = AEGIS_AES_BLOCK_XOR(k1, n1); + + memset(context_bytes, 0, sizeof context_bytes); + context_bytes[0 * 16] = 0x00; + context_bytes[0 * 16 + 1] = 0x03; + context_bytes[1 * 16] = 0x01; + context_bytes[1 * 16 + 1] = 0x03; + context_bytes[2 * 16] = 0x02; + context_bytes[2 * 16 + 1] = 0x03; + context_bytes[3 * 16] = 0x03; + context_bytes[3 * 16 + 1] = 0x03; + context = AEGIS_AES_BLOCK_LOAD(context_bytes); + + state[0] = k0_n0; + state[1] = k1_n1; + state[2] = c1; + state[3] = c0; + state[4] = AEGIS_AES_BLOCK_XOR(k0, c0); + state[5] = AEGIS_AES_BLOCK_XOR(k1, c1); + for (i = 0; i < 4; i++) { + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[5] = AEGIS_AES_BLOCK_XOR(state[5], context); + AEGIS_update(state, k0); + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[5] = AEGIS_AES_BLOCK_XOR(state[5], context); + AEGIS_update(state, k1); + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[5] = AEGIS_AES_BLOCK_XOR(state[5], context); + AEGIS_update(state, k0_n0); + state[3] = AEGIS_AES_BLOCK_XOR(state[3], context); + state[5] = AEGIS_AES_BLOCK_XOR(state[5], context); + AEGIS_update(state, k1_n1); + } +} + +static void +AEGIS_mac(uint8_t *mac, size_t maclen, uint64_t adlen, uint64_t mlen, AEGIS_AES_BLOCK_T *const state) +{ + uint8_t mac_multi_0[AES_BLOCK_LENGTH]; + uint8_t mac_multi_1[AES_BLOCK_LENGTH]; + AEGIS_AES_BLOCK_T tmp; + int i; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(mlen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } + + if (maclen == 16) { + tmp = AEGIS_AES_BLOCK_XOR(state[5], state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac_multi_0, tmp); + for (i = 0; i < 16; i++) { + mac[i] = mac_multi_0[i] ^ mac_multi_0[1 * 16 + i] ^ mac_multi_0[2 * 16 + i] ^ + mac_multi_0[3 * 16 + i]; + } + } else if (maclen == 32) { + tmp = AEGIS_AES_BLOCK_XOR(state[2], AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(mac_multi_0, tmp); + for (i = 0; i < 16; i++) { + mac[i] = mac_multi_0[i] ^ mac_multi_0[1 * 16 + i] ^ mac_multi_0[2 * 16 + i] ^ + mac_multi_0[3 * 16 + i]; + } + + tmp = AEGIS_AES_BLOCK_XOR(state[5], AEGIS_AES_BLOCK_XOR(state[4], state[3])); + AEGIS_AES_BLOCK_STORE(mac_multi_1, tmp); + for (i = 0; i < 16; i++) { + mac[i + 16] = mac_multi_1[i] ^ mac_multi_1[1 * 16 + i] ^ mac_multi_1[2 * 16 + i] ^ + mac_multi_1[3 * 16 + i]; + } + } else { + memset(mac, 0, maclen); + } +} + +static inline void +AEGIS_absorb(const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + + msg = AEGIS_AES_BLOCK_LOAD(src); + AEGIS_update(state, msg); +} + +static void +AEGIS_enc(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + AEGIS_AES_BLOCK_T tmp; + + msg = AEGIS_AES_BLOCK_LOAD(src); + tmp = AEGIS_AES_BLOCK_XOR(msg, state[5]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[1]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(dst, tmp); + + AEGIS_update(state, msg); +} + +static void +AEGIS_dec(uint8_t *const dst, const uint8_t *const src, AEGIS_AES_BLOCK_T *const state) +{ + AEGIS_AES_BLOCK_T msg; + + msg = AEGIS_AES_BLOCK_LOAD(src); + msg = AEGIS_AES_BLOCK_XOR(msg, state[5]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[4]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[1]); + msg = AEGIS_AES_BLOCK_XOR(msg, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(dst, msg); + + AEGIS_update(state, msg); +} + +static void +AEGIS_declast(uint8_t *const dst, const uint8_t *const src, size_t len, + AEGIS_AES_BLOCK_T *const state) +{ + uint8_t pad[AEGIS_RATE]; + AEGIS_AES_BLOCK_T msg; + + memset(pad, 0, sizeof pad); + memcpy(pad, src, len); + + msg = AEGIS_AES_BLOCK_LOAD(pad); + msg = AEGIS_AES_BLOCK_XOR(msg, state[5]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[4]); + msg = AEGIS_AES_BLOCK_XOR(msg, state[1]); + msg = AEGIS_AES_BLOCK_XOR(msg, AEGIS_AES_BLOCK_AND(state[2], state[3])); + AEGIS_AES_BLOCK_STORE(pad, msg); + + memset(pad + len, 0, sizeof pad - len); + memcpy(dst, pad, len); + + msg = AEGIS_AES_BLOCK_LOAD(pad); + + AEGIS_update(state, msg); +} + +static void +AEGIS_mac_nr(uint8_t *mac, size_t maclen, uint64_t adlen, AEGIS_AES_BLOCK_T *state) +{ + uint8_t t[2 * AES_BLOCK_LENGTH]; + uint8_t r[AEGIS_RATE]; + AEGIS_AES_BLOCK_T tmp; + int i; + const int d = AES_BLOCK_LENGTH / 16; + + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, adlen << 3); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } + + memset(r, 0, sizeof r); + if (maclen == 16) { +#if AES_BLOCK_LENGTH > 16 + tmp = AEGIS_AES_BLOCK_XOR(state[5], state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + + for (i = 1; i < d; i++) { + memcpy(r, t + i * 16, 16); + AEGIS_absorb(r, state); + } + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, d); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } +#endif + tmp = AEGIS_AES_BLOCK_XOR(state[5], state[4]); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[3], state[2])); + tmp = AEGIS_AES_BLOCK_XOR(tmp, AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac, t, 16); + } else if (maclen == 32) { +#if AES_BLOCK_LENGTH > 16 + tmp = AEGIS_AES_BLOCK_XOR(state[2], AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + tmp = AEGIS_AES_BLOCK_XOR(state[5], AEGIS_AES_BLOCK_XOR(state[4], state[3])); + AEGIS_AES_BLOCK_STORE(t + AES_BLOCK_LENGTH, tmp); + for (i = 1; i < d; i++) { + memcpy(r, t + i * 16, 16); + AEGIS_absorb(r, state); + memcpy(r, t + AES_BLOCK_LENGTH + i * 16, 16); + AEGIS_absorb(r, state); + } + tmp = AEGIS_AES_BLOCK_LOAD_64x2(maclen << 3, d); + tmp = AEGIS_AES_BLOCK_XOR(tmp, state[3]); + for (i = 0; i < 7; i++) { + AEGIS_update(state, tmp); + } +#endif + tmp = AEGIS_AES_BLOCK_XOR(state[2], AEGIS_AES_BLOCK_XOR(state[1], state[0])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac, t, 16); + tmp = AEGIS_AES_BLOCK_XOR(state[5], AEGIS_AES_BLOCK_XOR(state[4], state[3])); + AEGIS_AES_BLOCK_STORE(t, tmp); + memcpy(mac + 16, t, 16); + } else { + memset(mac, 0, maclen); + } +} + +static int +AEGIS_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } + + AEGIS_mac(mac, maclen, adlen, mlen, state); + + return 0; +} + +static int +AEGIS_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, size_t maclen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + const size_t mlen = clen; + size_t i; + int ret; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, state); + } + if (adlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(src, state); + } + if (m != NULL) { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + } else { + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, state); + } + } + if (mlen % AEGIS_RATE) { + if (m != NULL) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } else { + AEGIS_declast(dst, c + i, mlen % AEGIS_RATE, state); + } + } + + COMPILER_ASSERT(sizeof computed_mac >= 32); + AEGIS_mac(computed_mac, maclen, adlen, mlen, state); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret != 0 && m != NULL) { + memset(m, 0, mlen); + } + return ret; +} + +static void +AEGIS_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + memset(src, 0, sizeof src); + if (npub == NULL) { + npub = src; + } + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= len; i += AEGIS_RATE) { + AEGIS_enc(out + i, src, state); + } + if (len % AEGIS_RATE) { + AEGIS_enc(dst, src, state); + memcpy(out + i, dst, len % AEGIS_RATE); + } +} + +static void +AEGIS_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, state); + } + if (mlen % AEGIS_RATE) { + memset(src, 0, AEGIS_RATE); + memcpy(src, m + i, mlen % AEGIS_RATE); + AEGIS_enc(dst, src, state); + memcpy(c + i, dst, mlen % AEGIS_RATE); + } +} + +static void +AEGIS_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS state; + const size_t mlen = clen; + size_t i; + + AEGIS_init(k, npub, state); + + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, state); + } + if (mlen % AEGIS_RATE) { + AEGIS_declast(m + i, c + i, mlen % AEGIS_RATE, state); + } +} + +typedef struct AEGIS_STATE { + AEGIS_BLOCKS blocks; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + uint64_t mlen; + size_t pos; +} AEGIS_STATE; + +typedef struct AEGIS_MAC_STATE { + AEGIS_BLOCKS blocks; + AEGIS_BLOCKS blocks0; + uint8_t buf[AEGIS_RATE]; + uint64_t adlen; + size_t pos; +} AEGIS_MAC_STATE; + +#ifndef AEGIS_OMIT_INCREMENTAL + +static void +AEGIS_state_init(aegis256x4_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + + memcpy(blocks, st->blocks, sizeof blocks); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->mlen = 0; + st->pos = 0; + + AEGIS_init(k, npub, blocks); + for (i = 0; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (adlen % AEGIS_RATE) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen % AEGIS_RATE); + AEGIS_absorb(st->buf, blocks); + } + st->adlen = adlen; + + memcpy(st->blocks, blocks, sizeof blocks); +} + +static int +AEGIS_state_encrypt_update(aegis256x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += mlen; + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = mlen < available ? mlen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, m + i, n); + m += n; + mlen -= n; + st->pos += n; + } + if (st->pos == sizeof st->buf) { + if (clen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + clen_max -= AEGIS_RATE; + AEGIS_enc(c, st->buf, blocks); + *written += AEGIS_RATE; + c += AEGIS_RATE; + st->pos = 0; + } else { + return 0; + } + } + if (clen_max < (mlen & ~(size_t) (AEGIS_RATE - 1))) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= mlen; i += AEGIS_RATE) { + AEGIS_enc(c + i, m + i, blocks); + } + *written += i; + left = mlen % AEGIS_RATE; + if (left != 0) { + memcpy(st->buf, m + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_detached_final(aegis256x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(mac, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_encrypt_final(aegis256x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t src[AEGIS_RATE]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (clen_max < st->pos + maclen) { + errno = ERANGE; + return -1; + } + if (st->pos != 0) { + memset(src, 0, sizeof src); + memcpy(src, st->buf, st->pos); + AEGIS_enc(dst, src, blocks); + memcpy(c, dst, st->pos); + } + AEGIS_mac(c + st->pos, maclen, st->adlen, st->mlen, blocks); + + *written = st->pos + maclen; + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_update(aegis256x4_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *c, size_t clen) +{ + AEGIS_BLOCKS blocks; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + size_t i = 0; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + st->mlen += clen; + + if (st->pos != 0) { + const size_t available = (sizeof st->buf) - st->pos; + const size_t n = clen < available ? clen : available; + + if (n != 0) { + memcpy(st->buf + st->pos, c, n); + c += n; + clen -= n; + st->pos += n; + } + if (st->pos < (sizeof st->buf)) { + return 0; + } + st->pos = 0; + if (m != NULL) { + if (mlen_max < AEGIS_RATE) { + errno = ERANGE; + return -1; + } + mlen_max -= AEGIS_RATE; + AEGIS_dec(m, st->buf, blocks); + m += AEGIS_RATE; + } else { + AEGIS_dec(dst, st->buf, blocks); + } + *written += AEGIS_RATE; + } + + if (m != NULL) { + if (mlen_max < (clen % AEGIS_RATE)) { + errno = ERANGE; + return -1; + } + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(m + i, c + i, blocks); + } + } else { + for (i = 0; i + AEGIS_RATE <= clen; i += AEGIS_RATE) { + AEGIS_dec(dst, c + i, blocks); + } + } + *written += i; + left = clen % AEGIS_RATE; + if (left) { + memcpy(st->buf, c + i, left); + st->pos = left; + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_decrypt_detached_final(aegis256x4_state *st_, uint8_t *m, size_t mlen_max, size_t *written, + const uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + CRYPTO_ALIGN(AEGIS_ALIGNMENT) uint8_t dst[AEGIS_RATE]; + AEGIS_STATE *const st = + (AEGIS_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + int ret; + + memcpy(blocks, st->blocks, sizeof blocks); + + *written = 0; + if (st->pos != 0) { + if (m != NULL) { + if (mlen_max < st->pos) { + errno = ERANGE; + return -1; + } + AEGIS_declast(m, st->buf, st->pos, blocks); + } else { + AEGIS_declast(dst, st->buf, st->pos, blocks); + } + } + AEGIS_mac(computed_mac, maclen, st->adlen, st->mlen, blocks); + ret = -1; + if (maclen == 16) { + ret = aegis_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = aegis_verify_32(computed_mac, mac); + } + if (ret == 0) { + *written = st->pos; + } else { + memset(m, 0, st->pos); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return ret; +} + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +#ifndef AEGIS_OMIT_MAC_API + +static void +AEGIS_state_mac_init(aegis256x4_mac_state *st_, const uint8_t *npub, const uint8_t *k) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + + COMPILER_ASSERT((sizeof *st) + AEGIS_ALIGNMENT <= sizeof *st_); + st->pos = 0; + + memcpy(blocks, st->blocks, sizeof blocks); + + AEGIS_init(k, npub, blocks); + + memcpy(st->blocks0, blocks, sizeof blocks); + memcpy(st->blocks, blocks, sizeof blocks); + st->adlen = 0; +} + +static int +AEGIS_state_mac_update(aegis256x4_mac_state *st_, const uint8_t *ad, size_t adlen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t i; + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + st->adlen += adlen; + if (left != 0) { + if (left + adlen < AEGIS_RATE) { + memcpy(st->buf + left, ad, adlen); + return 0; + } + memcpy(st->buf + left, ad, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + ad += AEGIS_RATE - left; + adlen -= AEGIS_RATE - left; + } + for (i = 0; i + AEGIS_RATE * 2 <= adlen; i += AEGIS_RATE * 2) { + AEGIS_AES_BLOCK_T msg0, msg1; + + msg0 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 0); + msg1 = AEGIS_AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 1); + COMPILER_ASSERT(AES_BLOCK_LENGTH * 2 == AEGIS_RATE * 2); + + AEGIS_update(blocks, msg0); + AEGIS_update(blocks, msg1); + } + for (; i + AEGIS_RATE <= adlen; i += AEGIS_RATE) { + AEGIS_absorb(ad + i, blocks); + } + if (i < adlen) { + memset(st->buf, 0, AEGIS_RATE); + memcpy(st->buf, ad + i, adlen - i); + } + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static int +AEGIS_state_mac_final(aegis256x4_mac_state *st_, uint8_t *mac, size_t maclen) +{ + AEGIS_BLOCKS blocks; + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + size_t left; + + memcpy(blocks, st->blocks, sizeof blocks); + + left = st->adlen % AEGIS_RATE; + if (left != 0) { + memset(st->buf + left, 0, AEGIS_RATE - left); + AEGIS_absorb(st->buf, blocks); + } + AEGIS_mac_nr(mac, maclen, st->adlen, blocks); + + memcpy(st->blocks, blocks, sizeof blocks); + + return 0; +} + +static void +AEGIS_state_mac_reset(aegis256x4_mac_state *st_) +{ + AEGIS_MAC_STATE *const st = + (AEGIS_MAC_STATE *) ((((uintptr_t) &st_->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + st->adlen = 0; + st->pos = 0; + memcpy(st->blocks, st->blocks0, sizeof(AEGIS_BLOCKS)); +} + +static void +AEGIS_state_mac_clone(aegis256x4_mac_state *dst, const aegis256x4_mac_state *src) +{ + AEGIS_MAC_STATE *const dst_ = + (AEGIS_MAC_STATE *) ((((uintptr_t) &dst->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + const AEGIS_MAC_STATE *const src_ = + (const AEGIS_MAC_STATE *) ((((uintptr_t) &src->opaque) + (AEGIS_ALIGNMENT - 1)) & + ~(uintptr_t) (AEGIS_ALIGNMENT - 1)); + *dst_ = *src_; +} + +#endif /* AEGIS_OMIT_MAC_API */ + +#undef AEGIS_RATE +#undef AEGIS_ALIGNMENT + +#undef AEGIS_init +#undef AEGIS_mac +#undef AEGIS_mac_nr +#undef AEGIS_absorb +#undef AEGIS_enc +#undef AEGIS_dec +#undef AEGIS_declast diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_soft.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_soft.c new file mode 100644 index 0000000000..76356651e3 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_soft.c @@ -0,0 +1,104 @@ +/* +** Name: aegis256x4_soft.c +** Purpose: Implementation of AEGIS-256x4 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include +#include + +#include "../common/common.h" +#include "../common/cpu.h" + +#include "../common/softaes.h" +#include "aegis256x4.h" +#include "aegis256x4_soft.h" + +#define AES_BLOCK_LENGTH 64 + +typedef struct { + SoftAesBlock b0; + SoftAesBlock b1; + SoftAesBlock b2; + SoftAesBlock b3; +} aegis256x4_soft_aes_block_t; + +#define AEGIS_AES_BLOCK_T aegis256x4_soft_aes_block_t +#define AEGIS_BLOCKS aegis256x4_soft_blocks +#define AEGIS_STATE _aegis256x4_soft_state +#define AEGIS_MAC_STATE _aegis256x4_soft_mac_state + +#define AEGIS_FUNC_PREFIX aegis256x4_soft_impl + +#include "../common/func_names_define.h" + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_XOR(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_xor(a.b0, b.b0), softaes_block_xor(a.b1, b.b1), + softaes_block_xor(a.b2, b.b2), softaes_block_xor(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_AND(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_and(a.b0, b.b0), softaes_block_and(a.b1, b.b1), + softaes_block_and(a.b2, b.b2), softaes_block_and(a.b3, b.b3) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD(const uint8_t *a) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_load(a), softaes_block_load(a + 16), + softaes_block_load(a + 32), softaes_block_load(a + 48) }; +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_BLOCK_LOAD_64x2(uint64_t a, uint64_t b) +{ + const SoftAesBlock t = softaes_block_load64x2(a, b); + return (AEGIS_AES_BLOCK_T) { t, t, t, t }; +} + +static inline void +AEGIS_AES_BLOCK_STORE(uint8_t *a, const AEGIS_AES_BLOCK_T b) +{ + softaes_block_store(a, b.b0); + softaes_block_store(a + 16, b.b1); + softaes_block_store(a + 32, b.b2); + softaes_block_store(a + 48, b.b3); +} + +static inline AEGIS_AES_BLOCK_T +AEGIS_AES_ENC(const AEGIS_AES_BLOCK_T a, const AEGIS_AES_BLOCK_T b) +{ + return (AEGIS_AES_BLOCK_T) { softaes_block_encrypt(a.b0, b.b0), softaes_block_encrypt(a.b1, b.b1), + softaes_block_encrypt(a.b2, b.b2), softaes_block_encrypt(a.b3, b.b3) }; +} + +static inline void +AEGIS_update(AEGIS_AES_BLOCK_T *const state, const AEGIS_AES_BLOCK_T d) +{ + AEGIS_AES_BLOCK_T tmp; + + tmp = state[5]; + state[5] = AEGIS_AES_ENC(state[4], state[5]); + state[4] = AEGIS_AES_ENC(state[3], state[4]); + state[3] = AEGIS_AES_ENC(state[2], state[3]); + state[2] = AEGIS_AES_ENC(state[1], state[2]); + state[1] = AEGIS_AES_ENC(state[0], state[1]); + state[0] = AEGIS_AES_BLOCK_XOR(AEGIS_AES_ENC(tmp, state[0]), d); +} + +#include "aegis256x4_common.h" + +struct aegis256x4_implementation aegis256x4_soft_implementation = { +#include "../common/func_table.h" +}; + +#include "../common/type_names_undefine.h" +#include "../common/func_names_undefine.h" diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_soft.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_soft.h new file mode 100644 index 0000000000..4b2b065f3d --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/aegis256x4_soft.h @@ -0,0 +1,16 @@ +/* +** Name: aegis256x4_soft.h +** Purpose: Header for implementation structure of AEGIS-256x4 - Software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X4_SOFT_H +#define AEGIS256X4_SOFT_H + +#include "../common/common.h" +#include "implementations.h" + +extern struct aegis256x4_implementation aegis256x4_soft_implementation; + +#endif /* AEGIS256X4_SOFT_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/implementations.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/implementations.h new file mode 100644 index 0000000000..b420d297b7 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/aegis256x4/implementations.h @@ -0,0 +1,50 @@ +/* +** Name: implementations.h +** Purpose: Header for implementation structure of AEGIS-256x4 +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X4_IMPLEMENTATIONS_H +#define AEGIS256X4_IMPLEMENTATIONS_H + +#include +#include + +#include "aegis256x4.h" + +typedef struct aegis256x4_implementation { + int (*encrypt_detached)(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k); + int (*decrypt_detached)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + void (*stream)(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + void (*encrypt_unauthenticated)(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub, + const uint8_t *k); + void (*decrypt_unauthenticated)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub, + const uint8_t *k); +#ifndef AEGIS_OMIT_INCREMENTAL + void (*state_init)(aegis256x4_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + int (*state_encrypt_update)(aegis256x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen); + int (*state_encrypt_detached_final)(aegis256x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + int (*state_encrypt_final)(aegis256x4_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen); + int (*state_decrypt_detached_update)(aegis256x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen); + int (*state_decrypt_detached_final)(aegis256x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen); +#endif /* AEGIS_OMIT_INCREMENTAL */ +#ifndef AEGIS_OMIT_MAC_API + void (*state_mac_init)(aegis256x4_mac_state *st_, const uint8_t *npub, const uint8_t *k); + int (*state_mac_update)(aegis256x4_mac_state *st_, const uint8_t *ad, size_t adlen); + int (*state_mac_final)(aegis256x4_mac_state *st_, uint8_t *mac, size_t maclen); + void (*state_mac_reset)(aegis256x4_mac_state *st); + void (*state_mac_clone)(aegis256x4_mac_state *dst, const aegis256x4_mac_state *src); +#endif /* AEGIS_OMIT_MAC_API */ +} aegis256x4_implementation; + +#endif /* AEGIS256X4_IMPLEMENTATIONS_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/aeshardware.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/aeshardware.h new file mode 100644 index 0000000000..7a802d4e88 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/aeshardware.h @@ -0,0 +1,98 @@ +/* +** Name: aeshardware.h +** Purpose: Header for AES hardware support detection +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS_AES_HARDWARE_H +#define AEGIS_AES_HARDWARE_H + +#define AEGIS_AES_HARDWARE_NONE 0 +#define AEGIS_AES_HARDWARE_NI 1 +#define AEGIS_AES_HARDWARE_NEON 2 +#define AEGIS_AES_HARDWARE_ALTIVEC 3 + +#ifndef AEGIS_OMIT_AES_HARDWARE_SUPPORT + +#if defined __ARM_FEATURE_CRYPTO +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NEON + + +/* --- CLang --- */ +#elif defined(__clang__) + +#if __has_attribute(target) && __has_include() && (defined(__x86_64__) || defined(__i386)) +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NI + +#elif __has_attribute(target) && __has_include() && (defined(__aarch64__)) +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NEON + +#endif + + +/* --- GNU C/C++ */ +#elif defined(__GNUC__) + +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) && (defined(__x86_64__) || defined(__i386)) +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NI +#elif defined(__aarch64__) || (defined(__arm__) && defined(__ARM_NEON)) +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NEON +#endif + + +/* --- Visual C/C++ --- */ +#elif defined (_MSC_VER) + +/* Architecture: x86 or x86_64 */ +#if (defined(_M_X64) || defined(_M_IX86)) && _MSC_FULL_VER >= 150030729 +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NI + +/* Architecture: ARM 64-bit */ +#elif defined(_M_ARM64) +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NEON + +/* Use header instead of */ +#ifndef USE_ARM64_NEON_H +#define USE_ARM64_NEON_H +#endif + +/* Architecture: ARM 32-bit */ +#elif defined _M_ARM +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NEON + +/* The following #define is required to enable intrinsic definitions + that do not omit one of the parameters for vaes[ed]q_u8 */ +#ifndef _ARM_USE_NEW_NEON_INTRINSICS +#define _ARM_USE_NEW_NEON_INTRINSICS +#endif + +#endif + +#else + +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NONE + +#endif + +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NONE + +/* Original checks of libaegis */ +#if defined(__ARM_FEATURE_CRYPTO) && defined(__ARM_FEATURE_AES) && defined(__ARM_NEON) +# define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NEON +#elif defined(__AES__) && defined(__AVX__) +# define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NI +#elif defined(__ALTIVEC__) && defined(__CRYPTO__) +# define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_ALTIVEC +#endif + +#endif + +#else /* AEGIS_OMIT_AES_HARDWARE_SUPPORT defined */ + +/* Omit AES hardware support */ +#define HAS_AEGIS_AES_HARDWARE AEGIS_AES_HARDWARE_NONE + +#endif /* SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT */ + +#endif /* AEGIS_AES_HARDWARE_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/common.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/common.c new file mode 100644 index 0000000000..3d3ec8c96e --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/common.c @@ -0,0 +1,93 @@ +/* +** Name: common.c +** Purpose: Implementation of common utility functions +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include + +#include "common.h" +#include "cpu.h" + +static volatile uint16_t optblocker_u16; + +static inline int +aegis_verify_n(const uint8_t *x_, const uint8_t *y_, const int n) +{ + const volatile uint8_t *volatile x = (const volatile uint8_t *volatile) x_; + const volatile uint8_t *volatile y = (const volatile uint8_t *volatile) y_; + volatile uint16_t d = 0U; + int i; + + for (i = 0; i < n; i++) { + d |= x[i] ^ y[i]; + } +#if defined(__GNUC__) || defined(__clang__) + __asm__("" : "+r"(d) :); +#endif + d--; + d = ((d >> 13) ^ optblocker_u16) >> 2; + + return (int) d - 1; +} + +AEGIS_API +int +aegis_verify_16(const uint8_t *x, const uint8_t *y) +{ + return aegis_verify_n(x, y, 16); +} + +AEGIS_API +int +aegis_verify_32(const uint8_t *x, const uint8_t *y) +{ + return aegis_verify_n(x, y, 32); +} + +AEGIS_PRIVATE int aegis128l_pick_best_implementation(void); +AEGIS_PRIVATE int aegis128x2_pick_best_implementation(void); +AEGIS_PRIVATE int aegis128x4_pick_best_implementation(void); +AEGIS_PRIVATE int aegis256_pick_best_implementation(void); +AEGIS_PRIVATE int aegis256x2_pick_best_implementation(void); +AEGIS_PRIVATE int aegis256x4_pick_best_implementation(void); + +AEGIS_API +int +aegis_init(void) +{ + static int initialized = 0; + + if (initialized) { + return 0; + } + if (aegis_runtime_get_cpu_features() != 0) { + return 0; + } + if (aegis128l_pick_best_implementation() != 0 || aegis128x2_pick_best_implementation() != 0 || + aegis128x4_pick_best_implementation() != 0 || aegis256_pick_best_implementation() != 0 || + aegis256x2_pick_best_implementation() != 0 || aegis256x4_pick_best_implementation() != 0) { + return -1; + } + initialized = 1; + + return 0; +} + +#if 0 +#if defined(_MSC_VER) +# pragma section(".CRT$XCU", read) +static void __cdecl _do_aegis_init(void); +__declspec(allocate(".CRT$XCU")) void (*aegis_init_constructor)(void) = _do_aegis_init; +#else +static void _do_aegis_init(void) __attribute__((constructor)); +#endif + +static void +_do_aegis_init(void) +{ + (void) aegis_init(); +} +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/common.h new file mode 100644 index 0000000000..cabe1ff533 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/common.h @@ -0,0 +1,161 @@ +/* +** Name: common.h +** Purpose: Common header for AEGIS implementations +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS_COMMON_H +#define AEGIS_COMMON_H + +#include +#include +#include +#include + +#include "../include/aegis.h" +#include "cpu.h" + +#ifdef __linux__ +# define HAVE_SYS_AUXV_H +# define HAVE_GETAUXVAL +#endif +#ifdef __ANDROID_API__ +# if __ANDROID_API__ < 18 +# undef HAVE_GETAUXVAL +# endif +# if defined(__clang__) || defined(__GNUC__) +# if __has_include() +# define HAVE_ANDROID_GETCPUFEATURES +# endif +# endif +#endif +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) + +# define HAVE_CPUID +# define NATIVE_LITTLE_ENDIAN +# if defined(__clang__) || defined(__GNUC__) +# define HAVE_AVX_ASM +# endif +#endif +#if HAS_AEGIS_AES_HARDWARE == AEGIS_AES_HARDWARE_NI +# define HAVE_AVXINTRIN_H +# define HAVE_AVX2INTRIN_H +# define HAVE_AVX512FINTRIN_H +# define HAVE_TMMINTRIN_H +# define HAVE_WMMINTRIN_H +# define HAVE_VAESINTRIN_H +# ifdef __GNUC__ +# if !__has_include() +# undef HAVE_VAESINTRIN_H +# endif +# endif +#endif + +#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# ifndef NATIVE_LITTLE_ENDIAN +# define NATIVE_LITTLE_ENDIAN +# endif +#endif + +#if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define CRYPTO_ALIGN(x) __declspec(align(x)) +#else +# define CRYPTO_ALIGN(x) __attribute__((aligned(x))) +#endif + +#define AEGIS_LOAD32_LE(SRC) aegis_load32_le(SRC) +static inline uint32_t +aegis_load32_le(const uint8_t src[4]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[0]; + w |= (uint32_t) src[1] << 8; + w |= (uint32_t) src[2] << 16; + w |= (uint32_t) src[3] << 24; + return w; +#endif +} + +#define AEGIS_STORE32_LE(DST, W) aegis_store32_le((DST), (W)) +static inline void +aegis_store32_le(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; + w >>= 8; + dst[1] = (uint8_t) w; + w >>= 8; + dst[2] = (uint8_t) w; + w >>= 8; + dst[3] = (uint8_t) w; +#endif +} + +#define AEGIS_ROTL32(X, B) aegis_rotl32((X), (B)) +static inline uint32_t +aegis_rotl32(const uint32_t x, const int b) +{ + return (x << b) | (x >> (32 - b)); +} + +#define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1]) + +#ifndef ERANGE +# define ERANGE 34 +#endif +#ifndef EINVAL +# define EINVAL 22 +#endif + +#define AEGIS_CONCAT(A,B) AEGIS_CONCAT_(A,B) +#define AEGIS_CONCAT_(A,B) A##B +#define AEGIS_FUNC(name) AEGIS_CONCAT(AEGIS_FUNC_PREFIX,AEGIS_CONCAT(_,name)) + +#define AEGIS_API_IMPL_LIST_STD \ + .encrypt_detached = AEGIS_encrypt_detached, \ + .decrypt_detached = AEGIS_decrypt_detached, \ + .encrypt_unauthenticated = AEGIS_encrypt_unauthenticated, \ + .decrypt_unauthenticated = AEGIS_decrypt_unauthenticated, \ + .stream = AEGIS_stream, +#define AEGIS_API_IMPL_LIST_INC \ + .state_init = AEGIS_state_init, \ + .state_encrypt_update = AEGIS_state_encrypt_update, \ + .state_encrypt_detached_final = AEGIS_state_encrypt_detached_final, \ + .state_encrypt_final = AEGIS_state_encrypt_final, \ + .state_decrypt_detached_update = AEGIS_state_decrypt_detached_update, \ + .state_decrypt_detached_final = AEGIS_state_decrypt_detached_final, +#define AEGIS_API_IMPL_LIST_MAC \ + .state_mac_init = AEGIS_state_mac_init, \ + .state_mac_update = AEGIS_state_mac_update, \ + .state_mac_final = AEGIS_state_mac_final, \ + .state_mac_reset = AEGIS_state_mac_reset, \ + .state_mac_clone = AEGIS_state_mac_clone, + +#if 0 +#define AEGIS_API_IMPL_LIST \ + .encrypt_detached = AEGIS_encrypt_detached, \ + .decrypt_detached = AEGIS_decrypt_detached, \ + .encrypt_unauthenticated = AEGIS_encrypt_unauthenticated, \ + .decrypt_unauthenticated = AEGIS_decrypt_unauthenticated, \ + .stream = AEGIS_stream, \ + .state_init = AEGIS_state_init, \ + .state_encrypt_update = AEGIS_state_encrypt_update, \ + .state_encrypt_detached_final = AEGIS_state_encrypt_detached_final, \ + .state_encrypt_final = AEGIS_state_encrypt_final, \ + .state_decrypt_detached_update = AEGIS_state_decrypt_detached_update, \ + .state_decrypt_detached_final = AEGIS_state_decrypt_detached_final, \ + .state_mac_init = AEGIS_state_mac_init, \ + .state_mac_update = AEGIS_state_mac_update, \ + .state_mac_final = AEGIS_state_mac_final, \ + .state_mac_reset = AEGIS_state_mac_reset, \ + .state_mac_clone = AEGIS_state_mac_clone, +#endif + +#endif /* AEGIS_COMMON_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/cpu.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/cpu.c new file mode 100644 index 0000000000..ab6c393d0f --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/cpu.c @@ -0,0 +1,351 @@ +/* +** Name: cpu.c +** Purpose: Implementation of CPU feature identification +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include "cpu.h" +#include "common.h" + +#include +#include +#include + +#ifdef HAVE_ANDROID_GETCPUFEATURES +# include +#endif +#ifdef __APPLE__ +# include +# include +# include +#endif +#ifdef HAVE_SYS_AUXV_H +# include +#endif +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) +# include +#endif + +typedef struct CPUFeatures_ { + int initialized; + int has_neon; + int has_armcrypto; + int has_avx; + int has_avx2; + int has_avx512f; + int has_aesni; + int has_vaes; + int has_altivec; +} CPUFeatures; + +static CPUFeatures _cpu_features; + +#define CPUID_EBX_AVX2 0x00000020 +#define CPUID_EBX_AVX512F 0x00010000 + +#define CPUID_ECX_AESNI 0x02000000 +#define CPUID_ECX_XSAVE 0x04000000 +#define CPUID_ECX_OSXSAVE 0x08000000 +#define CPUID_ECX_AVX 0x10000000 +#define CPUID_ECX_VAES 0x00000200 + +#define XCR0_SSE 0x00000002 +#define XCR0_AVX 0x00000004 +#define XCR0_OPMASK 0x00000020 +#define XCR0_ZMM_HI256 0x00000040 +#define XCR0_HI16_ZMM 0x00000080 + +static int +_runtime_arm_cpu_features(CPUFeatures *const cpu_features) +{ +#ifndef __ARM_ARCH + return -1; /* LCOV_EXCL_LINE */ +#endif + +#if defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) + cpu_features->has_neon = 1; +#elif defined(HAVE_ANDROID_GETCPUFEATURES) && defined(ANDROID_CPU_ARM_FEATURE_NEON) + cpu_features->has_neon = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0; +#elif (defined(__aarch64__) || defined(_M_ARM64)) && defined(AT_HWCAP) +# ifdef HAVE_GETAUXVAL + cpu_features->has_neon = (getauxval(AT_HWCAP) & (1L << 1)) != 0; +# elif defined(HAVE_ELF_AUX_INFO) + { + unsigned long buf; + if (elf_aux_info(AT_HWCAP, (void *) &buf, (int) sizeof buf) == 0) { + cpu_features->has_neon = (buf & (1L << 1)) != 0; + } + } +# endif +#elif defined(__arm__) && defined(AT_HWCAP) +# ifdef HAVE_GETAUXVAL + cpu_features->has_neon = (getauxval(AT_HWCAP) & (1L << 12)) != 0; +# elif defined(HAVE_ELF_AUX_INFO) + { + unsigned long buf; + if (elf_aux_info(AT_HWCAP, (void *) &buf, (int) sizeof buf) == 0) { + cpu_features->has_neon = (buf & (1L << 12)) != 0; + } + } +# endif +#endif + + if (cpu_features->has_neon == 0) { + return 0; + } + +#if __ARM_FEATURE_CRYPTO + cpu_features->has_armcrypto = 1; +#elif defined(_M_ARM64) + cpu_features->has_armcrypto = + 1; /* assuming all CPUs supported by ARM Windows have the crypto extensions */ +#elif defined(__APPLE__) && defined(CPU_TYPE_ARM64) && defined(CPU_SUBTYPE_ARM64E) + { + cpu_type_t cpu_type; + cpu_subtype_t cpu_subtype; + size_t cpu_type_len = sizeof cpu_type; + size_t cpu_subtype_len = sizeof cpu_subtype; + + if (sysctlbyname("hw.cputype", &cpu_type, &cpu_type_len, NULL, 0) == 0 && + cpu_type == CPU_TYPE_ARM64 && + sysctlbyname("hw.cpusubtype", &cpu_subtype, &cpu_subtype_len, NULL, 0) == 0 && + (cpu_subtype == CPU_SUBTYPE_ARM64E || cpu_subtype == CPU_SUBTYPE_ARM64_V8)) { + cpu_features->has_armcrypto = 1; + } + } +#elif defined(HAVE_ANDROID_GETCPUFEATURES) && defined(ANDROID_CPU_ARM_FEATURE_AES) + cpu_features->has_armcrypto = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES) != 0x0; +#elif (defined(__aarch64__) || defined(_M_ARM64)) && defined(AT_HWCAP) +# ifdef HAVE_GETAUXVAL + cpu_features->has_armcrypto = (getauxval(AT_HWCAP) & (1L << 3)) != 0; +# elif defined(HAVE_ELF_AUX_INFO) + { + unsigned long buf; + if (elf_aux_info(AT_HWCAP, (void *) &buf, (int) sizeof buf) == 0) { + cpu_features->has_armcrypto = (buf & (1L << 3)) != 0; + } + } +# endif +#elif defined(__arm__) && defined(AT_HWCAP2) +# ifdef HAVE_GETAUXVAL + cpu_features->has_armcrypto = (getauxval(AT_HWCAP2) & (1L << 0)) != 0; +# elif defined(HAVE_ELF_AUX_INFO) + { + unsigned long buf; + if (elf_aux_info(AT_HWCAP2, (void *) &buf, (int) sizeof buf) == 0) { + cpu_features->has_armcrypto = (buf & (1L << 0)) != 0; + } + } +# endif +#endif + + return 0; +} + +static void +_cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type) +{ +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) + __cpuid((int *) cpu_info, cpu_info_type); +#elif defined(HAVE_CPUID) + cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; +# ifdef __i386__ + __asm__ __volatile__( + "pushfl; pushfl; " + "popl %0; " + "movl %0, %1; xorl %2, %0; " + "pushl %0; " + "popfl; pushfl; popl %0; popfl" + : "=&r"(cpu_info[0]), "=&r"(cpu_info[1]) + : "i"(0x200000)); + if (((cpu_info[0] ^ cpu_info[1]) & 0x200000) == 0x0) { + return; /* LCOV_EXCL_LINE */ + } +# endif +# ifdef __i386__ + __asm__ __volatile__("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1" + : "=a"(cpu_info[0]), "=&r"(cpu_info[1]), "=c"(cpu_info[2]), + "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# elif defined(__x86_64__) + __asm__ __volatile__("xchgq %%rbx, %q1; cpuid; xchgq %%rbx, %q1" + : "=a"(cpu_info[0]), "=&r"(cpu_info[1]), "=c"(cpu_info[2]), + "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# else + __asm__ __volatile__("cpuid" + : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), + "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# endif +#else + (void) cpu_info_type; + cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; +#endif +} + +static int +_runtime_intel_cpu_features(CPUFeatures *const cpu_features) +{ + unsigned int cpu_info[4]; + uint32_t xcr0 = 0U; + + _cpuid(cpu_info, 0x0); + if (cpu_info[0] == 0U) { + return -1; /* LCOV_EXCL_LINE */ + } + _cpuid(cpu_info, 0x00000001); + + (void) xcr0; +#ifdef HAVE_AVXINTRIN_H + if ((cpu_info[2] & (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) == + (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) { + xcr0 = 0U; +# if defined(HAVE__XGETBV) || \ + (defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) && _MSC_FULL_VER >= 160040219) + xcr0 = (uint32_t) _xgetbv(0); +# elif defined(_MSC_VER) && defined(_M_IX86) + /* + * Visual Studio documentation states that eax/ecx/edx don't need to + * be preserved in inline assembly code. But that doesn't seem to + * always hold true on Visual Studio 2010. + */ + __asm { + push eax + push ecx + push edx + xor ecx, ecx + _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0 + mov xcr0, eax + pop edx + pop ecx + pop eax + } +# elif defined(HAVE_AVX_ASM) + __asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" /* XGETBV */ + : "=a"(xcr0) + : "c"((uint32_t) 0U) + : "%edx"); +# endif + if ((xcr0 & (XCR0_SSE | XCR0_AVX)) == (XCR0_SSE | XCR0_AVX)) { + cpu_features->has_avx = 1; + } + } +#endif + +#ifdef HAVE_WMMINTRIN_H + cpu_features->has_aesni = ((cpu_info[2] & CPUID_ECX_AESNI) != 0x0); +#endif + +#ifdef HAVE_AVX2INTRIN_H + if (cpu_features->has_avx) { + unsigned int cpu_info7[4]; + + _cpuid(cpu_info7, 0x00000007); + cpu_features->has_avx2 = ((cpu_info7[1] & CPUID_EBX_AVX2) != 0x0); + cpu_features->has_vaes = + cpu_features->has_aesni && ((cpu_info7[2] & CPUID_ECX_VAES) != 0x0); + } +#endif + + cpu_features->has_avx512f = 0; +#ifdef HAVE_AVX512FINTRIN_H + if (cpu_features->has_avx2) { + unsigned int cpu_info7[4]; + + _cpuid(cpu_info7, 0x00000007); + /* LCOV_EXCL_START */ + if ((cpu_info7[1] & CPUID_EBX_AVX512F) == CPUID_EBX_AVX512F && + (xcr0 & (XCR0_OPMASK | XCR0_ZMM_HI256 | XCR0_HI16_ZMM)) == + (XCR0_OPMASK | XCR0_ZMM_HI256 | XCR0_HI16_ZMM)) { + cpu_features->has_avx512f = 1; + } + /* LCOV_EXCL_STOP */ + } +#endif + + return 0; +} + +static int +_runtime_powerpc_cpu_features(CPUFeatures *const cpu_features) +{ + cpu_features->has_altivec = 0; +#if defined(__ALTIVEC__) && defined(__CRYPTO__) + cpu_features->has_altivec = 1; +#endif + return 0; +} + +AEGIS_PRIVATE +int +aegis_runtime_get_cpu_features(void) +{ + int ret = -1; + + memset(&_cpu_features, 0, sizeof _cpu_features); + + ret &= _runtime_arm_cpu_features(&_cpu_features); + ret &= _runtime_intel_cpu_features(&_cpu_features); + ret &= _runtime_powerpc_cpu_features(&_cpu_features); + _cpu_features.initialized = 1; + + return ret; +} + +AEGIS_PRIVATE +int +aegis_runtime_has_neon(void) +{ + return _cpu_features.has_neon; +} + +AEGIS_PRIVATE +int +aegis_runtime_has_armcrypto(void) +{ + return _cpu_features.has_armcrypto; +} + +AEGIS_PRIVATE +int +aegis_runtime_has_avx(void) +{ + return _cpu_features.has_avx; +} + +AEGIS_PRIVATE +int +aegis_runtime_has_avx2(void) +{ + return _cpu_features.has_avx2; +} + +AEGIS_PRIVATE +int +aegis_runtime_has_avx512f(void) +{ + return _cpu_features.has_avx512f; +} + +AEGIS_PRIVATE +int +aegis_runtime_has_aesni(void) +{ + return _cpu_features.has_aesni; +} + +AEGIS_PRIVATE +int +aegis_runtime_has_vaes(void) +{ + return _cpu_features.has_vaes; +} + +AEGIS_PRIVATE +int +aegis_runtime_has_altivec(void) +{ + return _cpu_features.has_altivec; +} \ No newline at end of file diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/cpu.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/cpu.h new file mode 100644 index 0000000000..4b8a7a3fa1 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/cpu.h @@ -0,0 +1,40 @@ +/* +** Name: cpu.h +** Purpose: Header for CPU identification and AES hardware support detection +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS_CPU_H +#define AEGIS_CPU_H + +#include "aeshardware.h" + +AEGIS_PRIVATE +int aegis_runtime_get_cpu_features(void); + +AEGIS_PRIVATE +int aegis_runtime_has_neon(void); + +AEGIS_PRIVATE +int aegis_runtime_has_armcrypto(void); + +AEGIS_PRIVATE +int aegis_runtime_has_avx(void); + +AEGIS_PRIVATE +int aegis_runtime_has_avx2(void); + +AEGIS_PRIVATE +int aegis_runtime_has_avx512f(void); + +AEGIS_PRIVATE +int aegis_runtime_has_aesni(void); + +AEGIS_PRIVATE +int aegis_runtime_has_vaes(void); + +AEGIS_PRIVATE +int aegis_runtime_has_altivec(void); + +#endif /* AEGIS_CPU_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_names_define.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_names_define.h new file mode 100644 index 0000000000..bc906661c5 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_names_define.h @@ -0,0 +1,36 @@ +/* +** Name: func_names_define.h +** Purpose: Defines for AEGIS function names +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +/* +** NOTE: +** Do NOT use include guards, because including this header +** multiple times is intended behaviour. +*/ + +#define AEGIS_AES_BLOCK_XOR AEGIS_FUNC(aes_block_xor) +#define AEGIS_AES_BLOCK_AND AEGIS_FUNC(aes_block_and) +#define AEGIS_AES_BLOCK_LOAD AEGIS_FUNC(aes_block_load) +#define AEGIS_AES_BLOCK_LOAD_64x2 AEGIS_FUNC(aes_block_load_64x2) +#define AEGIS_AES_BLOCK_STORE AEGIS_FUNC(aes_block_store) +#define AEGIS_AES_ENC AEGIS_FUNC(aes_enc) +#define AEGIS_update AEGIS_FUNC(update) +#define AEGIS_encrypt_detached AEGIS_FUNC(encrypt_detached) +#define AEGIS_decrypt_detached AEGIS_FUNC(decrypt_detached) +#define AEGIS_encrypt_unauthenticated AEGIS_FUNC(encrypt_unauthenticated) +#define AEGIS_decrypt_unauthenticated AEGIS_FUNC(decrypt_unauthenticated) +#define AEGIS_stream AEGIS_FUNC(stream) +#define AEGIS_state_init AEGIS_FUNC(state_init) +#define AEGIS_state_encrypt_update AEGIS_FUNC(state_encrypt_update) +#define AEGIS_state_encrypt_detached_final AEGIS_FUNC(state_encrypt_detached_final) +#define AEGIS_state_encrypt_final AEGIS_FUNC(state_encrypt_final) +#define AEGIS_state_decrypt_detached_update AEGIS_FUNC(state_decrypt_detached_update) +#define AEGIS_state_decrypt_detached_final AEGIS_FUNC(state_decrypt_detached_final) +#define AEGIS_state_mac_init AEGIS_FUNC(state_mac_init) +#define AEGIS_state_mac_update AEGIS_FUNC(state_mac_update) +#define AEGIS_state_mac_final AEGIS_FUNC(state_mac_final) +#define AEGIS_state_mac_reset AEGIS_FUNC(state_mac_reset) +#define AEGIS_state_mac_clone AEGIS_FUNC(state_mac_clone) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_names_undefine.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_names_undefine.h new file mode 100644 index 0000000000..561599f7c9 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_names_undefine.h @@ -0,0 +1,40 @@ +/* +** Name: func_names_undefine.h +** Purpose: Undefines for AEGIS function names +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +/* +** NOTE: +** Do NOT use include guards, because including this header +** multiple times is intended behaviour. +*/ + +/* Undefine function name prefix */ +#undef AEGIS_FUNC_PREFIX + +/* Undefine all function names */ +#undef AEGIS_AES_BLOCK_XOR +#undef AEGIS_AES_BLOCK_AND +#undef AEGIS_AES_BLOCK_LOAD +#undef AEGIS_AES_BLOCK_LOAD_64x2 +#undef AEGIS_AES_BLOCK_STORE +#undef AEGIS_AES_ENC +#undef AEGIS_update +#undef AEGIS_encrypt_detached +#undef AEGIS_decrypt_detached +#undef AEGIS_encrypt_unauthenticated +#undef AEGIS_decrypt_unauthenticated +#undef AEGIS_stream +#undef AEGIS_state_init +#undef AEGIS_state_encrypt_update +#undef AEGIS_state_encrypt_detached_final +#undef AEGIS_state_encrypt_final +#undef AEGIS_state_decrypt_detached_update +#undef AEGIS_state_decrypt_detached_final +#undef AEGIS_state_mac_init +#undef AEGIS_state_mac_update +#undef AEGIS_state_mac_final +#undef AEGIS_state_mac_reset +#undef AEGIS_state_mac_clone diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_table.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_table.h new file mode 100644 index 0000000000..d4d73b06bb --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/func_table.h @@ -0,0 +1,21 @@ +/* +** Name: func_table.h +** Purpose: Table of AEGIS API function implementations +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +/* +** NOTE: +** Do NOT use include guards, because including this header +** multiple times is intended behaviour. +*/ + +AEGIS_API_IMPL_LIST_STD +#ifndef AEGIS_OMIT_INCREMENTAL +AEGIS_API_IMPL_LIST_INC +#endif +#ifndef AEGIS_OMIT_MAC_API +AEGIS_API_IMPL_LIST_MAC +#endif + diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/softaes.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/softaes.c new file mode 100644 index 0000000000..d69391e818 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/softaes.c @@ -0,0 +1,347 @@ +/* +** Name: softaes.c +** Purpose: Implementation of AES via software +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#include +#include +#include +#include + +#include "common.h" +#include "softaes.h" + +#if defined(__wasm__) && !defined(FAVOR_PERFORMANCE) +# define FAVOR_PERFORMANCE +#endif + +#ifndef SOFTAES_STRIDE +# define SOFTAES_STRIDE 16 +#endif + +#ifdef FAVOR_PERFORMANCE +static const uint32_t _aes_lut[1024] = { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, + 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, + 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, + 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, + 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, + 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, + 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, + 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, + 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, + 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, + 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, + 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, + 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, + 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, + 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, + 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, + 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, + 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, + 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, + 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, + 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, + 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, + 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, + 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, + 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, + 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, + 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, + 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, + 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, + 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, + 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, + 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, + 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, + 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, + 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, + 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, + 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, + 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, + 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, + 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, + 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, + 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, + 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, + 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, + 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, + 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, + 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, + 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, + 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, + 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, + 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, + 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, + 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, + 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, + 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, + 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, + 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, + 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, + 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, + 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, + 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, + 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, + 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, + 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, + 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, + 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, + 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, + 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, + 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, + 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, + 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, + 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, + 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, + 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, + 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, + 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, + 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, + 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, + 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, + 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, + 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, + 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, + 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, + 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, + 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, + 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, + 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, + 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, + 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 +}; + +static const uint32_t* const LUT0 = _aes_lut + 0 * 256; +static const uint32_t* const LUT1 = _aes_lut + 1 * 256; +static const uint32_t* const LUT2 = _aes_lut + 2 * 256; +static const uint32_t* const LUT3 = _aes_lut + 3 * 256; + +SoftAesBlock +softaes_block_encrypt(const SoftAesBlock block, const SoftAesBlock rk) +{ + SoftAesBlock out; + uint8_t ix0[4], ix1[4], ix2[4], ix3[4]; + const uint32_t s0 = block.w0; + const uint32_t s1 = block.w1; + const uint32_t s2 = block.w2; + const uint32_t s3 = block.w3; + + ix0[0] = (uint8_t) s0; + ix0[1] = (uint8_t) s1; + ix0[2] = (uint8_t) s2; + ix0[3] = (uint8_t) s3; + + ix1[0] = (uint8_t) (s1 >> 8); + ix1[1] = (uint8_t) (s2 >> 8); + ix1[2] = (uint8_t) (s3 >> 8); + ix1[3] = (uint8_t) (s0 >> 8); + + ix2[0] = (uint8_t) (s2 >> 16); + ix2[1] = (uint8_t) (s3 >> 16); + ix2[2] = (uint8_t) (s0 >> 16); + ix2[3] = (uint8_t) (s1 >> 16); + + ix3[0] = (uint8_t) (s3 >> 24); + ix3[1] = (uint8_t) (s0 >> 24); + ix3[2] = (uint8_t) (s1 >> 24); + ix3[3] = (uint8_t) (s2 >> 24); + + out.w0 = LUT0[ix0[0]]; + out.w1 = LUT0[ix0[1]]; + out.w2 = LUT0[ix0[2]]; + out.w3 = LUT0[ix0[3]]; + + out.w0 ^= LUT1[ix1[0]]; + out.w1 ^= LUT1[ix1[1]]; + out.w2 ^= LUT1[ix1[2]]; + out.w3 ^= LUT1[ix1[3]]; + + out.w0 ^= LUT2[ix2[0]]; + out.w1 ^= LUT2[ix2[1]]; + out.w2 ^= LUT2[ix2[2]]; + out.w3 ^= LUT2[ix2[3]]; + + out.w0 ^= LUT3[ix3[0]]; + out.w1 ^= LUT3[ix3[1]]; + out.w2 ^= LUT3[ix3[2]]; + out.w3 ^= LUT3[ix3[3]]; + + out.w0 ^= rk.w0; + out.w1 ^= rk.w1; + out.w2 ^= rk.w2; + out.w3 ^= rk.w3; + + return out; +} +#else + +uint32_t _aes_lut[256] __attribute__((visibility("hidden"))) = { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, + 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c +}; + +static const uint32_t* const LUT = _aes_lut; + +static SoftAesBlock +_encrypt(const uint8_t ix0[4], const uint8_t ix1[4], const uint8_t ix2[4], const uint8_t ix3[4]) +{ + CRYPTO_ALIGN(64) uint32_t t[4][4][256 / SOFTAES_STRIDE]; + CRYPTO_ALIGN(64) uint8_t of[4][4]; + CRYPTO_ALIGN(64) SoftAesBlock out; + size_t i; + size_t j; + + for (j = 0; j < 4; j++) { + of[j][0] = ix0[j] % SOFTAES_STRIDE; + of[j][1] = ix1[j] % SOFTAES_STRIDE; + of[j][2] = ix2[j] % SOFTAES_STRIDE; + of[j][3] = ix3[j] % SOFTAES_STRIDE; + } + for (i = 0; i < 256 / SOFTAES_STRIDE; i++) { + for (j = 0; j < 4; j++) { + t[j][0][i] = LUT[(i * SOFTAES_STRIDE) | of[j][0]]; + t[j][1][i] = LUT[(i * SOFTAES_STRIDE) | of[j][1]]; + t[j][2][i] = LUT[(i * SOFTAES_STRIDE) | of[j][2]]; + t[j][3][i] = LUT[(i * SOFTAES_STRIDE) | of[j][3]]; + } + } + +# if defined(__GNUC__) || defined(__clang__) + __asm__ __volatile__("" : : "r"(t) : "memory"); +# endif + + out.w0 = t[0][0][ix0[0] / SOFTAES_STRIDE]; + out.w0 ^= AEGIS_ROTL32(t[0][1][ix1[0] / SOFTAES_STRIDE], 8); + out.w0 ^= AEGIS_ROTL32(t[0][2][ix2[0] / SOFTAES_STRIDE], 16); + out.w0 ^= AEGIS_ROTL32(t[0][3][ix3[0] / SOFTAES_STRIDE], 24); + + out.w1 = t[1][0][ix0[1] / SOFTAES_STRIDE]; + out.w1 ^= AEGIS_ROTL32(t[1][1][ix1[1] / SOFTAES_STRIDE], 8); + out.w1 ^= AEGIS_ROTL32(t[1][2][ix2[1] / SOFTAES_STRIDE], 16); + out.w1 ^= AEGIS_ROTL32(t[1][3][ix3[1] / SOFTAES_STRIDE], 24); + + out.w2 = t[2][0][ix0[2] / SOFTAES_STRIDE]; + out.w2 ^= AEGIS_ROTL32(t[2][1][ix1[2] / SOFTAES_STRIDE], 8); + out.w2 ^= AEGIS_ROTL32(t[2][2][ix2[2] / SOFTAES_STRIDE], 16); + out.w2 ^= AEGIS_ROTL32(t[2][3][ix3[2] / SOFTAES_STRIDE], 24); + + out.w3 = t[3][0][ix0[3] / SOFTAES_STRIDE]; + out.w3 ^= AEGIS_ROTL32(t[3][1][ix1[3] / SOFTAES_STRIDE], 8); + out.w3 ^= AEGIS_ROTL32(t[3][2][ix2[3] / SOFTAES_STRIDE], 16); + out.w3 ^= AEGIS_ROTL32(t[3][3][ix3[3] / SOFTAES_STRIDE], 24); + + return out; +} + +SoftAesBlock +softaes_block_encrypt(const SoftAesBlock block, const SoftAesBlock rk) +{ + CRYPTO_ALIGN(64) SoftAesBlock out; + CRYPTO_ALIGN(64) uint8_t ix0[4], ix1[4], ix2[4], ix3[4]; + const uint32_t s0 = block.w0; + const uint32_t s1 = block.w1; + const uint32_t s2 = block.w2; + const uint32_t s3 = block.w3; + + ix0[0] = (uint8_t) s0; + ix0[1] = (uint8_t) s1; + ix0[2] = (uint8_t) s2; + ix0[3] = (uint8_t) s3; + + ix1[0] = (uint8_t) (s1 >> 8); + ix1[1] = (uint8_t) (s2 >> 8); + ix1[2] = (uint8_t) (s3 >> 8); + ix1[3] = (uint8_t) (s0 >> 8); + + ix2[0] = (uint8_t) (s2 >> 16); + ix2[1] = (uint8_t) (s3 >> 16); + ix2[2] = (uint8_t) (s0 >> 16); + ix2[3] = (uint8_t) (s1 >> 16); + + ix3[0] = (uint8_t) (s3 >> 24); + ix3[1] = (uint8_t) (s0 >> 24); + ix3[2] = (uint8_t) (s1 >> 24); + ix3[3] = (uint8_t) (s2 >> 24); + + out = _encrypt(ix0, ix1, ix2, ix3); + + out.w0 ^= rk.w0; + out.w1 ^= rk.w1; + out.w2 ^= rk.w2; + out.w3 ^= rk.w3; + + return out; +} +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/softaes.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/softaes.h new file mode 100644 index 0000000000..81c774cbfb --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/softaes.h @@ -0,0 +1,73 @@ +/* +** Name: softaes.h +** Purpose: Header for API of AES software implementation +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS_SOFTAES_H +#define AEGIS_SOFTAES_H + +#include + +#include "common.h" + +typedef struct SoftAesBlock { + uint32_t w0; + uint32_t w1; + uint32_t w2; + uint32_t w3; +} SoftAesBlock; + +static SoftAesBlock +softaes_block_encrypt(const SoftAesBlock block, const SoftAesBlock rk); + +static inline SoftAesBlock +softaes_block_load(const uint8_t in[16]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + SoftAesBlock out; + memcpy(&out, in, 16); +#else + const SoftAesBlock out = { AEGIS_LOAD32_LE(in + 0), AEGIS_LOAD32_LE(in + 4), AEGIS_LOAD32_LE(in + 8), + AEGIS_LOAD32_LE(in + 12) }; +#endif + return out; +} + +static inline SoftAesBlock +softaes_block_load64x2(const uint64_t a, const uint64_t b) +{ + const SoftAesBlock out = { (uint32_t) b, (uint32_t) (b >> 32), (uint32_t) a, + (uint32_t) (a >> 32) }; + return out; +} + +static inline void +softaes_block_store(uint8_t out[16], const SoftAesBlock in) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(out, &in, 16); +#else + AEGIS_STORE32_LE(out + 0, in.w0); + AEGIS_STORE32_LE(out + 4, in.w1); + AEGIS_STORE32_LE(out + 8, in.w2); + AEGIS_STORE32_LE(out + 12, in.w3); +#endif +} + +static inline SoftAesBlock +softaes_block_xor(const SoftAesBlock a, const SoftAesBlock b) +{ + const SoftAesBlock out = { a.w0 ^ b.w0, a.w1 ^ b.w1, a.w2 ^ b.w2, a.w3 ^ b.w3 }; + return out; +} + +static inline SoftAesBlock +softaes_block_and(const SoftAesBlock a, const SoftAesBlock b) +{ + const SoftAesBlock out = { a.w0 & b.w0, a.w1 & b.w1, a.w2 & b.w2, a.w3 & b.w3 }; + return out; +} + +#endif /* AEGIS_SOFTAES_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/type_names_undefine.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/type_names_undefine.h new file mode 100644 index 0000000000..d098230c82 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/common/type_names_undefine.h @@ -0,0 +1,21 @@ +/* +** Name: type_names_undefine.h +** Purpose: Undefines for AEGIS type names +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +/* +** NOTE: +** Do NOT use include guards, because including this header +** multiple times is intended behaviour. +*/ + +/* Undefine AES block length */ +#undef AES_BLOCK_LENGTH + +/* Undefine type names */ +#undef AEGIS_AES_BLOCK_T +#undef AEGIS_BLOCKS +#undef AEGIS_STATE +#undef AEGIS_MAC_STATE diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis.h new file mode 100644 index 0000000000..c10728835a --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis.h @@ -0,0 +1,80 @@ +/* +** Name: aegis.h +** Purpose: Header for AEGIS API +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS_H +#define AEGIS_H + +#include + +#if !defined(__clang__) && !defined(__GNUC__) +# ifdef __attribute__ +# undef __attribute__ +# endif +# define __attribute__(a) +#endif + +#ifndef CRYPTO_ALIGN +# if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define CRYPTO_ALIGN(x) __declspec(align(x)) +# else +# define CRYPTO_ALIGN(x) __attribute__((aligned(x))) +# endif +#endif + +#ifndef AEGIS_API +#define AEGIS_API +#endif +#ifndef AEGIS_PRIVATE +#define AEGIS_PRIVATE static +#endif + +#include "aegis128l.h" +#include "aegis128x2.h" +#include "aegis128x4.h" +#include "aegis256.h" +#include "aegis256x2.h" +#include "aegis256x4.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initialize the AEGIS library. + * + * This function does runtime CPU capability detection, and must be called once + * in your application before doing anything else with the library. + * + * If you don't, AEGIS will still work, but it may be much slower. + * + * The function can be called multiple times but is not thread-safe. + */ +AEGIS_API +int aegis_init(void); + +/* Compare two 16-byte blocks for equality. + * + * This function is designed to be used in constant-time code. + * + * Returns 0 if the blocks are equal, -1 otherwise. + */ +AEGIS_API +int aegis_verify_16(const uint8_t *x, const uint8_t *y) __attribute__((warn_unused_result)); + +/* Compare two 32-byte blocks for equality. + * + * This function is designed to be used in constant-time code. + * + * Returns 0 if the blocks are equal, -1 otherwise. + */ +AEGIS_API +int aegis_verify_32(const uint8_t *x, const uint8_t *y) __attribute__((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif /* AEGIS_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128l.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128l.h new file mode 100644 index 0000000000..155218f5e6 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128l.h @@ -0,0 +1,371 @@ +/* +** Name: aegis128l.h +** Purpose: Header for AEGIS-128L API +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128L_H +#define AEGIS128L_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The length of an AEGIS key, in bytes */ +#define aegis128l_KEYBYTES 16 + +/* The length of an AEGIS nonce, in bytes */ +#define aegis128l_NPUBBYTES 16 + +/* The minimum length of an AEGIS authentication tag, in bytes */ +#define aegis128l_ABYTES_MIN 16 + +/* The maximum length of an AEGIS authentication tag, in bytes */ +#define aegis128l_ABYTES_MAX 32 + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +#define aegis128l_TAILBYTES_MAX 31 + +/* An AEGIS state, for incremental updates */ +typedef struct aegis128l_state { + CRYPTO_ALIGN(32) uint8_t opaque[256]; +} aegis128l_state; + +/* An AEGIS state, only for MAC updates */ +typedef struct aegis128l_mac_state { + CRYPTO_ALIGN(32) uint8_t opaque[384]; +} aegis128l_mac_state; + + +/* The length of an AEGIS key, in bytes */ +AEGIS_API +size_t aegis128l_keybytes(void); + +/* The length of an AEGIS nonce, in bytes */ +AEGIS_API +size_t aegis128l_npubbytes(void); + +/* The minimum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis128l_abytes_min(void); + +/* The maximum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis128l_abytes_max(void); + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +AEGIS_API +size_t aegis128l_tailbytes_max(void); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * c: ciphertext output buffer + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +int aegis128l_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, + size_t mlen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128l_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) __attribute__((warn_unused_result)); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * c: ciphertext output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +int aegis128l_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128l_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) + __attribute__((warn_unused_result)); + +#ifndef AEGIS_OMIT_INCREMENTAL + +/* + * Initialize a state for incremental encryption or decryption. + * + * st_: state to initialize + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128l_state_init(aegis128l_state *st_, const uint8_t *ad, size_t adlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message chunk. + * The same function can be used regardless of whether the tag will be attached or not. + * + * st_: state to update + * c: ciphertext output buffer + * clen_max: length of the ciphertext chunk buffer (must be >= mlen) + * written: number of ciphertext bytes actually written + * m: plaintext input buffer + * mlen: length of the plaintext + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128l_state_encrypt_update(aegis128l_state *st_, uint8_t *c, size_t clen_max, + size_t *written, const uint8_t *m, size_t mlen); + +/* + * Finalize the incremental encryption and generate the authentication tag. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes) + * written: number of ciphertext bytes actually written + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128l_state_encrypt_detached_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + +/* + * Finalize the incremental encryption and attach the authentication tag + * to the final ciphertext chunk. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes+maclen) + * written: number of ciphertext bytes actually written + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128l_state_encrypt_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, + size_t *written, size_t maclen); + +/* + * Decrypt a message chunk. + * + * The output should never be released to the caller until the tag has been verified. + * + * st_: state to update + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= clen) + * written: number of plaintext bytes actually written + * c: ciphertext chunk input buffer + * clen: length of the ciphertext chunk + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128l_state_decrypt_detached_update(aegis128l_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) + __attribute__((warn_unused_result)); + +/* + * Decrypt the final message chunk and verify the authentication tag. + * + * st_: state to finalize + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= remaining bytes) + * written: number of plaintext bytes actually written + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128l_state_decrypt_detached_final(aegis128l_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) + __attribute__((warn_unused_result)); + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +/* + * Return a deterministic pseudo-random byte sequence. + * + * out: output buffer + * len: number of bytes to generate + * npub: nonce input buffer (16 bytes) - Can be set to `NULL` if only one sequence has to be + * generated from a given key. + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128l_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * c: ciphertext output buffer + * m: plaintext input buffer + * mlen: length of the plaintext + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128l_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128l_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, + const uint8_t *npub, const uint8_t *k); + +#ifndef AEGIS_OMIT_MAC_API + +/* + * Initialize a state for generating a MAC. + * + * st_: state to initialize + * k: key input buffer (16 bytes) + * + * - The same key MUST NOT be used both for MAC and encryption. + * - If the key is secret, the MAC is secure against forgery. + * - However, if the key is known, arbitrary inputs matching a tag can be efficiently computed. + * + * The recommended way to use the MAC mode is to generate a random key and keep it secret. + * + * After initialization, the state can be reused to generate multiple MACs by cloning it + * with `aegis128l_mac_state_clone()`. It is only safe to copy a state directly without using + * the clone function if the state is guaranteed to be properly aligned. + * + * A state can also be reset for reuse without cloning with `aegis128l_mac_reset()`. + */ +AEGIS_API +void aegis128l_mac_init(aegis128l_mac_state *st_, const uint8_t *k, const uint8_t *npub); + +/* + * Update the MAC state with input data. + * + * st_: state to update + * m: input data + * mlen: length of the input data + * + * This function can be called multiple times. + * + * Once the full input has been absorb, call either `_mac_final` or `_mac_verify`. + */ +AEGIS_API +int aegis128l_mac_update(aegis128l_mac_state *st_, const uint8_t *m, size_t mlen); + +/* + * Finalize the MAC and generate the authentication tag. + * + * st_: state to finalize + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32. 32 is recommended). + */ +AEGIS_API +int aegis128l_mac_final(aegis128l_mac_state *st_, uint8_t *mac, size_t maclen); + +/* + * Verify a MAC in constant time. + * + * st_: state to verify + * mac: authentication tag to verify + * maclen: length of the authentication tag (16 or 32) + * + * Returns 0 if the tag is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128l_mac_verify(aegis128l_mac_state *st_, const uint8_t *mac, size_t maclen); + +/* + * Reset an AEGIS_MAC state. + */ +AEGIS_API +void aegis128l_mac_reset(aegis128l_mac_state *st_); + +/* + * Clone an AEGIS-MAC state. + * + * dst: destination state + * src: source state + * + * This function MUST be used in order to clone states. + */ +AEGIS_API +void aegis128l_mac_state_clone(aegis128l_mac_state *dst, const aegis128l_mac_state *src); + +#endif /* AEGIS_OMIT_MAC_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* AEGIS128L_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128x2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128x2.h new file mode 100644 index 0000000000..898af84c16 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128x2.h @@ -0,0 +1,370 @@ +/* +** Name: aegis128x2.h +** Purpose: Header for AEGIS-128x2 API +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X2_H +#define AEGIS128X2_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The length of an AEGIS key, in bytes */ +#define aegis128x2_KEYBYTES 16 + +/* The length of an AEGIS nonce, in bytes */ +#define aegis128x2_NPUBBYTES 16 + +/* The minimum length of an AEGIS authentication tag, in bytes */ +#define aegis128x2_ABYTES_MIN 16 + +/* The maximum length of an AEGIS authentication tag, in bytes */ +#define aegis128x2_ABYTES_MAX 32 + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +#define aegis128x2_TAILBYTES_MAX 63 + +/* An AEGIS state, for incremental updates */ +typedef struct aegis128x2_state { + CRYPTO_ALIGN(64) uint8_t opaque[448]; +} aegis128x2_state; + +/* An AEGIS state, only for MAC updates */ +typedef struct aegis128x2_mac_state { + CRYPTO_ALIGN(64) uint8_t opaque[704]; +} aegis128x2_mac_state; + +/* The length of an AEGIS key, in bytes */ +AEGIS_API +size_t aegis128x2_keybytes(void); + +/* The length of an AEGIS nonce, in bytes */ +AEGIS_API +size_t aegis128x2_npubbytes(void); + +/* The minimum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis128x2_abytes_min(void); + +/* The maximum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis128x2_abytes_max(void); + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +AEGIS_API +size_t aegis128x2_tailbytes_max(void); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * c: ciphertext output buffer + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +int aegis128x2_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, + size_t mlen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128x2_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) __attribute__((warn_unused_result)); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * c: ciphertext output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +int aegis128x2_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128x2_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) + __attribute__((warn_unused_result)); + +#ifndef AEGIS_OMIT_INCREMENTAL + +/* + * Initialize a state for incremental encryption or decryption. + * + * st_: state to initialize + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128x2_state_init(aegis128x2_state *st_, const uint8_t *ad, size_t adlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message chunk. + * The same function can be used regardless of whether the tag will be attached or not. + * + * st_: state to update + * c: ciphertext output buffer + * clen_max: length of the ciphertext chunk buffer (must be >= mlen) + * written: number of ciphertext bytes actually written + * m: plaintext input buffer + * mlen: length of the plaintext + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x2_state_encrypt_update(aegis128x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, const uint8_t *m, size_t mlen); + +/* + * Finalize the incremental encryption and generate the authentication tag. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes) + * written: number of ciphertext bytes actually written + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x2_state_encrypt_detached_final(aegis128x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + +/* + * Finalize the incremental encryption and attach the authentication tag + * to the final ciphertext chunk. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes+maclen) + * written: number of ciphertext bytes actually written + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x2_state_encrypt_final(aegis128x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, size_t maclen); + +/* + * Decrypt a message chunk. + * + * The output should never be released to the caller until the tag has been verified. + * + * st_: state to update + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= clen) + * written: number of plaintext bytes actually written + * c: ciphertext chunk input buffer + * clen: length of the ciphertext chunk + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x2_state_decrypt_detached_update(aegis128x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) + __attribute__((warn_unused_result)); + +/* + * Decrypt the final message chunk and verify the authentication tag. + * + * st_: state to finalize + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= remaining bytes) + * written: number of plaintext bytes actually written + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x2_state_decrypt_detached_final(aegis128x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) + __attribute__((warn_unused_result)); + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +/* + * Return a deterministic pseudo-random byte sequence. + * + * out: output buffer + * len: number of bytes to generate + * npub: nonce input buffer (16 bytes) - Can be set to `NULL` if only one sequence has to be + * generated from a given key. + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128x2_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * c: ciphertext output buffer + * m: plaintext input buffer + * mlen: length of the plaintext + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128x2_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128x2_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, + const uint8_t *npub, const uint8_t *k); + +#ifndef AEGIS_OMIT_MAC_API + +/* + * Initialize a state for generating a MAC. + * + * st_: state to initialize + * k: key input buffer (16 bytes) + * + * - The same key MUST NOT be used both for MAC and encryption. + * - If the key is secret, the MAC is secure against forgery. + * - However, if the key is known, arbitrary inputs matching a tag can be efficiently computed. + * + * The recommended way to use the MAC mode is to generate a random key and keep it secret. + * + * After initialization, the state can be reused to generate multiple MACs by cloning it + * with `aegis128x2_mac_state_clone()`. It is only safe to copy a state directly without using + * the clone function if the state is guaranteed to be properly aligned. + * + * A state can also be reset for reuse without cloning with `aegis128x2_mac_reset()`. + */ +AEGIS_API +void aegis128x2_mac_init(aegis128x2_mac_state *st_, const uint8_t *k, const uint8_t *npub); + +/* + * Update the MAC state with input data. + * + * st_: state to update + * m: input data + * mlen: length of the input data + * + * This function can be called multiple times. + * + * Once the full input has been absorb, call either `_mac_final` or `_mac_verify`. + */ +AEGIS_API +int aegis128x2_mac_update(aegis128x2_mac_state *st_, const uint8_t *m, size_t mlen); + +/* + * Finalize the MAC and generate the authentication tag. + * + * st_: state to finalize + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32. 32 is recommended). + */ +AEGIS_API +int aegis128x2_mac_final(aegis128x2_mac_state *st_, uint8_t *mac, size_t maclen); + +/* + * Verify a MAC in constant time. + * + * st_: state to verify + * mac: authentication tag to verify + * maclen: length of the authentication tag (16 or 32) + * + * Returns 0 if the tag is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128x2_mac_verify(aegis128x2_mac_state *st_, const uint8_t *mac, size_t maclen); + +/* + * Reset an AEGIS_MAC state. + */ +AEGIS_API +void aegis128x2_mac_reset(aegis128x2_mac_state *st_); + +/* + * Clone an AEGIS-MAC state. + * + * dst: destination state + * src: source state + * + * This function MUST be used in order to clone states. + */ +AEGIS_API +void aegis128x2_mac_state_clone(aegis128x2_mac_state *dst, const aegis128x2_mac_state *src); + +#endif /* AEGIS_OMIT_MAC_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* AEGIS128X2_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128x4.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128x4.h new file mode 100644 index 0000000000..779b4a9b02 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis128x4.h @@ -0,0 +1,371 @@ +/* +** Name: aegis128x4.h +** Purpose: Header for AEGIS-128x4 API +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS128X4_H +#define AEGIS128X4_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The length of an AEGIS key, in bytes */ +#define aegis128x4_KEYBYTES 16 + +/* The length of an AEGIS nonce, in bytes */ +#define aegis128x4_NPUBBYTES 16 + +/* The minimum length of an AEGIS authentication tag, in bytes */ +#define aegis128x4_ABYTES_MIN 16 + +/* The maximum length of an AEGIS authentication tag, in bytes */ +#define aegis128x4_ABYTES_MAX 32 + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +#define aegis128x4_TAILBYTES_MAX 127 + +/* An AEGIS state, for incremental updates */ +typedef struct aegis128x4_state { + CRYPTO_ALIGN(64) uint8_t opaque[832]; +} aegis128x4_state; + +/* An AEGIS state, only for MAC updates */ +typedef struct aegis128x4_mac_state { + CRYPTO_ALIGN(64) uint8_t opaque[1344]; +} aegis128x4_mac_state; + + +/* The length of an AEGIS key, in bytes */ +AEGIS_API +size_t aegis128x4_keybytes(void); + +/* The length of an AEGIS nonce, in bytes */ +AEGIS_API +size_t aegis128x4_npubbytes(void); + +/* The minimum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis128x4_abytes_min(void); + +/* The maximum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis128x4_abytes_max(void); + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +AEGIS_API +size_t aegis128x4_tailbytes_max(void); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * c: ciphertext output buffer + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +int aegis128x4_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, + size_t mlen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128x4_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) __attribute__((warn_unused_result)); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * c: ciphertext output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +int aegis128x4_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128x4_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) + __attribute__((warn_unused_result)); + +#ifndef AEGIS_OMIT_INCREMENTAL + +/* + * Initialize a state for incremental encryption or decryption. + * + * st_: state to initialize + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128x4_state_init(aegis128x4_state *st_, const uint8_t *ad, size_t adlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message chunk. + * The same function can be used regardless of whether the tag will be attached or not. + * + * st_: state to update + * c: ciphertext output buffer + * clen_max: length of the ciphertext chunk buffer (must be >= mlen) + * written: number of ciphertext bytes actually written + * m: plaintext input buffer + * mlen: length of the plaintext + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x4_state_encrypt_update(aegis128x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, const uint8_t *m, size_t mlen); + +/* + * Finalize the incremental encryption and generate the authentication tag. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes) + * written: number of ciphertext bytes actually written + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x4_state_encrypt_detached_final(aegis128x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + +/* + * Finalize the incremental encryption and attach the authentication tag + * to the final ciphertext chunk. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes+maclen) + * written: number of ciphertext bytes actually written + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x4_state_encrypt_final(aegis128x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, size_t maclen); + +/* + * Decrypt a message chunk. + * + * The output should never be released to the caller until the tag has been verified. + * + * st_: state to update + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= clen) + * written: number of plaintext bytes actually written + * c: ciphertext chunk input buffer + * clen: length of the ciphertext chunk + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x4_state_decrypt_detached_update(aegis128x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) + __attribute__((warn_unused_result)); + +/* + * Decrypt the final message chunk and verify the authentication tag. + * + * st_: state to finalize + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= remaining bytes) + * written: number of plaintext bytes actually written + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis128x4_state_decrypt_detached_final(aegis128x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) + __attribute__((warn_unused_result)); + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +/* + * Return a deterministic pseudo-random byte sequence. + * + * out: output buffer + * len: number of bytes to generate + * npub: nonce input buffer (16 bytes) - Can be set to `NULL` if only one sequence has to be + * generated from a given key. + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128x4_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * c: ciphertext output buffer + * m: plaintext input buffer + * mlen: length of the plaintext + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128x4_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * npub: nonce input buffer (16 bytes) + * k: key input buffer (16 bytes) + */ +AEGIS_API +void aegis128x4_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, + const uint8_t *npub, const uint8_t *k); + +#ifndef AEGIS_OMIT_MAC_API + +/* + * Initialize a state for generating a MAC. + * + * st_: state to initialize + * k: key input buffer (16 bytes) + * + * - The same key MUST NOT be used both for MAC and encryption. + * - If the key is secret, the MAC is secure against forgery. + * - However, if the key is known, arbitrary inputs matching a tag can be efficiently computed. + * + * The recommended way to use the MAC mode is to generate a random key and keep it secret. + * + * After initialization, the state can be reused to generate multiple MACs by cloning it + * with `aegis128x4_mac_state_clone()`. It is only safe to copy a state directly without using + * the clone function if the state is guaranteed to be properly aligned. + * + * A state can also be reset for reuse without cloning with `aegis128x4_mac_reset()`. + */ +AEGIS_API +void aegis128x4_mac_init(aegis128x4_mac_state *st_, const uint8_t *k, const uint8_t *npub); + +/* + * Update the MAC state with input data. + * + * st_: state to update + * m: input data + * mlen: length of the input data + * + * This function can be called multiple times. + * + * Once the full input has been absorb, call either `_mac_final` or `_mac_verify`. + */ +AEGIS_API +int aegis128x4_mac_update(aegis128x4_mac_state *st_, const uint8_t *m, size_t mlen); + +/* + * Finalize the MAC and generate the authentication tag. + * + * st_: state to finalize + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32. 32 is recommended). + */ +AEGIS_API +int aegis128x4_mac_final(aegis128x4_mac_state *st_, uint8_t *mac, size_t maclen); + +/* + * Verify a MAC in constant time. + * + * st_: state to verify + * mac: authentication tag to verify + * maclen: length of the authentication tag (16 or 32) + * + * Returns 0 if the tag is authentic, -1 otherwise. + */ +AEGIS_API +int aegis128x4_mac_verify(aegis128x4_mac_state *st_, const uint8_t *mac, size_t maclen); + +/* + * Reset an AEGIS_MAC state. + */ +AEGIS_API +void aegis128x4_mac_reset(aegis128x4_mac_state *st_); + +/* + * Clone an AEGIS-MAC state. + * + * dst: destination state + * src: source state + * + * This function MUST be used in order to clone states. + */ +AEGIS_API +void aegis128x4_mac_state_clone(aegis128x4_mac_state *dst, const aegis128x4_mac_state *src); + +#endif /* AEGIS_OMIT_MAC_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* AEGIS128X4_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256.h new file mode 100644 index 0000000000..af4551269b --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256.h @@ -0,0 +1,370 @@ +/* +** Name: aegis256.h +** Purpose: Header for AEGIS-256 API +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256_H +#define AEGIS256_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The length of an AEGIS key, in bytes */ +#define aegis256_KEYBYTES 32 + +/* The length of an AEGIS nonce, in bytes */ +#define aegis256_NPUBBYTES 32 + +/* The minimum length of an AEGIS authentication tag, in bytes */ +#define aegis256_ABYTES_MIN 16 + +/* The maximum length of an AEGIS authentication tag, in bytes */ +#define aegis256_ABYTES_MAX 32 + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +#define aegis256_TAILBYTES_MAX 15 + +/* An AEGIS state, for incremental updates */ +typedef struct aegis256_state { + CRYPTO_ALIGN(16) uint8_t opaque[192]; +} aegis256_state; + +/* An AEGIS state, only for MAC updates */ +typedef struct aegis256_mac_state { + CRYPTO_ALIGN(16) uint8_t opaque[288]; +} aegis256_mac_state; + +/* The length of an AEGIS key, in bytes */ +AEGIS_API +size_t aegis256_keybytes(void); + +/* The length of an AEGIS nonce, in bytes */ +AEGIS_API +size_t aegis256_npubbytes(void); + +/* The minimum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis256_abytes_min(void); + +/* The maximum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis256_abytes_max(void); + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +AEGIS_API +size_t aegis256_tailbytes_max(void); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * c: ciphertext output buffer + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +int aegis256_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, + size_t mlen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) __attribute__((warn_unused_result)); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * c: ciphertext output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +int aegis256_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) + __attribute__((warn_unused_result)); + +#ifndef AEGIS_OMIT_INCREMENTAL + +/* + * Initialize a state for incremental encryption or decryption. + * + * st_: state to initialize + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256_state_init(aegis256_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + +/* + * Encrypt a message chunk. + * The same function can be used regardless of whether the tag will be attached or not. + * + * st_: state to update + * c: ciphertext output buffer + * clen_max: length of the ciphertext chunk buffer (must be >= mlen) + * written: number of ciphertext bytes actually written + * m: plaintext input buffer + * mlen: length of the plaintext + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256_state_encrypt_update(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + const uint8_t *m, size_t mlen); + +/* + * Finalize the incremental encryption and generate the authentication tag. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes) + * written: number of ciphertext bytes actually written + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256_state_encrypt_detached_final(aegis256_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + +/* + * Finalize the incremental encryption and attach the authentication tag + * to the final ciphertext chunk. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes+maclen) + * written: number of ciphertext bytes actually written + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256_state_encrypt_final(aegis256_state *st_, uint8_t *c, size_t clen_max, size_t *written, + size_t maclen); + +/* + * Decrypt a message chunk. + * + * The output should never be released to the caller until the tag has been verified. + * + * st_: state to update + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= clen) + * written: number of plaintext bytes actually written + * c: ciphertext chunk input buffer + * clen: length of the ciphertext chunk + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256_state_decrypt_detached_update(aegis256_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) + __attribute__((warn_unused_result)); + +/* + * Decrypt the final message chunk and verify the authentication tag. + * + * st_: state to finalize + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= remaining bytes) + * written: number of plaintext bytes actually written + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256_state_decrypt_detached_final(aegis256_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) + __attribute__((warn_unused_result)); + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +/* + * Return a deterministic pseudo-random byte sequence. + * + * out: output buffer + * len: number of bytes to generate + * npub: nonce input buffer (32 bytes) - Can be set to `NULL` if only one sequence has to be + * generated from a given key. + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * c: ciphertext output buffer + * m: plaintext input buffer + * mlen: length of the plaintext + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, + const uint8_t *npub, const uint8_t *k); + +#ifndef AEGIS_OMIT_MAC_API + +/* + * Initialize a state for generating a MAC. + * + * st_: state to initialize + * k: key input buffer (32 bytes) + * + * - The same key MUST NOT be used both for MAC and encryption. + * - If the key is secret, the MAC is secure against forgery. + * - However, if the key is known, arbitrary inputs matching a tag can be efficiently computed. + * + * The recommended way to use the MAC mode is to generate a random key and keep it secret. + * + * After initialization, the state can be reused to generate multiple MACs by cloning it + * with `aegis256_mac_state_clone()`. It is only safe to copy a state directly without using + * the clone function if the state is guaranteed to be properly aligned. + * + * A state can also be reset for reuse without cloning with `aegis256_mac_reset()`. + */ +AEGIS_API +void aegis256_mac_init(aegis256_mac_state *st_, const uint8_t *k, const uint8_t *npub); + +/* + * Update the MAC state with input data. + * + * st_: state to update + * m: input data + * mlen: length of the input data + * + * This function can be called multiple times. + * + * Once the full input has been absorb, call either `_mac_final` or `_mac_verify`. + */ +AEGIS_API +int aegis256_mac_update(aegis256_mac_state *st_, const uint8_t *m, size_t mlen); + +/* + * Finalize the MAC and generate the authentication tag. + * + * st_: state to finalize + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32. 32 is recommended). + */ +AEGIS_API +int aegis256_mac_final(aegis256_mac_state *st_, uint8_t *mac, size_t maclen); + +/* + * Verify a MAC in constant time. + * + * st_: state to verify + * mac: authentication tag to verify + * maclen: length of the authentication tag (16 or 32) + * + * Returns 0 if the tag is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256_mac_verify(aegis256_mac_state *st_, const uint8_t *mac, size_t maclen); + +/* + * Reset an AEGIS_MAC state. + */ +AEGIS_API +void aegis256_mac_reset(aegis256_mac_state *st_); + +/* + * Clone an AEGIS-MAC state. + * + * dst: destination state + * src: source state + * + * This function MUST be used in order to clone states. + */ +AEGIS_API +void aegis256_mac_state_clone(aegis256_mac_state *dst, const aegis256_mac_state *src); + +#endif /* AEGIS_OMIT_MAC_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* AEGIS256_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256x2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256x2.h new file mode 100644 index 0000000000..38aa10837e --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256x2.h @@ -0,0 +1,370 @@ +/* +** Name: aegis256x2.h +** Purpose: Header for AEGIS-256x2 API +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X2_H +#define AEGIS256X2_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The length of an AEGIS key, in bytes */ +#define aegis256x2_KEYBYTES 32 + +/* The length of an AEGIS nonce, in bytes */ +#define aegis256x2_NPUBBYTES 32 + +/* The minimum length of an AEGIS authentication tag, in bytes */ +#define aegis256x2_ABYTES_MIN 16 + +/* The maximum length of an AEGIS authentication tag, in bytes */ +#define aegis256x2_ABYTES_MAX 32 + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +#define aegis256x2_TAILBYTES_MAX 31 + +/* An AEGIS state, for incremental updates */ +typedef struct aegis256x2_state { + CRYPTO_ALIGN(32) uint8_t opaque[320]; +} aegis256x2_state; + +/* An AEGIS state, only for MAC updates */ +typedef struct aegis256x2_mac_state { + CRYPTO_ALIGN(32) uint8_t opaque[512]; +} aegis256x2_mac_state; + +/* The length of an AEGIS key, in bytes */ +AEGIS_API +size_t aegis256x2_keybytes(void); + +/* The length of an AEGIS nonce, in bytes */ +AEGIS_API +size_t aegis256x2_npubbytes(void); + +/* The minimum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis256x2_abytes_min(void); + +/* The maximum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis256x2_abytes_max(void); + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +AEGIS_API +size_t aegis256x2_tailbytes_max(void); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * c: ciphertext output buffer + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +int aegis256x2_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, + size_t mlen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256x2_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) __attribute__((warn_unused_result)); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * c: ciphertext output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +int aegis256x2_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256x2_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) + __attribute__((warn_unused_result)); + +#ifndef AEGIS_OMIT_INCREMENTAL + +/* + * Initialize a state for incremental encryption or decryption. + * + * st_: state to initialize + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256x2_state_init(aegis256x2_state *st_, const uint8_t *ad, size_t adlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message chunk. + * The same function can be used regardless of whether the tag will be attached or not. + * + * st_: state to update + * c: ciphertext output buffer + * clen_max: length of the ciphertext chunk buffer (must be >= mlen) + * written: number of ciphertext bytes actually written + * m: plaintext input buffer + * mlen: length of the plaintext + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x2_state_encrypt_update(aegis256x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, const uint8_t *m, size_t mlen); + +/* + * Finalize the incremental encryption and generate the authentication tag. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes) + * written: number of ciphertext bytes actually written + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x2_state_encrypt_detached_final(aegis256x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + +/* + * Finalize the incremental encryption and attach the authentication tag + * to the final ciphertext chunk. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes+maclen) + * written: number of ciphertext bytes actually written + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x2_state_encrypt_final(aegis256x2_state *st_, uint8_t *c, size_t clen_max, + size_t *written, size_t maclen); + +/* + * Decrypt a message chunk. + * + * The output should never be released to the caller until the tag has been verified. + * + * st_: state to update + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= clen) + * written: number of plaintext bytes actually written + * c: ciphertext chunk input buffer + * clen: length of the ciphertext chunk + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x2_state_decrypt_detached_update(aegis256x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) + __attribute__((warn_unused_result)); + +/* + * Decrypt the final message chunk and verify the authentication tag. + * + * st_: state to finalize + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= remaining bytes) + * written: number of plaintext bytes actually written + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x2_state_decrypt_detached_final(aegis256x2_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) + __attribute__((warn_unused_result)); + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +/* + * Return a deterministic pseudo-random byte sequence. + * + * out: output buffer + * len: number of bytes to generate + * npub: nonce input buffer (32 bytes) - Can be set to `NULL` if only one sequence has to be + * generated from a given key. + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256x2_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * c: ciphertext output buffer + * m: plaintext input buffer + * mlen: length of the plaintext + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256x2_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256x2_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, + const uint8_t *npub, const uint8_t *k); + +#ifndef AEGIS_OMIT_MAC_API + +/* + * Initialize a state for generating a MAC. + * + * st_: state to initialize + * k: key input buffer (32 bytes) + * + * - The same key MUST NOT be used both for MAC and encryption. + * - If the key is secret, the MAC is secure against forgery. + * - However, if the key is known, arbitrary inputs matching a tag can be efficiently computed. + * + * The recommended way to use the MAC mode is to generate a random key and keep it secret. + * + * After initialization, the state can be reused to generate multiple MACs by cloning it + * with `aegis256x2_mac_state_clone()`. It is only safe to copy a state directly without using + * the clone function if the state is guaranteed to be properly aligned. + * + * A state can also be reset for reuse without cloning with `aegis256x2_mac_reset()`. + */ +AEGIS_API +void aegis256x2_mac_init(aegis256x2_mac_state *st_, const uint8_t *k, const uint8_t *npub); + +/* + * Update the MAC state with input data. + * + * st_: state to update + * m: input data + * mlen: length of the input data + * + * This function can be called multiple times. + * + * Once the full input has been absorb, call either `_mac_final` or `_mac_verify`. + */ +AEGIS_API +int aegis256x2_mac_update(aegis256x2_mac_state *st_, const uint8_t *m, size_t mlen); + +/* + * Finalize the MAC and generate the authentication tag. + * + * st_: state to finalize + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32. 32 is recommended). + */ +AEGIS_API +int aegis256x2_mac_final(aegis256x2_mac_state *st_, uint8_t *mac, size_t maclen); + +/* + * Verify a MAC in constant time. + * + * st_: state to verify + * mac: authentication tag to verify + * maclen: length of the authentication tag (16 or 32) + * + * Returns 0 if the tag is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256x2_mac_verify(aegis256x2_mac_state *st_, const uint8_t *mac, size_t maclen); + +/* + * Reset an AEGIS_MAC state. + */ +AEGIS_API +void aegis256x2_mac_reset(aegis256x2_mac_state *st_); + +/* + * Clone an AEGIS-MAC state. + * + * dst: destination state + * src: source state + * + * This function MUST be used in order to clone states. + */ +AEGIS_API +void aegis256x2_mac_state_clone(aegis256x2_mac_state *dst, const aegis256x2_mac_state *src); + +#endif /* AEGIS_OMIT_MAC_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* AEGIS256X2_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256x4.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256x4.h new file mode 100644 index 0000000000..1de793c146 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/include/aegis256x4.h @@ -0,0 +1,370 @@ +/* +** Name: aegis256x4.h +** Purpose: Header for AEGIS-256x4 API +** Copyright: (c) 2023-2024 Frank Denis +** SPDX-License-Identifier: MIT +*/ + +#ifndef AEGIS256X4_H +#define AEGIS256X4_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The length of an AEGIS key, in bytes */ +#define aegis256x4_KEYBYTES 32 + +/* The length of an AEGIS nonce, in bytes */ +#define aegis256x4_NPUBBYTES 32 + +/* The minimum length of an AEGIS authentication tag, in bytes */ +#define aegis256x4_ABYTES_MIN 16 + +/* The maximum length of an AEGIS authentication tag, in bytes */ +#define aegis256x4_ABYTES_MAX 32 + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +#define aegis256x4_TAILBYTES_MAX 63 + +/* An AEGIS state, for incremental updates */ +typedef struct aegis256x4_state { + CRYPTO_ALIGN(64) uint8_t opaque[576]; +} aegis256x4_state; + +/* An AEGIS state, only for MAC updates */ +typedef struct aegis256x4_mac_state { + CRYPTO_ALIGN(64) uint8_t opaque[960]; +} aegis256x4_mac_state; + +/* The length of an AEGIS key, in bytes */ +AEGIS_API +size_t aegis256x4_keybytes(void); + +/* The length of an AEGIS nonce, in bytes */ +AEGIS_API +size_t aegis256x4_npubbytes(void); + +/* The minimum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis256x4_abytes_min(void); + +/* The maximum length of an AEGIS authentication tag, in bytes */ +AEGIS_API +size_t aegis256x4_abytes_max(void); + +/* + * When using AEGIS in incremental mode, this is the maximum number + * of leftover ciphertext bytes that can be returned at finalization. + */ +AEGIS_API +size_t aegis256x4_tailbytes_max(void); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * c: ciphertext output buffer + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +int aegis256x4_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, + size_t mlen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext separately. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256x4_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k) __attribute__((warn_unused_result)); + +/* + * Encrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * c: ciphertext output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * m: plaintext input buffer + * mlen: length of the plaintext + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +int aegis256x4_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message with AEGIS in one shot mode, returning the tag and the ciphertext together. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * maclen: length of the authentication tag (16 or 32) + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + * + * Returns 0 if the ciphertext is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256x4_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad, + size_t adlen, const uint8_t *npub, const uint8_t *k) + __attribute__((warn_unused_result)); + +#ifndef AEGIS_OMIT_INCREMENTAL + +/* + * Initialize a state for incremental encryption or decryption. + * + * st_: state to initialize + * ad: additional data input buffer + * adlen: length of the additional data + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256x4_state_init(aegis256x4_state *st_, const uint8_t *ad, size_t adlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message chunk. + * The same function can be used regardless of whether the tag will be attached or not. + * + * st_: state to update + * c: ciphertext output buffer + * clen_max: length of the ciphertext chunk buffer (must be >= mlen) + * written: number of ciphertext bytes actually written + * m: plaintext input buffer + * mlen: length of the plaintext + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x4_state_encrypt_update(aegis256x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, const uint8_t *m, size_t mlen); + +/* + * Finalize the incremental encryption and generate the authentication tag. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes) + * written: number of ciphertext bytes actually written + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x4_state_encrypt_detached_final(aegis256x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, uint8_t *mac, size_t maclen); + +/* + * Finalize the incremental encryption and attach the authentication tag + * to the final ciphertext chunk. + * + * st_: state to finalize + * c: output buffer for the final ciphertext chunk + * clen_max: length of the ciphertext chunk buffer (must be >= remaining bytes+maclen) + * written: number of ciphertext bytes actually written + * maclen: length of the authentication tag to generate (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x4_state_encrypt_final(aegis256x4_state *st_, uint8_t *c, size_t clen_max, + size_t *written, size_t maclen); + +/* + * Decrypt a message chunk. + * + * The output should never be released to the caller until the tag has been verified. + * + * st_: state to update + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= clen) + * written: number of plaintext bytes actually written + * c: ciphertext chunk input buffer + * clen: length of the ciphertext chunk + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x4_state_decrypt_detached_update(aegis256x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *c, size_t clen) + __attribute__((warn_unused_result)); + +/* + * Decrypt the final message chunk and verify the authentication tag. + * + * st_: state to finalize + * m: plaintext output buffer + * mlen_max: length of the plaintext chunk buffer (must be >= remaining bytes) + * written: number of plaintext bytes actually written + * mac: authentication tag input buffer + * maclen: length of the authentication tag (16 or 32) + * + * Return 0 on success, -1 on failure. + */ +AEGIS_API +int aegis256x4_state_decrypt_detached_final(aegis256x4_state *st_, uint8_t *m, size_t mlen_max, + size_t *written, const uint8_t *mac, size_t maclen) + __attribute__((warn_unused_result)); + +#endif /* AEGIS_OMIT_INCREMENTAL */ + +/* + * Return a deterministic pseudo-random byte sequence. + * + * out: output buffer + * len: number of bytes to generate + * npub: nonce input buffer (32 bytes) - Can be set to `NULL` if only one sequence has to be + * generated from a given key. + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256x4_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k); + +/* + * Encrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * c: ciphertext output buffer + * m: plaintext input buffer + * mlen: length of the plaintext + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256x4_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, + const uint8_t *npub, const uint8_t *k); + +/* + * Decrypt a message WITHOUT AUTHENTICATION, similar to AES-CTR. + * + * WARNING: this is an insecure mode of operation, provided for compatibility with specific + * protocols that bring their own authentication scheme. + * + * m: plaintext output buffer + * c: ciphertext input buffer + * clen: length of the ciphertext + * npub: nonce input buffer (32 bytes) + * k: key input buffer (32 bytes) + */ +AEGIS_API +void aegis256x4_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, + const uint8_t *npub, const uint8_t *k); + +#ifndef AEGIS_OMIT_MAC_API + +/* + * Initialize a state for generating a MAC. + * + * st_: state to initialize + * k: key input buffer (32 bytes) + * + * - The same key MUST NOT be used both for MAC and encryption. + * - If the key is secret, the MAC is secure against forgery. + * - However, if the key is known, arbitrary inputs matching a tag can be efficiently computed. + * + * The recommended way to use the MAC mode is to generate a random key and keep it secret. + * + * After initialization, the state can be reused to generate multiple MACs by cloning it + * with `aegis256x4_mac_state_clone()`. It is only safe to copy a state directly without using + * the clone function if the state is guaranteed to be properly aligned. + * + * A state can also be reset for reuse without cloning with `aegis256x4_mac_reset()`. + */ +AEGIS_API +void aegis256x4_mac_init(aegis256x4_mac_state *st_, const uint8_t *k, const uint8_t *npub); + +/* + * Update the MAC state with input data. + * + * st_: state to update + * m: input data + * mlen: length of the input data + * + * This function can be called multiple times. + * + * Once the full input has been absorb, call either `_mac_final` or `_mac_verify`. + */ +AEGIS_API +int aegis256x4_mac_update(aegis256x4_mac_state *st_, const uint8_t *m, size_t mlen); + +/* + * Finalize the MAC and generate the authentication tag. + * + * st_: state to finalize + * mac: authentication tag output buffer + * maclen: length of the authentication tag to generate (16 or 32. 32 is recommended). + */ +AEGIS_API +int aegis256x4_mac_final(aegis256x4_mac_state *st_, uint8_t *mac, size_t maclen); + +/* + * Verify a MAC in constant time. + * + * st_: state to verify + * mac: authentication tag to verify + * maclen: length of the authentication tag (16 or 32) + * + * Returns 0 if the tag is authentic, -1 otherwise. + */ +AEGIS_API +int aegis256x4_mac_verify(aegis256x4_mac_state *st_, const uint8_t *mac, size_t maclen); + +/* + * Reset an AEGIS_MAC state. + */ +AEGIS_API +void aegis256x4_mac_reset(aegis256x4_mac_state *st_); + +/* + * Clone an AEGIS-MAC state. + * + * dst: destination state + * src: source state + * + * This function MUST be used in order to clone states. + */ +AEGIS_API +void aegis256x4_mac_state_clone(aegis256x4_mac_state *dst, const aegis256x4_mac_state *src); + +#endif /* AEGIS_OMIT_MAC_API */ + +#ifdef __cplusplus +} +#endif + +#endif /* AEGIS256X4_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/libaegis.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/libaegis.c new file mode 100644 index 0000000000..a726d5bd9b --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aegis/libaegis.c @@ -0,0 +1,86 @@ +/* +** Name: libaegis.c +** Purpose: Amalgamation of the AEGIS library +** Copyright: (c) 2024-2024 Ulrich Telle +** SPDX-License-Identifier: MIT +*/ + +/* +** AEGIS library source code +*/ + +#ifndef AEGIS_API +#define AEGIS_API +#endif +#ifndef AEGIS_PRIVATE +#define AEGIS_PRIVATE static +#endif + +#include "common/cpu.h" + +/* AEGIS common functions */ +#include "common/common.c" +#include "common/cpu.c" +#include "common/softaes.c" + +#if defined(__GNUC__) +# pragma GCC push_options +#endif + +/* AEGIS 128 L */ +#include "aegis128l/implementations.h" +#include "aegis128l/aegis128l_aesni.c" +#include "aegis128l/aegis128l_altivec.c" +#include "aegis128l/aegis128l_armcrypto.c" +#include "aegis128l/aegis128l_soft.c" +#include "aegis128l/aegis128l.c" + +/* AEGIS 128 x2 */ +#include "aegis128x2/implementations.h" +#include "aegis128x2/aegis128x2_aesni.c" +#include "aegis128x2/aegis128x2_altivec.c" +#include "aegis128x2/aegis128x2_armcrypto.c" +#include "aegis128x2/aegis128x2_avx2.c" +#include "aegis128x2/aegis128x2_soft.c" +#include "aegis128x2/aegis128x2.c" + +/* AEGIS 128 x4 */ +#include "aegis128x4/implementations.h" +#include "aegis128x4/aegis128x4_aesni.c" +#include "aegis128x4/aegis128x4_altivec.c" +#include "aegis128x4/aegis128x4_armcrypto.c" +#include "aegis128x4/aegis128x4_avx2.c" +#include "aegis128x4/aegis128x4_avx512.c" +#include "aegis128x4/aegis128x4_soft.c" +#include "aegis128x4/aegis128x4.c" + +/* AEGIS 256 */ +#include "aegis256/implementations.h" +#include "aegis256/aegis256_aesni.c" +#include "aegis256/aegis256_altivec.c" +#include "aegis256/aegis256_armcrypto.c" +#include "aegis256/aegis256_soft.c" +#include "aegis256/aegis256.c" + +/* AEGIS 256 x2 */ +#include "aegis256x2/implementations.h" +#include "aegis256x2/aegis256x2_aesni.c" +#include "aegis256x2/aegis256x2_altivec.c" +#include "aegis256x2/aegis256x2_armcrypto.c" +#include "aegis256x2/aegis256x2_avx2.c" +#include "aegis256x2/aegis256x2_soft.c" +#include "aegis256x2/aegis256x2.c" + +/* AEGIS 256 x4 */ +#include "aegis256x4/implementations.h" +#include "aegis256x4/aegis256x4_aesni.c" +#include "aegis256x4/aegis256x4_altivec.c" +#include "aegis256x4/aegis256x4_armcrypto.c" +#include "aegis256x4/aegis256x4_avx2.c" +#include "aegis256x4/aegis256x4_avx512.c" +#include "aegis256x4/aegis256x4_soft.c" +#include "aegis256x4/aegis256x4.c" + +#if defined(__GNUC__) +# pragma GCC pop_options +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aes_hardware.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aes_hardware.c index 2787712f00..f33645c2be 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aes_hardware.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aes_hardware.c @@ -104,6 +104,37 @@ toUint32FromLE(const void* buffer) #if HAS_AES_HARDWARE == AES_HARDWARE_NI /* --- Implementation for AES-NI --- */ +/* Define SQLITE3MC_COMPILER_HAS_ATTRIBUTE */ +#if defined(__has_attribute) + #define SQLITE3MC_COMPILER_HAS_ATTRIBUTE(x) __has_attribute(x) + #define SQLITE3MC_COMPILER_ATTRIBUTE(x) __attribute__((x)) +#else + #define SQLITE3MC_COMPILER_HAS_ATTRIBUTE(x) 0 + #define SQLITE3MC_COMPILER_ATTRIBUTE(x) /**/ +#endif + +/* Define SQLITE3MC_FORCE_INLINE */ +#if !defined(SQLITE3MC_FORCE_INLINE) + #if SQLITE3MC_COMPILER_HAS_ATTRIBUTE(always_inline) + #define SQLITE3MC_FORCE_INLINE inline SQLITE3MC_COMPILER_ATTRIBUTE(always_inline) + #elif defined(_MSC_VER) + #define SQLITE3MC_FORCE_INLINE __forceinline + #else + #define SQLITE3MC_FORCE_INLINE inline + #endif +#endif + +/* Define SQLITE3MC_FUNC_ISA */ +#if SQLITE3MC_COMPILER_HAS_ATTRIBUTE(target) + #define SQLITE3MC_FUNC_ISA(isa) SQLITE3MC_COMPILER_ATTRIBUTE(target(isa)) +#else + #define SQLITE3MC_FUNC_ISA(isa) +#endif + +/* Define SQLITE3MC_FUNC_ISA_INLINE */ +#define SQLITE3MC_FUNC_ISA_INLINE(isa) SQLITE3MC_FUNC_ISA(isa) SQLITE3MC_FORCE_INLINE + + /* ** Define function for detecting hardware AES support at runtime */ @@ -140,6 +171,7 @@ aesHardwareCheck() #include #include +SQLITE3MC_FUNC_ISA("sse4.2,aes") static int aesGenKeyEncryptInternal(const unsigned char* userKey, const int bits, __m128i* keyData) { @@ -193,12 +225,13 @@ aesGenKeyEncryptInternal(const unsigned char* userKey, const int bits, __m128i* return rc; } +SQLITE3MC_FUNC_ISA("sse4.2,aes") static int aesGenKeyEncrypt(const unsigned char* userKey, const int bits, unsigned char* keyData) { int numberOfRounds = (bits == 128) ? 10 : (bits == 192) ? 12 : (bits == 256) ? 14 : 0; int rc = (!userKey || !keyData) ? -1 : (numberOfRounds > 0) ? 0 : -2; - + if (rc == 0) { __m128i tempKey[_MAX_ROUNDS + 1]; @@ -215,6 +248,7 @@ aesGenKeyEncrypt(const unsigned char* userKey, const int bits, unsigned char* ke return rc; } +SQLITE3MC_FUNC_ISA("sse4.2,aes") static int aesGenKeyDecrypt(const unsigned char* userKey, const int bits, unsigned char* keyData) { @@ -249,6 +283,7 @@ aesGenKeyDecrypt(const unsigned char* userKey, const int bits, unsigned char* ke ** AES CBC CTS Encryption */ +SQLITE3MC_FUNC_ISA("sse4.2,aes") static void aesEncryptCBC(const unsigned char* in, unsigned char* out, @@ -316,6 +351,7 @@ aesEncryptCBC(const unsigned char* in, /* ** AES CBC CTS decryption */ +SQLITE3MC_FUNC_ISA("sse4.2,aes") static void aesDecryptCBC(const unsigned char* in, unsigned char* out, @@ -347,7 +383,7 @@ aesDecryptCBC(const unsigned char* in, int offset; --numBlocks; offset = numBlocks * 16; - + /* Decrypt the last plain block. */ last_in = _mm_loadu_si128(&((__m128i*) in)[numBlocks]); data = _mm_xor_si128(last_in, key[numberOfRounds - 0]); @@ -477,7 +513,7 @@ aesGenKeyEncryptInternal(const unsigned char* userKey, const int bits, uint8x16_ int i; int j; int numberOfRounds = (bits == 128) ? 10 : (bits == 192) ? 12 : (bits == 256) ? 14 : 0; - int keyWords = bits / 32; + int keyWords = bits / 32; int schedWords = (numberOfRounds + 1) * 4; /* @@ -538,7 +574,7 @@ aesGenKeyEncrypt(const unsigned char* userKey, const int bits, unsigned char* ke { int numberOfRounds = (bits == 128) ? 10 : (bits == 192) ? 12 : (bits == 256) ? 14 : 0; int rc = (!userKey || !keyData) ? -1 : (numberOfRounds > 0) ? 0 : -2; - + if (rc == 0) { uint8x16_t tempKey[_MAX_ROUNDS + 1]; @@ -648,7 +684,7 @@ aesEncryptCBC(const unsigned char* in, } feedback = vaeseq_u8(feedback, key[numberOfRounds-1]); feedback = veorq_u8(feedback, key[numberOfRounds]); \ - + vst1q_u8(&out[(numBlocks-1)*16], feedback); memcpy(&out[numBlocks*16], lastblock, lenFrag); @@ -689,7 +725,7 @@ aesDecryptCBC(const unsigned char* in, int offset; --numBlocks; offset = numBlocks * 16; - + /* Decrypt the last plain block. */ last_in = vld1q_u8(&in[numBlocks*16]); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/include/argon2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/include/argon2.h new file mode 100644 index 0000000000..a5b0306082 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/include/argon2.h @@ -0,0 +1,445 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_H +#define ARGON2_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Symbols visibility control */ +#ifdef A2_VISCTL +#define ARGON2_PUBLIC __attribute__((visibility("default"))) +#define ARGON2_LOCAL __attribute__ ((visibility ("hidden"))) +#elif defined(_MSC_VER) +#ifndef ARGON2_PUBLIC +#define ARGON2_PUBLIC __declspec(dllexport) +#endif +#ifndef ARGON2_LOCAL +#define ARGON2_LOCAL +#endif +#else +#ifndef ARGON2_PUBLIC +#define ARGON2_PUBLIC +#endif +#ifndef ARGON2_LOCAL +#define ARGON2_LOCAL +#endif +#endif + +/* + * Argon2 input parameter restrictions + */ + +/* Minimum and maximum number of lanes (degree of parallelism) */ +#define ARGON2_MIN_LANES UINT32_C(1) +#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) + +/* Minimum and maximum number of threads */ +#define ARGON2_MIN_THREADS UINT32_C(1) +#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) + +/* Number of synchronization points between lanes per pass */ +#define ARGON2_SYNC_POINTS UINT32_C(4) + +/* Minimum and maximum digest size in bytes */ +#define ARGON2_MIN_OUTLEN UINT32_C(4) +#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ +#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */ + +#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) +/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */ +#define ARGON2_MAX_MEMORY_BITS \ + ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) +#define ARGON2_MAX_MEMORY \ + ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) + +/* Minimum and maximum number of passes */ +#define ARGON2_MIN_TIME UINT32_C(1) +#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum password length in bytes */ +#define ARGON2_MIN_PWD_LENGTH UINT32_C(0) +#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum associated data length in bytes */ +#define ARGON2_MIN_AD_LENGTH UINT32_C(0) +#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum salt length in bytes */ +#define ARGON2_MIN_SALT_LENGTH UINT32_C(8) +#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum key length in bytes */ +#define ARGON2_MIN_SECRET UINT32_C(0) +#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) + +/* Flags to determine which fields are securely wiped (default = no wipe). */ +#define ARGON2_DEFAULT_FLAGS UINT32_C(0) +#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) +#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) + +/* Global flag to determine if we are wiping internal memory buffers. This flag + * is defined in core.c and defaults to 1 (wipe internal memory). */ +extern int FLAG_clear_internal_memory; + +/* Error codes */ +typedef enum Argon2_ErrorCodes { + ARGON2_OK = 0, + + ARGON2_OUTPUT_PTR_NULL = -1, + + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, + + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, + + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, + + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, + + ARGON2_SECRET_TOO_SHORT = -10, + ARGON2_SECRET_TOO_LONG = -11, + + ARGON2_TIME_TOO_SMALL = -12, + ARGON2_TIME_TOO_LARGE = -13, + + ARGON2_MEMORY_TOO_LITTLE = -14, + ARGON2_MEMORY_TOO_MUCH = -15, + + ARGON2_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, + + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + + ARGON2_MEMORY_ALLOCATION_ERROR = -22, + + ARGON2_FREE_MEMORY_CBK_NULL = -23, + ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, + + ARGON2_INCORRECT_PARAMETER = -25, + ARGON2_INCORRECT_TYPE = -26, + + ARGON2_OUT_PTR_MISMATCH = -27, + + ARGON2_THREADS_TOO_FEW = -28, + ARGON2_THREADS_TOO_MANY = -29, + + ARGON2_MISSING_ARGS = -30, + + ARGON2_ENCODING_FAIL = -31, + + ARGON2_DECODING_FAIL = -32, + + ARGON2_THREAD_FAIL = -33, + + ARGON2_DECODING_LENGTH_FAIL = -34, + + ARGON2_VERIFY_MISMATCH = -35 +} argon2_error_codes; + +/* Memory allocator types --- for external allocation */ +typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate); +typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); + +/* Argon2 external data structures */ + +/* + ***** + * Context: structure to hold Argon2 inputs: + * output array and its length, + * password and its length, + * salt and its length, + * secret and its length, + * associated data and its length, + * number of passes, amount of used memory (in KBytes, can be rounded up a bit) + * number of parallel threads that will be run. + * All the parameters above affect the output hash value. + * Additionally, two function pointers can be provided to allocate and + * deallocate the memory (if NULL, memory will be allocated internally). + * Also, three flags indicate whether to erase password, secret as soon as they + * are pre-hashed (and thus not needed anymore), and the entire memory + ***** + * Simplest situation: you have output array out[8], password is stored in + * pwd[32], salt is stored in salt[16], you do not have keys nor associated + * data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with + * 4 parallel lanes. + * You want to erase the password, but you're OK with last pass not being + * erased. You want to use the default memory allocator. + * Then you initialize: + Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) + */ +typedef struct Argon2_Context { + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ + + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ + + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ + + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ + + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ + + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ + + uint32_t version; /* version number */ + + allocate_fptr allocate_cbk; /* pointer to memory allocator */ + deallocate_fptr free_cbk; /* pointer to memory deallocator */ + + uint32_t flags; /* array of bool options */ +} argon2_context; + +/* Argon2 primitive type */ +typedef enum Argon2_type { + Argon2_d = 0, + Argon2_i = 1, + Argon2_id = 2 +} argon2_type; + +/* Version of the algorithm */ +typedef enum Argon2_version { + ARGON2_VERSION_10 = 0x10, + ARGON2_VERSION_13 = 0x13, + ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 +} argon2_version; + +/* + * Function that gives the string representation of an argon2_type. + * @param type The argon2_type that we want the string for + * @param uppercase Whether the string should have the first letter uppercase + * @return NULL if invalid type, otherwise the string representation. + */ +ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase); + +/* + * Function that performs memory-hard hashing with certain degree of parallelism + * @param context Pointer to the Argon2 internal structure + * @return Error code if smth is wrong, ARGON2_OK otherwise + */ +ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type); + +/** + * Hashes a password with Argon2i, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +/** + * Hashes a password with Argon2i, producing a raw hash at @hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash - updated by the function + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type, + const uint32_t version); + +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd, + const size_t pwdlen, argon2_type type); + +/** + * Argon2d: Version of Argon2 that picks memory blocks depending + * on the password and salt. Only for side-channel-free + * environment!! + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2d_ctx(argon2_context *context); + +/** + * Argon2i: Version of Argon2 that picks memory blocks + * independent on the password and salt. Good for side-channels, + * but worse w.r.t. tradeoff attacks if only one pass is used. + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2i_ctx(argon2_context *context); + +/** + * Argon2id: Version of Argon2 where the first half-pass over memory is + * password-independent, the rest are password-dependent (on the password and + * salt). OK against side channels (they reduce to 1/2-pass Argon2i), and + * better with w.r.t. tradeoff attacks (similar to Argon2d). + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2id_ctx(argon2_context *context); + +/** + * Verify if a given password is correct for Argon2d hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash); + +/** + * Verify if a given password is correct for Argon2i hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash); + +/** + * Verify if a given password is correct for Argon2id hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context, + const char *hash); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash, + argon2_type type); + +/** + * Get the associated error message for given error code + * @return The error message associated with the given error code + */ +ARGON2_PUBLIC const char *argon2_error_message(int error_code); + +/** + * Returns the encoded hash length for the given input parameters + * @param t_cost Number of iterations + * @param m_cost Memory usage in kibibytes + * @param parallelism Number of threads; used to compute lanes + * @param saltlen Salt size in bytes + * @param hashlen Hash size in bytes + * @param type The argon2_type that we want the encoded length for + * @return The encoded hash length in bytes + */ +ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, + uint32_t parallelism, uint32_t saltlen, + uint32_t hashlen, argon2_type type); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/libargon2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/libargon2.c new file mode 100644 index 0000000000..5f7cc96bc5 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/libargon2.c @@ -0,0 +1,26 @@ +#ifndef ARGON2_API +#define ARGON2_API static +#endif + +#ifndef ARGON2_PRIVATE +#define ARGON2_PRIVATE static +#endif + +#ifndef ARGON2_PUBLIC +#define ARGON2_PUBLIC static +#endif + +#ifndef ARGON2_LOCAL +#define ARGON2_LOCAL static +#endif + +#ifndef BLAKE2B_API +#define BLAKE2B_API static +#endif + +#include "src/blake2/blake2b.c" +#include "src/argon2.c" +#include "src/core.c" +#include "src/encoding.c" +#include "src/ref.c" +#include "src/thread.c" diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/argon2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/argon2.c new file mode 100644 index 0000000000..1985b8f531 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/argon2.c @@ -0,0 +1,452 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "argon2.h" +#include "encoding.h" +#include "core.h" + +const char *argon2_type2string(argon2_type type, int uppercase) { + switch (type) { + case Argon2_d: + return uppercase ? "Argon2d" : "argon2d"; + case Argon2_i: + return uppercase ? "Argon2i" : "argon2i"; + case Argon2_id: + return uppercase ? "Argon2id" : "argon2id"; + } + + return NULL; +} + +int argon2_ctx(argon2_context *context, argon2_type type) { + /* 1. Validate all inputs */ + int result = _argon2_validate_inputs(context); + uint32_t memory_blocks, segment_length; + argon2_instance_t instance; + + if (ARGON2_OK != result) { + return result; + } + + if (Argon2_d != type && Argon2_i != type && Argon2_id != type) { + return ARGON2_INCORRECT_TYPE; + } + + /* 2. Align memory size */ + /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ + memory_blocks = context->m_cost; + + if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { + memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; + } + + segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS); + /* Ensure that all segments have equal length */ + memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); + + instance.version = context->version; + instance.memory = NULL; + instance.passes = context->t_cost; + instance.memory_blocks = memory_blocks; + instance.segment_length = segment_length; + instance.lane_length = segment_length * ARGON2_SYNC_POINTS; + instance.lanes = context->lanes; + instance.threads = context->threads; + instance.type = type; + + if (instance.threads > instance.lanes) { + instance.threads = instance.lanes; + } + + /* 3. Initialization: Hashing inputs, allocating memory, filling first + * blocks + */ + result = _argon2_initialize(&instance, context); + + if (ARGON2_OK != result) { + return result; + } + + /* 4. Filling memory */ + result = _argon2_fill_memory_blocks(&instance); + + if (ARGON2_OK != result) { + return result; + } + /* 5. Finalization */ + _argon2_finalize(context, &instance); + + return ARGON2_OK; +} + +int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type, + const uint32_t version){ + + argon2_context context; + int result; + uint8_t *out; + + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { + return ARGON2_PWD_TOO_LONG; + } + + if (saltlen > ARGON2_MAX_SALT_LENGTH) { + return ARGON2_SALT_TOO_LONG; + } + + if (hashlen > ARGON2_MAX_OUTLEN) { + return ARGON2_OUTPUT_TOO_LONG; + } + + if (hashlen < ARGON2_MIN_OUTLEN) { + return ARGON2_OUTPUT_TOO_SHORT; + } + + out = malloc(hashlen); + if (!out) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + context.out = (uint8_t *)out; + context.outlen = (uint32_t)hashlen; + context.pwd = CONST_CAST(uint8_t *)pwd; + context.pwdlen = (uint32_t)pwdlen; + context.salt = CONST_CAST(uint8_t *)salt; + context.saltlen = (uint32_t)saltlen; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.t_cost = t_cost; + context.m_cost = m_cost; + context.lanes = parallelism; + context.threads = parallelism; + context.allocate_cbk = NULL; + context.free_cbk = NULL; + context.flags = ARGON2_DEFAULT_FLAGS; + context.version = version; + + result = argon2_ctx(&context, type); + + if (result != ARGON2_OK) { + _argon2_clear_internal_memory(out, hashlen); + free(out); + return result; + } + + /* if raw hash requested, write it */ + if (hash) { + memcpy(hash, out, hashlen); + } + + /* if encoding requested, write it */ + if (encoded && encodedlen) { + if (_argon2_encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) { + _argon2_clear_internal_memory(out, hashlen); /* wipe buffers if error */ + _argon2_clear_internal_memory(encoded, encodedlen); + free(out); + return ARGON2_ENCODING_FAIL; + } + } + _argon2_clear_internal_memory(out, hashlen); + free(out); + + return ARGON2_OK; +} + +int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_i, + ARGON2_VERSION_NUMBER); +} + +int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER); +} + +int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_d, + ARGON2_VERSION_NUMBER); +} + +int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER); +} + +int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen) { + + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_id, + ARGON2_VERSION_NUMBER); +} + +int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen) { + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_id, + ARGON2_VERSION_NUMBER); +} + +static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) { + size_t i; + uint8_t d = 0U; + + for (i = 0U; i < len; i++) { + d |= b1[i] ^ b2[i]; + } + return (int)((1 & ((d - 1) >> 8)) - 1); +} + +int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, + argon2_type type) { + + argon2_context ctx; + uint8_t *desired_result = NULL; + + int ret = ARGON2_OK; + + size_t encoded_len; + uint32_t max_field_len; + + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { + return ARGON2_PWD_TOO_LONG; + } + + if (encoded == NULL) { + return ARGON2_DECODING_FAIL; + } + + encoded_len = strlen(encoded); + if (encoded_len > UINT32_MAX) { + return ARGON2_DECODING_FAIL; + } + + /* No field can be longer than the encoded length */ + max_field_len = (uint32_t)encoded_len; + + ctx.saltlen = max_field_len; + ctx.outlen = max_field_len; + + ctx.salt = malloc(ctx.saltlen); + ctx.out = malloc(ctx.outlen); + if (!ctx.salt || !ctx.out) { + ret = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + ctx.pwd = (uint8_t *)pwd; + ctx.pwdlen = (uint32_t)pwdlen; + + ret = _argon2_decode_string(&ctx, encoded, type); + if (ret != ARGON2_OK) { + goto fail; + } + + /* Set aside the desired result, and get a new buffer. */ + desired_result = ctx.out; + ctx.out = malloc(ctx.outlen); + if (!ctx.out) { + ret = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + ret = argon2_verify_ctx(&ctx, (char *)desired_result, type); + if (ret != ARGON2_OK) { + goto fail; + } + +fail: + free(ctx.salt); + free(ctx.out); + free(desired_result); + + return ret; +} + +int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_i); +} + +int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_d); +} + +int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) { + + return argon2_verify(encoded, pwd, pwdlen, Argon2_id); +} + +int argon2d_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_d); +} + +int argon2i_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_i); +} + +int argon2id_ctx(argon2_context *context) { + return argon2_ctx(context, Argon2_id); +} + +int argon2_verify_ctx(argon2_context *context, const char *hash, + argon2_type type) { + int ret = argon2_ctx(context, type); + if (ret != ARGON2_OK) { + return ret; + } + + if (argon2_compare((uint8_t *)hash, context->out, context->outlen)) { + return ARGON2_VERIFY_MISMATCH; + } + + return ARGON2_OK; +} + +int argon2d_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_d); +} + +int argon2i_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_i); +} + +int argon2id_verify_ctx(argon2_context *context, const char *hash) { + return argon2_verify_ctx(context, hash, Argon2_id); +} + +const char *argon2_error_message(int error_code) { + switch (error_code) { + case ARGON2_OK: + return "OK"; + case ARGON2_OUTPUT_PTR_NULL: + return "Output pointer is NULL"; + case ARGON2_OUTPUT_TOO_SHORT: + return "Output is too short"; + case ARGON2_OUTPUT_TOO_LONG: + return "Output is too long"; + case ARGON2_PWD_TOO_SHORT: + return "Password is too short"; + case ARGON2_PWD_TOO_LONG: + return "Password is too long"; + case ARGON2_SALT_TOO_SHORT: + return "Salt is too short"; + case ARGON2_SALT_TOO_LONG: + return "Salt is too long"; + case ARGON2_AD_TOO_SHORT: + return "Associated data is too short"; + case ARGON2_AD_TOO_LONG: + return "Associated data is too long"; + case ARGON2_SECRET_TOO_SHORT: + return "Secret is too short"; + case ARGON2_SECRET_TOO_LONG: + return "Secret is too long"; + case ARGON2_TIME_TOO_SMALL: + return "Time cost is too small"; + case ARGON2_TIME_TOO_LARGE: + return "Time cost is too large"; + case ARGON2_MEMORY_TOO_LITTLE: + return "Memory cost is too small"; + case ARGON2_MEMORY_TOO_MUCH: + return "Memory cost is too large"; + case ARGON2_LANES_TOO_FEW: + return "Too few lanes"; + case ARGON2_LANES_TOO_MANY: + return "Too many lanes"; + case ARGON2_PWD_PTR_MISMATCH: + return "Password pointer is NULL, but password length is not 0"; + case ARGON2_SALT_PTR_MISMATCH: + return "Salt pointer is NULL, but salt length is not 0"; + case ARGON2_SECRET_PTR_MISMATCH: + return "Secret pointer is NULL, but secret length is not 0"; + case ARGON2_AD_PTR_MISMATCH: + return "Associated data pointer is NULL, but ad length is not 0"; + case ARGON2_MEMORY_ALLOCATION_ERROR: + return "Memory allocation error"; + case ARGON2_FREE_MEMORY_CBK_NULL: + return "The free memory callback is NULL"; + case ARGON2_ALLOCATE_MEMORY_CBK_NULL: + return "The allocate memory callback is NULL"; + case ARGON2_INCORRECT_PARAMETER: + return "Argon2_Context context is NULL"; + case ARGON2_INCORRECT_TYPE: + return "There is no such version of Argon2"; + case ARGON2_OUT_PTR_MISMATCH: + return "Output pointer mismatch"; + case ARGON2_THREADS_TOO_FEW: + return "Not enough threads"; + case ARGON2_THREADS_TOO_MANY: + return "Too many threads"; + case ARGON2_MISSING_ARGS: + return "Missing arguments"; + case ARGON2_ENCODING_FAIL: + return "Encoding failed"; + case ARGON2_DECODING_FAIL: + return "Decoding failed"; + case ARGON2_THREAD_FAIL: + return "Threading failure"; + case ARGON2_DECODING_LENGTH_FAIL: + return "Some of encoded parameters are too long or too short"; + case ARGON2_VERIFY_MISMATCH: + return "The password does not match the supplied hash"; + default: + return "Unknown error code"; + } +} + +size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism, + uint32_t saltlen, uint32_t hashlen, argon2_type type) { + return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) + + _argon2_numlen(t_cost) + _argon2_numlen(m_cost) + _argon2_numlen(parallelism) + + _argon2_b64len(saltlen) + _argon2_b64len(hashlen) + _argon2_numlen(ARGON2_VERSION_NUMBER) + 1; +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/bench.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/bench.c new file mode 100644 index 0000000000..63355192ae --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/bench.c @@ -0,0 +1,111 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#include "argon2.h" + +static uint64_t rdtsc(void) { +#ifdef _WIN32 + return __rdtsc(); +#else +#if defined(__amd64__) || defined(__x86_64__) + uint64_t rax, rdx; + __asm__ __volatile__("rdtsc" : "=a"(rax), "=d"(rdx) : :); + return (rdx << 32) | rax; +#elif defined(__i386__) || defined(__i386) || defined(__X86__) + uint64_t rax; + __asm__ __volatile__("rdtsc" : "=A"(rax) : :); + return rax; +#else +#error "Not implemented!" +#endif +#endif +} + +/* + * Benchmarks Argon2 with salt length 16, password length 16, t_cost 3, + and different m_cost and threads + */ +static void benchmark() { +#define BENCH_OUTLEN 16 +#define BENCH_INLEN 16 + const uint32_t inlen = BENCH_INLEN; + const unsigned outlen = BENCH_OUTLEN; + unsigned char out[BENCH_OUTLEN]; + unsigned char pwd_array[BENCH_INLEN]; + unsigned char salt_array[BENCH_INLEN]; +#undef BENCH_INLEN +#undef BENCH_OUTLEN + + uint32_t t_cost = 3; + uint32_t m_cost; + uint32_t thread_test[4] = {1, 2, 4, 8}; + argon2_type types[3] = {Argon2_i, Argon2_d, Argon2_id}; + + memset(pwd_array, 0, inlen); + memset(salt_array, 1, inlen); + + for (m_cost = (uint32_t)1 << 10; m_cost <= (uint32_t)1 << 22; m_cost *= 2) { + unsigned i; + for (i = 0; i < 4; ++i) { + double run_time = 0; + uint32_t thread_n = thread_test[i]; + + unsigned j; + for (j = 0; j < 3; ++j) { + clock_t start_time, stop_time; + uint64_t start_cycles, stop_cycles; + uint64_t delta; + double mcycles; + + argon2_type type = types[j]; + start_time = clock(); + start_cycles = rdtsc(); + + argon2_hash(t_cost, m_cost, thread_n, pwd_array, inlen, + salt_array, inlen, out, outlen, NULL, 0, type, + ARGON2_VERSION_NUMBER); + + stop_cycles = rdtsc(); + stop_time = clock(); + + delta = (stop_cycles - start_cycles) / (m_cost); + mcycles = (double)(stop_cycles - start_cycles) / (1UL << 20); + run_time += ((double)stop_time - start_time) / (CLOCKS_PER_SEC); + + printf("%s %d iterations %d MiB %d threads: %2.2f cpb %2.2f " + "Mcycles \n", argon2_type2string(type, 1), t_cost, + m_cost >> 10, thread_n, (float)delta / 1024, mcycles); + } + + printf("%2.4f seconds\n\n", run_time); + } + } +} + +int main() { + benchmark(); + return ARGON2_OK; +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2-impl.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2-impl.h new file mode 100644 index 0000000000..9c3e35ed89 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2-impl.h @@ -0,0 +1,157 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef PORTABLE_BLAKE2_IMPL_H +#define PORTABLE_BLAKE2_IMPL_H + +#include +#include + +#ifdef _WIN32 +#define BLAKE2_INLINE __inline +#elif defined(__GNUC__) || defined(__clang__) +#define BLAKE2_INLINE __inline__ +#else +#define BLAKE2_INLINE +#endif + +/* Argon2 Team - Begin Code */ +/* + Not an exhaustive list, but should cover the majority of modern platforms + Additionally, the code will always be correct---this is only a performance + tweak. +*/ +#if (defined(__BYTE_ORDER__) && \ + (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ + defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \ + defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \ + defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \ + defined(_M_ARM) +#define NATIVE_LITTLE_ENDIAN +#endif +/* Argon2 Team - End Code */ + +static BLAKE2_INLINE uint32_t _blake2b_load32(const void *src) { +#if defined(NATIVE_LITTLE_ENDIAN) + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = (const uint8_t *)src; + uint32_t w = *p++; + w |= (uint32_t)(*p++) << 8; + w |= (uint32_t)(*p++) << 16; + w |= (uint32_t)(*p++) << 24; + return w; +#endif +} + +static BLAKE2_INLINE uint64_t _blake2b_load64(const void *src) { +#if defined(NATIVE_LITTLE_ENDIAN) + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = (const uint8_t *)src; + uint64_t w = *p++; + w |= (uint64_t)(*p++) << 8; + w |= (uint64_t)(*p++) << 16; + w |= (uint64_t)(*p++) << 24; + w |= (uint64_t)(*p++) << 32; + w |= (uint64_t)(*p++) << 40; + w |= (uint64_t)(*p++) << 48; + w |= (uint64_t)(*p++) << 56; + return w; +#endif +} + +static BLAKE2_INLINE void _blake2b_store32(void *dst, uint32_t w) { +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +#endif +} + +static BLAKE2_INLINE void _blake2b_store64(void *dst, uint64_t w) { +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +#endif +} + +static BLAKE2_INLINE uint64_t _blake2b_load48(const void *src) { + const uint8_t *p = (const uint8_t *)src; + uint64_t w = *p++; + w |= (uint64_t)(*p++) << 8; + w |= (uint64_t)(*p++) << 16; + w |= (uint64_t)(*p++) << 24; + w |= (uint64_t)(*p++) << 32; + w |= (uint64_t)(*p++) << 40; + return w; +} + +static BLAKE2_INLINE void _blake2b_store48(void *dst, uint64_t w) { + uint8_t *p = (uint8_t *)dst; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; + w >>= 8; + *p++ = (uint8_t)w; +} + +static BLAKE2_INLINE uint32_t _blake2b_rotr32(const uint32_t w, const unsigned c) { + return (w >> c) | (w << (32 - c)); +} + +static BLAKE2_INLINE uint64_t _blake2b_rotr64(const uint64_t w, const unsigned c) { + return (w >> c) | (w << (64 - c)); +} + +ARGON2_PRIVATE +void _argon2_clear_internal_memory(void *v, size_t n); + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2.h new file mode 100644 index 0000000000..f4a80d47ab --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2.h @@ -0,0 +1,89 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef PORTABLE_BLAKE2_H +#define PORTABLE_BLAKE2_H + +#include "argon2.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +enum blake2b_constant { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 +}; + +#pragma pack(push, 1) +typedef struct __blake2b_param { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint64_t node_offset; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ +} blake2b_param; +#pragma pack(pop) + +typedef struct __blake2b_state { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + unsigned buflen; + unsigned outlen; + uint8_t last_node; +} blake2b_state; + +/* Ensure param structs have not been wrongly padded */ +/* Poor man's static_assert */ +enum { + blake2_size_check_0 = 1 / !!(CHAR_BIT == 8), + blake2_size_check_2 = + 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT) +}; + +/* Streaming API */ +ARGON2_LOCAL int blake2b_init(blake2b_state *S, size_t outlen); +ARGON2_LOCAL int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, + size_t keylen); +ARGON2_LOCAL int blake2b_init_param(blake2b_state *S, const blake2b_param *P); +ARGON2_LOCAL int blake2b_update(blake2b_state *S, const void *in, size_t inlen); +ARGON2_LOCAL int blake2b_final(blake2b_state *S, void *out, size_t outlen); + +/* Simple API */ +ARGON2_LOCAL int blake2b(void *out, size_t outlen, const void *in, size_t inlen, + const void *key, size_t keylen); + +/* Argon2 Team - Begin Code */ +ARGON2_LOCAL int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen); +/* Argon2 Team - End Code */ + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2b.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2b.c new file mode 100644 index 0000000000..3518dfbdb3 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blake2b.c @@ -0,0 +1,397 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint64_t blake2b_IV[8] = { + UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), + UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1), + UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f), + UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)}; + +static const unsigned int blake2b_sigma[12][16] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, + {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, + {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, + {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, + {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, + {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, + {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, +}; + +static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *BS) { + BS->f[1] = (uint64_t)-1; +} + +static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *BS) { + if (BS->last_node) { + blake2b_set_lastnode(BS); + } + BS->f[0] = (uint64_t)-1; +} + +static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *BS, + uint64_t inc) { + BS->t[0] += inc; + BS->t[1] += (BS->t[0] < inc); +} + +static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *BS) { + _argon2_clear_internal_memory(BS, sizeof(*BS)); /* wipe */ + blake2b_set_lastblock(BS); /* invalidate for further use */ +} + +static BLAKE2_INLINE void blake2b_init0(blake2b_state *BS) { + memset(BS, 0, sizeof(*BS)); + memcpy(BS->h, blake2b_IV, sizeof(BS->h)); +} + +BLAKE2B_API +int blake2b_init_param(blake2b_state *BS, const blake2b_param *BP) { + const unsigned char *p = (const unsigned char *)BP; + unsigned int i; + + if (NULL == BP || NULL == BS) { + return -1; + } + + blake2b_init0(BS); + /* IV XOR Parameter Block */ + for (i = 0; i < 8; ++i) { + BS->h[i] ^= _blake2b_load64(&p[i * sizeof(BS->h[i])]); + } + BS->outlen = BP->digest_length; + return 0; +} + +/* Sequential blake2b initialization */ +BLAKE2B_API +int blake2b_init(blake2b_state *BS, size_t outlen) { + blake2b_param BP; + + if (BS == NULL) { + return -1; + } + + if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { + blake2b_invalidate_state(BS); + return -1; + } + + /* Setup Parameter Block for unkeyed BLAKE2 */ + BP.digest_length = (uint8_t)outlen; + BP.key_length = 0; + BP.fanout = 1; + BP.depth = 1; + BP.leaf_length = 0; + BP.node_offset = 0; + BP.node_depth = 0; + BP.inner_length = 0; + memset(BP.reserved, 0, sizeof(BP.reserved)); + memset(BP.salt, 0, sizeof(BP.salt)); + memset(BP.personal, 0, sizeof(BP.personal)); + + return blake2b_init_param(BS, &BP); +} + +BLAKE2B_API +int blake2b_init_key(blake2b_state *BS, size_t outlen, const void *key, + size_t keylen) { + blake2b_param BP; + + if (BS == NULL) { + return -1; + } + + if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { + blake2b_invalidate_state(BS); + return -1; + } + + if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) { + blake2b_invalidate_state(BS); + return -1; + } + + /* Setup Parameter Block for keyed BLAKE2 */ + BP.digest_length = (uint8_t)outlen; + BP.key_length = (uint8_t)keylen; + BP.fanout = 1; + BP.depth = 1; + BP.leaf_length = 0; + BP.node_offset = 0; + BP.node_depth = 0; + BP.inner_length = 0; + memset(BP.reserved, 0, sizeof(BP.reserved)); + memset(BP.salt, 0, sizeof(BP.salt)); + memset(BP.personal, 0, sizeof(BP.personal)); + + if (blake2b_init_param(BS, &BP) < 0) { + blake2b_invalidate_state(BS); + return -1; + } + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, BLAKE2B_BLOCKBYTES); + memcpy(block, key, keylen); + blake2b_update(BS, block, BLAKE2B_BLOCKBYTES); + /* Burn the key from stack */ + _argon2_clear_internal_memory(block, BLAKE2B_BLOCKBYTES); + } + return 0; +} + +static void blake2b_compress(blake2b_state *BS, const uint8_t *block) { + uint64_t m[16]; + uint64_t v[16]; + unsigned int i, r; + + for (i = 0; i < 16; ++i) { + m[i] = _blake2b_load64(block + i * sizeof(m[i])); + } + + for (i = 0; i < 8; ++i) { + v[i] = BS->h[i]; + } + + v[8] = blake2b_IV[0]; + v[9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = blake2b_IV[4] ^ BS->t[0]; + v[13] = blake2b_IV[5] ^ BS->t[1]; + v[14] = blake2b_IV[6] ^ BS->f[0]; + v[15] = blake2b_IV[7] ^ BS->f[1]; + +#define BLAKE2B_G(r, i, a, b, c, d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ + d = _blake2b_rotr64(d ^ a, 32); \ + c = c + d; \ + b = _blake2b_rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ + d = _blake2b_rotr64(d ^ a, 16); \ + c = c + d; \ + b = _blake2b_rotr64(b ^ c, 63); \ + } while ((void)0, 0) + +#define BLAKE2B_ROUND(r) \ + do { \ + BLAKE2B_G(r, 0, v[0], v[4], v[8], v[12]); \ + BLAKE2B_G(r, 1, v[1], v[5], v[9], v[13]); \ + BLAKE2B_G(r, 2, v[2], v[6], v[10], v[14]); \ + BLAKE2B_G(r, 3, v[3], v[7], v[11], v[15]); \ + BLAKE2B_G(r, 4, v[0], v[5], v[10], v[15]); \ + BLAKE2B_G(r, 5, v[1], v[6], v[11], v[12]); \ + BLAKE2B_G(r, 6, v[2], v[7], v[8], v[13]); \ + BLAKE2B_G(r, 7, v[3], v[4], v[9], v[14]); \ + } while ((void)0, 0) + + for (r = 0; r < 12; ++r) { + BLAKE2B_ROUND(r); + } + + for (i = 0; i < 8; ++i) { + BS->h[i] = BS->h[i] ^ v[i] ^ v[i + 8]; + } + +#undef BLAKE2B_G +#undef BLAKE2B_ROUND +} + +BLAKE2B_API +int blake2b_update(blake2b_state *BS, const void *in, size_t inlen) { + const uint8_t *pin = (const uint8_t *)in; + + if (inlen == 0) { + return 0; + } + + /* Sanity check */ + if (BS == NULL || in == NULL) { + return -1; + } + + /* Is this a reused state? */ + if (BS->f[0] != 0) { + return -1; + } + + if (BS->buflen + inlen > BLAKE2B_BLOCKBYTES) { + /* Complete current block */ + size_t left = BS->buflen; + size_t fill = BLAKE2B_BLOCKBYTES - left; + memcpy(&BS->buf[left], pin, fill); + blake2b_increment_counter(BS, BLAKE2B_BLOCKBYTES); + blake2b_compress(BS, BS->buf); + BS->buflen = 0; + inlen -= fill; + pin += fill; + /* Avoid buffer copies when possible */ + while (inlen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(BS, BLAKE2B_BLOCKBYTES); + blake2b_compress(BS, pin); + inlen -= BLAKE2B_BLOCKBYTES; + pin += BLAKE2B_BLOCKBYTES; + } + } + memcpy(&BS->buf[BS->buflen], pin, inlen); + BS->buflen += (unsigned int)inlen; + return 0; +} + +BLAKE2B_API +int blake2b_final(blake2b_state *BS, void *out, size_t outlen) { + uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; + unsigned int i; + + /* Sanity checks */ + if (BS == NULL || out == NULL || outlen < BS->outlen) { + return -1; + } + + /* Is this a reused state? */ + if (BS->f[0] != 0) { + return -1; + } + + blake2b_increment_counter(BS, BS->buflen); + blake2b_set_lastblock(BS); + memset(&BS->buf[BS->buflen], 0, BLAKE2B_BLOCKBYTES - BS->buflen); /* Padding */ + blake2b_compress(BS, BS->buf); + + for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */ + _blake2b_store64(buffer + sizeof(BS->h[i]) * i, BS->h[i]); + } + + memcpy(out, buffer, BS->outlen); + _argon2_clear_internal_memory(buffer, sizeof(buffer)); + _argon2_clear_internal_memory(BS->buf, sizeof(BS->buf)); + _argon2_clear_internal_memory(BS->h, sizeof(BS->h)); + return 0; +} + +BLAKE2B_API +int blake2b(void *out, size_t outlen, const void *in, size_t inlen, + const void *key, size_t keylen) { + blake2b_state BS; + int ret = -1; + + /* Verify parameters */ + if (NULL == in && inlen > 0) { + goto fail; + } + + if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) { + goto fail; + } + + if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) { + goto fail; + } + + if (keylen > 0) { + if (blake2b_init_key(&BS, outlen, key, keylen) < 0) { + goto fail; + } + } else { + if (blake2b_init(&BS, outlen) < 0) { + goto fail; + } + } + + if (blake2b_update(&BS, in, inlen) < 0) { + goto fail; + } + ret = blake2b_final(&BS, out, outlen); + +fail: + _argon2_clear_internal_memory(&BS, sizeof(BS)); + return ret; +} + +/* Argon2 Team - Begin Code */ +BLAKE2B_API +int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) { + uint8_t *out = (uint8_t *)pout; + blake2b_state blake_state; + uint8_t outlen_bytes[sizeof(uint32_t)] = {0}; + int ret = -1; + + if (outlen > UINT32_MAX) { + goto fail; + } + + /* Ensure little-endian byte order! */ + _blake2b_store32(outlen_bytes, (uint32_t)outlen); + +#define BLAKE2B_TRY(statement) \ + do { \ + ret = statement; \ + if (ret < 0) { \ + goto fail; \ + } \ + } while ((void)0, 0) + + if (outlen <= BLAKE2B_OUTBYTES) { + BLAKE2B_TRY(blake2b_init(&blake_state, outlen)); + BLAKE2B_TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); + BLAKE2B_TRY(blake2b_update(&blake_state, in, inlen)); + BLAKE2B_TRY(blake2b_final(&blake_state, out, outlen)); + } else { + uint32_t toproduce; + uint8_t out_buffer[BLAKE2B_OUTBYTES]; + uint8_t in_buffer[BLAKE2B_OUTBYTES]; + BLAKE2B_TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES)); + BLAKE2B_TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); + BLAKE2B_TRY(blake2b_update(&blake_state, in, inlen)); + BLAKE2B_TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES)); + memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); + out += BLAKE2B_OUTBYTES / 2; + toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2; + + while (toproduce > BLAKE2B_OUTBYTES) { + memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); + BLAKE2B_TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer, + BLAKE2B_OUTBYTES, NULL, 0)); + memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); + out += BLAKE2B_OUTBYTES / 2; + toproduce -= BLAKE2B_OUTBYTES / 2; + } + + memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); + BLAKE2B_TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL, + 0)); + memcpy(out, out_buffer, toproduce); + } +fail: + _argon2_clear_internal_memory(&blake_state, sizeof(blake_state)); + return ret; +#undef BLAKE2B_TRY +} +/* Argon2 Team - End Code */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blamka-round-opt.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blamka-round-opt.h new file mode 100644 index 0000000000..3127f2a373 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blamka-round-opt.h @@ -0,0 +1,471 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef BLAKE_ROUND_MKA_OPT_H +#define BLAKE_ROUND_MKA_OPT_H + +#include "blake2-impl.h" + +#include +#if defined(__SSSE3__) +#include /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */ +#endif + +#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__)) +#include +#endif + +#if !defined(__AVX512F__) +#if !defined(__AVX2__) +#if !defined(__XOP__) +#if defined(__SSSE3__) +#define r16 \ + (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define r24 \ + (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) +#else /* defined(__SSE2__) */ +#define _mm_roti_epi64(r, c) \ + _mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c)))) +#endif +#else +#endif + +static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) { + const __m128i z = _mm_mul_epu32(x, y); + return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z)); +} + +#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -32); \ + D1 = _mm_roti_epi64(D1, -32); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -24); \ + B1 = _mm_roti_epi64(B1, -24); \ + } while ((void)0, 0) + +#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -16); \ + D1 = _mm_roti_epi64(D1, -16); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -63); \ + B1 = _mm_roti_epi64(B1, -63); \ + } while ((void)0, 0) + +#if defined(__SSSE3__) +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \ + __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D1, D0, 8); \ + t1 = _mm_alignr_epi8(D0, D1, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \ + __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D0, D1, 8); \ + t1 = _mm_alignr_epi8(D1, D0, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void)0, 0) +#else /* SSE2 */ +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = D0; \ + __m128i t1 = B0; \ + D0 = C0; \ + C0 = C1; \ + C1 = D0; \ + D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \ + D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \ + B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \ + B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0, t1; \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + t0 = B0; \ + t1 = D0; \ + B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \ + B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \ + D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \ + D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \ + } while ((void)0, 0) +#endif + +#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void)0, 0) +#else /* __AVX2__ */ + +#include + +#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1)) +#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define rotr16(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define rotr63(x) _mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x))) + +#define G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr32(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr24(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr32(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr24(B1); \ + } while((void)0, 0); + +#define G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr16(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr63(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr16(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr63(B1); \ + } while((void)0, 0); + +#define DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while((void)0, 0); + +#define DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while(0); + +#define UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while((void)0, 0); + +#define UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0x33); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0xCC); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while((void)0, 0); + +#define BLAKE2_ROUND_1(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + } while((void)0, 0); + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + } while((void)0, 0); + +#endif /* __AVX2__ */ + +#else /* __AVX512F__ */ + +#include + +#define ror64(x, n) _mm512_ror_epi64((x), (n)) + +static __m512i muladd(__m512i x, __m512i y) +{ + __m512i z = _mm512_mul_epu32(x, y); + return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z)); +} + +#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ +\ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ +\ + D0 = ror64(D0, 32); \ + D1 = ror64(D1, 32); \ +\ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ +\ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ +\ + B0 = ror64(B0, 24); \ + B1 = ror64(B1, 24); \ + } while ((void)0, 0) + +#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ +\ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ +\ + D0 = ror64(D0, 16); \ + D1 = ror64(D1, 16); \ +\ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ +\ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ +\ + B0 = ror64(B0, 63); \ + B1 = ror64(B1, 63); \ + } while ((void)0, 0) + +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ +\ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ +\ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ +\ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ +\ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ +\ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void)0, 0) + +#define SWAP_HALVES(A0, A1) \ + do { \ + __m512i t0, t1; \ + t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \ + t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \ + A0 = t0; \ + A1 = t1; \ + } while((void)0, 0) + +#define SWAP_QUARTERS(A0, A1) \ + do { \ + SWAP_HALVES(A0, A1); \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + } while((void)0, 0) + +#define UNSWAP_QUARTERS(A0, A1) \ + do { \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + SWAP_HALVES(A0, A1); \ + } while((void)0, 0) + +#define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \ + do { \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + SWAP_QUARTERS(A0, A1); \ + SWAP_QUARTERS(B0, B1); \ + SWAP_QUARTERS(C0, C1); \ + SWAP_QUARTERS(D0, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + UNSWAP_QUARTERS(A0, A1); \ + UNSWAP_QUARTERS(B0, B1); \ + UNSWAP_QUARTERS(C0, C1); \ + UNSWAP_QUARTERS(D0, D1); \ + } while ((void)0, 0) + +#endif /* __AVX512F__ */ +#endif /* BLAKE_ROUND_MKA_OPT_H */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blamka-round-ref.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blamka-round-ref.h new file mode 100644 index 0000000000..341b97163c --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/blake2/blamka-round-ref.h @@ -0,0 +1,56 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef BLAKE_ROUND_MKA_H +#define BLAKE_ROUND_MKA_H + +#include "blake2.h" +#include "blake2-impl.h" + +/* designed by the Lyra PHC team */ +static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) { + const uint64_t m = UINT64_C(0xFFFFFFFF); + const uint64_t xy = (x & m) * (y & m); + return x + y + 2 * xy; +} + +#define BLAKE2_G(a, b, c, d) \ + do { \ + a = fBlaMka(a, b); \ + d = _blake2b_rotr64(d ^ a, 32); \ + c = fBlaMka(c, d); \ + b = _blake2b_rotr64(b ^ c, 24); \ + a = fBlaMka(a, b); \ + d = _blake2b_rotr64(d ^ a, 16); \ + c = fBlaMka(c, d); \ + b = _blake2b_rotr64(b ^ c, 63); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ + v12, v13, v14, v15) \ + do { \ + BLAKE2_G(v0, v4, v8, v12); \ + BLAKE2_G(v1, v5, v9, v13); \ + BLAKE2_G(v2, v6, v10, v14); \ + BLAKE2_G(v3, v7, v11, v15); \ + BLAKE2_G(v0, v5, v10, v15); \ + BLAKE2_G(v1, v6, v11, v12); \ + BLAKE2_G(v2, v7, v8, v13); \ + BLAKE2_G(v3, v4, v9, v14); \ + } while ((void)0, 0) + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/core.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/core.c new file mode 100644 index 0000000000..fccdc74b14 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/core.c @@ -0,0 +1,667 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +/*For memory wiping*/ +#ifdef _WIN32 +#include +#include /* For SecureZeroMemory */ +#endif +#if defined __STDC_LIB_EXT1__ +#define __STDC_WANT_LIB_EXT1__ 1 +#endif +#define VC_GE_2005(version) (version >= 1400) + +/* for explicit_bzero() on glibc */ +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif + +#include +#include +#include + +#include "core.h" +#include "thread.h" +#include "blake2/blake2.h" +#include "blake2/blake2-impl.h" + +#ifdef GENKAT +#include "genkat.h" +#endif + +#if defined(__clang__) +#if __has_attribute(optnone) +#define NOT_OPTIMIZED __attribute__((optnone)) +#endif +#elif defined(__GNUC__) +#ifndef GCC_VERSION +#define GCC_VERSION \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif +#if GCC_VERSION >= 40400 +#define NOT_OPTIMIZED __attribute__((optimize("O0"))) +#endif +#endif +#ifndef NOT_OPTIMIZED +#define NOT_OPTIMIZED +#endif + +/***************Instance and Position constructors**********/ +ARGON2_PRIVATE +void _argon2_init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); } + +ARGON2_PRIVATE +void _argon2_copy_block(block *dst, const block *src) { + memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); +} + +ARGON2_PRIVATE +void _argon2_xor_block(block *dst, const block *src) { + int i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] ^= src->v[i]; + } +} + +static void _argon2_load_block(block *dst, const void *input) { + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] = _blake2b_load64((const uint8_t *)input + i * sizeof(dst->v[i])); + } +} + +static void _argon2_store_block(void *output, const block *src) { + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + _blake2b_store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); + } +} + +/***************Memory functions*****************/ + +ARGON2_PRIVATE +int _argon2_allocate_memory(const argon2_context *context, uint8_t **memory, + size_t num, size_t size) { + size_t memory_size = num*size; + if (memory == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + /* 1. Check for multiplication overflow */ + if (size != 0 && memory_size / size != num) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + /* 2. Try to allocate with appropriate allocator */ + if (context->allocate_cbk) { + (context->allocate_cbk)(memory, memory_size); + } else { + *memory = malloc(memory_size); + } + + if (*memory == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + return ARGON2_OK; +} + +ARGON2_PRIVATE +void _argon2_free_memory(const argon2_context *context, uint8_t *memory, + size_t num, size_t size) { + size_t memory_size = num*size; + _argon2_clear_internal_memory(memory, memory_size); + if (context->free_cbk) { + (context->free_cbk)(memory, memory_size); + } else { + free(memory); + } +} + +#if defined(__OpenBSD__) +#define HAVE_EXPLICIT_BZERO 1 +#elif defined(__GLIBC__) && defined(__GLIBC_PREREQ) +#if __GLIBC_PREREQ(2,25) +#define HAVE_EXPLICIT_BZERO 1 +#endif +#endif + +ARGON2_PRIVATE +void NOT_OPTIMIZED _argon2_secure_wipe_memory(void *v, size_t n) { +#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER) || defined(__MINGW32__) + SecureZeroMemory(v, n); +#elif defined memset_s + memset_s(v, n, 0, n); +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(v, n); +#else + static void *(*const volatile memset_sec)(void *, int, size_t) = &memset; + memset_sec(v, 0, n); +#endif +} + +/* Memory clear flag defaults to true. */ +int FLAG_clear_internal_memory = 1; + +ARGON2_PRIVATE +void _argon2_clear_internal_memory(void *v, size_t n) { + if (FLAG_clear_internal_memory && v) { + _argon2_secure_wipe_memory(v, n); + } +} + +ARGON2_PRIVATE +void _argon2_finalize(const argon2_context *context, argon2_instance_t *instance) { + if (context != NULL && instance != NULL) { + block blockhash; + uint32_t l; + + _argon2_copy_block(&blockhash, instance->memory + instance->lane_length - 1); + + /* XOR the last blocks */ + for (l = 1; l < instance->lanes; ++l) { + uint32_t last_block_in_lane = + l * instance->lane_length + (instance->lane_length - 1); + _argon2_xor_block(&blockhash, instance->memory + last_block_in_lane); + } + + /* Hash the result */ + { + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + _argon2_store_block(blockhash_bytes, &blockhash); + blake2b_long(context->out, context->outlen, blockhash_bytes, + ARGON2_BLOCK_SIZE); + /* clear blockhash and blockhash_bytes */ + _argon2_clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE); + _argon2_clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); + } + +#ifdef GENKAT + print_tag(context->out, context->outlen); +#endif + + _argon2_free_memory(context, (uint8_t *)instance->memory, + instance->memory_blocks, sizeof(block)); + } +} + +ARGON2_PRIVATE +uint32_t _argon2_index_alpha(const argon2_instance_t *instance, + const argon2_position_t *position, uint32_t pseudo_rand, + int same_lane) { + /* + * Pass 0: + * This lane : all already finished segments plus already constructed + * blocks in this segment + * Other lanes : all already finished segments + * Pass 1+: + * This lane : (SYNC_POINTS - 1) last segments plus already constructed + * blocks in this segment + * Other lanes : (SYNC_POINTS - 1) last segments + */ + uint32_t reference_area_size; + uint64_t relative_position; + uint32_t start_position, absolute_position; + + if (0 == position->pass) { + /* First pass */ + if (0 == position->slice) { + /* First slice */ + reference_area_size = + position->index - 1; /* all but the previous */ + } else { + if (same_lane) { + /* The same lane => add current segment */ + reference_area_size = + position->slice * instance->segment_length + + position->index - 1; + } else { + reference_area_size = + position->slice * instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + } else { + /* Second pass */ + if (same_lane) { + reference_area_size = instance->lane_length - + instance->segment_length + position->index - + 1; + } else { + reference_area_size = instance->lane_length - + instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + + /* 1.2.4. Mapping pseudo_rand to 0.. and produce + * relative position */ + relative_position = pseudo_rand; + relative_position = relative_position * relative_position >> 32; + relative_position = reference_area_size - 1 - + (reference_area_size * relative_position >> 32); + + /* 1.2.5 Computing starting position */ + start_position = 0; + + if (0 != position->pass) { + start_position = (position->slice == ARGON2_SYNC_POINTS - 1) + ? 0 + : (position->slice + 1) * instance->segment_length; + } + + /* 1.2.6. Computing absolute position */ + absolute_position = (start_position + relative_position) % + instance->lane_length; /* absolute position */ + return absolute_position; +} + +/* Single-threaded version for p=1 case */ +static int _argon2_fill_memory_blocks_st(argon2_instance_t *instance) { + uint32_t r, s, l; + + for (r = 0; r < instance->passes; ++r) { + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + for (l = 0; l < instance->lanes; ++l) { + argon2_position_t position = {r, l, (uint8_t)s, 0}; + _argon2_fill_segment(instance, position); + } + } +#ifdef GENKAT + internal_kat(instance, r); /* Print all memory blocks */ +#endif + } + return ARGON2_OK; +} + +#if !defined(ARGON2_NO_THREADS) + +#ifdef _WIN32 +static unsigned __stdcall _argon2_fill_segment_thr(void *thread_data) +#else +static void *_argon2_fill_segment_thr(void *thread_data) +#endif +{ + argon2_thread_data *my_data = thread_data; + _argon2_fill_segment(my_data->instance_ptr, my_data->pos); + argon2_thread_exit(); + return 0; +} + +/* Multi-threaded version for p > 1 case */ +static int _argon2_fill_memory_blocks_mt(argon2_instance_t *instance) { + uint32_t r, s; + argon2_thread_handle_t *thread = NULL; + argon2_thread_data *thr_data = NULL; + int rc = ARGON2_OK; + + /* 1. Allocating space for threads */ + thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t)); + if (thread == NULL) { + rc = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + thr_data = calloc(instance->lanes, sizeof(argon2_thread_data)); + if (thr_data == NULL) { + rc = ARGON2_MEMORY_ALLOCATION_ERROR; + goto fail; + } + + for (r = 0; r < instance->passes; ++r) { + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + uint32_t l, ll; + + /* 2. Calling threads */ + for (l = 0; l < instance->lanes; ++l) { + argon2_position_t position; + + /* 2.1 Join a thread if limit is exceeded */ + if (l >= instance->threads) { + if (argon2_thread_join(thread[l - instance->threads])) { + rc = ARGON2_THREAD_FAIL; + goto fail; + } + } + + /* 2.2 Create thread */ + position.pass = r; + position.lane = l; + position.slice = (uint8_t)s; + position.index = 0; + thr_data[l].instance_ptr = + instance; /* preparing the thread input */ + memcpy(&(thr_data[l].pos), &position, + sizeof(argon2_position_t)); + if (argon2_thread_create(&thread[l], &_argon2_fill_segment_thr, + (void *)&thr_data[l])) { + /* Wait for already running threads */ + for (ll = 0; ll < l; ++ll) + argon2_thread_join(thread[ll]); + rc = ARGON2_THREAD_FAIL; + goto fail; + } + + /* fill_segment(instance, position); */ + /*Non-thread equivalent of the lines above */ + } + + /* 3. Joining remaining threads */ + for (l = instance->lanes - instance->threads; l < instance->lanes; + ++l) { + if (argon2_thread_join(thread[l])) { + rc = ARGON2_THREAD_FAIL; + goto fail; + } + } + } + +#ifdef GENKAT + internal_kat(instance, r); /* Print all memory blocks */ +#endif + } + +fail: + if (thread != NULL) { + free(thread); + } + if (thr_data != NULL) { + free(thr_data); + } + return rc; +} + +#endif /* ARGON2_NO_THREADS */ + +ARGON2_PRIVATE +int _argon2_fill_memory_blocks(argon2_instance_t *instance) { + if (instance == NULL || instance->lanes == 0) { + return ARGON2_INCORRECT_PARAMETER; + } +#if defined(ARGON2_NO_THREADS) + return _argon2_fill_memory_blocks_st(instance); +#else + return instance->threads == 1 ? + _argon2_fill_memory_blocks_st(instance) : _argon2_fill_memory_blocks_mt(instance); +#endif +} + +ARGON2_PRIVATE +int _argon2_validate_inputs(const argon2_context *context) { + if (NULL == context) { + return ARGON2_INCORRECT_PARAMETER; + } + + if (NULL == context->out) { + return ARGON2_OUTPUT_PTR_NULL; + } + + /* Validate output length */ + if (ARGON2_MIN_OUTLEN > context->outlen) { + return ARGON2_OUTPUT_TOO_SHORT; + } + + if (ARGON2_MAX_OUTLEN < context->outlen) { + return ARGON2_OUTPUT_TOO_LONG; + } + + /* Validate password (required param) */ + if (NULL == context->pwd) { + if (0 != context->pwdlen) { + return ARGON2_PWD_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) { + return ARGON2_PWD_TOO_SHORT; + } + + if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) { + return ARGON2_PWD_TOO_LONG; + } + + /* Validate salt (required param) */ + if (NULL == context->salt) { + if (0 != context->saltlen) { + return ARGON2_SALT_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_SALT_LENGTH > context->saltlen) { + return ARGON2_SALT_TOO_SHORT; + } + + if (ARGON2_MAX_SALT_LENGTH < context->saltlen) { + return ARGON2_SALT_TOO_LONG; + } + + /* Validate secret (optional param) */ + if (NULL == context->secret) { + if (0 != context->secretlen) { + return ARGON2_SECRET_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_SECRET > context->secretlen) { + return ARGON2_SECRET_TOO_SHORT; + } + if (ARGON2_MAX_SECRET < context->secretlen) { + return ARGON2_SECRET_TOO_LONG; + } + } + + /* Validate associated data (optional param) */ + if (NULL == context->ad) { + if (0 != context->adlen) { + return ARGON2_AD_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_AD_LENGTH > context->adlen) { + return ARGON2_AD_TOO_SHORT; + } + if (ARGON2_MAX_AD_LENGTH < context->adlen) { + return ARGON2_AD_TOO_LONG; + } + } + + /* Validate memory cost */ + if (ARGON2_MIN_MEMORY > context->m_cost) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + if (ARGON2_MAX_MEMORY < context->m_cost) { + return ARGON2_MEMORY_TOO_MUCH; + } + + if (context->m_cost < 8 * context->lanes) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + /* Validate time cost */ + if (ARGON2_MIN_TIME > context->t_cost) { + return ARGON2_TIME_TOO_SMALL; + } + + if (ARGON2_MAX_TIME < context->t_cost) { + return ARGON2_TIME_TOO_LARGE; + } + + /* Validate lanes */ + if (ARGON2_MIN_LANES > context->lanes) { + return ARGON2_LANES_TOO_FEW; + } + + if (ARGON2_MAX_LANES < context->lanes) { + return ARGON2_LANES_TOO_MANY; + } + + /* Validate threads */ + if (ARGON2_MIN_THREADS > context->threads) { + return ARGON2_THREADS_TOO_FEW; + } + + if (ARGON2_MAX_THREADS < context->threads) { + return ARGON2_THREADS_TOO_MANY; + } + + if (NULL != context->allocate_cbk && NULL == context->free_cbk) { + return ARGON2_FREE_MEMORY_CBK_NULL; + } + + if (NULL == context->allocate_cbk && NULL != context->free_cbk) { + return ARGON2_ALLOCATE_MEMORY_CBK_NULL; + } + + return ARGON2_OK; +} + +ARGON2_PRIVATE +void _argon2_fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) { + uint32_t l; + /* Make the first and second block in each lane as G(H0||0||i) or + G(H0||1||i) */ + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + for (l = 0; l < instance->lanes; ++l) { + + _blake2b_store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); + _blake2b_store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + _argon2_load_block(&instance->memory[l * instance->lane_length + 0], + blockhash_bytes); + + _blake2b_store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + _argon2_load_block(&instance->memory[l * instance->lane_length + 1], + blockhash_bytes); + } + _argon2_clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); +} + +ARGON2_PRIVATE +void _argon2_initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type) { + blake2b_state BlakeHash; + uint8_t value[sizeof(uint32_t)]; + + if (NULL == context || NULL == blockhash) { + return; + } + + blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH); + + _blake2b_store32(&value, context->lanes); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + _blake2b_store32(&value, context->outlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + _blake2b_store32(&value, context->m_cost); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + _blake2b_store32(&value, context->t_cost); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + _blake2b_store32(&value, context->version); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + _blake2b_store32(&value, (uint32_t)type); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + _blake2b_store32(&value, context->pwdlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->pwd != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->pwd, + context->pwdlen); + + if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { + _argon2_secure_wipe_memory(context->pwd, context->pwdlen); + context->pwdlen = 0; + } + } + + _blake2b_store32(&value, context->saltlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->salt != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->salt, + context->saltlen); + } + + _blake2b_store32(&value, context->secretlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->secret != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->secret, + context->secretlen); + + if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { + _argon2_secure_wipe_memory(context->secret, context->secretlen); + context->secretlen = 0; + } + } + + _blake2b_store32(&value, context->adlen); + blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); + + if (context->ad != NULL) { + blake2b_update(&BlakeHash, (const uint8_t *)context->ad, + context->adlen); + } + + blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH); +} + +ARGON2_PRIVATE +int _argon2_initialize(argon2_instance_t *instance, argon2_context *context) { + uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; + int result = ARGON2_OK; + + if (instance == NULL || context == NULL) + return ARGON2_INCORRECT_PARAMETER; + instance->context_ptr = context; + + /* 1. Memory allocation */ + result = _argon2_allocate_memory(context, (uint8_t **)&(instance->memory), + instance->memory_blocks, sizeof(block)); + if (result != ARGON2_OK) { + return result; + } + + /* 2. Initial hashing */ + /* H_0 + 8 extra bytes to produce the first blocks */ + /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */ + /* Hashing all inputs */ + _argon2_initial_hash(blockhash, context, instance->type); + /* Zeroing 8 extra bytes */ + _argon2_clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, + ARGON2_PREHASH_SEED_LENGTH - + ARGON2_PREHASH_DIGEST_LENGTH); + +#ifdef GENKAT + initial_kat(blockhash, context, instance->type); +#endif + + /* 3. Creating first blocks, we always have at least two blocks in a slice + */ + _argon2_fill_first_blocks(blockhash, instance); + /* Clearing the hash */ + _argon2_clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH); + + return ARGON2_OK; +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/core.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/core.h new file mode 100644 index 0000000000..28d18f9099 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/core.h @@ -0,0 +1,243 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_CORE_H +#define ARGON2_CORE_H + +#include "argon2.h" + +#define CONST_CAST(x) (x)(uintptr_t) + +/**********************Argon2 internal constants*******************************/ + +enum argon2_core_constants { + /* Memory block size in bytes */ + ARGON2_BLOCK_SIZE = 1024, + ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, + ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, + ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, + ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, + + /* Number of pseudo-random values generated by one call to Blake in Argon2i + to + generate reference block positions */ + ARGON2_ADDRESSES_IN_BLOCK = 128, + + /* Pre-hashing digest length and its extension*/ + ARGON2_PREHASH_DIGEST_LENGTH = 64, + ARGON2_PREHASH_SEED_LENGTH = 72 +}; + +/*************************Argon2 internal data types***********************/ + +/* + * Structure for the (1KB) memory block implemented as 128 64-bit words. + * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no + * bounds checking). + */ +typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block; + +/*****************Functions that work with the block******************/ + +/* Initialize each byte of the block with @in */ +ARGON2_PRIVATE +void _argon2_init_block_value(block *b, uint8_t in); + +/* Copy block @src to block @dst */ +ARGON2_PRIVATE +void _argon2_copy_block(block *dst, const block *src); + +/* XOR @src onto @dst bytewise */ +ARGON2_PRIVATE +void _argon2_xor_block(block *dst, const block *src); + +/* + * Argon2 instance: memory pointer, number of passes, amount of memory, type, + * and derived values. + * Used to evaluate the number and location of blocks to construct in each + * thread + */ +typedef struct Argon2_instance_t { + block *memory; /* Memory pointer */ + uint32_t version; + uint32_t passes; /* Number of passes */ + uint32_t memory_blocks; /* Number of blocks in memory */ + uint32_t segment_length; + uint32_t lane_length; + uint32_t lanes; + uint32_t threads; + argon2_type type; + int print_internals; /* whether to print the memory blocks */ + argon2_context *context_ptr; /* points back to original context */ +} argon2_instance_t; + +/* + * Argon2 position: where we construct the block right now. Used to distribute + * work between threads. + */ +typedef struct Argon2_position_t { + uint32_t pass; + uint32_t lane; + uint8_t slice; + uint32_t index; +} argon2_position_t; + +/*Struct that holds the inputs for thread handling FillSegment*/ +typedef struct Argon2_thread_data { + argon2_instance_t *instance_ptr; + argon2_position_t pos; +} argon2_thread_data; + +/*************************Argon2 core functions********************************/ + +/* Allocates memory to the given pointer, uses the appropriate allocator as + * specified in the context. Total allocated memory is num*size. + * @param context argon2_context which specifies the allocator + * @param memory pointer to the pointer to the memory + * @param size the size in bytes for each element to be allocated + * @param num the number of elements to be allocated + * @return ARGON2_OK if @memory is a valid pointer and memory is allocated + */ +ARGON2_PRIVATE +int _argon2_allocate_memory(const argon2_context *context, uint8_t **memory, + size_t num, size_t size); + +/* + * Frees memory at the given pointer, uses the appropriate deallocator as + * specified in the context. Also cleans the memory using clear_internal_memory. + * @param context argon2_context which specifies the deallocator + * @param memory pointer to buffer to be freed + * @param size the size in bytes for each element to be deallocated + * @param num the number of elements to be deallocated + */ +ARGON2_PRIVATE +void _argon2_free_memory(const argon2_context *context, uint8_t *memory, + size_t num, size_t size); + +/* Function that securely cleans the memory. This ignores any flags set + * regarding clearing memory. Usually one just calls clear_internal_memory. + * @param mem Pointer to the memory + * @param s Memory size in bytes + */ +ARGON2_PRIVATE +void _argon2_secure_wipe_memory(void *v, size_t n); + +/* Function that securely clears the memory if FLAG_clear_internal_memory is + * set. If the flag isn't set, this function does nothing. + * @param mem Pointer to the memory + * @param s Memory size in bytes + */ +ARGON2_PRIVATE +void _argon2_clear_internal_memory(void *v, size_t n); + +/* + * Computes absolute position of reference block in the lane following a skewed + * distribution and using a pseudo-random value as input + * @param instance Pointer to the current instance + * @param position Pointer to the current position + * @param pseudo_rand 32-bit pseudo-random value used to determine the position + * @param same_lane Indicates if the block will be taken from the current lane. + * If so we can reference the current segment + * @pre All pointers must be valid + */ +ARGON2_PRIVATE +uint32_t _argon2_index_alpha(const argon2_instance_t *instance, + const argon2_position_t *position, uint32_t pseudo_rand, + int same_lane); + +/* + * Function that validates all inputs against predefined restrictions and return + * an error code + * @param context Pointer to current Argon2 context + * @return ARGON2_OK if everything is all right, otherwise one of error codes + * (all defined in + */ +ARGON2_PRIVATE +int _argon2_validate_inputs(const argon2_context *context); + +/* + * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears + * password and secret if needed + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param blockhash Buffer for pre-hashing digest + * @param type Argon2 type + * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes + * allocated + */ +ARGON2_PRIVATE +void _argon2_initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type); + +/* + * Function creates first 2 blocks per lane + * @param instance Pointer to the current instance + * @param blockhash Pointer to the pre-hashing digest + * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values + */ +ARGON2_PRIVATE +void _argon2_fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); + +/* + * Function allocates memory, hashes the inputs with Blake, and creates first + * two blocks. Returns the pointer to the main memory with 2 blocks per lane + * initialized + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param instance Current Argon2 instance + * @return Zero if successful, -1 if memory failed to allocate. @context->state + * will be modified if successful. + */ +ARGON2_PRIVATE +int _argon2_initialize(argon2_instance_t *instance, argon2_context *context); + +/* + * XORing the last block of each lane, hashing it, making the tag. Deallocates + * the memory. + * @param context Pointer to current Argon2 context (use only the out parameters + * from it) + * @param instance Pointer to current instance of Argon2 + * @pre instance->state must point to necessary amount of memory + * @pre context->out must point to outlen bytes of memory + * @pre if context->free_cbk is not NULL, it should point to a function that + * deallocates memory + */ +ARGON2_PRIVATE +void _argon2_finalize(const argon2_context *context, argon2_instance_t *instance); + +/* + * Function that fills the segment using previous segments also from other + * threads + * @param context current context + * @param instance Pointer to the current instance + * @param position Current position + * @pre all block pointers must be valid + */ +ARGON2_PRIVATE +void _argon2_fill_segment(const argon2_instance_t *instance, + argon2_position_t position); + +/* + * Function that fills the entire memory t_cost times based on the first two + * blocks in each lane + * @param instance Pointer to the current instance + * @return ARGON2_OK if successful, @context->state + */ +ARGON2_PRIVATE +int _argon2_fill_memory_blocks(argon2_instance_t *instance); + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/encoding.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/encoding.c new file mode 100644 index 0000000000..57e8536a55 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/encoding.c @@ -0,0 +1,468 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include +#include +#include "encoding.h" +#include "core.h" + +/* + * Example code for a decoder and encoder of "hash strings", with Argon2 + * parameters. + * + * This code comprises three sections: + * + * -- The first section contains generic Base64 encoding and decoding + * functions. It is conceptually applicable to any hash function + * implementation that uses Base64 to encode and decode parameters, + * salts and outputs. It could be made into a library, provided that + * the relevant functions are made public (non-static) and be given + * reasonable names to avoid collisions with other functions. + * + * -- The second section is specific to Argon2. It encodes and decodes + * the parameters, salts and outputs. It does not compute the hash + * itself. + * + * The code was originally written by Thomas Pornin , + * to whom comments and remarks may be sent. It is released under what + * should amount to Public Domain or its closest equivalent; the + * following mantra is supposed to incarnate that fact with all the + * proper legal rituals: + * + * --------------------------------------------------------------------- + * This file is provided under the terms of Creative Commons CC0 1.0 + * Public Domain Dedication. To the extent possible under law, the + * author (Thomas Pornin) has waived all copyright and related or + * neighboring rights to this file. This work is published from: Canada. + * --------------------------------------------------------------------- + * + * Copyright (c) 2015 Thomas Pornin + */ + +/* ==================================================================== */ +/* + * Common code; could be shared between different hash functions. + * + * Note: the Base64 functions below assume that uppercase letters (resp. + * lowercase letters) have consecutive numerical codes, that fit on 8 + * bits. All modern systems use ASCII-compatible charsets, where these + * properties are true. If you are stuck with a dinosaur of a system + * that still defaults to EBCDIC then you already have much bigger + * interoperability issues to deal with. + */ + +/* + * Some macros for constant-time comparisons. These work over values in + * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true". + */ +#define ARGON2_EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF) +#define ARGON2_GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF) +#define ARGON2_GE(x, y) (ARGON2_GT(y, x) ^ 0xFF) +#define ARGON2_LT(x, y) ARGON2_GT(y, x) +#define ARGON2_LE(x, y) ARGON2_GE(y, x) + +/* + * Convert value x (0..63) to corresponding Base64 character. + */ +static int _argon2_b64_byte_to_char(unsigned x) { + return (ARGON2_LT(x, 26) & (x + 'A')) | + (ARGON2_GE(x, 26) & ARGON2_LT(x, 52) & (x + ('a' - 26))) | + (ARGON2_GE(x, 52) & ARGON2_LT(x, 62) & (x + ('0' - 52))) | (ARGON2_EQ(x, 62) & '+') | + (ARGON2_EQ(x, 63) & '/'); +} + +/* + * Convert character c to the corresponding 6-bit value. If character c + * is not a Base64 character, then 0xFF (255) is returned. + */ +static unsigned _argon2_b64_char_to_byte(int c) { + unsigned x; + + x = (ARGON2_GE(c, 'A') & ARGON2_LE(c, 'Z') & (c - 'A')) | + (ARGON2_GE(c, 'a') & ARGON2_LE(c, 'z') & (c - ('a' - 26))) | + (ARGON2_GE(c, '0') & ARGON2_LE(c, '9') & (c - ('0' - 52))) | (ARGON2_EQ(c, '+') & 62) | + (ARGON2_EQ(c, '/') & 63); + return x | (ARGON2_EQ(x, 0) & (ARGON2_EQ(c, 'A') ^ 0xFF)); +} + +/* + * Convert some bytes to Base64. 'dst_len' is the length (in characters) + * of the output buffer 'dst'; if that buffer is not large enough to + * receive the result (including the terminating 0), then (size_t)-1 + * is returned. Otherwise, the zero-terminated Base64 string is written + * in the buffer, and the output length (counted WITHOUT the terminating + * zero) is returned. + */ +static size_t _argon2_to_base64(char *dst, size_t dst_len, const void *src, + size_t src_len) { + size_t olen; + const unsigned char *buf; + unsigned acc, acc_len; + + olen = (src_len / 3) << 2; + switch (src_len % 3) { + case 2: + olen++; + /* fall through */ + case 1: + olen += 2; + break; + } + if (dst_len <= olen) { + return (size_t)-1; + } + acc = 0; + acc_len = 0; + buf = (const unsigned char *)src; + while (src_len-- > 0) { + acc = (acc << 8) + (*buf++); + acc_len += 8; + while (acc_len >= 6) { + acc_len -= 6; + *dst++ = (char)_argon2_b64_byte_to_char((acc >> acc_len) & 0x3F); + } + } + if (acc_len > 0) { + *dst++ = (char)_argon2_b64_byte_to_char((acc << (6 - acc_len)) & 0x3F); + } + *dst++ = 0; + return olen; +} + +/* + * Decode Base64 chars into bytes. The '*dst_len' value must initially + * contain the length of the output buffer '*dst'; when the decoding + * ends, the actual number of decoded bytes is written back in + * '*dst_len'. + * + * Decoding stops when a non-Base64 character is encountered, or when + * the output buffer capacity is exceeded. If an error occurred (output + * buffer is too small, invalid last characters leading to unprocessed + * buffered bits), then NULL is returned; otherwise, the returned value + * points to the first non-Base64 character in the source stream, which + * may be the terminating zero. + */ +static const char *_argon2_from_base64(void *dst, size_t *dst_len, const char *src) { + size_t len; + unsigned char *buf; + unsigned acc, acc_len; + + buf = (unsigned char *)dst; + len = 0; + acc = 0; + acc_len = 0; + for (;;) { + unsigned d; + + d = _argon2_b64_char_to_byte(*src); + if (d == 0xFF) { + break; + } + src++; + acc = (acc << 6) + d; + acc_len += 6; + if (acc_len >= 8) { + acc_len -= 8; + if ((len++) >= *dst_len) { + return NULL; + } + *buf++ = (acc >> acc_len) & 0xFF; + } + } + + /* + * If the input length is equal to 1 modulo 4 (which is + * invalid), then there will remain 6 unprocessed bits; + * otherwise, only 0, 2 or 4 bits are buffered. The buffered + * bits must also all be zero. + */ + if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) { + return NULL; + } + *dst_len = len; + return src; +} + +/* + * Decode decimal integer from 'str'; the value is written in '*v'. + * Returned value is a pointer to the next non-decimal character in the + * string. If there is no digit at all, or the value encoding is not + * minimal (extra leading zeros), or the value does not fit in an + * 'unsigned long', then NULL is returned. + */ +static const char *_argon2_decode_decimal(const char *str, unsigned long *v) { + const char *orig; + unsigned long acc; + + acc = 0; + for (orig = str;; str++) { + int c; + + c = *str; + if (c < '0' || c > '9') { + break; + } + c -= '0'; + if (acc > (ULONG_MAX / 10)) { + return NULL; + } + acc *= 10; + if ((unsigned long)c > (ULONG_MAX - acc)) { + return NULL; + } + acc += (unsigned long)c; + } + if (str == orig || (*orig == '0' && str != (orig + 1))) { + return NULL; + } + *v = acc; + return str; +} + +/* ==================================================================== */ +/* + * Code specific to Argon2. + * + * The code below applies the following format: + * + * $argon2[$v=]$m=,t=,p=$$ + * + * where is either 'd', 'id', or 'i', is a decimal integer (positive, + * fits in an 'unsigned long'), and is Base64-encoded data (no '=' padding + * characters, no newline or whitespace). + * + * The last two binary chunks (encoded in Base64) are, in that order, + * the salt and the output. Both are required. The binary salt length and the + * output length must be in the allowed ranges defined in argon2.h. + * + * The ctx struct must contain buffers large enough to hold the salt and pwd + * when it is fed into decode_string. + */ + +ARGON2_PRIVATE +int _argon2_decode_string(argon2_context *ctx, const char *str, argon2_type type) { + +/* check for prefix */ +#define ARGON2_CC(prefix) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) != 0) { \ + return ARGON2_DECODING_FAIL; \ + } \ + str += cc_len; \ + } while ((void)0, 0) + +/* optional prefix checking with supplied code */ +#define ARGON2_CC_opt(prefix, code) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) == 0) { \ + str += cc_len; \ + { code; } \ + } \ + } while ((void)0, 0) + +/* Decoding prefix into decimal */ +#define ARGON2_DECIMAL(x) \ + do { \ + unsigned long dec_x; \ + str = _argon2_decode_decimal(str, &dec_x); \ + if (str == NULL) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = dec_x; \ + } while ((void)0, 0) + + +/* Decoding prefix into uint32_t decimal */ +#define ARGON2_DECIMAL_U32(x) \ + do { \ + unsigned long dec_x; \ + str = _argon2_decode_decimal(str, &dec_x); \ + if (str == NULL || dec_x > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = (uint32_t)dec_x; \ + } while ((void)0, 0) + + +/* Decoding base64 into a binary buffer */ +#define ARGON2_BIN(buf, max_len, len) \ + do { \ + size_t bin_len = (max_len); \ + str = _argon2_from_base64(buf, &bin_len, str); \ + if (str == NULL || bin_len > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (len) = (uint32_t)bin_len; \ + } while ((void)0, 0) + + size_t maxsaltlen = ctx->saltlen; + size_t maxoutlen = ctx->outlen; + int validation_result; + const char* type_string; + + /* We should start with the argon2_type we are using */ + type_string = argon2_type2string(type, 0); + if (!type_string) { + return ARGON2_INCORRECT_TYPE; + } + + ARGON2_CC("$"); + ARGON2_CC(type_string); + + /* Reading the version number if the default is suppressed */ + ctx->version = ARGON2_VERSION_10; + ARGON2_CC_opt("$v=", ARGON2_DECIMAL_U32(ctx->version)); + + ARGON2_CC("$m="); + ARGON2_DECIMAL_U32(ctx->m_cost); + ARGON2_CC(",t="); + ARGON2_DECIMAL_U32(ctx->t_cost); + ARGON2_CC(",p="); + ARGON2_DECIMAL_U32(ctx->lanes); + ctx->threads = ctx->lanes; + + ARGON2_CC("$"); + ARGON2_BIN(ctx->salt, maxsaltlen, ctx->saltlen); + ARGON2_CC("$"); + ARGON2_BIN(ctx->out, maxoutlen, ctx->outlen); + + /* The rest of the fields get the default values */ + ctx->secret = NULL; + ctx->secretlen = 0; + ctx->ad = NULL; + ctx->adlen = 0; + ctx->allocate_cbk = NULL; + ctx->free_cbk = NULL; + ctx->flags = ARGON2_DEFAULT_FLAGS; + + /* On return, must have valid context */ + validation_result = _argon2_validate_inputs(ctx); + if (validation_result != ARGON2_OK) { + return validation_result; + } + + /* Can't have any additional characters */ + if (*str == 0) { + return ARGON2_OK; + } else { + return ARGON2_DECODING_FAIL; + } +#undef ARGON2_CC +#undef ARGON2_CC_opt +#undef ARGON2_DECIMAL +#undef ARGON2_DECIMAL_U32 +#undef ARGON2_BIN +} + +ARGON2_PRIVATE +int _argon2_encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type) { +#define ARGON2_SS(str) \ + do { \ + size_t pp_len = strlen(str); \ + if (pp_len >= dst_len) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + memcpy(dst, str, pp_len + 1); \ + dst += pp_len; \ + dst_len -= pp_len; \ + } while ((void)0, 0) + +#define ARGON2_SX(x) \ + do { \ + char tmp[30]; \ + sprintf(tmp, "%lu", (unsigned long)(x)); \ + ARGON2_SS(tmp); \ + } while ((void)0, 0) + +#define ARGON2_SB(buf, len) \ + do { \ + size_t sb_len = _argon2_to_base64(dst, dst_len, buf, len); \ + if (sb_len == (size_t)-1) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + dst += sb_len; \ + dst_len -= sb_len; \ + } while ((void)0, 0) + + const char* type_string = argon2_type2string(type, 0); + int validation_result = _argon2_validate_inputs(ctx); + + if (!type_string) { + return ARGON2_ENCODING_FAIL; + } + + if (validation_result != ARGON2_OK) { + return validation_result; + } + + + ARGON2_SS("$"); + ARGON2_SS(type_string); + + ARGON2_SS("$v="); + ARGON2_SX(ctx->version); + + ARGON2_SS("$m="); + ARGON2_SX(ctx->m_cost); + ARGON2_SS(",t="); + ARGON2_SX(ctx->t_cost); + ARGON2_SS(",p="); + ARGON2_SX(ctx->lanes); + + ARGON2_SS("$"); + ARGON2_SB(ctx->salt, ctx->saltlen); + + ARGON2_SS("$"); + ARGON2_SB(ctx->out, ctx->outlen); + return ARGON2_OK; + +#undef ARGON2_SS +#undef ARGON2_SX +#undef ARGON2_SB +} + +ARGON2_PRIVATE +size_t _argon2_b64len(uint32_t len) { + size_t olen = ((size_t)len / 3) << 2; + + switch (len % 3) { + case 2: + olen++; + /* fall through */ + case 1: + olen += 2; + break; + } + + return olen; +} + +ARGON2_PRIVATE +size_t _argon2_numlen(uint32_t num) { + size_t len = 1; + while (num >= 10) { + ++len; + num = num / 10; + } + return len; +} + diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/encoding.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/encoding.h new file mode 100644 index 0000000000..8b70cfc61f --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/encoding.h @@ -0,0 +1,61 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_ENCODING_H +#define ARGON2_ENCODING_H +#include "argon2.h" + +#define ARGON2_MAX_DECODED_LANES UINT32_C(255) +#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8) +#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12) + +/* +* encode an Argon2 hash string into the provided buffer. 'dst_len' +* contains the size, in characters, of the 'dst' buffer; if 'dst_len' +* is less than the number of required characters (including the +* terminating 0), then this function returns ARGON2_ENCODING_ERROR. +* +* on success, ARGON2_OK is returned. +*/ +ARGON2_PRIVATE +int _argon2_encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type); + +/* +* Decodes an Argon2 hash string into the provided structure 'ctx'. +* The only fields that must be set prior to this call are ctx.saltlen and +* ctx.outlen (which must be the maximal salt and out length values that are +* allowed), ctx.salt and ctx.out (which must be buffers of the specified +* length), and ctx.pwd and ctx.pwdlen which must hold a valid password. +* +* Invalid input string causes an error. On success, the ctx is valid and all +* fields have been initialized. +* +* Returned value is ARGON2_OK on success, other ARGON2_ codes on error. +*/ +ARGON2_PRIVATE +int _argon2_decode_string(argon2_context *ctx, const char *str, argon2_type type); + +/* Returns the length of the encoded byte stream with length len */ +ARGON2_PRIVATE +size_t _argon2_b64len(uint32_t len); + +/* Returns the length of the encoded number num */ +ARGON2_PRIVATE +size_t _argon2_numlen(uint32_t num); + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/genkat.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/genkat.c new file mode 100644 index 0000000000..dbbc072964 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/genkat.c @@ -0,0 +1,213 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include +#include "argon2.h" +#include "core.h" +#ifdef __MINGW32__ +#include +#else +/* Don't use (it's not C89) */ +#define PRIx64 "llx" +#endif + +void initial_kat(const uint8_t *blockhash, const argon2_context *context, + argon2_type type) { + unsigned i; + + if (blockhash != NULL && context != NULL) { + printf("=======================================\n"); + + printf("%s version number %d\n", argon2_type2string(type, 1), + context->version); + + printf("=======================================\n"); + + + printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag " + "length: %u bytes\n", + context->m_cost, context->t_cost, context->lanes, + context->outlen); + + printf("Password[%u]: ", context->pwdlen); + + if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { + printf("CLEARED\n"); + } else { + for (i = 0; i < context->pwdlen; ++i) { + printf("%2.2x ", ((unsigned char *)context->pwd)[i]); + } + + printf("\n"); + } + + printf("Salt[%u]: ", context->saltlen); + + for (i = 0; i < context->saltlen; ++i) { + printf("%2.2x ", ((unsigned char *)context->salt)[i]); + } + + printf("\n"); + + printf("Secret[%u]: ", context->secretlen); + + if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { + printf("CLEARED\n"); + } else { + for (i = 0; i < context->secretlen; ++i) { + printf("%2.2x ", ((unsigned char *)context->secret)[i]); + } + + printf("\n"); + } + + printf("Associated data[%u]: ", context->adlen); + + for (i = 0; i < context->adlen; ++i) { + printf("%2.2x ", ((unsigned char *)context->ad)[i]); + } + + printf("\n"); + + printf("Pre-hashing digest: "); + + for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) { + printf("%2.2x ", ((unsigned char *)blockhash)[i]); + } + + printf("\n"); + } +} + +void print_tag(const void *out, uint32_t outlen) { + unsigned i; + if (out != NULL) { + printf("Tag: "); + + for (i = 0; i < outlen; ++i) { + printf("%2.2x ", ((uint8_t *)out)[i]); + } + + printf("\n"); + } +} + +void internal_kat(const argon2_instance_t *instance, uint32_t pass) { + + if (instance != NULL) { + uint32_t i, j; + printf("\n After pass %u:\n", pass); + + for (i = 0; i < instance->memory_blocks; ++i) { + uint32_t how_many_words = + (instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK) + ? 1 + : ARGON2_QWORDS_IN_BLOCK; + + for (j = 0; j < how_many_words; ++j) + printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j, + (unsigned long long)instance->memory[i].v[j]); + } + } +} + +static void fatal(const char *error) { + fprintf(stderr, "Error: %s\n", error); + exit(1); +} + +static void generate_testvectors(argon2_type type, const uint32_t version) { +#define TEST_OUTLEN 32 +#define TEST_PWDLEN 32 +#define TEST_SALTLEN 16 +#define TEST_SECRETLEN 8 +#define TEST_ADLEN 12 + argon2_context context; + + unsigned char out[TEST_OUTLEN]; + unsigned char pwd[TEST_PWDLEN]; + unsigned char salt[TEST_SALTLEN]; + unsigned char secret[TEST_SECRETLEN]; + unsigned char ad[TEST_ADLEN]; + const allocate_fptr myown_allocator = NULL; + const deallocate_fptr myown_deallocator = NULL; + + unsigned t_cost = 3; + unsigned m_cost = 32; + unsigned lanes = 4; + + memset(pwd, 1, TEST_OUTLEN); + memset(salt, 2, TEST_SALTLEN); + memset(secret, 3, TEST_SECRETLEN); + memset(ad, 4, TEST_ADLEN); + + context.out = out; + context.outlen = TEST_OUTLEN; + context.version = version; + context.pwd = pwd; + context.pwdlen = TEST_PWDLEN; + context.salt = salt; + context.saltlen = TEST_SALTLEN; + context.secret = secret; + context.secretlen = TEST_SECRETLEN; + context.ad = ad; + context.adlen = TEST_ADLEN; + context.t_cost = t_cost; + context.m_cost = m_cost; + context.lanes = lanes; + context.threads = lanes; + context.allocate_cbk = myown_allocator; + context.free_cbk = myown_deallocator; + context.flags = ARGON2_DEFAULT_FLAGS; + +#undef TEST_OUTLEN +#undef TEST_PWDLEN +#undef TEST_SALTLEN +#undef TEST_SECRETLEN +#undef TEST_ADLEN + + argon2_ctx(&context, type); +} + +int main(int argc, char *argv[]) { + /* Get and check Argon2 type */ + const char *type_str = (argc > 1) ? argv[1] : "i"; + argon2_type type = Argon2_i; + uint32_t version = ARGON2_VERSION_NUMBER; + if (!strcmp(type_str, "d")) { + type = Argon2_d; + } else if (!strcmp(type_str, "i")) { + type = Argon2_i; + } else if (!strcmp(type_str, "id")) { + type = Argon2_id; + } else { + fatal("wrong Argon2 type"); + } + + /* Get and check Argon2 version number */ + if (argc > 2) { + version = strtoul(argv[2], NULL, 10); + } + if (ARGON2_VERSION_10 != version && ARGON2_VERSION_NUMBER != version) { + fatal("wrong Argon2 version number"); + } + + generate_testvectors(type, version); + return ARGON2_OK; +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/genkat.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/genkat.h new file mode 100644 index 0000000000..3a7162a6b0 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/genkat.h @@ -0,0 +1,51 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_KAT_H +#define ARGON2_KAT_H + +#include "core.h" + +/* + * Initial KAT function that prints the inputs to the file + * @param blockhash Array that contains pre-hashing digest + * @param context Holds inputs + * @param type Argon2 type + * @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes + * @pre context member pointers must point to allocated memory of size according + * to the length values + */ +void initial_kat(const uint8_t *blockhash, const argon2_context *context, + argon2_type type); + +/* + * Function that prints the output tag + * @param out output array pointer + * @param outlen digest length + * @pre out must point to @a outlen bytes + **/ +void print_tag(const void *out, uint32_t outlen); + +/* + * Function that prints the internal state at given moment + * @param instance pointer to the current instance + * @param pass current pass number + * @pre instance must have necessary memory allocated + **/ +void internal_kat(const argon2_instance_t *instance, uint32_t pass); + +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/opt.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/opt.c new file mode 100644 index 0000000000..6c5e403fcf --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/opt.c @@ -0,0 +1,283 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "argon2.h" +#include "core.h" + +#include "blake2/blake2.h" +#include "blake2/blamka-round-opt.h" + +/* + * Function fills a new memory block and optionally XORs the old block over the new one. + * Memory must be initialized. + * @param state Pointer to the just produced block. Content will be updated(!) + * @param ref_block Pointer to the reference block + * @param next_block Pointer to the block to be XORed over. May coincide with @ref_block + * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) + * @pre all block pointers must be valid + */ +#if defined(__AVX512F__) +static void fill_block(__m512i *state, const block *ref_block, + block *next_block, int with_xor) { + __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i)); + block_XY[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i)); + } + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_1( + state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3], + state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_2( + state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i], + state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]); + } + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512(state[i], block_XY[i]); + _mm512_storeu_si512((__m512i *)next_block->v + i, state[i]); + } +} +#elif defined(__AVX2__) +static void fill_block(__m256i *state, const block *ref_block, + block *next_block, int with_xor) { + __m256i block_XY[ARGON2_HWORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i)); + block_XY[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i)); + } + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5], + state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i], + state[16 + i], state[20 + i], state[24 + i], state[28 + i]); + } + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256(state[i], block_XY[i]); + _mm256_storeu_si256((__m256i *)next_block->v + i, state[i]); + } +} +#else +static void fill_block(__m128i *state, const block *ref_block, + block *next_block, int with_xor) { + __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; + unsigned int i; + + if (with_xor) { + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i)); + block_XY[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)next_block->v + i)); + } + } else { + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i)); + } + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], + state[8 * i + 3], state[8 * i + 4], state[8 * i + 5], + state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i], + state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i], + state[8 * 6 + i], state[8 * 7 + i]); + } + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128(state[i], block_XY[i]); + _mm_storeu_si128((__m128i *)next_block->v + i, state[i]); + } +} +#endif + +static void next_addresses(block *address_block, block *input_block) { + /*Temporary zero-initialized blocks*/ +#if defined(__AVX512F__) + __m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK]; + __m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK]; +#elif defined(__AVX2__) + __m256i zero_block[ARGON2_HWORDS_IN_BLOCK]; + __m256i zero2_block[ARGON2_HWORDS_IN_BLOCK]; +#else + __m128i zero_block[ARGON2_OWORDS_IN_BLOCK]; + __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK]; +#endif + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + + /*Increasing index counter*/ + input_block->v[6]++; + + /*First iteration of G*/ + fill_block(zero_block, input_block, address_block, 0); + + /*Second iteration of G*/ + fill_block(zero2_block, address_block, address_block, 0); +} + +void fill_segment(const argon2_instance_t *instance, + argon2_position_t position) { + block *ref_block = NULL, *curr_block = NULL; + block address_block, input_block; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; +#if defined(__AVX512F__) + __m512i state[ARGON2_512BIT_WORDS_IN_BLOCK]; +#elif defined(__AVX2__) + __m256i state[ARGON2_HWORDS_IN_BLOCK]; +#else + __m128i state[ARGON2_OWORDS_IN_BLOCK]; +#endif + int data_independent_addressing; + + if (instance == NULL) { + return; + } + + data_independent_addressing = + (instance->type == Argon2_i) || + (instance->type == Argon2_id && (position.pass == 0) && + (position.slice < ARGON2_SYNC_POINTS / 2)); + + if (data_independent_addressing) { + init_block_value(&input_block, 0); + + input_block.v[0] = position.pass; + input_block.v[1] = position.lane; + input_block.v[2] = position.slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + + /* Don't forget to generate the first block of addresses: */ + if (data_independent_addressing) { + next_addresses(&address_block, &input_block); + } + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + next_addresses(&address_block, &input_block); + } + pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } else { + pseudo_rand = instance->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = + instance->memory + instance->lane_length * ref_lane + ref_index; + curr_block = instance->memory + curr_offset; + if (ARGON2_VERSION_10 == instance->version) { + /* version 1.2.1 and earlier: overwrite, not XOR */ + fill_block(state, ref_block, curr_block, 0); + } else { + if(0 == position.pass) { + fill_block(state, ref_block, curr_block, 0); + } else { + fill_block(state, ref_block, curr_block, 1); + } + } + } +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/ref.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/ref.c new file mode 100644 index 0000000000..37a7033e75 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/ref.c @@ -0,0 +1,195 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include + +#include "argon2.h" +#include "core.h" + +#include "blake2/blamka-round-ref.h" +#include "blake2/blake2-impl.h" +#include "blake2/blake2.h" + + +/* + * Function fills a new memory block and optionally XORs the old block over the new one. + * @next_block must be initialized. + * @param prev_block Pointer to the previous block + * @param ref_block Pointer to the reference block + * @param next_block Pointer to the block to be constructed + * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) + * @pre all block pointers must be valid + */ +static void _argon2_fill_block(const block *prev_block, const block *ref_block, + block *next_block, int with_xor) { + block blockR, block_tmp; + unsigned i; + + _argon2_copy_block(&blockR, ref_block); + _argon2_xor_block(&blockR, prev_block); + _argon2_copy_block(&block_tmp, &blockR); + /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */ + if (with_xor) { + /* Saving the next block contents for XOR over: */ + _argon2_xor_block(&block_tmp, next_block); + /* Now blockR = ref_block + prev_block and + block_tmp = ref_block + prev_block + next_block */ + } + + /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then + (16,17,..31)... finally (112,113,...127) */ + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND_NOMSG( + blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], + blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], + blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], + blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], + blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], + blockR.v[16 * i + 15]); + } + + /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then + (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ + for (i = 0; i < 8; i++) { + BLAKE2_ROUND_NOMSG( + blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], + blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], + blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], + blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], + blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], + blockR.v[2 * i + 113]); + } + + _argon2_copy_block(next_block, &block_tmp); + _argon2_xor_block(next_block, &blockR); +} + +static void _argon2_next_addresses(block *address_block, block *input_block, + const block *zero_block) { + input_block->v[6]++; + _argon2_fill_block(zero_block, input_block, address_block, 0); + _argon2_fill_block(zero_block, address_block, address_block, 0); +} + +ARGON2_PRIVATE +void _argon2_fill_segment(const argon2_instance_t *instance, + argon2_position_t position) { + block *ref_block = NULL, *curr_block = NULL; + block address_block, input_block, zero_block; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index; + uint32_t i; + int data_independent_addressing; + + if (instance == NULL) { + return; + } + + data_independent_addressing = + (instance->type == Argon2_i) || + (instance->type == Argon2_id && (position.pass == 0) && + (position.slice < ARGON2_SYNC_POINTS / 2)); + + if (data_independent_addressing) { + _argon2_init_block_value(&zero_block, 0); + _argon2_init_block_value(&input_block, 0); + + input_block.v[0] = position.pass; + input_block.v[1] = position.lane; + input_block.v[2] = position.slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + + /* Don't forget to generate the first block of addresses: */ + if (data_independent_addressing) { + _argon2_next_addresses(&address_block, &input_block, &zero_block); + } + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + _argon2_next_addresses(&address_block, &input_block, &zero_block); + } + pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } else { + pseudo_rand = instance->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = _argon2_index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = + instance->memory + instance->lane_length * ref_lane + ref_index; + curr_block = instance->memory + curr_offset; + if (ARGON2_VERSION_10 == instance->version) { + /* version 1.2.1 and earlier: overwrite, not XOR */ + _argon2_fill_block(instance->memory + prev_offset, ref_block, curr_block, 0); + } else { + if(0 == position.pass) { + _argon2_fill_block(instance->memory + prev_offset, ref_block, + curr_block, 0); + } else { + _argon2_fill_block(instance->memory + prev_offset, ref_block, + curr_block, 1); + } + } + } +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/run.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/run.c new file mode 100644 index 0000000000..702b618e35 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/run.c @@ -0,0 +1,337 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#define _GNU_SOURCE 1 + +#include +#include +#include +#include +#include + +#include "argon2.h" +#include "core.h" + +#define T_COST_DEF 3 +#define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */ +#define LANES_DEF 1 +#define THREADS_DEF 1 +#define OUTLEN_DEF 32 +#define MAX_PASS_LEN 128 + +#define UNUSED_PARAMETER(x) (void)(x) + +static void usage(const char *cmd) { + printf("Usage: %s [-h] salt [-i|-d|-id] [-t iterations] " + "[-m log2(memory in KiB) | -k memory in KiB] [-p parallelism] " + "[-l hash length] [-e|-r] [-v (10|13)]\n", + cmd); + printf("\tPassword is read from stdin\n"); + printf("Parameters:\n"); + printf("\tsalt\t\tThe salt to use, at least 8 characters\n"); + printf("\t-i\t\tUse Argon2i (this is the default)\n"); + printf("\t-d\t\tUse Argon2d instead of Argon2i\n"); + printf("\t-id\t\tUse Argon2id instead of Argon2i\n"); + printf("\t-t N\t\tSets the number of iterations to N (default = %d)\n", + T_COST_DEF); + printf("\t-m N\t\tSets the memory usage of 2^N KiB (default %d)\n", + LOG_M_COST_DEF); + printf("\t-k N\t\tSets the memory usage of N KiB (default %d)\n", + 1 << LOG_M_COST_DEF); + printf("\t-p N\t\tSets parallelism to N threads (default %d)\n", + THREADS_DEF); + printf("\t-l N\t\tSets hash output length to N bytes (default %d)\n", + OUTLEN_DEF); + printf("\t-e\t\tOutput only encoded hash\n"); + printf("\t-r\t\tOutput only the raw bytes of the hash\n"); + printf("\t-v (10|13)\tArgon2 version (defaults to the most recent version, currently %x)\n", + ARGON2_VERSION_NUMBER); + printf("\t-h\t\tPrint %s usage\n", cmd); +} + +static void fatal(const char *error) { + fprintf(stderr, "Error: %s\n", error); + exit(1); +} + +static void print_hex(uint8_t *bytes, size_t bytes_len) { + size_t i; + for (i = 0; i < bytes_len; ++i) { + printf("%02x", bytes[i]); + } + printf("\n"); +} + +/* +Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the +Base64-encoded hash string +@out output array with at least 32 bytes allocated +@pwd NULL-terminated string, presumably from argv[] +@salt salt array +@t_cost number of iterations +@m_cost amount of requested memory in KB +@lanes amount of requested parallelism +@threads actual parallelism +@type Argon2 type we want to run +@encoded_only display only the encoded hash +@raw_only display only the hexadecimal of the hash +@version Argon2 version +*/ +static void run(uint32_t outlen, char *pwd, size_t pwdlen, char *salt, uint32_t t_cost, + uint32_t m_cost, uint32_t lanes, uint32_t threads, + argon2_type type, int encoded_only, int raw_only, uint32_t version) { + clock_t start_time, stop_time; + size_t saltlen, encodedlen; + int result; + unsigned char * out = NULL; + char * encoded = NULL; + + start_time = clock(); + + if (!pwd) { + fatal("password missing"); + } + + if (!salt) { + clear_internal_memory(pwd, pwdlen); + fatal("salt missing"); + } + + saltlen = strlen(salt); + if(UINT32_MAX < saltlen) { + fatal("salt is too long"); + } + + UNUSED_PARAMETER(lanes); + + out = malloc(outlen + 1); + if (!out) { + clear_internal_memory(pwd, pwdlen); + fatal("could not allocate memory for output"); + } + + encodedlen = argon2_encodedlen(t_cost, m_cost, lanes, (uint32_t)saltlen, outlen, type); + encoded = malloc(encodedlen + 1); + if (!encoded) { + clear_internal_memory(pwd, pwdlen); + fatal("could not allocate memory for hash"); + } + + result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen, + out, outlen, encoded, encodedlen, type, + version); + if (result != ARGON2_OK) + fatal(argon2_error_message(result)); + + stop_time = clock(); + + if (encoded_only) + puts(encoded); + + if (raw_only) + print_hex(out, outlen); + + if (encoded_only || raw_only) { + free(out); + free(encoded); + return; + } + + printf("Hash:\t\t"); + print_hex(out, outlen); + free(out); + + printf("Encoded:\t%s\n", encoded); + + printf("%2.3f seconds\n", + ((double)stop_time - start_time) / (CLOCKS_PER_SEC)); + + result = argon2_verify(encoded, pwd, pwdlen, type); + if (result != ARGON2_OK) + fatal(argon2_error_message(result)); + printf("Verification ok\n"); + free(encoded); +} + +int main(int argc, char *argv[]) { + uint32_t outlen = OUTLEN_DEF; + uint32_t m_cost = 1 << LOG_M_COST_DEF; + uint32_t t_cost = T_COST_DEF; + uint32_t lanes = LANES_DEF; + uint32_t threads = THREADS_DEF; + argon2_type type = Argon2_i; /* Argon2i is the default type */ + int types_specified = 0; + int m_cost_specified = 0; + int encoded_only = 0; + int raw_only = 0; + uint32_t version = ARGON2_VERSION_NUMBER; + int i; + size_t pwdlen; + char pwd[MAX_PASS_LEN], *salt; + + if (argc < 2) { + usage(argv[0]); + return ARGON2_MISSING_ARGS; + } else if (argc >= 2 && strcmp(argv[1], "-h") == 0) { + usage(argv[0]); + return 1; + } + + /* get password from stdin */ + pwdlen = fread(pwd, 1, sizeof pwd, stdin); + if(pwdlen < 1) { + fatal("no password read"); + } + if(pwdlen == MAX_PASS_LEN) { + fatal("Provided password longer than supported in command line utility"); + } + + salt = argv[1]; + + /* parse options */ + for (i = 2; i < argc; i++) { + const char *a = argv[i]; + unsigned long input = 0; + if (!strcmp(a, "-h")) { + usage(argv[0]); + return 1; + } else if (!strcmp(a, "-m")) { + if (m_cost_specified) { + fatal("-m or -k can only be used once"); + } + m_cost_specified = 1; + if (i < argc - 1) { + i++; + input = strtoul(argv[i], NULL, 10); + if (input == 0 || input == ULONG_MAX || + input > ARGON2_MAX_MEMORY_BITS) { + fatal("bad numeric input for -m"); + } + m_cost = ARGON2_MIN(UINT64_C(1) << input, UINT32_C(0xFFFFFFFF)); + if (m_cost > ARGON2_MAX_MEMORY) { + fatal("m_cost overflow"); + } + continue; + } else { + fatal("missing -m argument"); + } + } else if (!strcmp(a, "-k")) { + if (m_cost_specified) { + fatal("-m or -k can only be used once"); + } + m_cost_specified = 1; + if (i < argc - 1) { + i++; + input = strtoul(argv[i], NULL, 10); + if (input == 0 || input == ULONG_MAX) { + fatal("bad numeric input for -k"); + } + m_cost = ARGON2_MIN(input, UINT32_C(0xFFFFFFFF)); + if (m_cost > ARGON2_MAX_MEMORY) { + fatal("m_cost overflow"); + } + continue; + } else { + fatal("missing -k argument"); + } + } else if (!strcmp(a, "-t")) { + if (i < argc - 1) { + i++; + input = strtoul(argv[i], NULL, 10); + if (input == 0 || input == ULONG_MAX || + input > ARGON2_MAX_TIME) { + fatal("bad numeric input for -t"); + } + t_cost = input; + continue; + } else { + fatal("missing -t argument"); + } + } else if (!strcmp(a, "-p")) { + if (i < argc - 1) { + i++; + input = strtoul(argv[i], NULL, 10); + if (input == 0 || input == ULONG_MAX || + input > ARGON2_MAX_THREADS || input > ARGON2_MAX_LANES) { + fatal("bad numeric input for -p"); + } + threads = input; + lanes = threads; + continue; + } else { + fatal("missing -p argument"); + } + } else if (!strcmp(a, "-l")) { + if (i < argc - 1) { + i++; + input = strtoul(argv[i], NULL, 10); + outlen = input; + continue; + } else { + fatal("missing -l argument"); + } + } else if (!strcmp(a, "-i")) { + type = Argon2_i; + ++types_specified; + } else if (!strcmp(a, "-d")) { + type = Argon2_d; + ++types_specified; + } else if (!strcmp(a, "-id")) { + type = Argon2_id; + ++types_specified; + } else if (!strcmp(a, "-e")) { + encoded_only = 1; + } else if (!strcmp(a, "-r")) { + raw_only = 1; + } else if (!strcmp(a, "-v")) { + if (i < argc - 1) { + i++; + if (!strcmp(argv[i], "10")) { + version = ARGON2_VERSION_10; + } else if (!strcmp(argv[i], "13")) { + version = ARGON2_VERSION_13; + } else { + fatal("invalid Argon2 version"); + } + } else { + fatal("missing -v argument"); + } + } else { + fatal("unknown argument"); + } + } + + if (types_specified > 1) { + fatal("cannot specify multiple Argon2 types"); + } + + if(encoded_only && raw_only) + fatal("cannot provide both -e and -r"); + + if(!encoded_only && !raw_only) { + printf("Type:\t\t%s\n", argon2_type2string(type, 1)); + printf("Iterations:\t%u\n", t_cost); + printf("Memory:\t\t%u KiB\n", m_cost); + printf("Parallelism:\t%u\n", lanes); + } + + run(outlen, pwd, pwdlen, salt, t_cost, m_cost, lanes, threads, type, + encoded_only, raw_only, version); + + return ARGON2_OK; +} + diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/test.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/test.c new file mode 100644 index 0000000000..055c19a360 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/test.c @@ -0,0 +1,289 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#include +#include +#include +#include +#include +#include + +#include "argon2.h" + +#define OUT_LEN 32 +#define ENCODED_LEN 108 + +/* Test harness will assert: + * argon2_hash() returns ARGON2_OK + * HEX output matches expected + * encoded output matches expected + * argon2_verify() correctly verifies value + */ + +void hashtest(uint32_t version, uint32_t t, uint32_t m, uint32_t p, char *pwd, + char *salt, char *hexref, char *mcfref, argon2_type type) { + unsigned char out[OUT_LEN]; + unsigned char hex_out[OUT_LEN * 2 + 4]; + char encoded[ENCODED_LEN]; + int ret, i; + + printf("Hash test: $v=%d t=%d, m=%d, p=%d, pass=%s, salt=%s: ", version, + t, m, p, pwd, salt); + + ret = argon2_hash(t, 1 << m, p, pwd, strlen(pwd), salt, strlen(salt), out, + OUT_LEN, encoded, ENCODED_LEN, type, version); + assert(ret == ARGON2_OK); + + for (i = 0; i < OUT_LEN; ++i) + sprintf((char *)(hex_out + i * 2), "%02x", out[i]); + assert(memcmp(hex_out, hexref, OUT_LEN * 2) == 0); + + if (ARGON2_VERSION_NUMBER == version) { + assert(memcmp(encoded, mcfref, strlen(mcfref)) == 0); + } + + ret = argon2_verify(encoded, pwd, strlen(pwd), type); + assert(ret == ARGON2_OK); + ret = argon2_verify(mcfref, pwd, strlen(pwd), type); + assert(ret == ARGON2_OK); + + printf("PASS\n"); +} + +int main() { + int ret; + unsigned char out[OUT_LEN]; + char const *msg; + int version; + + version = ARGON2_VERSION_10; + printf("Test Argon2i version number: %02x\n", version); + + /* Multiple test cases for various input values */ + hashtest(version, 2, 16, 1, "password", "somesalt", + "f6c4db4a54e2a370627aff3db6176b94a2a209a62c8e36152711802f7b30c694", + "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" + "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", Argon2_i); +#ifdef TEST_LARGE_RAM + hashtest(version, 2, 20, 1, "password", "somesalt", + "9690ec55d28d3ed32562f2e73ea62b02b018757643a2ae6e79528459de8106e9", + "$argon2i$m=1048576,t=2,p=1$c29tZXNhbHQ" + "$lpDsVdKNPtMlYvLnPqYrArAYdXZDoq5ueVKEWd6BBuk", Argon2_i); +#endif + hashtest(version, 2, 18, 1, "password", "somesalt", + "3e689aaa3d28a77cf2bc72a51ac53166761751182f1ee292e3f677a7da4c2467", + "$argon2i$m=262144,t=2,p=1$c29tZXNhbHQ" + "$Pmiaqj0op3zyvHKlGsUxZnYXURgvHuKS4/Z3p9pMJGc", Argon2_i); + hashtest(version, 2, 8, 1, "password", "somesalt", + "fd4dd83d762c49bdeaf57c47bdcd0c2f1babf863fdeb490df63ede9975fccf06", + "$argon2i$m=256,t=2,p=1$c29tZXNhbHQ" + "$/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY", Argon2_i); + hashtest(version, 2, 8, 2, "password", "somesalt", + "b6c11560a6a9d61eac706b79a2f97d68b4463aa3ad87e00c07e2b01e90c564fb", + "$argon2i$m=256,t=2,p=2$c29tZXNhbHQ" + "$tsEVYKap1h6scGt5ovl9aLRGOqOth+AMB+KwHpDFZPs", Argon2_i); + hashtest(version, 1, 16, 1, "password", "somesalt", + "81630552b8f3b1f48cdb1992c4c678643d490b2b5eb4ff6c4b3438b5621724b2", + "$argon2i$m=65536,t=1,p=1$c29tZXNhbHQ" + "$gWMFUrjzsfSM2xmSxMZ4ZD1JCytetP9sSzQ4tWIXJLI", Argon2_i); + hashtest(version, 4, 16, 1, "password", "somesalt", + "f212f01615e6eb5d74734dc3ef40ade2d51d052468d8c69440a3a1f2c1c2847b", + "$argon2i$m=65536,t=4,p=1$c29tZXNhbHQ" + "$8hLwFhXm6110c03D70Ct4tUdBSRo2MaUQKOh8sHChHs", Argon2_i); + hashtest(version, 2, 16, 1, "differentpassword", "somesalt", + "e9c902074b6754531a3a0be519e5baf404b30ce69b3f01ac3bf21229960109a3", + "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" + "$6ckCB0tnVFMaOgvlGeW69ASzDOabPwGsO/ISKZYBCaM", Argon2_i); + hashtest(version, 2, 16, 1, "password", "diffsalt", + "79a103b90fe8aef8570cb31fc8b22259778916f8336b7bdac3892569d4f1c497", + "$argon2i$m=65536,t=2,p=1$ZGlmZnNhbHQ" + "$eaEDuQ/orvhXDLMfyLIiWXeJFvgza3vaw4kladTxxJc", Argon2_i); + + /* Error state tests */ + + /* Handle an invalid encoding correctly (it is missing a $) */ + ret = argon2_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ" + "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", strlen("password"), Argon2_i); + assert(ret == ARGON2_DECODING_FAIL); + printf("Recognise an invalid encoding: PASS\n"); + + /* Handle an invalid encoding correctly (it is missing a $) */ + ret = argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" + "9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", strlen("password"), Argon2_i); + assert(ret == ARGON2_DECODING_FAIL); + printf("Recognise an invalid encoding: PASS\n"); + + /* Handle an invalid encoding correctly (salt is too short) */ + ret = argon2_verify("$argon2i$m=65536,t=2,p=1$" + "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", strlen("password"), Argon2_i); + assert(ret == ARGON2_SALT_TOO_SHORT); + printf("Recognise an invalid salt in encoding: PASS\n"); + + /* Handle an mismatching hash (the encoded password is "passwore") */ + ret = argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" + "$b2G3seW+uPzerwQQC+/E1K50CLLO7YXy0JRcaTuswRo", + "password", strlen("password"), Argon2_i); + assert(ret == ARGON2_VERIFY_MISMATCH); + printf("Verify with mismatched password: PASS\n"); + + msg = argon2_error_message(ARGON2_DECODING_FAIL); + assert(strcmp(msg, "Decoding failed") == 0); + printf("Decode an error message: PASS\n"); + + printf("\n"); + + version = ARGON2_VERSION_NUMBER; + printf("Test Argon2i version number: %02x\n", version); + + /* Multiple test cases for various input values */ + hashtest(version, 2, 16, 1, "password", "somesalt", + "c1628832147d9720c5bd1cfd61367078729f6dfb6f8fea9ff98158e0d7816ed0", + "$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", Argon2_i); +#ifdef TEST_LARGE_RAM + hashtest(version, 2, 20, 1, "password", "somesalt", + "d1587aca0922c3b5d6a83edab31bee3c4ebaef342ed6127a55d19b2351ad1f41", + "$argon2i$v=19$m=1048576,t=2,p=1$c29tZXNhbHQ" + "$0Vh6ygkiw7XWqD7asxvuPE667zQu1hJ6VdGbI1GtH0E", Argon2_i); +#endif + hashtest(version, 2, 18, 1, "password", "somesalt", + "296dbae80b807cdceaad44ae741b506f14db0959267b183b118f9b24229bc7cb", + "$argon2i$v=19$m=262144,t=2,p=1$c29tZXNhbHQ" + "$KW266AuAfNzqrUSudBtQbxTbCVkmexg7EY+bJCKbx8s", Argon2_i); + hashtest(version, 2, 8, 1, "password", "somesalt", + "89e9029f4637b295beb027056a7336c414fadd43f6b208645281cb214a56452f", + "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ" + "$iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8", Argon2_i); + hashtest(version, 2, 8, 2, "password", "somesalt", + "4ff5ce2769a1d7f4c8a491df09d41a9fbe90e5eb02155a13e4c01e20cd4eab61", + "$argon2i$v=19$m=256,t=2,p=2$c29tZXNhbHQ" + "$T/XOJ2mh1/TIpJHfCdQan76Q5esCFVoT5MAeIM1Oq2E", Argon2_i); + hashtest(version, 1, 16, 1, "password", "somesalt", + "d168075c4d985e13ebeae560cf8b94c3b5d8a16c51916b6f4ac2da3ac11bbecf", + "$argon2i$v=19$m=65536,t=1,p=1$c29tZXNhbHQ" + "$0WgHXE2YXhPr6uVgz4uUw7XYoWxRkWtvSsLaOsEbvs8", Argon2_i); + hashtest(version, 4, 16, 1, "password", "somesalt", + "aaa953d58af3706ce3df1aefd4a64a84e31d7f54175231f1285259f88174ce5b", + "$argon2i$v=19$m=65536,t=4,p=1$c29tZXNhbHQ" + "$qqlT1YrzcGzj3xrv1KZKhOMdf1QXUjHxKFJZ+IF0zls", Argon2_i); + hashtest(version, 2, 16, 1, "differentpassword", "somesalt", + "14ae8da01afea8700c2358dcef7c5358d9021282bd88663a4562f59fb74d22ee", + "$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "$FK6NoBr+qHAMI1jc73xTWNkCEoK9iGY6RWL1n7dNIu4", Argon2_i); + hashtest(version, 2, 16, 1, "password", "diffsalt", + "b0357cccfbef91f3860b0dba447b2348cbefecadaf990abfe9cc40726c521271", + "$argon2i$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ" + "$sDV8zPvvkfOGCw26RHsjSMvv7K2vmQq/6cxAcmxSEnE", Argon2_i); + + + /* Error state tests */ + + /* Handle an invalid encoding correctly (it is missing a $) */ + ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1c29tZXNhbHQ" + "$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", + "password", strlen("password"), Argon2_i); + assert(ret == ARGON2_DECODING_FAIL); + printf("Recognise an invalid encoding: PASS\n"); + + /* Handle an invalid encoding correctly (it is missing a $) */ + ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", + "password", strlen("password"), Argon2_i); + assert(ret == ARGON2_DECODING_FAIL); + printf("Recognise an invalid encoding: PASS\n"); + + /* Handle an invalid encoding correctly (salt is too short) */ + ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$" + "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", strlen("password"), Argon2_i); + assert(ret == ARGON2_SALT_TOO_SHORT); + printf("Recognise an invalid salt in encoding: PASS\n"); + + /* Handle an mismatching hash (the encoded password is "passwore") */ + ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "$8iIuixkI73Js3G1uMbezQXD0b8LG4SXGsOwoQkdAQIM", + "password", strlen("password"), Argon2_i); + assert(ret == ARGON2_VERIFY_MISMATCH); + printf("Verify with mismatched password: PASS\n"); + + msg = argon2_error_message(ARGON2_DECODING_FAIL); + assert(strcmp(msg, "Decoding failed") == 0); + printf("Decode an error message: PASS\n\n"); + + printf("Test Argon2id version number: %02x\n", version); + + /* Multiple test cases for various input values */ + hashtest(version, 2, 16, 1, "password", "somesalt", + "09316115d5cf24ed5a15a31a3ba326e5cf32edc24702987c02b6566f61913cf7", + "$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "$CTFhFdXPJO1aFaMaO6Mm5c8y7cJHAph8ArZWb2GRPPc", Argon2_id); + hashtest(version, 2, 18, 1, "password", "somesalt", + "78fe1ec91fb3aa5657d72e710854e4c3d9b9198c742f9616c2f085bed95b2e8c", + "$argon2id$v=19$m=262144,t=2,p=1$c29tZXNhbHQ" + "$eP4eyR+zqlZX1y5xCFTkw9m5GYx0L5YWwvCFvtlbLow", Argon2_id); + hashtest(version, 2, 8, 1, "password", "somesalt", + "9dfeb910e80bad0311fee20f9c0e2b12c17987b4cac90c2ef54d5b3021c68bfe", + "$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ" + "$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4", Argon2_id); + hashtest(version, 2, 8, 2, "password", "somesalt", + "6d093c501fd5999645e0ea3bf620d7b8be7fd2db59c20d9fff9539da2bf57037", + "$argon2id$v=19$m=256,t=2,p=2$c29tZXNhbHQ" + "$bQk8UB/VmZZF4Oo79iDXuL5/0ttZwg2f/5U52iv1cDc", Argon2_id); + hashtest(version, 1, 16, 1, "password", "somesalt", + "f6a5adc1ba723dddef9b5ac1d464e180fcd9dffc9d1cbf76cca2fed795d9ca98", + "$argon2id$v=19$m=65536,t=1,p=1$c29tZXNhbHQ" + "$9qWtwbpyPd3vm1rB1GThgPzZ3/ydHL92zKL+15XZypg", Argon2_id); + hashtest(version, 4, 16, 1, "password", "somesalt", + "9025d48e68ef7395cca9079da4c4ec3affb3c8911fe4f86d1a2520856f63172c", + "$argon2id$v=19$m=65536,t=4,p=1$c29tZXNhbHQ" + "$kCXUjmjvc5XMqQedpMTsOv+zyJEf5PhtGiUghW9jFyw", Argon2_id); + hashtest(version, 2, 16, 1, "differentpassword", "somesalt", + "0b84d652cf6b0c4beaef0dfe278ba6a80df6696281d7e0d2891b817d8c458fde", + "$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "$C4TWUs9rDEvq7w3+J4umqA32aWKB1+DSiRuBfYxFj94", Argon2_id); + hashtest(version, 2, 16, 1, "password", "diffsalt", + "bdf32b05ccc42eb15d58fd19b1f856b113da1e9a5874fdcc544308565aa8141c", + "$argon2id$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ" + "$vfMrBczELrFdWP0ZsfhWsRPaHppYdP3MVEMIVlqoFBw", Argon2_id); + + /* Common error state tests */ + + printf("\n"); + printf("Common error state tests\n"); + + ret = argon2_hash(2, 1, 1, "password", strlen("password"), + "diffsalt", strlen("diffsalt"), + out, OUT_LEN, NULL, 0, Argon2_id, version); + assert(ret == ARGON2_MEMORY_TOO_LITTLE); + printf("Fail on invalid memory: PASS\n"); + + ret = argon2_hash(2, 1 << 12, 1, NULL, strlen("password"), + "diffsalt", strlen("diffsalt"), + out, OUT_LEN, NULL, 0, Argon2_id, version); + assert(ret == ARGON2_PWD_PTR_MISMATCH); + printf("Fail on invalid null pointer: PASS\n"); + + ret = argon2_hash(2, 1 << 12, 1, "password", strlen("password"), "s", 1, + out, OUT_LEN, NULL, 0, Argon2_id, version); + assert(ret == ARGON2_SALT_TOO_SHORT); + printf("Fail on salt too short: PASS\n"); + + return 0; +} diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/thread.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/thread.c new file mode 100644 index 0000000000..1bceb15b7b --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/thread.c @@ -0,0 +1,60 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#if !defined(ARGON2_NO_THREADS) + +#include "thread.h" +#if defined(_WIN32) +#include +#endif + +ARGON2_PRIVATE +int argon2_thread_create(argon2_thread_handle_t *handle, + argon2_thread_func_t func, void *args) { + if (NULL == handle || func == NULL) { + return -1; + } +#if defined(_WIN32) + *handle = _beginthreadex(NULL, 0, func, args, 0, NULL); + return *handle != 0 ? 0 : -1; +#else + return pthread_create(handle, NULL, func, args); +#endif +} + +ARGON2_PRIVATE +int argon2_thread_join(argon2_thread_handle_t handle) { +#if defined(_WIN32) + if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) { + return CloseHandle((HANDLE)handle) != 0 ? 0 : -1; + } + return -1; +#else + return pthread_join(handle, NULL); +#endif +} + +ARGON2_PRIVATE +void argon2_thread_exit(void) { +#if defined(_WIN32) + _endthreadex(0); +#else + pthread_exit(NULL); +#endif +} + +#endif /* ARGON2_NO_THREADS */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/thread.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/thread.h new file mode 100644 index 0000000000..227f591737 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/argon2/src/thread.h @@ -0,0 +1,70 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_THREAD_H +#define ARGON2_THREAD_H + +#if !defined(ARGON2_NO_THREADS) + +/* + Here we implement an abstraction layer for the simple requirements + of the Argon2 code. We only require 3 primitives---thread creation, + joining, and termination---so full emulation of the pthreads API + is unwarranted. Currently we wrap pthreads and Win32 threads. + + The API defines 2 types: the function pointer type, + argon2_thread_func_t, + and the type of the thread handle---argon2_thread_handle_t. +*/ +#if defined(_WIN32) +#include +typedef unsigned(__stdcall *argon2_thread_func_t)(void *); +typedef uintptr_t argon2_thread_handle_t; +#else +#include +typedef void *(*argon2_thread_func_t)(void *); +typedef pthread_t argon2_thread_handle_t; +#endif + +/* Creates a thread + * @param handle pointer to a thread handle, which is the output of this + * function. Must not be NULL. + * @param func A function pointer for the thread's entry point. Must not be + * NULL. + * @param args Pointer that is passed as an argument to @func. May be NULL. + * @return 0 if @handle and @func are valid pointers and a thread is successfully + * created. + */ +ARGON2_PRIVATE +int argon2_thread_create(argon2_thread_handle_t *handle, + argon2_thread_func_t func, void *args); + +/* Waits for a thread to terminate + * @param handle Handle to a thread created with argon2_thread_create. + * @return 0 if @handle is a valid handle, and joining completed successfully. +*/ +ARGON2_PRIVATE +int argon2_thread_join(argon2_thread_handle_t handle); + +/* Terminate the current thread. Must be run inside a thread created by + * argon2_thread_create. +*/ +ARGON2_PRIVATE +void argon2_thread_exit(void); + +#endif /* ARGON2_NO_THREADS */ +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/aead.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/aead.c index 1d9132e267..b65e63e360 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/aead.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/aead.c @@ -88,7 +88,7 @@ forceinline void ascon_adata(ascon_state_t* s, const uint8_t* ad, ASCON_P(s, nr); } /* domain separation */ - s->x[4] ^= 1; + s->x[4] ^= ASCON_DSEP(); ascon_printstate("domain separation", s); } @@ -197,6 +197,7 @@ forceinline void ascon_final(ascon_state_t* s, const ascon_key_t* key) { ascon_printstate("final 2nd key xor", s); } +SQLITE_PRIVATE int ascon_aead_encrypt(uint8_t* ctext, uint8_t tag[ASCON_AEAD_TAG_LEN], const uint8_t* mtext, uint64_t mlen, @@ -220,6 +221,7 @@ int ascon_aead_encrypt(uint8_t* ctext, return 0; } +SQLITE_PRIVATE int ascon_aead_decrypt(uint8_t* mtext, const uint8_t* ctext, uint64_t clen, const uint8_t* ad, uint64_t adlen, diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_aead.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_aead.h index 0955c7638e..4c205bacb4 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_aead.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_aead.h @@ -13,6 +13,10 @@ #ifndef CRYPTO_AEAD_H #define CRYPTO_AEAD_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #include /* @@ -27,6 +31,7 @@ ** \param nonce Buffer with nonce data ** \param k Buffer with key data */ +SQLITE_PRIVATE int ascon_aead_encrypt(uint8_t* ctext, uint8_t tag[ASCON_AEAD_TAG_LEN], const uint8_t* mtext, uint64_t mlen, const uint8_t* ad, uint64_t adlen, @@ -45,6 +50,7 @@ int ascon_aead_encrypt(uint8_t* ctext, uint8_t tag[ASCON_AEAD_TAG_LEN], ** \param nonce Buffer with nonce data ** \param k Buffer with key data */ +SQLITE_PRIVATE int ascon_aead_decrypt(uint8_t* mtext, const uint8_t* ctext, uint64_t clen, const uint8_t* ad, uint64_t adlen, const uint8_t tag[ASCON_AEAD_TAG_LEN], diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_hash.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_hash.h index af9b04e29d..4f326f1e12 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_hash.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_hash.h @@ -13,6 +13,10 @@ #ifndef CRYPTO_HASH_H #define CRYPTO_HASH_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #include /* @@ -22,6 +26,7 @@ ** \param in Buffer with input data ** \param passwordlen Length of input data in bytes */ +SQLITE_PRIVATE int ascon_hash(uint8_t* out, const uint8_t* in, uint64_t inlen); #endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_pbkdf2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_pbkdf2.h index 95d7f9d743..d9f247b824 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_pbkdf2.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_pbkdf2.h @@ -17,6 +17,10 @@ #ifndef ASCON_PBKDF2_H #define ASCON_PBKDF2_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #include /* @@ -35,6 +39,7 @@ ** \param saltlen Number of bytes in the salt ** \param count Number of iterations to perform */ +SQLITE_PRIVATE void ascon_pbkdf2(uint8_t* out, uint32_t outlen, const uint8_t* password, uint32_t passwordlen, const uint8_t* salt, uint32_t saltlen, uint32_t count) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/hash.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/hash.c index 46d17623ec..ae400f10e3 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/hash.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/hash.c @@ -89,6 +89,7 @@ forceinline void ascon_squeeze(ascon_state_t* s, uint8_t* out, ascon_printstate("squeeze output", s); } +SQLITE_PRIVATE int ascon_hash(uint8_t* out, const uint8_t* in, uint64_t inlen) { ascon_state_t s; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/pbkdf2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/pbkdf2.c index 8db33c998d..1f84d551cf 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/pbkdf2.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/pbkdf2.c @@ -15,6 +15,7 @@ #define ASCON_HASH_SIZE 32 #define ASCON_PBKDF2_SIZE 32 +SQLITE_PRIVATE void ascon_pbkdf2_init(ascon_state_t* state, const char* functionName, const unsigned char* custom, uint32_t customlen, uint32_t outlen) { @@ -60,10 +61,11 @@ void ascon_pbkdf2_init(ascon_state_t* state, const char* functionName, * Note: Instead of HMAC like in RFC 8018, use the following PRF: * PRF(P, X) = ASCON-cXOF(X, 256, "PBKDF2", P) */ -static void ascon_pbkdf2_f(ascon_state_t* state, - uint8_t* T, /*uint8_t* U,*/ - const uint8_t* salt, uint32_t saltlen, - uint32_t count, uint32_t blocknum) +static +void ascon_pbkdf2_f(ascon_state_t* state, + uint8_t* T, /*uint8_t* U,*/ + const uint8_t* salt, uint32_t saltlen, + uint32_t count, uint32_t blocknum) { uint32_t asconSaltLen = (saltlen < ASCON_SALT_LEN) ? saltlen : ASCON_SALT_LEN; uint8_t temp[ASCON_SALT_LEN+4]; @@ -73,7 +75,7 @@ static void ascon_pbkdf2_f(ascon_state_t* state, memset(temp, 0, ASCON_SALT_LEN); memcpy(temp, salt, asconSaltLen); STORE32_BE(temp+ASCON_SALT_LEN, blocknum); - + /* Copy initial state */ for (j = 0; j < 5; ++j) state2.x[j] = state->x[j]; @@ -109,6 +111,7 @@ static void ascon_pbkdf2_f(ascon_state_t* state, sqlite3mcSecureZeroMemory(&state2, sizeof(ascon_state_t)); } +SQLITE_PRIVATE void ascon_pbkdf2(uint8_t* out, uint32_t outlen, const uint8_t* password, uint32_t passwordlen, const uint8_t* salt, uint32_t saltlen, uint32_t count) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/prolog.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/prolog.h index 4e65e45cdd..5efe9ba0ae 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/prolog.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/prolog.h @@ -1,6 +1,6 @@ /* ** Name: prolog.h -** Purpose: Include important header files, before +** Purpose: Include important header files, before ** Based on: Public domain Ascon reference implementation ** and optimized variants for 32- and 64-bit ** (see https://github.com/ascon/ascon-c) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/word.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/word.h index cfd960a00e..972b55d2f0 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/word.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/word.h @@ -15,6 +15,8 @@ typedef union { #define ASCON_U64TOWORD(x) ASCON_U64BIG(x) #define ASCON_WORDTOU64(x) ASCON_U64BIG(x) +#define ASCON_LOAD(b, n) ASCON_LOADBYTES(b, n) +#define ASCON_STORE(b, w, n) ASCON_STOREBYTES(b, w, n) forceinline uint64_t ASCON_ROR(uint64_t x, int n) { return x >> n | x << (-n & 63); } @@ -32,6 +34,8 @@ forceinline int ASCON_NOTZERO(uint64_t a, uint64_t b) { forceinline uint64_t ASCON_PAD(int i) { return 0x80ull << (56 - 8 * i); } +forceinline uint64_t ASCON_DSEP() { return 0x01; } + forceinline uint64_t ASCON_PRFS_MLEN(uint64_t len) { return len << 51; } forceinline uint64_t ASCON_CLEAR(uint64_t w, int n) { @@ -45,16 +49,6 @@ forceinline uint64_t ASCON_MASK(int n) { return ~0ull >> (64 - 8 * n); } -forceinline uint64_t ASCON_LOAD(const uint8_t* bytes, int n) { - uint64_t x = *(uint64_t*)bytes & ASCON_MASK(n); - return ASCON_U64TOWORD(x); -} - -forceinline void ASCON_STORE(uint8_t* bytes, uint64_t w, int n) { - *(uint64_t*)bytes &= ~ASCON_MASK(n); - *(uint64_t*)bytes |= ASCON_WORDTOU64(w); -} - forceinline uint64_t ASCON_LOADBYTES(const uint8_t* bytes, int n) { uint64_t x = 0; memcpy(&x, bytes, n); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/carray.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/carray.c index b1caa98c3f..df8c6b2700 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/carray.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/carray.c @@ -46,7 +46,7 @@ ** ctype TEXT HIDDEN ** ); ** -** If the hidden columns "pointer" and "count" are unconstrained, then +** If the hidden columns "pointer" and "count" are unconstrained, then ** the virtual table has no rows. Otherwise, the virtual table interprets ** the integer value of "pointer" as a pointer to the array and "count" ** as the number of elements in the array. The virtual table steps through @@ -64,7 +64,7 @@ SQLITE_EXTENSION_INIT1 #else # include #endif - + /* Allowed values for the mFlags parameter to sqlite3_carray_bind(). ** Must exactly match the definitions in carray.h. */ @@ -76,14 +76,6 @@ SQLITE_EXTENSION_INIT1 # define CARRAY_BLOB 4 /* Data is struct iovec* */ #endif -#ifndef SQLITE_API -# ifdef _WIN32 -# define SQLITE_API __declspec(dllexport) -# else -# define SQLITE_API -# endif -#endif - #ifndef SQLITE_OMIT_VIRTUALTABLE /* @@ -271,7 +263,7 @@ static int carrayEof(sqlite3_vtab_cursor *cur){ ** to the first row of output. */ static int carrayFilter( - sqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -385,7 +377,7 @@ static int carrayBestIndex( } /* -** This following structure defines all the methods for the +** This following structure defines all the methods for the ** carray virtual table. */ static sqlite3_module carrayModule = { @@ -468,7 +460,7 @@ SQLITE_API int sqlite3_carray_bind( for(i=0; iaData = sqlite3_malloc64( sz ); if( pNew->aData==0 ){ sqlite3_free(pNew); @@ -541,9 +533,13 @@ static void inttoptrFunc( #endif /* SQLITE_OMIT_VIRTUALTABLE */ -SQLITE_API int sqlite3_carray_init( - sqlite3 *db, - char **pzErrMsg, +#ifndef SQLITE_API +#define SQLITE_API +#endif +SQLITE_API +int sqlite3_carray_init( + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/chacha20poly1305.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/chacha20poly1305.c index 57a96931b6..13bdad6e6a 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/chacha20poly1305.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/chacha20poly1305.c @@ -74,6 +74,7 @@ static void chacha20_block(uint32_t x[16]) #undef CC20QR } +SQLITE_PRIVATE void chacha20_xor(void* buffer, size_t n, const uint8_t key[32], const uint8_t nonce[12], uint32_t counter) { @@ -141,6 +142,7 @@ void chacha20_xor(void* buffer, size_t n, const uint8_t key[32], /* * Poly1305 authentication tags */ +SQLITE_PRIVATE void poly1305(const uint8_t* msg, size_t n, const uint8_t key[32], uint8_t tag[16]) { @@ -210,6 +212,7 @@ void poly1305(const uint8_t* msg, size_t n, const uint8_t key[32], s4 = d4; STORE32_LE(tag + 12, s4); } +SQLITE_PRIVATE int poly1305_tagcmp(const uint8_t tag1[16], const uint8_t tag2[16]) { uint8_t d = 0; @@ -286,7 +289,7 @@ static size_t entropy(void* buf, size_t n) } #else - + #include #define RtlGenRandom SystemFunction036 BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); @@ -405,6 +408,7 @@ static size_t entropy(void* buf, size_t n) /* * ChaCha20 random number generator */ +SQLITE_PRIVATE void chacha20_rng(void* out, size_t n) { static uint8_t key[32], nonce[12], buffer[64] = { 0 }; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_aegis.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_aegis.c new file mode 100644 index 0000000000..4c518a4e90 --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_aegis.c @@ -0,0 +1,507 @@ +/* +** Name: cipher_aegis.c +** Purpose: Implementation of cipher AEGIS +** Author: Ulrich Telle +** Created: 2024-12-10 +** Copyright: (c) 2024-2024 Ulrich Telle +** License: MIT +*/ + +#include "cipher_common.h" + +/* --- Aegis --- */ +#if HAVE_CIPHER_AEGIS + +#define CIPHER_NAME_AEGIS "aegis" + +/* +** Configuration parameters for "aegis" +** +** - tcost : number of iterations for key derivation with Argon2 +** - mcost : amount of memory in kB for key derivation with Argon2 +** - pcost : parallelism, number of threads for key derivation with Argon2 +** - algorithm : AEGIS variant to be used for page encryption +*/ + +#define AEGIS_ALGORITHM_128L 1 +#define AEGIS_ALGORITHM_128X2 2 +#define AEGIS_ALGORITHM_128X4 3 +#define AEGIS_ALGORITHM_256 4 +#define AEGIS_ALGORITHM_256X2 5 +#define AEGIS_ALGORITHM_256X4 6 + +#define AEGIS_ALGORITHM_MIN AEGIS_ALGORITHM_128L +#define AEGIS_ALGORITHM_MAX AEGIS_ALGORITHM_256X4 +#define AEGIS_ALGORITHM_DEFAULT AEGIS_ALGORITHM_256 + +#define AEGIS_TCOST_DEFAULT 2 +#define AEGIS_MCOST_DEFAULT (19*1024) +#define AEGIS_PCOST_DEFAULT 1 + +SQLITE_PRIVATE const char* mcAegisAlgorithmNames[AEGIS_ALGORITHM_MAX+1] = +{ "", "aegis-128l", "aegis-128x2", "aegis-128x4", "aegis-256", "aegis-256x2", "aegis-256x4" }; + +SQLITE_PRIVATE int sqlite3mcAegisAlgorithmToIndex(const char* algorithmName) +{ + int j = 0; + for (j = AEGIS_ALGORITHM_MIN; j <= AEGIS_ALGORITHM_MAX; j++) + { + if (sqlite3_stricmp(algorithmName, mcAegisAlgorithmNames[j]) == 0) + break; + } + if (j <= AEGIS_ALGORITHM_MAX) + return j; + else + return -1; +} + +SQLITE_PRIVATE const char* sqlite3mcAegisAlgorithmToString(int algorithmIndex) +{ + if (algorithmIndex >= AEGIS_ALGORITHM_MIN && algorithmIndex <= AEGIS_ALGORITHM_MAX) + return mcAegisAlgorithmNames[algorithmIndex]; + else + return "unknown"; +} + +typedef int (*AegisEncryptDetached_t)(uint8_t* c, uint8_t* mac, size_t maclen, + const uint8_t* m, size_t mlen, + const uint8_t* ad, size_t adlen, + const uint8_t* npub, const uint8_t* k); + +typedef int (*AegisDecryptDetached_t)(uint8_t* m, const uint8_t* c, size_t clen, + const uint8_t* mac, size_t maclen, + const uint8_t* ad, size_t adlen, + const uint8_t* npub, const uint8_t* k); + +typedef void (*AegisEncryptUnauthenticated_t)(uint8_t* c, const uint8_t* m, size_t mlen, + const uint8_t* npub, const uint8_t* k); + +typedef void (*AegisDecryptUnauthenticated_t)(uint8_t* m, const uint8_t* c, size_t clen, + const uint8_t* npub, const uint8_t* k); + +typedef void (*AegisStream_t)(uint8_t* out, size_t len, const uint8_t* npub, const uint8_t* k); + +typedef struct _AegisCryptFunctions +{ + AegisEncryptDetached_t encrypt; + AegisDecryptDetached_t decrypt; + AegisEncryptUnauthenticated_t encryptNoTag; + AegisEncryptUnauthenticated_t decryptNoTag; + AegisStream_t stream; +} AegisCryptFunctions; + +SQLITE_PRIVATE const AegisCryptFunctions mcAegisCryptFunctions[] = +{ + { NULL, NULL }, /* Dummy entry */ + { aegis128l_encrypt_detached, aegis128l_decrypt_detached, + aegis128l_encrypt_unauthenticated, aegis128l_decrypt_unauthenticated, + aegis128l_stream }, + { aegis128x2_encrypt_detached, aegis128x2_decrypt_detached, + aegis128x2_encrypt_unauthenticated, aegis128x2_decrypt_unauthenticated, + aegis128x2_stream }, + { aegis128x4_encrypt_detached, aegis128x4_decrypt_detached, + aegis128x4_encrypt_unauthenticated, aegis128x4_decrypt_unauthenticated, + aegis128x4_stream }, + { aegis256_encrypt_detached, aegis256_decrypt_detached, + aegis256_encrypt_unauthenticated, aegis256_decrypt_unauthenticated, + aegis256_stream }, + { aegis256x2_encrypt_detached, aegis256x2_decrypt_detached, + aegis256x2_encrypt_unauthenticated, aegis256x2_decrypt_unauthenticated, + aegis256x2_stream }, + { aegis256x4_encrypt_detached, aegis256x4_decrypt_detached, + aegis256x4_encrypt_unauthenticated, aegis256x4_decrypt_unauthenticated, + aegis256x4_stream } +}; + +SQLITE_PRIVATE CipherParams mcAegisParams[] = +{ + { "tcost", AEGIS_TCOST_DEFAULT, AEGIS_TCOST_DEFAULT, 1, 0x7fffffff }, + { "mcost", AEGIS_MCOST_DEFAULT, AEGIS_MCOST_DEFAULT, 1, 0x7fffffff }, + { "pcost", AEGIS_PCOST_DEFAULT, AEGIS_PCOST_DEFAULT, 1, 0x7fffffff }, + { "algorithm", AEGIS_ALGORITHM_DEFAULT, AEGIS_ALGORITHM_DEFAULT, AEGIS_ALGORITHM_MIN, AEGIS_ALGORITHM_MAX }, + CIPHER_PARAMS_SENTINEL +}; + +#define KEYLENGTH_AEGIS_128 16 +#define KEYLENGTH_AEGIS_256 32 +#define KEYLENGTH_AEGIS_MAX 32 + +#define PAGE_NONCE_LEN_AEGIS_128 16 +#define PAGE_NONCE_LEN_AEGIS_256 32 +#define PAGE_NONCE_LEN_AEGIS_MAX 32 + +#if AEGIS_ALGORITHM_DEFAULT < AEGIS_ALGORITHM_256 +#define KEYLENGTH_AEGIS_DEFAULT KEYLENGTH_AEGIS_128 +#define PAGE_NONCE_LEN_AEGIS_DEFAULT PAGE_NONCE_LEN_AEGIS_128 +#else +#define KEYLENGTH_AEGIS_DEFAULT KEYLENGTH_AEGIS_256 +#define PAGE_NONCE_LEN_AEGIS_DEFAULT PAGE_NONCE_LEN_AEGIS_256 +#endif + +#define SALTLENGTH_AEGIS 16 + +#define PAGE_TAG_LEN_AEGIS 32 +#define PAGE_RESERVED_AEGIS (PAGE_NONCE_LEN_AEGIS + PAGE_TAG_LEN_AEGIS) + +#define OTK_LEN_MAX_AEGIS (PAGE_TAG_LEN_AEGIS + PAGE_NONCE_LEN_AEGIS_MAX + 4) + +typedef struct _aegisCipher +{ + int m_argon2Tcost; + int m_argon2Mcost; + int m_argon2Pcost; + int m_aegisAlgorithm; + int m_keyLength; + int m_nonceLength; + uint8_t m_key[KEYLENGTH_AEGIS_MAX]; + uint8_t m_salt[SALTLENGTH_AEGIS]; +} AegisCipher; + +static void* +AllocateAegisCipher(sqlite3* db) +{ + AegisCipher* aegisCipher = (AegisCipher*) sqlite3_malloc(sizeof(AegisCipher)); + if (aegisCipher != NULL) + { + memset(aegisCipher, 0, sizeof(AegisCipher)); + aegisCipher->m_keyLength = 0; + memset(aegisCipher->m_key, 0, KEYLENGTH_AEGIS_MAX); + memset(aegisCipher->m_salt, 0, SALTLENGTH_AEGIS); + } + if (aegisCipher != NULL) + { + CipherParams* cipherParams = sqlite3mcGetCipherParams(db, CIPHER_NAME_AEGIS); + aegisCipher->m_argon2Tcost = sqlite3mcGetCipherParameter(cipherParams, "tcost"); + aegisCipher->m_argon2Mcost = sqlite3mcGetCipherParameter(cipherParams, "mcost"); + aegisCipher->m_argon2Pcost = sqlite3mcGetCipherParameter(cipherParams, "pcost"); + aegisCipher->m_aegisAlgorithm = sqlite3mcGetCipherParameter(cipherParams, "algorithm"); + if (aegisCipher->m_aegisAlgorithm < AEGIS_ALGORITHM_256) + { + aegisCipher->m_keyLength = KEYLENGTH_AEGIS_128; + aegisCipher->m_nonceLength = PAGE_NONCE_LEN_AEGIS_128; + } + else + { + aegisCipher->m_keyLength = KEYLENGTH_AEGIS_256; + aegisCipher->m_nonceLength = PAGE_NONCE_LEN_AEGIS_256; + } + } + return aegisCipher; +} + +static void +FreeAegisCipher(void* cipher) +{ + AegisCipher* aegisCipher = (AegisCipher*) cipher; + memset(aegisCipher, 0, sizeof(AegisCipher)); + sqlite3_free(aegisCipher); +} + +static void +CloneAegisCipher(void* cipherTo, void* cipherFrom) +{ + AegisCipher* aegisCipherTo = (AegisCipher*) cipherTo; + AegisCipher* aegisCipherFrom = (AegisCipher*) cipherFrom; + + aegisCipherTo->m_argon2Tcost = aegisCipherFrom->m_argon2Tcost; + aegisCipherTo->m_argon2Mcost = aegisCipherFrom->m_argon2Mcost; + aegisCipherTo->m_argon2Pcost = aegisCipherFrom->m_argon2Pcost; + + aegisCipherTo->m_aegisAlgorithm = aegisCipherFrom->m_aegisAlgorithm; + aegisCipherTo->m_keyLength = aegisCipherFrom->m_keyLength; + aegisCipherTo->m_nonceLength = aegisCipherFrom->m_nonceLength; + + memcpy(aegisCipherTo->m_key, aegisCipherFrom->m_key, aegisCipherFrom->m_keyLength); + memcpy(aegisCipherTo->m_salt, aegisCipherFrom->m_salt, SALTLENGTH_AEGIS); +} + +static int +GetLegacyAegisCipher(void* cipher) +{ + AegisCipher* aegisCipher = (AegisCipher*) cipher; + return 0; +} + +static int +GetPageSizeAegisCipher(void* cipher) +{ + AegisCipher* aegisCipher = (AegisCipher*) cipher; + int pageSize = 0; + return pageSize; +} + +static int +GetReservedAegisCipher(void* cipher) +{ + AegisCipher* aegisCipher = (AegisCipher*) cipher; + return (aegisCipher->m_nonceLength + PAGE_TAG_LEN_AEGIS); +} + +static unsigned char* +GetSaltAegisCipher(void* cipher) +{ + AegisCipher* aegisCipher = (AegisCipher*) cipher; + return aegisCipher->m_salt; +} + +static void +GenerateKeyAegisCipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +{ + AegisCipher* aegisCipher = (AegisCipher*) cipher; + int bypass = 0; + + int keyOnly = 1; + if (rekey || cipherSalt == NULL) + { + chacha20_rng(aegisCipher->m_salt, SALTLENGTH_AEGIS); + keyOnly = 0; + } + else + { + memcpy(aegisCipher->m_salt, cipherSalt, SALTLENGTH_AEGIS); + } + + /* Bypass key derivation if the key string starts with "raw:" */ + if (passwordLength > 4 && !memcmp(userPassword, "raw:", 4)) + { + const int nRaw = passwordLength - 4; + const unsigned char* zRaw = (const unsigned char*) userPassword + 4; + if (nRaw == aegisCipher->m_keyLength) + { + /* Binary key */ + memcpy(aegisCipher->m_key, zRaw, aegisCipher->m_keyLength); + bypass = 1; + } + else if (nRaw == aegisCipher->m_keyLength + SALTLENGTH_AEGIS) + { + /* Binary key and salt) */ + if (!keyOnly) + { + memcpy(aegisCipher->m_salt, zRaw + aegisCipher->m_keyLength, SALTLENGTH_AEGIS); + } + memcpy(aegisCipher->m_key, zRaw, aegisCipher->m_keyLength); + bypass = 1; + } + else if (nRaw == 2 * aegisCipher->m_keyLength) + { + /* Hex-encoded key */ + if (sqlite3mcIsHexKey(zRaw, nRaw) != 0) + { + sqlite3mcConvertHex2Bin(zRaw, nRaw, aegisCipher->m_key); + bypass = 1; + } + } + else if (nRaw == 2 * (aegisCipher->m_keyLength + SALTLENGTH_AEGIS)) + { + /* Hex-encoded key and salt */ + if (sqlite3mcIsHexKey(zRaw, nRaw) != 0) + { + sqlite3mcConvertHex2Bin(zRaw, 2 * aegisCipher->m_keyLength, aegisCipher->m_key); + if (!keyOnly) + { + sqlite3mcConvertHex2Bin(zRaw + 2 * aegisCipher->m_keyLength, 2 * SALTLENGTH_AEGIS, aegisCipher->m_salt); + } + bypass = 1; + } + } + } + + if (!bypass) + { + int rc = argon2id_hash_raw((uint32_t) aegisCipher->m_argon2Tcost, + (uint32_t) aegisCipher->m_argon2Mcost, + (uint32_t) aegisCipher->m_argon2Pcost, + userPassword, passwordLength, + aegisCipher->m_salt, SALTLENGTH_AEGIS, + aegisCipher->m_key, aegisCipher->m_keyLength); + } + SQLITE3MC_DEBUG_LOG("generate: codec=%p pFile=%p\n", aegisCipher, fd); + SQLITE3MC_DEBUG_HEX("generate key:", aegisCipher->m_key, aegisCipher->m_keyLength); + SQLITE3MC_DEBUG_HEX("generate salt:", aegisCipher->m_salt, SALTLENGTH_AEGIS); +} + +static int +AegisGenNonce(AegisCipher* aegisCipher, uint8_t* out, int outLength, int page) +{ + uint8_t nonce[PAGE_NONCE_LEN_AEGIS_MAX]; + memset(nonce, 0, PAGE_NONCE_LEN_AEGIS_MAX); + STORE32_LE(out, page); + STORE32_LE(out + 4, page); + mcAegisCryptFunctions[aegisCipher->m_aegisAlgorithm].stream(out, outLength, nonce, aegisCipher->m_key); + return 0; +} + +static int +AegisGenOtk(AegisCipher* aegisCipher, uint8_t* out, int outLength, uint8_t* nonce, int nonceLength, int page) +{ + mcAegisCryptFunctions[aegisCipher->m_aegisAlgorithm].stream(out, outLength, nonce, aegisCipher->m_key); + STORE32_BE(out + (outLength - 4), page); + return 0; +} + +static int +EncryptPageAegisCipher(void* cipher, int page, unsigned char* data, int len, int reserved) +{ + AegisCipher* aegisCipher = (AegisCipher*) cipher; + int rc = SQLITE_OK; + int nReserved = (reserved == 0) ? 0 : GetReservedAegisCipher(cipher); + int n = len - nReserved; + uint64_t mlen = n; + + /* Generate one-time keys */ + uint8_t otk[OTK_LEN_MAX_AEGIS]; + int offset; + memset(otk, 0, OTK_LEN_MAX_AEGIS); + + /* Check whether number of required reserved bytes and actually reserved bytes match */ + if (nReserved > reserved) + { + return SQLITE_CORRUPT; + } + + if (nReserved > 0) + { + /* Encrypt and authenticate */ + + /* Generate nonce */ + chacha20_rng(data + n + PAGE_TAG_LEN_AEGIS, aegisCipher->m_nonceLength); + AegisGenOtk(aegisCipher, otk, aegisCipher->m_keyLength + aegisCipher->m_nonceLength, + data + n + PAGE_TAG_LEN_AEGIS, aegisCipher->m_nonceLength, page); + + offset = (page == 1) ? CIPHER_PAGE1_OFFSET : 0; + mcAegisCryptFunctions[aegisCipher->m_aegisAlgorithm].encrypt( + data + offset, data + n, PAGE_TAG_LEN_AEGIS, + data + offset, mlen - offset, + NULL, 0, otk + aegisCipher->m_keyLength, otk); + + if (page == 1) + { + memcpy(data, aegisCipher->m_salt, SALTLENGTH_AEGIS); + } + } + else + { + /* Encrypt only */ + uint8_t nonce[PAGE_NONCE_LEN_AEGIS_MAX]; + AegisGenNonce(aegisCipher, nonce, aegisCipher->m_nonceLength, page); + AegisGenOtk(aegisCipher, otk, aegisCipher->m_keyLength + aegisCipher->m_nonceLength, + nonce, aegisCipher->m_nonceLength, page); + + /* Encrypt */ + offset = (page == 1) ? CIPHER_PAGE1_OFFSET : 0; + mcAegisCryptFunctions[aegisCipher->m_aegisAlgorithm].encryptNoTag( + data + offset, + data + offset, mlen - offset, + otk + aegisCipher->m_keyLength, otk); + + if (page == 1) + { + memcpy(data, aegisCipher->m_salt, SALTLENGTH_AEGIS); + } + } + + return rc; +} + +static int +DecryptPageAegisCipher(void* cipher, int page, unsigned char* data, int len, int reserved, int hmacCheck) +{ + AegisCipher* aegisCipher = (AegisCipher*) cipher; + int rc = SQLITE_OK; + int nReserved = (reserved == 0) ? 0 : GetReservedAegisCipher(cipher); + int n = len - nReserved; + uint64_t clen = n; + int tagOk; + + /* Generate one-time keys */ + uint8_t otk[OTK_LEN_MAX_AEGIS]; + int offset; + memset(otk, 0, OTK_LEN_MAX_AEGIS); + + /* Check whether number of required reserved bytes and actually reserved bytes match */ + if (nReserved > reserved) + { + return (page == 1) ? SQLITE_NOTADB : SQLITE_CORRUPT; + } + + if (nReserved > 0) + { + /* Decrypt and verify MAC */ + AegisGenOtk(aegisCipher, otk, aegisCipher->m_keyLength + aegisCipher->m_nonceLength, + data + n + PAGE_TAG_LEN_AEGIS, aegisCipher->m_nonceLength, page); + + /* Determine MAC and decrypt */ + offset = (page == 1) ? CIPHER_PAGE1_OFFSET : 0; + + if (hmacCheck != 0) + { + /* Verify the MAC */ + tagOk = mcAegisCryptFunctions[aegisCipher->m_aegisAlgorithm].decrypt( + data + offset, + data + offset, clen - offset, + data + n, PAGE_TAG_LEN_AEGIS, + NULL, 0, otk + aegisCipher->m_keyLength, otk); + if (tagOk != 0) + { + SQLITE3MC_DEBUG_LOG("decrypt: codec=%p page=%d\n", aegisCipher, page); + SQLITE3MC_DEBUG_HEX("decrypt key:", aegisCipher->m_key, aegisCipher->m_keyLength); + SQLITE3MC_DEBUG_HEX("decrypt otk:", otk, 64); + SQLITE3MC_DEBUG_HEX("decrypt data+00:", data, 16); + SQLITE3MC_DEBUG_HEX("decrypt data+24:", data + 24, 16); + SQLITE3MC_DEBUG_HEX("decrypt data+n:", data + n, PAGE_TAG_LEN_AEGIS); + /* Bad MAC */ + rc = (page == 1) ? SQLITE_NOTADB : SQLITE_CORRUPT; + } + } + else + { + mcAegisCryptFunctions[aegisCipher->m_aegisAlgorithm].decryptNoTag( + data + offset, + data + offset, clen - offset, + otk + aegisCipher->m_keyLength, otk); + } + + if (page == 1 && rc == SQLITE_OK) + { + memcpy(data, SQLITE_FILE_HEADER, 16); + } + } + else + { + /* Decrypt only */ + uint8_t nonce[PAGE_NONCE_LEN_AEGIS_MAX]; + AegisGenNonce(aegisCipher, nonce, aegisCipher->m_nonceLength, page); + AegisGenOtk(aegisCipher, otk, aegisCipher->m_keyLength + aegisCipher->m_nonceLength, + nonce, aegisCipher->m_nonceLength, page); + + /* Decrypt */ + offset = (page == 1) ? CIPHER_PAGE1_OFFSET : 0; + mcAegisCryptFunctions[aegisCipher->m_aegisAlgorithm].decryptNoTag( + data + offset, + data + offset, clen - offset, + otk + aegisCipher->m_keyLength, otk); + + if (page == 1) + { + memcpy(data, SQLITE_FILE_HEADER, 16); + } + } + + return rc; +} + +SQLITE_PRIVATE const CipherDescriptor mcAegisDescriptor = +{ + CIPHER_NAME_AEGIS, + AllocateAegisCipher, + FreeAegisCipher, + CloneAegisCipher, + GetLegacyAegisCipher, + GetPageSizeAegisCipher, + GetReservedAegisCipher, + GetSaltAegisCipher, + GenerateKeyAegisCipher, + EncryptPageAegisCipher, + DecryptPageAegisCipher +}; +#endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_ascon.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_ascon.c index 89d658a621..c702104f77 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_ascon.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_ascon.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher Ascon ** Author: Ulrich Telle ** Created: 2023-11-13 -** Copyright: (c) 2023-2023 Ulrich Telle +** Copyright: (c) 2023-2024 Ulrich Telle ** License: MIT */ @@ -114,21 +114,18 @@ GetSaltAscon128Cipher(void* cipher) } static void -GenerateKeyAscon128Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyAscon128Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { Ascon128Cipher* ascon128Cipher = (Ascon128Cipher*) cipher; int bypass = 0; - Pager *pPager = pBt->pPager; - sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL; - int keyOnly = 1; - if (rekey || fd == NULL || sqlite3OsRead(fd, ascon128Cipher->m_salt, SALTLENGTH_ASCON128, 0) != SQLITE_OK) + if (rekey || cipherSalt == NULL) { chacha20_rng(ascon128Cipher->m_salt, SALTLENGTH_ASCON128); keyOnly = 0; } - else if (cipherSalt != NULL) + else { memcpy(ascon128Cipher->m_salt, cipherSalt, SALTLENGTH_ASCON128); } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_chacha20.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_chacha20.c index f93a867468..67dca9c51e 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_chacha20.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_chacha20.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher ChaCha20 - Poly1305 ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -140,21 +140,18 @@ GetSaltChaCha20Cipher(void* cipher) } static void -GenerateKeyChaCha20Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyChaCha20Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { ChaCha20Cipher* chacha20Cipher = (ChaCha20Cipher*) cipher; int bypass = 0; - Pager *pPager = pBt->pPager; - sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL; - int keyOnly = 1; - if (rekey || fd == NULL || sqlite3OsRead(fd, chacha20Cipher->m_salt, SALTLENGTH_CHACHA20, 0) != SQLITE_OK) + if (rekey || cipherSalt == NULL) { chacha20_rng(chacha20Cipher->m_salt, SALTLENGTH_CHACHA20); keyOnly = 0; } - else if (cipherSalt != NULL) + else { memcpy(chacha20Cipher->m_salt, cipherSalt, SALTLENGTH_CHACHA20); } @@ -274,7 +271,8 @@ EncryptPageChaCha20Cipher(void* cipher, int page, unsigned char* data, int len, return rc; } -int chacha20_ismemset(const void* v, unsigned char value, int len) +static int +chacha20_ismemset(const void* v, unsigned char value, int len) { const unsigned char* a = v; int i = 0, result = 0; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.c index 6e4eed953d..8963fc378a 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of SQLite codecs ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2022 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -55,6 +55,7 @@ typedef struct _CipherName char m_name[CIPHER_NAME_MAXLEN]; } CipherName; +static char globalConfigTableName[CIPHER_NAME_MAXLEN] = ""; static int globalCipherCount = 0; static char* globalSentinelName = ""; static CipherName globalCipherNameTable[CODEC_COUNT_LIMIT + 2] = { 0 }; @@ -116,20 +117,21 @@ sqlite3mcCloneCodecParameterTable() } SQLITE_PRIVATE void -sqlite3mcFreeCodecParameterTable(CodecParameter* codecParams) +sqlite3mcFreeCodecParameterTable(void* ptr) { + CodecParameter* codecParams = (CodecParameter*)ptr; sqlite3_free(codecParams[0].m_params); sqlite3_free(codecParams); } static const CipherDescriptor mcSentinelDescriptor = { - "", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + "", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const CipherDescriptor mcDummyDescriptor = { - "@dummy@", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + "@dummy@", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static CipherDescriptor globalCodecDescriptorTable[CODEC_COUNT_MAX + 1]; @@ -144,7 +146,7 @@ sqlite3mcGetCipherType(sqlite3* db) { CodecParameter* codecParams = (db != NULL) ? sqlite3mcGetCodecParams(db) : globalCodecParameterTable; CipherParams* cipherParamTable = (codecParams != NULL) ? codecParams[0].m_params : commonParams; - int cipherType = CODEC_TYPE; + int cipherType = CODEC_TYPE_UNKNOWN; CipherParams* cipher = cipherParamTable; for (; cipher->m_name[0] != 0; ++cipher) { @@ -207,6 +209,7 @@ sqlite3mcCodecInit(Codec* codec) memset(codec->m_page, 0, sizeof(codec->m_page)); codec->m_pageSize = 0; codec->m_reserved = 0; + codec->m_lastError = SQLITE_OK; codec->m_hasKeySalt = 0; memset(codec->m_keySalt, 0, sizeof(codec->m_keySalt)); } @@ -245,6 +248,10 @@ sqlite3mcCodecSetup(Codec* codec, int cipherType, char* userPassword, int passwo { int rc = SQLITE_OK; CipherParams* globalParams = sqlite3mcGetCipherParams(codec->m_db, CIPHER_NAME_GLOBAL); + if (cipherType <= CODEC_TYPE_UNKNOWN) + { + return SQLITE_ERROR; + } codec->m_isEncrypted = 1; codec->m_hmacCheck = sqlite3mcGetCipherParameter(globalParams, "hmac_check"); codec->m_walLegacy = sqlite3mcGetCipherParameter(globalParams, "mc_legacy_wal"); @@ -270,6 +277,10 @@ sqlite3mcSetupWriteCipher(Codec* codec, int cipherType, char* userPassword, int { int rc = SQLITE_OK; CipherParams* globalParams = sqlite3mcGetCipherParams(codec->m_db, CIPHER_NAME_GLOBAL); + if (cipherType <= CODEC_TYPE_UNKNOWN) + { + return SQLITE_ERROR; + } if (codec->m_writeCipher != NULL) { globalCodecDescriptorTable[codec->m_writeCipherType-1].m_freeCipher(codec->m_writeCipher); @@ -414,7 +425,7 @@ sqlite3mcGetLegacyWriteCipher(Codec* codec) SQLITE_PRIVATE int sqlite3mcGetPageSizeReadCipher(Codec* codec) { - int pageSize = (codec->m_hasReadCipher && codec->m_readCipher != NULL) ? globalCodecDescriptorTable[codec->m_readCipherType - 1].m_getPageSize(codec->m_readCipher) : 0; + int pageSize = (codec->m_hasReadCipher && codec->m_readCipher != NULL) ? globalCodecDescriptorTable[codec->m_readCipherType - 1].m_getPageSize(codec->m_readCipher) : -1; return pageSize; } @@ -447,6 +458,21 @@ sqlite3mcReservedEqual(Codec* codec) return (readReserved == writeReserved); } +SQLITE_PRIVATE void +sqlite3mcSetCodecLastError(Codec* codec, int error) +{ + if (codec) + { + codec->m_lastError = error; + } +} + +SQLITE_PRIVATE int +sqlite3mcGetCodecLastError(Codec* codec) +{ + return codec ? codec->m_lastError : SQLITE_OK; +} + SQLITE_PRIVATE unsigned char* sqlite3mcGetSaltWriteCipher(Codec* codec) { @@ -500,6 +526,9 @@ sqlite3mcCodecCopy(Codec* codec, Codec* other) codec->m_bt = other->m_bt; #endif codec->m_btShared = other->m_btShared; + + codec->m_lastError = SQLITE_OK; + return rc; } @@ -570,16 +599,30 @@ sqlite3mcPadPassword(char* password, int pswdlen, unsigned char pswd[32]) } } +SQLITE_PRIVATE unsigned char* mcReadDatabaseHeader(Codec* codec, unsigned char* dbHeader) +{ + Pager* pPager = codec->m_btShared->pPager; + sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL; + if (fd == NULL || sqlite3OsRead(fd, dbHeader, KEYSALT_LENGTH, 0) != SQLITE_OK) + return NULL; + else + return dbHeader; +} + SQLITE_PRIVATE void sqlite3mcGenerateReadKey(Codec* codec, char* userPassword, int passwordLength, unsigned char* cipherSalt) { - globalCodecDescriptorTable[codec->m_readCipherType-1].m_generateKey(codec->m_readCipher, codec->m_btShared, userPassword, passwordLength, 0, cipherSalt); + unsigned char dbHeader[KEYSALT_LENGTH]; + unsigned char* pDbHeader = (cipherSalt == NULL) ? mcReadDatabaseHeader(codec, dbHeader) : cipherSalt; + globalCodecDescriptorTable[codec->m_readCipherType-1].m_generateKey(codec->m_readCipher, userPassword, passwordLength, 0, pDbHeader); } SQLITE_PRIVATE void sqlite3mcGenerateWriteKey(Codec* codec, char* userPassword, int passwordLength, unsigned char* cipherSalt) { - globalCodecDescriptorTable[codec->m_writeCipherType-1].m_generateKey(codec->m_writeCipher, codec->m_btShared, userPassword, passwordLength, 1, cipherSalt); + unsigned char dbHeader[KEYSALT_LENGTH]; + unsigned char* pDbHeader = (cipherSalt == NULL) ? mcReadDatabaseHeader(codec, dbHeader) : cipherSalt; + globalCodecDescriptorTable[codec->m_writeCipherType-1].m_generateKey(codec->m_writeCipher, userPassword, passwordLength, 1, pDbHeader); } SQLITE_PRIVATE int @@ -610,10 +653,10 @@ sqlite3mcConfigureSQLCipherVersion(sqlite3* db, int configDefault, int legacyVer static char* defNames[] = { "default:legacy_page_size", "default:kdf_iter", "default:hmac_use", "default:kdf_algorithm", "default:hmac_algorithm", NULL }; static int versionParams[SQLCIPHER_VERSION_MAX][5] = { - { 1024, 4000, 0, SQLCIPHER_KDF_ALGORITHM_SHA1, SQLCIPHER_HMAC_ALGORITHM_SHA1 }, - { 1024, 4000, 1, SQLCIPHER_KDF_ALGORITHM_SHA1, SQLCIPHER_HMAC_ALGORITHM_SHA1 }, - { 1024, 64000, 1, SQLCIPHER_KDF_ALGORITHM_SHA1, SQLCIPHER_HMAC_ALGORITHM_SHA1 }, - { 4096, 256000, 1, SQLCIPHER_KDF_ALGORITHM_SHA512, SQLCIPHER_HMAC_ALGORITHM_SHA512 } + { 1024, 4000, 0, SQLCIPHER_ALGORITHM_SHA1, SQLCIPHER_ALGORITHM_SHA1 }, + { 1024, 4000, 1, SQLCIPHER_ALGORITHM_SHA1, SQLCIPHER_ALGORITHM_SHA1 }, + { 1024, 64000, 1, SQLCIPHER_ALGORITHM_SHA1, SQLCIPHER_ALGORITHM_SHA1 }, + { 4096, 256000, 1, SQLCIPHER_ALGORITHM_SHA512, SQLCIPHER_ALGORITHM_SHA512 } }; if (legacyVersion > 0 && legacyVersion <= SQLCIPHER_VERSION_MAX) { diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.h index a1bae217c1..15bee4c5aa 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.h @@ -87,6 +87,7 @@ typedef struct _Codec unsigned char m_page[SQLITE_MAX_PAGE_SIZE + 24]; int m_pageSize; int m_reserved; + int m_lastError; int m_hasKeySalt; unsigned char m_keySalt[KEYSALT_LENGTH]; } Codec; @@ -158,6 +159,9 @@ SQLITE_PRIVATE int sqlite3mcGetReservedWriteCipher(Codec* codec); SQLITE_PRIVATE int sqlite3mcReservedEqual(Codec* codec); +SQLITE_PRIVATE void sqlite3mcSetCodecLastError(Codec* codec, int error); +SQLITE_PRIVATE int sqlite3mcGetCodecLastError(Codec* codec); + SQLITE_PRIVATE unsigned char* sqlite3mcGetSaltWriteCipher(Codec* codec); SQLITE_PRIVATE int sqlite3mcCodecCopy(Codec* codec, Codec* other); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.c index 6937968d7b..769ab52de9 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.c @@ -3,7 +3,7 @@ ** Purpose: Configuration of SQLite codecs ** Author: Ulrich Telle ** Created: 2020-03-02 -** Copyright: (c) 2006-2023 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -29,18 +29,7 @@ sqlite3mcConfigTable(sqlite3_context* context, int argc, sqlite3_value** argv) SQLITE_PRIVATE CodecParameter* sqlite3mcGetCodecParams(sqlite3* db) { - CodecParameter* codecParams = NULL; - sqlite3_stmt* pStmt = 0; - int rc = sqlite3_prepare_v2(db, "SELECT sqlite3mc_config_table();", -1, &pStmt, 0); - if (rc == SQLITE_OK) - { - if (SQLITE_ROW == sqlite3_step(pStmt)) - { - sqlite3_value* ptrValue = sqlite3_column_value(pStmt, 0); - codecParams = (CodecParameter*) sqlite3_value_pointer(ptrValue, "sqlite3mc_codec_params"); - } - sqlite3_finalize(pStmt); - } + CodecParameter* codecParams = (CodecParameter*) sqlite3_get_clientdata(db, globalConfigTableName); return codecParams; } @@ -188,6 +177,21 @@ sqlite3mc_cipher_name(int cipherIndex) return cipherName; } +static +int checkParameterValue(const char* paramName, int value) +{ + int ok = 1; + if (sqlite3_stricmp(paramName, "legacy_page_size") == 0 && value > 0) + { + ok = value >= 512 && value <= SQLITE_MAX_PAGE_SIZE && ((value - 1) & value) == 0; + } + if (ok && sqlite3_stricmp(paramName, "plaintext_header_size") == 0 && value > 0) + { + ok = value % 16 == 0; + } + return ok; +} + SQLITE_API int sqlite3mc_config_cipher(sqlite3* db, const char* cipherName, const char* paramName, int newValue) { @@ -294,7 +298,8 @@ sqlite3mc_config_cipher(sqlite3* db, const char* cipherName, const char* paramNa value = (hasDefaultPrefix) ? param->m_default : (hasMinPrefix) ? param->m_minValue : (hasMaxPrefix) ? param->m_maxValue : param->m_value; if (!hasMinPrefix && !hasMaxPrefix) { - if (newValue >= 0 && newValue >= param->m_minValue && newValue <= param->m_maxValue) + if (newValue >= 0 && newValue >= param->m_minValue && newValue <= param->m_maxValue && + checkParameterValue(paramName, newValue)) { if (hasDefaultPrefix) { @@ -763,20 +768,53 @@ sqlite3mcConfigureFromUri(sqlite3* db, const char *zDbName, int configDefault) } #endif +#if HAVE_CIPHER_AEGIS + int hasAegisAlgorithm = 0; + int aegisAlgorithm = 0; + if (sqlite3_stricmp(cipherName, "aegis") == 0) + { + const char* algorithm = sqlite3_uri_parameter(dbFileName, "algorithm"); + if (algorithm != NULL && *algorithm != 0) + { + int intValue = -1; + int isIntValue = sqlite3GetInt32(algorithm, &intValue) != 0; + if (!isIntValue) + { + intValue = sqlite3mcAegisAlgorithmToIndex(algorithm); + } + if (intValue > 0) + { + hasAegisAlgorithm = 1; + aegisAlgorithm = intValue; + } + } + } +#endif + /* Check all cipher specific parameters */ for (j = 0; cipherParams[j].m_name[0] != 0; ++j) { + int value = -1; if (skipLegacy && sqlite3_stricmp(cipherParams[j].m_name, "legacy") == 0) continue; - int value = (int) sqlite3_uri_int64(dbFileName, cipherParams[j].m_name, -1); +#if HAVE_CIPHER_AEGIS + if (hasAegisAlgorithm && sqlite3_stricmp(cipherParams[j].m_name, "algorithm") == 0) + { + value = aegisAlgorithm; + } + else +#endif + { + value = (int)sqlite3_uri_int64(dbFileName, cipherParams[j].m_name, -1); + } if (value >= 0) { /* Configure cipher parameter if it was given in the URI */ - char* param = (configDefault) ? sqlite3_mprintf("default:%s", cipherParams[j].m_name) : cipherParams[j].m_name; + const char* param = (configDefault) ? sqlite3_mprintf("default:%s", cipherParams[j].m_name) : cipherParams[j].m_name; sqlite3mc_config_cipher(db, cipherName, param, value); if (configDefault) { - sqlite3_free(param); + sqlite3_free((char*) param); } } } @@ -857,8 +895,16 @@ int libsql_extra_pragma(sqlite3* db, const char* zDbName, void* pArg) { value = sqlite3mc_config(db, "cipher", cipherId); } - rc = SQLITE_OK; - ((char**)pArg)[0] = sqlite3_mprintf("%s", globalCodecDescriptorTable[value - 1].m_name); + if (value > 0) + { + ((char**)pArg)[0] = sqlite3_mprintf("%s", globalCodecDescriptorTable[value - 1].m_name); + rc = SQLITE_OK; + } + else + { + ((char**)pArg)[0] = sqlite3_mprintf("Cipher '%s' could not be located.", pragmaValue); + rc = SQLITE_ERROR; + } } else { @@ -1049,6 +1095,19 @@ int libsql_extra_pragma(sqlite3* db, const char* zDbName, void* pArg) if (cipherParams != NULL) { const char* cipherName = globalCodecParameterTable[j].m_name; +#if HAVE_CIPHER_AEGIS + int isAegisAlgorithm = 0; + if (sqlite3_stricmp(cipherName, "aegis") == 0 && + sqlite3_stricmp(pragmaName, "algorithm") == 0) + { + if (!isIntValue) + { + intValue = sqlite3mcAegisAlgorithmToIndex(pragmaValue); + isIntValue = 1; + } + isAegisAlgorithm = 1; + } +#endif for (j = 0; cipherParams[j].m_name[0] != 0; ++j) { if (sqlite3_stricmp(pragmaName, cipherParams[j].m_name) == 0) break; @@ -1059,7 +1118,16 @@ int libsql_extra_pragma(sqlite3* db, const char* zDbName, void* pArg) if (isIntValue) { int value = sqlite3mc_config_cipher(db, cipherName, param, intValue); - ((char**)pArg)[0] = sqlite3_mprintf("%d", value); +#if HAVE_CIPHER_AEGIS + if (isAegisAlgorithm) + { + ((char**)pArg)[0] = sqlite3_mprintf("%s", sqlite3mcAegisAlgorithmToString(value)); + } + else +#endif + { + ((char**)pArg)[0] = sqlite3_mprintf("%d", value); + } rc = SQLITE_OK; } else diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.h index 5a57c70359..451b98ac54 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.h @@ -16,7 +16,7 @@ SQLITE_PRIVATE void sqlite3mcConfigTable(sqlite3_context* context, int argc, sql SQLITE_PRIVATE CodecParameter* sqlite3mcGetCodecParams(sqlite3* db); /* Forward declaration */ -static unsigned char* sqlite3mcGetSaltWriteCipher(Codec* codec); +SQLITE_PRIVATE unsigned char* sqlite3mcGetSaltWriteCipher(Codec* codec); SQLITE_PRIVATE void sqlite3mcCodecDataSql(sqlite3_context* context, int argc, sqlite3_value** argv); SQLITE_PRIVATE void sqlite3mcConfigParams(sqlite3_context* context, int argc, sqlite3_value** argv); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sds_rc4.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sds_rc4.c index eda420f88c..2b940984b1 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sds_rc4.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sds_rc4.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher System.Data.SQLite3 RC4 ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -116,7 +116,7 @@ GetSaltRC4Cipher(void* cipher) } static void -GenerateKeyRC4Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyRC4Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { RC4Cipher* rc4Cipher = (RC4Cipher*) cipher; unsigned char digest[SHA1_DIGEST_SIZE]; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sqlcipher.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sqlcipher.c index e97467ff24..f356fe0723 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sqlcipher.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sqlcipher.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher SQLCipher (version 1 to 4) ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -31,13 +31,11 @@ #define SQLCIPHER_HMAC_PGNO_NATIVE 0 #define SQLCIPHER_HMAC_SALT_MASK 0x3a -#define SQLCIPHER_KDF_ALGORITHM_SHA1 0 -#define SQLCIPHER_KDF_ALGORITHM_SHA256 1 -#define SQLCIPHER_KDF_ALGORITHM_SHA512 2 +#define SQLCIPHER_ALGORITHM_SHA1 0 +#define SQLCIPHER_ALGORITHM_SHA256 1 +#define SQLCIPHER_ALGORITHM_SHA512 2 -#define SQLCIPHER_HMAC_ALGORITHM_SHA1 0 -#define SQLCIPHER_HMAC_ALGORITHM_SHA256 1 -#define SQLCIPHER_HMAC_ALGORITHM_SHA512 2 +#define SQLCIPHER_HMAC_ALGO_COMPAT 1 #define SQLCIPHER_VERSION_1 1 #define SQLCIPHER_VERSION_2 2 @@ -58,13 +56,13 @@ #if SQLCIPHER_VERSION_DEFAULT < SQLCIPHER_VERSION_4 #define SQLCIPHER_KDF_ITER 64000 #define SQLCIPHER_LEGACY_PAGE_SIZE 1024 -#define SQLCIPHER_KDF_ALGORITHM SQLCIPHER_KDF_ALGORITHM_SHA1 -#define SQLCIPHER_HMAC_ALGORITHM SQLCIPHER_HMAC_ALGORITHM_SHA1 +#define SQLCIPHER_KDF_ALGORITHM SQLCIPHER_ALGORITHM_SHA1 +#define SQLCIPHER_HMAC_ALGORITHM SQLCIPHER_ALGORITHM_SHA1 #else #define SQLCIPHER_KDF_ITER 256000 #define SQLCIPHER_LEGACY_PAGE_SIZE 4096 -#define SQLCIPHER_KDF_ALGORITHM SQLCIPHER_KDF_ALGORITHM_SHA512 -#define SQLCIPHER_HMAC_ALGORITHM SQLCIPHER_HMAC_ALGORITHM_SHA512 +#define SQLCIPHER_KDF_ALGORITHM SQLCIPHER_ALGORITHM_SHA512 +#define SQLCIPHER_HMAC_ALGORITHM SQLCIPHER_ALGORITHM_SHA512 #endif SQLITE_PRIVATE CipherParams mcSQLCipherParams[] = @@ -78,6 +76,7 @@ SQLITE_PRIVATE CipherParams mcSQLCipherParams[] = { "hmac_salt_mask", SQLCIPHER_HMAC_SALT_MASK, SQLCIPHER_HMAC_SALT_MASK, 0x00, 0xff }, { "kdf_algorithm", SQLCIPHER_KDF_ALGORITHM, SQLCIPHER_KDF_ALGORITHM, 0, 2 }, { "hmac_algorithm", SQLCIPHER_HMAC_ALGORITHM, SQLCIPHER_HMAC_ALGORITHM, 0, 2 }, + { "hmac_algorithm_compat", SQLCIPHER_HMAC_ALGO_COMPAT, SQLCIPHER_HMAC_ALGO_COMPAT, 0, 1 }, { "plaintext_header_size", 0, 0, 0, 100 /* restrict to db header size */ }, CIPHER_PARAMS_SENTINEL }; @@ -98,6 +97,7 @@ typedef struct _sqlCipherCipher int m_hmacSaltMask; int m_kdfAlgorithm; int m_hmacAlgorithm; + int m_hmacAlgorithmCompat; int m_plaintextHeaderSize; int m_keyLength; uint8_t m_key[KEYLENGTH_SQLCIPHER]; @@ -139,6 +139,7 @@ AllocateSQLCipherCipher(sqlite3* db) sqlCipherCipher->m_hmacSaltMask = sqlite3mcGetCipherParameter(cipherParams, "hmac_salt_mask"); sqlCipherCipher->m_kdfAlgorithm = sqlite3mcGetCipherParameter(cipherParams, "kdf_algorithm"); sqlCipherCipher->m_hmacAlgorithm = sqlite3mcGetCipherParameter(cipherParams, "hmac_algorithm"); + sqlCipherCipher->m_hmacAlgorithmCompat = sqlite3mcGetCipherParameter(cipherParams, "hmac_algorithm_compat"); if (sqlCipherCipher->m_legacy >= SQLCIPHER_VERSION_4) { int plaintextHeaderSize = sqlite3mcGetCipherParameter(cipherParams, "plaintext_header_size"); @@ -176,6 +177,7 @@ CloneSQLCipherCipher(void* cipherTo, void* cipherFrom) sqlCipherCipherTo->m_hmacSaltMask = sqlCipherCipherFrom->m_hmacSaltMask; sqlCipherCipherTo->m_kdfAlgorithm = sqlCipherCipherFrom->m_kdfAlgorithm; sqlCipherCipherTo->m_hmacAlgorithm = sqlCipherCipherFrom->m_hmacAlgorithm; + sqlCipherCipherTo->m_hmacAlgorithmCompat = sqlCipherCipherFrom->m_hmacAlgorithmCompat; sqlCipherCipherTo->m_plaintextHeaderSize = sqlCipherCipherFrom->m_plaintextHeaderSize; sqlCipherCipherTo->m_keyLength = sqlCipherCipherFrom->m_keyLength; memcpy(sqlCipherCipherTo->m_key, sqlCipherCipherFrom->m_key, KEYLENGTH_SQLCIPHER); @@ -217,11 +219,11 @@ GetReservedSQLCipherCipher(void* cipher) { switch (sqlCipherCipher->m_hmacAlgorithm) { - case SQLCIPHER_HMAC_ALGORITHM_SHA1: - case SQLCIPHER_HMAC_ALGORITHM_SHA256: + case SQLCIPHER_ALGORITHM_SHA1: + case SQLCIPHER_ALGORITHM_SHA256: reserved += SHA256_DIGEST_SIZE; break; - case SQLCIPHER_HMAC_ALGORITHM_SHA512: + case SQLCIPHER_ALGORITHM_SHA512: default: reserved += SHA512_DIGEST_SIZE; break; @@ -238,18 +240,15 @@ GetSaltSQLCipherCipher(void* cipher) } static void -GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeySQLCipherCipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { SQLCipherCipher* sqlCipherCipher = (SQLCipherCipher*) cipher; - Pager *pPager = pBt->pPager; - sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL; - - if (rekey || fd == NULL || sqlite3OsRead(fd, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, 0) != SQLITE_OK) + if (rekey || cipherSalt == NULL) { chacha20_rng(sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER); } - else if (cipherSalt != NULL) + else { memcpy(sqlCipherCipher->m_salt, cipherSalt, SALTLENGTH_SQLCIPHER); } @@ -271,19 +270,19 @@ GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int { switch (sqlCipherCipher->m_kdfAlgorithm) { - case SQLCIPHER_KDF_ALGORITHM_SHA1: + case SQLCIPHER_ALGORITHM_SHA1: fastpbkdf2_hmac_sha1((unsigned char*) userPassword, passwordLength, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, sqlCipherCipher->m_kdfIter, sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER); break; - case SQLCIPHER_KDF_ALGORITHM_SHA256: + case SQLCIPHER_ALGORITHM_SHA256: fastpbkdf2_hmac_sha256((unsigned char*) userPassword, passwordLength, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, sqlCipherCipher->m_kdfIter, sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER); break; - case SQLCIPHER_KDF_ALGORITHM_SHA512: + case SQLCIPHER_ALGORITHM_SHA512: default: fastpbkdf2_hmac_sha512((unsigned char*) userPassword, passwordLength, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, @@ -296,6 +295,7 @@ GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int if (sqlCipherCipher->m_hmacUse != 0) { int j; + int algorithm = (sqlCipherCipher->m_hmacAlgorithmCompat) ? sqlCipherCipher->m_kdfAlgorithm : sqlCipherCipher->m_hmacAlgorithm; unsigned char hmacSaltMask = sqlCipherCipher->m_hmacSaltMask; unsigned char hmacSalt[SALTLENGTH_SQLCIPHER]; memcpy(hmacSalt, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER); @@ -303,21 +303,21 @@ GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int { hmacSalt[j] ^= hmacSaltMask; } - switch (sqlCipherCipher->m_hmacAlgorithm) + switch (algorithm) { - case SQLCIPHER_HMAC_ALGORITHM_SHA1: + case SQLCIPHER_ALGORITHM_SHA1: fastpbkdf2_hmac_sha1(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER, hmacSalt, SALTLENGTH_SQLCIPHER, sqlCipherCipher->m_fastKdfIter, sqlCipherCipher->m_hmacKey, KEYLENGTH_SQLCIPHER); break; - case SQLCIPHER_HMAC_ALGORITHM_SHA256: + case SQLCIPHER_ALGORITHM_SHA256: fastpbkdf2_hmac_sha256(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER, hmacSalt, SALTLENGTH_SQLCIPHER, sqlCipherCipher->m_fastKdfIter, sqlCipherCipher->m_hmacKey, KEYLENGTH_SQLCIPHER); break; - case SQLCIPHER_HMAC_ALGORITHM_SHA512: + case SQLCIPHER_ALGORITHM_SHA512: default: fastpbkdf2_hmac_sha512(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER, hmacSalt, SALTLENGTH_SQLCIPHER, @@ -334,11 +334,13 @@ GetHmacSizeSQLCipherCipher(int algorithm) int hmacSize = SHA512_DIGEST_SIZE; switch (algorithm) { - case SQLCIPHER_HMAC_ALGORITHM_SHA1: + case SQLCIPHER_ALGORITHM_SHA1: hmacSize = SHA1_DIGEST_SIZE; break; - case SQLCIPHER_HMAC_ALGORITHM_SHA256: - case SQLCIPHER_HMAC_ALGORITHM_SHA512: + case SQLCIPHER_ALGORITHM_SHA256: + hmacSize = SHA256_DIGEST_SIZE; + break; + case SQLCIPHER_ALGORITHM_SHA512: default: hmacSize = SHA512_DIGEST_SIZE; break; @@ -356,7 +358,7 @@ EncryptPageSQLCipherCipher(void* cipher, int page, unsigned char* data, int len, int n = len - nReserved; int offset = (page == 1) ? (sqlCipherCipher->m_legacy != 0) ? 16 : 24 : 0; int blen; - unsigned char iv[64]; + unsigned char iv[128]; int usePlaintextHeader = 0; /* Check whether a plaintext header should be used */ @@ -373,10 +375,10 @@ EncryptPageSQLCipherCipher(void* cipher, int page, unsigned char* data, int len, } /* Generate nonce (64 bytes) */ - memset(iv, 0, 64); + memset(iv, 0, 128); if (nReserved > 0) { - chacha20_rng(iv, 64); + chacha20_rng(iv, 128); } else { diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes128.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes128.c index e84a88009f..67be9c21a7 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes128.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes128.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher wxSQLite3 AES 128-bit ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -130,7 +130,7 @@ GetSaltAES128Cipher(void* cipher) } static void -GenerateKeyAES128Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyAES128Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { AES128Cipher* aesCipher = (AES128Cipher*) cipher; unsigned char userPad[32]; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes256.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes256.c index 906888a555..5fa8ba76b6 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes256.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes256.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher wxSQLite3 AES 256-bit ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -136,7 +136,7 @@ GetSaltAES256Cipher(void* cipher) } static void -GenerateKeyAES256Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyAES256Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { AES256Cipher* aesCipher = (AES256Cipher*) cipher; unsigned char userPad[32]; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codec_algos.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codec_algos.c index 7efa5db7c9..3c1951a2d5 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codec_algos.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codec_algos.c @@ -135,7 +135,7 @@ sqlite3mcAES128(Rijndael* aesCtx, int page, int encrypt, unsigned char encryptio { len = RijndaelBlockDecrypt(aesCtx, datain, datalen*8, dataout); } - + /* It is a good idea to check the error code */ if (len < 0) { @@ -189,7 +189,7 @@ sqlite3mcAES256(Rijndael* aesCtx, int page, int encrypt, unsigned char encryptio { len = RijndaelBlockDecrypt(aesCtx, datain, datalen*8, dataout); } - + /* It is a good idea to check the error code */ if (len < 0) { diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c index 6754109ebc..22b7e39874 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c @@ -65,7 +65,7 @@ sqlite3_activate_see(const char *info) /* ** Free the encryption data structure associated with a pager instance. -** (called from the modified code in pager.c) +** (called from the modified code in pager.c) */ SQLITE_PRIVATE void sqlite3mcCodecFree(void *pCodecArg) @@ -95,12 +95,15 @@ mcReportCodecError(BtShared* pBt, int error) { pBt->pPager->eState = PAGER_ERROR; } - setGetterMethod(pBt->pPager); if (error == SQLITE_OK) { /* Clear cache to force reread of database after a new passphrase has been set */ sqlite3PagerClearCache(pBt->pPager); + /* unlock required? + pager_unlock(pBt->pPager); + */ } + setGetterMethod(pBt->pPager); } /* @@ -119,6 +122,7 @@ sqlite3mcCodec(void* pCodecArg, void* data, Pgno nPageNum, int nMode) codec = (Codec*) pCodecArg; if (!sqlite3mcIsEncrypted(codec)) { + sqlite3mcSetCodecLastError(codec, rc); return data; } @@ -132,7 +136,11 @@ sqlite3mcCodec(void* pCodecArg, void* data, Pgno nPageNum, int nMode) if (sqlite3mcHasReadCipher(codec)) { rc = sqlite3mcDecrypt(codec, nPageNum, (unsigned char*) data, pageSize); - if (rc != SQLITE_OK) mcReportCodecError(sqlite3mcGetBtShared(codec), rc); + if (rc != SQLITE_OK) + { + mcReportCodecError(sqlite3mcGetBtShared(codec), rc); + memset(data, 0, pageSize); + } } break; @@ -166,6 +174,7 @@ sqlite3mcCodec(void* pCodecArg, void* data, Pgno nPageNum, int nMode) } break; } + sqlite3mcSetCodecLastError(codec, rc); return data; } @@ -175,6 +184,9 @@ sqlite3mcGetMainCodec(sqlite3* db); SQLITE_PRIVATE void sqlite3mcSetCodec(sqlite3* db, const char* zDbName, const char* zFileName, Codec* codec); +SQLITE_PRIVATE int +sqlite3mcIsEncryptionSupported(sqlite3* db, const char* zDbName); + static int mcAdjustBtree(Btree* pBt, int nPageSize, int nReserved, int isLegacy) { @@ -190,11 +202,12 @@ mcAdjustBtree(Btree* pBt, int nPageSize, int nReserved, int isLegacy) /* Adjust the page size and the reserved area */ if (pager->pageSize != pagesize || pager->nReserve != nReserved) { + int reserved = (nReserved >= 0) ? nReserved : 0; if (isLegacy != 0) { pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; } - rc = sqlite3BtreeSetPageSize(pBt, pagesize, nReserved, 0); + rc = sqlite3BtreeSetPageSize(pBt, pagesize, reserved, 0); } return rc; } @@ -332,6 +345,11 @@ SQLITE_API int sqlite3_key_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) { int rc = SQLITE_ERROR; + if (!sqlite3mcIsEncryptionSupported(db, zDbName)) + { + sqlite3ErrorWithMsg(db, rc, "Setting key failed. Encryption is not supported by the VFS."); + return rc; + } if (zKey != NULL && nKey < 0) { /* Key is zero-terminated string */ @@ -348,7 +366,8 @@ sqlite3_key_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) return rc; } /* Configure cipher from URI parameters if requested */ - if (sqlite3FindFunction(db, "sqlite3mc_config_table", 0, SQLITE_UTF8, 0) == NULL) + void* codecParamTable = sqlite3_get_clientdata(db, globalConfigTableName); + if (codecParamTable == NULL) { /* ** Encryption extension of database connection not yet initialized; @@ -384,7 +403,15 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) int nReserved; Pager* pPager; Codec* codec; + int codecAllocated = 0; int rc = SQLITE_ERROR; + char* err = NULL; + + if (!sqlite3mcIsEncryptionSupported(db, zDbName)) + { + sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Encryption is not supported by the VFS."); + return rc; + } if (zKey != NULL && nKey < 0) { /* Key is zero-terminated string */ @@ -417,10 +444,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) sqlite3ErrorWithMsg(db, rc, "Rekeying is not supported in WAL journal mode."); return rc; } - + if ((zKey == NULL || nKey == 0) && (codec == NULL || !sqlite3mcIsEncrypted(codec))) { - /* Database not encrypted and key not specified, therefore do nothing */ + /* Database not encrypted and key not specified, therefore do nothing */ return SQLITE_OK; } @@ -428,9 +455,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) if (codec == NULL || !sqlite3mcIsEncrypted(codec)) { - /* Database not encrypted, but key specified, therefore encrypt database */ + /* Database not encrypted, but key specified, therefore encrypt database */ if (codec == NULL) { + codecAllocated = 1; codec = (Codec*) sqlite3_malloc(sizeof(Codec)); rc = (codec != NULL) ? sqlite3mcCodecInit(codec) : SQLITE_NOMEM; } @@ -454,14 +482,9 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) if (nReserved != nReservedWriteCipher) { /* Use VACUUM to change the number of reserved bytes */ - char* err = NULL; sqlite3mcSetReadReserved(codec, nReserved); sqlite3mcSetWriteReserved(codec, nReservedWriteCipher); rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, nReservedWriteCipher); - if (rc != SQLITE_OK && err != NULL) - { - sqlite3ErrorWithMsg(db, rc, err); - } goto leave_rekey; } } @@ -469,12 +492,17 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) { /* Pagesize cannot be changed for an encrypted database */ rc = SQLITE_ERROR; - sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Pagesize cannot be changed for an encrypted database."); + err = "Rekeying failed. Pagesize cannot be changed for an encrypted database."; goto leave_rekey; } } else { + sqlite3_mutex_leave(db->mutex); + if (codecAllocated) + { + sqlite3mcCodecFree(codec); + } return rc; } } @@ -486,14 +514,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) if (nReserved > 0) { /* Use VACUUM to change the number of reserved bytes */ - char* err = NULL; + err = NULL; sqlite3mcSetReadReserved(codec, nReserved); sqlite3mcSetWriteReserved(codec, 0); rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, 0); - if (rc != SQLITE_OK && err != NULL) - { - sqlite3ErrorWithMsg(db, rc, err); - } goto leave_rekey; } } @@ -511,14 +535,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) if (nReserved != nReservedWriteCipher) { /* Use VACUUM to change the number of reserved bytes */ - char* err = NULL; + err = NULL; sqlite3mcSetReadReserved(codec, nReserved); sqlite3mcSetWriteReserved(codec, nReservedWriteCipher); rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, nReservedWriteCipher); - if (rc != SQLITE_OK && err != NULL) - { - sqlite3ErrorWithMsg(db, rc, err); - } goto leave_rekey; } } @@ -526,14 +546,14 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) { /* Pagesize cannot be changed for an encrypted database */ rc = SQLITE_ERROR; - sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Pagesize cannot be changed for an encrypted database."); + err = "Rekeying failed. Pagesize cannot be changed for an encrypted database."; goto leave_rekey; } } else { /* Setup of write cipher failed */ - sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Setup of write cipher failed."); + err = "Rekeying failed. Setup of write cipher failed."; goto leave_rekey; } } @@ -584,8 +604,15 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) /* Set read key equal to write key if necessary */ if (sqlite3mcHasWriteCipher(codec)) { + /* Set Read cipher equal to Write cipher */ sqlite3mcCopyCipher(codec, 0); sqlite3mcSetHasReadCipher(codec, 1); + + /* Enforce page size and number of reserved bytes per page */ + int pageSize = sqlite3mcGetPageSizeWriteCipher(codec); + int reserved = sqlite3mcGetReservedWriteCipher(codec); + mcAdjustBtree(pBt, pageSize, reserved, sqlite3mcGetLegacyWriteCipher(codec)); + sqlite3mcCodecSizeChange(codec, pageSize, reserved); } else { @@ -615,6 +642,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) /* Remove codec for unencrypted database */ sqlite3mcSetCodec(db, zDbName, dbFileName, NULL); } + if (rc != SQLITE_OK && err != NULL) + { + sqlite3ErrorWithMsg(db, rc, err); + } return rc; } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/compress.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/compress.c index e6534e8a23..3fdf285865 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/compress.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/compress.c @@ -107,19 +107,19 @@ static void uncompressFunc( } } - -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_compress_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "compress", 1, + rc = sqlite3_create_function(db, "compress", 1, SQLITE_UTF8 | SQLITE_INNOCUOUS, 0, compressFunc, 0, 0); if( rc==SQLITE_OK ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/csv.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/csv.c index f980dfb028..78024a1244 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/csv.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/csv.c @@ -170,7 +170,7 @@ static int csv_getc(CsvReader *p){ return ((unsigned char*)p->zIn)[p->iIn++]; } -/* Increase the size of p->z and append character c to the end. +/* Increase the size of p->z and append character c to the end. ** Return 0 on success and non-zero if there is an OOM error */ static CSV_NOINLINE int csv_resize_and_append(CsvReader *p, char c){ char *zNew; @@ -289,9 +289,9 @@ static char *csv_read_one_field(CsvReader *p){ /* Forward references to the various virtual table methods implemented ** in this file. */ -static int csvtabCreate(sqlite3*, void*, int, const char*const*, +static int csvtabCreate(sqlite3*, void*, int, const char*const*, sqlite3_vtab**,char**); -static int csvtabConnect(sqlite3*, void*, int, const char*const*, +static int csvtabConnect(sqlite3*, void*, int, const char*const*, sqlite3_vtab**,char**); static int csvtabBestIndex(sqlite3_vtab*,sqlite3_index_info*); static int csvtabDisconnect(sqlite3_vtab*); @@ -476,7 +476,7 @@ static int csv_boolean_parameter( ** columns=N Assume the CSV file contains N columns. ** ** Only available if compiled with SQLITE_TEST: -** +** ** testflags=N Bitmask of test flags. Optional ** ** If schema= is omitted, then the columns are named "c0", "c1", "c2", @@ -503,7 +503,7 @@ static int csvtabConnect( CsvReader sRdr; /* A CSV file reader used to store an error ** message and/or to count the number of columns */ static const char *azParam[] = { - "filename", "data", "schema", + "filename", "data", "schema", }; char *azPValue[3]; /* Parameter values */ # define CSV_FILENAME (azPValue[0]) @@ -805,7 +805,7 @@ static int csvtabEof(sqlite3_vtab_cursor *cur){ ** the beginning. */ static int csvtabFilter( - sqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -861,7 +861,7 @@ static int csvtabBestIndex( unsigned char op; if( pIdxInfo->aConstraint[i].usable==0 ) continue; op = pIdxInfo->aConstraint[i].op; - if( op==SQLITE_INDEX_CONSTRAINT_EQ + if( op==SQLITE_INDEX_CONSTRAINT_EQ || op==SQLITE_INDEX_CONSTRAINT_LIKE || op==SQLITE_INDEX_CONSTRAINT_GLOB ){ @@ -944,18 +944,18 @@ static sqlite3_module CsvModuleFauxWrite = { #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ - -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif -/* +/* ** This routine is called when the extension is loaded. The new ** CSV virtual table module is registered with the calling database ** connection. */ +SQLITE_API int sqlite3_csv_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ #ifndef SQLITE_OMIT_VIRTUALTABLE diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/extensionfunctions.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/extensionfunctions.c index 5dcaa10cdf..2e38d54f60 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/extensionfunctions.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/extensionfunctions.c @@ -54,7 +54,7 @@ Usage instructions for the sqlite3 program: security measure; see "Security Considerations" in http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions. If the sqlite3 program and library are built this - way, you cannot use these functions from the program, you + way, you cannot use these functions from the program, you must write your own program using the sqlite3 API, and call sqlite3_enable_load_extension as described above, or else rebuilt the sqlite3 program to allow loadable extensions. @@ -125,7 +125,7 @@ Original code 2006 June 05 by relicoder. #define HAVE_ISBLANK 1 #endif #define SQLITE_SOUNDEX 1 -#define HAVE_TRIM 1 /* LMH 2007-03-25 if sqlite has trim functions */ +#define HAVE_TRIM 1 /* LMH 2007-03-25 if sqlite has trim functions */ #ifdef COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE #include "sqlite3ext.h" @@ -139,7 +139,7 @@ SQLITE_EXTENSION_INIT1 #include #include #include -#include /* LMH 2007-03-25 */ +#include /* LMH 2007-03-25 */ #include #include @@ -319,7 +319,7 @@ static int sqlite3ReadUtf8(const unsigned char *z){ ** pZ is a UTF-8 encoded unicode string. If nByte is less than zero, ** return the number of unicode characters in pZ up to (but not including) ** the first 0x00 byte. If nByte is not less than zero, return the -** number of unicode characters in the first nByte of pZ (or up to +** number of unicode characters in the first nByte of pZ (or up to ** the first 0x00, whichever comes first). */ static int sqlite3Utf8CharLen(const char *z, int nByte){ @@ -354,7 +354,7 @@ static int sqlite3Utf8CharLen(const char *z, int nByte){ ** ** Could have been implemented using pointers to functions but this way it's inline ** and thus more efficient. Lower * ranking though... -** +** ** Parameters: ** name: function name to de defined (eg: sinFunc) ** function: function defined in math.h to wrap (eg: sin) @@ -400,7 +400,7 @@ GEN_MATH_WRAP_DOUBLE_1(atanFunc, atan) /* ** Many of systems don't have inverse hyperbolic trig functions so this will emulate -** them on those systems in terms of log and sqrt (formulas are too trivial to demand +** them on those systems in terms of log and sqrt (formulas are too trivial to demand ** written proof here) */ @@ -572,7 +572,7 @@ static void squareFunc(sqlite3_context *context, int argc, sqlite3_value **argv) ** (see sqrt just before this). Here the result is always double */ /* LMH 2007-03-25 Changed to use errno; no pre-checking for errors. Also removes - but that was present in the pre-checking that called sqlite3_result_error on + but that was present in the pre-checking that called sqlite3_result_error on a non-positive first argument, which is not always an error. */ static void powerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ double r1 = 0.0; @@ -580,9 +580,9 @@ static void powerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ double val; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ r1 = sqlite3_value_double(argv[0]); r2 = sqlite3_value_double(argv[1]); @@ -590,9 +590,9 @@ static void powerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ val = pow(r1,r2); if (errno == 0) { sqlite3_result_double(context, val); - } else { + } else { sqlite3_result_error(context, strerror(errno), errno); - } + } } } @@ -606,9 +606,9 @@ static void atn2Func(sqlite3_context *context, int argc, sqlite3_value **argv){ double r2 = 0.0; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ r1 = sqlite3_value_double(argv[0]); r2 = sqlite3_value_double(argv[1]); @@ -705,14 +705,14 @@ static void floorFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ /* -** Given a string (s) in the first argument and an integer (n) in the second returns the +** Given a string (s) in the first argument and an integer (n) in the second returns the ** string that constains s contatenated n times */ static void replicateFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ unsigned char *z; /* input string */ unsigned char *zo; /* result string */ i64 iCount; /* times to repeat */ - i64 nLen; /* length of the input string (no multibyte considerations) */ + i64 nLen; /* length of the input string (no multibyte considerations) */ i64 nTLen; /* length of the result string (no multibyte considerations) */ i64 i=0; @@ -747,7 +747,7 @@ static void replicateFunc(sqlite3_context *context, int argc, sqlite3_value **ar } } -/* +/* ** Some systems (win32 among others) don't have an isblank function, this will emulate it. ** This function is not UFT-8 safe since it only analyses a byte character. */ @@ -812,9 +812,9 @@ static void padlFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *zt; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ zi = (char *)sqlite3_value_text(argv[0]); ilen = sqlite3_value_int64(argv[1]); @@ -866,9 +866,9 @@ static void padrFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *zt; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ zi = (char *)sqlite3_value_text(argv[0]); ilen = sqlite3_value_int64(argv[1]); @@ -921,9 +921,9 @@ static void padcFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *zt; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ zi = (char *)sqlite3_value_text(argv[0]); ilen = sqlite3_value_int64(argv[1]); @@ -980,17 +980,17 @@ static void strfilterFunc(sqlite3_context *context, int argc, sqlite3_value **ar int c2 = 0; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ zi1 = (char *)sqlite3_value_text(argv[0]); zi2 = (char *)sqlite3_value_text(argv[1]); - /* - ** maybe I could allocate less, but that would imply 2 passes, rather waste + /* + ** maybe I could allocate less, but that would imply 2 passes, rather waste ** (possibly) some memory */ - zo = sqlite3_malloc((int) (strlen(zi1)+1)); + zo = sqlite3_malloc((int) (strlen(zi1)+1)); if (!zo){ sqlite3_result_error_nomem(context); return; @@ -1034,11 +1034,11 @@ static int _substr(const char* z1, const char* z2, int s, const char** p){ if( '\0'==*z1 ){ return -1; } - + while( (sqliteCharVal((unsigned char *)z2) != 0) && (c++) 0 ){ sqliteNextChar(zt); } @@ -1186,7 +1186,7 @@ static void rightFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ return; } strcpy((char*) rz, (char*) (zt)); - sqlite3_result_text(context, (char*)rz, -1, SQLITE_TRANSIENT); + sqlite3_result_text(context, (char*)rz, -1, SQLITE_TRANSIENT); sqlite3_free(rz); } @@ -1224,7 +1224,7 @@ static void ltrimFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ return; } z = sqlite3_value_text(argv[0]); - sqlite3_result_text(context, ltrim(z), -1, SQLITE_TRANSIENT); + sqlite3_result_text(context, ltrim(z), -1, SQLITE_TRANSIENT); } /* @@ -1465,7 +1465,7 @@ static void modeStep(sqlite3_context *context, int argc, sqlite3_value **argv){ if( type == SQLITE_NULL) return; - + p = sqlite3_aggregate_context(context, sizeof(*p)); if( 0==(p->m) ){ @@ -1504,33 +1504,33 @@ static void modeIterate(void* e, i64 c, void* pp){ i64 ei; double ed; ModeCtx *p = (ModeCtx*)pp; - + if( 0==p->is_double ){ ei = *(int*)(e); - if( p->mcnt==c ){ + if( p->mcnt==c ){ ++p->mn; }else if( p->mcntriM = ei; p->mcnt = c; - p->mn=1; + p->mn=1; } }else{ ed = *(double*)(e); - if( p->mcnt==c ){ + if( p->mcnt==c ){ ++p->mn; }else if(p->mcntrdM = ed; p->mcnt = c; - p->mn=1; + p->mn=1; } } } /* ** Auxiliary function that iterates all elements in a map and finds the median -** (the value such that the number of elements smaller is equal the the number of +** (the value such that the number of elements smaller is equal the the number of ** elements larger) */ static void medianIterate(void* e, i64 c, void* pp){ @@ -1601,9 +1601,9 @@ static void _medianFinalize(sqlite3_context *context){ if( 0==p->is_double ) if( 1==p->mn ) - sqlite3_result_int64(context, p->riM); + sqlite3_result_int64(context, p->riM); else - sqlite3_result_double(context, p->riM*1.0/p->mn); + sqlite3_result_double(context, p->riM*1.0/p->mn); else sqlite3_result_double(context, p->rdM/p->mn); } @@ -1723,12 +1723,12 @@ static void differenceFunc(sqlite3_context *context, int argc, sqlite3_value **a const u8 *zIn2; assert( argc==2 ); - + if( sqlite3_value_type(argv[0])==SQLITE_NULL || sqlite3_value_type(argv[1])==SQLITE_NULL ){ sqlite3_result_null(context); return; } - + zIn1 = (u8*)sqlite3_value_text(argv[0]); zIn2 = (u8*)sqlite3_value_text(argv[1]); @@ -1865,7 +1865,7 @@ int RegisterExtensionFunctions(sqlite3 *db){ aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0); #if 0 if( aFuncs[i].needCollSeq ){ - struct FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, + struct FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0); if( pFunc && aFuncs[i].needCollSeq ){ pFunc->needCollSeq = 1; @@ -1882,7 +1882,7 @@ int RegisterExtensionFunctions(sqlite3 *db){ } /* sqlite3CreateFunc */ /* LMH no error checking */ - sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, + sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize); #if 0 if( aAggs[i].needCollSeq ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.c index a190f7616a..7ed8e16b80 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.c @@ -391,6 +391,7 @@ DECL_PBKDF2(sha512, sha512_extract, sha512_xor) +SQLITE_PRIVATE void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -402,6 +403,7 @@ void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, #endif } +SQLITE_PRIVATE void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -410,6 +412,7 @@ void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, PBKDF2(sha256)(pw, npw, salt, nsalt, iterations, out, nout); } +SQLITE_PRIVATE void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -418,6 +421,7 @@ void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, PBKDF2(sha512)(pw, npw, salt, nsalt, iterations, out, nout); } +SQLITE_PRIVATE void sqlcipher_hmac(int algorithm, unsigned char* key, int nkey, unsigned char* in, int in_sz, unsigned char* in2, int in2_sz, unsigned char* out) { switch (algorithm) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.h index 75f7e2c742..d523314576 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.h @@ -15,6 +15,10 @@ #ifndef FASTPBKDF2_H #define FASTPBKDF2_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #include #include "mystdint.h" @@ -31,6 +35,7 @@ extern "C" { * * This function cannot fail; it does not report errors. */ +SQLITE_PRIVATE void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -45,6 +50,7 @@ void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, * * This function cannot fail; it does not report errors. */ +SQLITE_PRIVATE void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -59,6 +65,7 @@ void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, * * This function cannot fail; it does not report errors. */ +SQLITE_PRIVATE void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -68,6 +75,7 @@ void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, * * This function cannot fail; it does not report errors. */ +SQLITE_PRIVATE void sqlcipher_hmac(int algorithm, unsigned char* key, int nkey, unsigned char* in, int in_sz, diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fileio.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fileio.c index ca8090ed2e..a9b5316026 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fileio.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fileio.c @@ -40,7 +40,7 @@ ** modification-time of the target file is set to this value before ** returning. ** -** If three or more arguments are passed to this function and an +** If five or more arguments are passed to this function and an ** error is encountered, an exception is raised. ** ** READFILE(FILE): @@ -69,8 +69,8 @@ ** directory, NULL. ** ** If a non-NULL value is specified for the optional $dir parameter and -** $path is a relative path, then $path is interpreted relative to $dir. -** And the paths returned in the "name" column of the table are also +** $path is a relative path, then $path is interpreted relative to $dir. +** And the paths returned in the "name" column of the table are also ** relative to directory $dir. ** ** Notes on building this extension for Windows: @@ -110,6 +110,13 @@ SQLITE_EXTENSION_INIT1 #include #include +/* When used as part of the CLI, the sqlite3_stdio.h module will have +** been included before this one. In that case use the sqlite3_stdio.h +** #defines. If not, create our own for fopen(). +*/ +#ifndef _SQLITE3_STDIO_H_ +# define sqlite3_fopen fopen +#endif /* ** Structure of the fsdir() table-valued function @@ -125,7 +132,7 @@ SQLITE_EXTENSION_INIT1 /* -** Set the result stored by context ctx to a blob containing the +** Set the result stored by context ctx to a blob containing the ** contents of file zName. Or, leave the result unchanged (NULL) ** if the file does not exist or is unreadable. ** @@ -142,7 +149,7 @@ static void readFileContents(sqlite3_context *ctx, const char *zName){ sqlite3 *db; int mxBlob; - in = fopen(zName, "rb"); + in = sqlite3_fopen(zName, "rb"); if( in==0 ){ /* File does not exist or is unreadable. Leave the result set to NULL. */ return; @@ -358,7 +365,7 @@ static int makeDirectory( } /* -** This function does the work for the writefile() UDF. Refer to +** This function does the work for the writefile() UDF. Refer to ** header comments at the top of this file for details. */ static int writeFile( @@ -397,7 +404,7 @@ static int writeFile( sqlite3_int64 nWrite = 0; const char *z; int rc = 0; - FILE *out = fopen(zFile, "wb"); + FILE *out = sqlite3_fopen(zFile, "wb"); if( out==0 ) return 1; z = (const char*)sqlite3_value_blob(pData); if( z ){ @@ -430,7 +437,7 @@ static int writeFile( GetSystemTime(¤tTime); SystemTimeToFileTime(¤tTime, &lastAccess); - intervals = Int32x32To64(mtime, 10000000) + 116444736000000000; + intervals = (mtime*10000000) + 116444736000000000; lastWrite.dwLowDateTime = (DWORD)intervals; lastWrite.dwHighDateTime = intervals >> 32; zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); @@ -460,10 +467,10 @@ static int writeFile( return 1; } #else - /* Legacy unix. + /* Legacy unix. ** ** Do not use utimes() on a symbolic link - it sees through the link and - ** modifies the timestamps on the target. Or fails if the target does + ** modifies the timestamps on the target. Or fails if the target does ** not exist. */ if( 0==S_ISLNK(mode) ){ struct timeval times[2]; @@ -481,7 +488,7 @@ static int writeFile( } /* -** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. +** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. ** Refer to header comments at the top of this file for details. */ static void writefileFunc( @@ -495,7 +502,7 @@ static void writefileFunc( sqlite3_int64 mtime = -1; if( argc<2 || argc>4 ){ - sqlite3_result_error(context, + sqlite3_result_error(context, "wrong number of arguments to function writefile()", -1 ); return; @@ -565,7 +572,7 @@ static void lsModeFunc( #ifndef SQLITE_OMIT_VIRTUALTABLE -/* +/* ** Cursor type for recursively iterating through a directory structure. */ typedef struct fsdir_cursor fsdir_cursor; @@ -713,7 +720,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){ } pCur->iLvl = iNew; pLvl = &pCur->aLvl[iNew]; - + pLvl->zDir = pCur->zPath; pCur->zPath = 0; pLvl->pDir = opendir(pLvl->zDir); @@ -844,7 +851,7 @@ static int fsdirEof(sqlite3_vtab_cursor *cur){ ** idxNum==2 Both PATH and DIR supplied */ static int fsdirFilter( - sqlite3_vtab_cursor *cur, + sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -933,7 +940,7 @@ static int fsdirBestIndex( } break; } - } + } } if( seenPath || seenDir ){ /* If input parameters are unusable, disallow this plan */ @@ -1001,18 +1008,19 @@ static int fsdirRegister(sqlite3 *db){ # define fsdirRegister(x) SQLITE_OK #endif -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_fileio_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "readfile", 1, + rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8|SQLITE_DIRECTONLY, 0, readfileFunc, 0, 0); if( rc==SQLITE_OK ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/md5.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/md5.c index 2c7c6a1345..42e9b330a8 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/md5.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/md5.c @@ -60,19 +60,19 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx); * architectures that lack an AND-NOT instruction, just like in Colin Plumb's * implementation. */ -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define H(x, y, z) (((x) ^ (y)) ^ (z)) -#define H2(x, y, z) ((x) ^ ((y) ^ (z))) -#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) /* * The MD5 transformation for all four rounds. */ #define STEP(f, a, b, c, d, x, t, s) \ - (a) += f((b), (c), (d)) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); /* * SET reads 4 input bytes in little-endian byte order and stores them @@ -84,18 +84,18 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx); */ #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) #define SET(n) \ - (*(MD5_u32plus *)&ptr[(n) * 4]) + (*(MD5_u32plus *)&ptr[(n) * 4]) #define GET(n) \ - SET(n) + SET(n) #else #define SET(n) \ - (ctx->block[(n)] = \ - (MD5_u32plus)ptr[(n) * 4] | \ - ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ - ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ - ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) + (ctx->block[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) #define GET(n) \ - (ctx->block[(n)]) + (ctx->block[(n)]) #endif /* diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/memory_secure.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/memory_secure.c index 171e2c645a..ee82bcafdb 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/memory_secure.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/memory_secure.c @@ -44,38 +44,6 @@ static volatile int mcSecureMemoryFlag = 0; /* Map of default memory allocation methods */ static volatile sqlite3_mem_methods mcDefaultMemoryMethods; -#if SQLITE3MC_ENABLE_RANDOM_FILL_MEMORY - -/* -** Fill a buffer with pseudo-random bytes. This is used to preset -** the content of a new memory allocation to unpredictable values and -** to clear the content of a freed allocation to unpredictable values. -*/ -static void mcRandomFill(char* pBuf, int nByte) -{ - unsigned int x, y, r; - x = SQLITE_PTR_TO_INT(pBuf); - y = nByte | 1; - while( nByte >= 4 ) - { - x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); - y = y*1103515245 + 12345; - r = x ^ y; - *(int*)pBuf = r; - pBuf += 4; - nByte -= 4; - } - while( nByte-- > 0 ) - { - x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); - y = y*1103515245 + 12345; - r = x ^ y; - *(pBuf++) = r & 0xff; - } -} - -#endif - /* ** Return the size of an allocation */ @@ -99,13 +67,8 @@ static void mcMemoryFree(void* pPrior) { if (mcSecureMemoryFlag) { -#if SQLITE3MC_USE_RANDOM_FILL_MEMORY - int nSize = mcMemorySize(pPrior); - mcRandomFill((char*) pPrior, nSize) -#else int nSize = mcMemorySize(pPrior); sqlite3mcSecureZeroMemory(pPrior, 0, nSize); -#endif } mcDefaultMemoryMethods.xFree(pPrior); } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.c index 87bdedb188..b46bc7677e 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.c @@ -1379,15 +1379,15 @@ static int tdefl_flush_block(tdefl_compressor *d, int flush) #ifdef MINIZ_UNALIGNED_USE_MEMCPY static mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8* p) { - mz_uint16 ret; - memcpy(&ret, p, sizeof(mz_uint16)); - return ret; + mz_uint16 ret; + memcpy(&ret, p, sizeof(mz_uint16)); + return ret; } static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16* p) { - mz_uint16 ret; - memcpy(&ret, p, sizeof(mz_uint16)); - return ret; + mz_uint16 ret; + memcpy(&ret, p, sizeof(mz_uint16)); + return ret; } #else #define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p) @@ -1495,9 +1495,9 @@ static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahe #ifdef MINIZ_UNALIGNED_USE_MEMCPY static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(const mz_uint8* p) { - mz_uint32 ret; - memcpy(&ret, p, sizeof(mz_uint32)); - return ret; + mz_uint32 ret; + memcpy(&ret, p, sizeof(mz_uint32)); + return ret; } #else #define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p) @@ -1572,7 +1572,7 @@ static mz_bool tdefl_compress_fast(tdefl_compressor *d) pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); #ifdef MINIZ_UNALIGNED_USE_MEMCPY - memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist)); + memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist)); #else *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; #endif @@ -2741,7 +2741,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex do { #ifdef MINIZ_UNALIGNED_USE_MEMCPY - memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2); + memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2); #else ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; @@ -2768,7 +2768,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex pOut_buf_cur[2] = pSrc[2]; pOut_buf_cur += 3; pSrc += 3; - counter -= 3; + counter -= 3; } if (counter > 0) { @@ -3706,47 +3706,47 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag if (extra_size_remaining) { - const mz_uint8 *pExtra_data; - void* buf = NULL; - - if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n) - { - buf = MZ_MALLOC(ext_data_size); - if(buf==NULL) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size) - { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - pExtra_data = (mz_uint8*)buf; - } - else - { - pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size; - } + const mz_uint8 *pExtra_data; + void* buf = NULL; + + if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n) + { + buf = MZ_MALLOC(ext_data_size); + if(buf==NULL) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + } + + pExtra_data = (mz_uint8*)buf; + } + else + { + pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size; + } do { mz_uint32 field_id; mz_uint32 field_data_size; - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } + if (extra_size_remaining < (sizeof(mz_uint16) * 2)) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } field_id = MZ_READ_LE16(pExtra_data); field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) - { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } + if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { @@ -3760,7 +3760,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; } while (extra_size_remaining); - MZ_FREE(buf); + MZ_FREE(buf); } } @@ -3965,7 +3965,7 @@ mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) { - MZ_FCLOSE(pFile); + MZ_FCLOSE(pFile); return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); } @@ -6177,16 +6177,16 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n } #endif /* #ifndef MINIZ_NO_TIME */ - if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) - { - uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size); - uncomp_size = buf_size; - if (uncomp_size <= 3) - { - level = 0; - store_data_uncompressed = MZ_TRUE; - } - } + if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + { + uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size); + uncomp_size = buf_size; + if (uncomp_size <= 3) + { + level = 0; + store_data_uncompressed = MZ_TRUE; + } + } archive_name_size = strlen(pArchive_name); if (archive_name_size > MZ_UINT16_MAX) @@ -6202,9 +6202,9 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n { /* Bail early if the archive would obviously become too large */ if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size - + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + - pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len - + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF) + + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len + + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF) { pState->m_zip64 = MZ_TRUE; /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ @@ -6303,13 +6303,13 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n cur_archive_file_ofs += archive_name_size; } - if (user_extra_data_len > 0) - { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + if (user_extra_data_len > 0) + { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - cur_archive_file_ofs += user_extra_data_len; - } + cur_archive_file_ofs += user_extra_data_len; + } if (store_data_uncompressed) { @@ -6461,8 +6461,8 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA { /* Bail early if the archive would obviously become too large */ if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE - + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 - + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF) + + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 + + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF) { pState->m_zip64 = MZ_TRUE; /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ @@ -6704,7 +6704,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), - (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size, + (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size, (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date)) return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); @@ -6753,20 +6753,20 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) { - MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque; - mz_int64 cur_ofs = MZ_FTELL64(pSrc_file); + MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pSrc_file); - if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET)))) - return 0; + if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET)))) + return 0; - return MZ_FREAD(pBuf, 1, n, pSrc_file); + return MZ_FREAD(pBuf, 1, n, pSrc_file); } mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, - const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) + const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) { - return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags, - user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len); + return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags, + user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len); } mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) @@ -7088,11 +7088,11 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive * { /* src is zip64, dest must be zip64 */ - /* name uint32_t's */ - /* id 1 (optional in zip64?) */ - /* crc 1 */ - /* comp_size 2 */ - /* uncomp_size 2 */ + /* name uint32_t's */ + /* id 1 (optional in zip64?) */ + /* crc 1 */ + /* comp_size 2 */ + /* uncomp_size 2 */ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6)) { pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.h index 6cc398c920..82be6580c3 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.h @@ -115,7 +115,7 @@ -/* Defines to completely disable specific portions of miniz.c: +/* Defines to completely disable specific portions of miniz.c: If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. */ /* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */ @@ -138,7 +138,7 @@ /* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. */ /*#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ -/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. +/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */ @@ -908,7 +908,7 @@ struct tinfl_decompressor_tag #ifdef __cplusplus } #endif - + #pragma once @@ -1226,13 +1226,13 @@ MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, c #if 0 /* TODO */ - typedef void *mz_zip_streaming_extract_state_ptr; - mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); - uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs); - size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size); - mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + typedef void *mz_zip_streaming_extract_state_ptr; + mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); + uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs); + size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size); + mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); #endif /* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */ @@ -1294,8 +1294,8 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const cha /* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */ /* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/ MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size, - const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, - const char *user_extra_data_central, mz_uint user_extra_data_central_len); + const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, + const char *user_extra_data_central, mz_uint user_extra_data_central_len); #ifndef MINIZ_NO_STDIO diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/mystdint.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/mystdint.h index 3648a1fee3..a6beaf8c26 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/mystdint.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/mystdint.h @@ -19,7 +19,7 @@ typedef unsigned long long uint64_t; #define UINT8_MAX 255 #define UINT16_MAX 65535 #define UINT32_MAX 0xffffffffU /* 4294967295U */ -#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ +#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ #else #include #endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/regexp.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/regexp.c index a50008ca35..e3d5fa3b51 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/regexp.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/regexp.c @@ -169,7 +169,7 @@ static void re_add_state(ReStateSet *pSet, int newState){ /* Extract the next unicode character from *pzIn and return it. Advance ** *pzIn to the first byte past the end of the character returned. To -** be clear: this routine converts utf8 to unicode. This routine is +** be clear: this routine converts utf8 to unicode. This routine is ** optimized for the common case where the next character is a single byte. */ static unsigned re_next_char(ReInput *p){ @@ -240,7 +240,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){ /* Look for the initial prefix match, if there is one. */ if( pRe->nInit ){ unsigned char x = pRe->zInit[0]; - while( in.i+pRe->nInit<=in.mx + while( in.i+pRe->nInit<=in.mx && (zIn[in.i]!=x || strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0) ){ @@ -656,7 +656,8 @@ static const char *re_subcompile_string(ReCompiled *p){ ** regular expression. Applications should invoke this routine once ** for every call to re_compile() to avoid memory leaks. */ -static void re_free(ReCompiled *pRe){ +static void re_free(void *p){ + ReCompiled *pRe = (ReCompiled*)p; if( pRe ){ sqlite3_free(pRe->aOp); sqlite3_free(pRe->aArg); @@ -710,7 +711,7 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ /* The following is a performance optimization. If the regex begins with ** ".*" (if the input regex lacks an initial "^") and afterwards there are ** one or more matching characters, enter those matching characters into - ** zInit[]. The re_match() routine can then search ahead in the input + ** zInit[]. The re_match() routine can then search ahead in the input ** string looking for the initial match without having to run the whole ** regex engine over the string. Do not worry about trying to match ** unicode characters beyond plane 0 - those are very rare and this is @@ -844,23 +845,23 @@ static void re_bytecode_func( #endif /* SQLITE_DEBUG */ - /* ** Invoke this routine to register the regexp() function with the ** SQLite database connection. */ -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_regexp_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused */ - rc = sqlite3_create_function(db, "regexp", 2, + rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0, re_sql_func, 0, 0); if( rc==SQLITE_OK ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rekeyvacuum.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rekeyvacuum.c index d50ed97e36..35e3eb3cd1 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rekeyvacuum.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rekeyvacuum.c @@ -27,7 +27,7 @@ ** Change 4: Call sqlite3mcBtreeSetPageSize instead of sqlite3BtreeSetPageSize for main database ** (sqlite3mcBtreeSetPageSize allows to reduce the number of reserved bytes) ** -** This code is generated by the script rekeyvacuum.sh from SQLite version 3.44.2 amalgamation. +** This code is generated by the script rekeyvacuum.sh from SQLite version 3.48.0 amalgamation. */ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( char **pzErrMsg, /* Write error message here */ @@ -50,6 +50,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ + u64 iRandom; /* Random value used for zDbVacuum[] */ + char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */ + if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); @@ -90,27 +93,29 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( pMain = db->aDb[iDb].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); - /* Attach the temporary database as 'vacuum_db'. The synchronous pragma + /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** ** An optimization would be to use a non-journaled pager. - ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but + ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but ** that actually made the VACUUM run slower. Very little journalling ** actually occurs when doing a vacuum since the vacuum_db is initially ** empty. Only the journal header is written. Apparently it takes more ** time to parse and run the PRAGMA to turn journalling off than it does ** to write the journal header file. */ + sqlite3_randomness(sizeof(iRandom),&iRandom); + sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom); nDb = db->nDb; - rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut); + rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum); db->openFlags = saved_openFlags; if( rc!=SQLITE_OK ) goto end_of_vacuum; assert( (db->nDb-1)==nDb ); pDb = &db->aDb[nDb]; - assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); + assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); pTemp = pDb->pBt; if( pOut ){ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); @@ -195,11 +200,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( ** the contents to the temporary database. */ rc = execSqlF(db, pzErrMsg, - "SELECT'INSERT INTO vacuum_db.'||quote(name)" + "SELECT'INSERT INTO %s.'||quote(name)" "||' SELECT*FROM\"%w\".'||quote(name)" - "FROM vacuum_db.sqlite_schema " + "FROM %s.sqlite_schema " "WHERE type='table'AND coalesce(rootpage,1)>0", - zDbMain + zDbVacuum, zDbMain, zDbVacuum ); assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); db->mDbFlags &= ~DBFLAG_Vacuum; @@ -211,11 +216,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( ** from the schema table. */ rc = execSqlF(db, pzErrMsg, - "INSERT INTO vacuum_db.sqlite_schema" + "INSERT INTO %s.sqlite_schema" " SELECT*FROM \"%w\".sqlite_schema" " WHERE type IN('view','trigger')" " OR(type='table'AND rootpage=0)", - zDbMain + zDbVacuum, zDbMain ); if( rc ) goto end_of_vacuum; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.c index fccca806d3..144e849088 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.c @@ -86,21 +86,21 @@ static UINT8 S[256]= { - 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, - 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, - 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, - 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, - 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, - 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, - 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, - 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, - 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, - 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, - 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, - 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, - 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, - 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, - 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22 }; @@ -171,7 +171,7 @@ static UINT8 T1[256][4]= {0x82,0x41,0x41,0xc3}, {0x29,0x99,0x99,0xb0}, {0x5a,0x2d,0x2d,0x77}, {0x1e,0x0f,0x0f,0x11}, {0x7b,0xb0,0xb0,0xcb}, {0xa8,0x54,0x54,0xfc}, {0x6d,0xbb,0xbb,0xd6}, {0x2c,0x16,0x16,0x3a} }; - + static UINT8 T2[256][4]= { {0xa5,0xc6,0x63,0x63}, {0x84,0xf8,0x7c,0x7c}, {0x99,0xee,0x77,0x77}, {0x8d,0xf6,0x7b,0x7b}, @@ -783,7 +783,7 @@ static UINT8 U1[256][4]= {0xa7,0x79,0xb4,0x92}, {0xa9,0x70,0xb9,0x99}, {0xbb,0x6b,0xae,0x84}, {0xb5,0x62,0xa3,0x8f}, {0x9f,0x5d,0x80,0xbe}, {0x91,0x54,0x8d,0xb5}, {0x83,0x4f,0x9a,0xa8}, {0x8d,0x46,0x97,0xa3} }; - + static UINT8 U2[256][4]= { {0x00,0x00,0x00,0x00}, {0x0b,0x0e,0x09,0x0d}, {0x16,0x1c,0x12,0x1a}, {0x1d,0x12,0x1b,0x17}, @@ -989,7 +989,7 @@ static UINT8 U4[256][4]= }; static UINT32 rcon[30]= -{ +{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, @@ -1003,11 +1003,13 @@ static UINT32 rcon[30]= ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ +SQLITE_PRIVATE void RijndaelCreate(Rijndael* rijndael) { rijndael->m_state = RIJNDAEL_State_Invalid; } +SQLITE_PRIVATE int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, UINT8* initVector) { UINT32 uKeyLenInBytes; @@ -1092,7 +1094,7 @@ int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, #endif } } -#ifndef TEST_AES_HW +#ifndef TEST_AES_HW else #endif #endif @@ -1104,7 +1106,7 @@ int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, if (rijndael->m_direction == RIJNDAEL_Direction_Decrypt) RijndaelKeyEncToDec(rijndael); } -#ifdef TEST_AES_HW +#ifdef TEST_AES_HW { int cmpkeyexp = memcmp((unsigned char*) rijndael->m_expandedKey, aesKeySched, (rijndael->m_uRounds+1)*16); int datalen = (rijndael->m_uRounds + 1) * 16; @@ -1134,10 +1136,10 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* numBlocks = inputLen/128; lenFrag = (inputLen % 128) / 8; - + switch (rijndael->m_mode) { - case RIJNDAEL_Direction_Mode_ECB: + case RIJNDAEL_Direction_Mode_ECB: for(i = numBlocks;i > 0;i--) { RijndaelEncrypt(rijndael, input, outBuffer); @@ -1149,7 +1151,7 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* #if HAS_AES_HARDWARE if (aesHardwareAvailable()) { -#ifndef TEST_AES_HW +#ifndef TEST_AES_HW aesEncryptCBC(input, outBuffer, rijndael->m_initVector, inputLen/8, (unsigned char*) (rijndael->m_expandedKey), rijndael->m_uRounds); #else TEST_AES_HW_DEBUG_LOG("aes enc: hw enabled\n"); @@ -1195,8 +1197,8 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* } break; case RIJNDAEL_Direction_Mode_CFB1: -#if STRICT_ALIGN - memcpy(iv,rijndael->m_initVector,16); +#if STRICT_ALIGN + memcpy(iv,rijndael->m_initVector,16); #else /* !STRICT_ALIGN */ *((UINT32*)iv[0]) = *((UINT32*)(rijndael->m_initVector )); *((UINT32*)iv[1]) = *((UINT32*)(rijndael->m_initVector + 4)); @@ -1240,7 +1242,7 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* break; } -#ifdef TEST_AES_HW +#ifdef TEST_AES_HW { int cmpdata = memcmp((unsigned char*) outOrig, outBuffer2, inputLen/8); TEST_AES_HW_DEBUG_LOG("aes enc: cmp=%d\n", cmpdata); @@ -1248,10 +1250,11 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* TEST_AES_HW_DEBUG_HEX("aes enc HW:", outBuffer2, 16); } #endif - + return 128 * numBlocks; } +SQLITE_PRIVATE int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer) { int i, numBlocks, padLen; @@ -1266,7 +1269,7 @@ int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 switch (rijndael->m_mode) { - case RIJNDAEL_Direction_Mode_ECB: + case RIJNDAEL_Direction_Mode_ECB: for(i = numBlocks; i > 0; i--) { RijndaelEncrypt(rijndael, input, outBuffer); @@ -1306,10 +1309,11 @@ int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 return -1; break; } - + return 16*(numBlocks + 1); } - + +SQLITE_PRIVATE int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* outBuffer) { int i, k, numBlocks, lenFrag; @@ -1329,7 +1333,7 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* switch (rijndael->m_mode) { - case RIJNDAEL_Direction_Mode_ECB: + case RIJNDAEL_Direction_Mode_ECB: for (i = numBlocks; i > 0; i--) { RijndaelDecrypt(rijndael, input, outBuffer); @@ -1384,8 +1388,8 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* } } } -#if STRICT_ALIGN - memcpy(iv,rijndael->m_initVector,16); +#if STRICT_ALIGN + memcpy(iv,rijndael->m_initVector,16); #else *((UINT32*)iv[0]) = *((UINT32*)(rijndael->m_initVector )); *((UINT32*)iv[1]) = *((UINT32*)(rijndael->m_initVector+ 4)); @@ -1414,8 +1418,8 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* } break; case RIJNDAEL_Direction_Mode_CFB1: -#if STRICT_ALIGN - memcpy(iv, rijndael->m_initVector, 16); +#if STRICT_ALIGN + memcpy(iv, rijndael->m_initVector, 16); #else *((UINT32*)iv[0]) = *((UINT32*)(rijndael->m_initVector)); *((UINT32*)iv[1]) = *((UINT32*)(rijndael->m_initVector+ 4)); @@ -1459,7 +1463,7 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* break; } -#ifdef TEST_AES_HW +#ifdef TEST_AES_HW { int cmpdata = memcmp((unsigned char*) outOrig, outBuffer2, inputLen/8); TEST_AES_HW_DEBUG_LOG("aes dec: cmp=%d\n", cmpdata); @@ -1467,10 +1471,11 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* TEST_AES_HW_DEBUG_HEX("aes dec HW:", outBuffer2, 16); } #endif - + return 128*numBlocks; } +SQLITE_PRIVATE int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer) { int i, numBlocks, padLen; @@ -1504,7 +1509,7 @@ int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 if (block[i] != padLen) return RIJNDAEL_CORRUPTED_DATA; } memcpy(outBuffer, block, 16 - padLen); - break; + break; case RIJNDAEL_Direction_Mode_CBC: memcpy(iv, rijndael->m_initVector, 16); /* all blocks but last */ @@ -1534,12 +1539,12 @@ int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 } memcpy(outBuffer, block, 16 - padLen); break; - + default: return -1; break; } - + return 16*numBlocks - padLen; } @@ -1549,6 +1554,7 @@ int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ +SQLITE_PRIVATE void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]) { int j,rconpointer = 0; @@ -1585,7 +1591,7 @@ void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]) t = 0; } } - + while(r <= rijndael->m_uRounds) { tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]]; @@ -1626,9 +1632,10 @@ void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]) t = 0; } } - } + } } +SQLITE_PRIVATE void RijndaelKeyEncToDec(Rijndael* rijndael) { UINT32 r; @@ -1645,8 +1652,9 @@ void RijndaelKeyEncToDec(Rijndael* rijndael) w = rijndael->m_expandedKey[r][3]; *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]); } -} +} +SQLITE_PRIVATE void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) { UINT32 r; @@ -1658,19 +1666,19 @@ void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)temp[3]) = *((UINT32*)(a+12)) ^ *((UINT32*)rijndael->m_expandedKey[0][3]); *((UINT32*)(b )) = *((UINT32*)T1[temp[0][0]]) ^ *((UINT32*)T2[temp[1][1]]) - ^ *((UINT32*)T3[temp[2][2]]) + ^ *((UINT32*)T3[temp[2][2]]) ^ *((UINT32*)T4[temp[3][3]]); *((UINT32*)(b + 4)) = *((UINT32*)T1[temp[1][0]]) ^ *((UINT32*)T2[temp[2][1]]) - ^ *((UINT32*)T3[temp[3][2]]) + ^ *((UINT32*)T3[temp[3][2]]) ^ *((UINT32*)T4[temp[0][3]]); *((UINT32*)(b + 8)) = *((UINT32*)T1[temp[2][0]]) ^ *((UINT32*)T2[temp[3][1]]) - ^ *((UINT32*)T3[temp[0][2]]) + ^ *((UINT32*)T3[temp[0][2]]) ^ *((UINT32*)T4[temp[1][3]]); *((UINT32*)(b +12)) = *((UINT32*)T1[temp[3][0]]) ^ *((UINT32*)T2[temp[0][1]]) - ^ *((UINT32*)T3[temp[1][2]]) + ^ *((UINT32*)T3[temp[1][2]]) ^ *((UINT32*)T4[temp[2][3]]); for(r = 1; r < rijndael->m_uRounds-1; r++) { @@ -1681,19 +1689,19 @@ void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)(b )) = *((UINT32*)T1[temp[0][0]]) ^ *((UINT32*)T2[temp[1][1]]) - ^ *((UINT32*)T3[temp[2][2]]) + ^ *((UINT32*)T3[temp[2][2]]) ^ *((UINT32*)T4[temp[3][3]]); *((UINT32*)(b + 4)) = *((UINT32*)T1[temp[1][0]]) ^ *((UINT32*)T2[temp[2][1]]) - ^ *((UINT32*)T3[temp[3][2]]) + ^ *((UINT32*)T3[temp[3][2]]) ^ *((UINT32*)T4[temp[0][3]]); *((UINT32*)(b + 8)) = *((UINT32*)T1[temp[2][0]]) ^ *((UINT32*)T2[temp[3][1]]) - ^ *((UINT32*)T3[temp[0][2]]) + ^ *((UINT32*)T3[temp[0][2]]) ^ *((UINT32*)T4[temp[1][3]]); *((UINT32*)(b +12)) = *((UINT32*)T1[temp[3][0]]) ^ *((UINT32*)T2[temp[0][1]]) - ^ *((UINT32*)T3[temp[1][2]]) + ^ *((UINT32*)T3[temp[1][2]]) ^ *((UINT32*)T4[temp[2][3]]); } *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds-1][0]); @@ -1722,11 +1730,12 @@ void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)(b+12)) ^= *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds][3]); } +SQLITE_PRIVATE void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) { int r; UINT8 temp[4][4]; - + *((UINT32*)temp[0]) = *((UINT32*)(a )) ^ *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds][0]); *((UINT32*)temp[1]) = *((UINT32*)(a+ 4)) ^ *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds][1]); *((UINT32*)temp[2]) = *((UINT32*)(a+ 8)) ^ *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds][2]); @@ -1734,19 +1743,19 @@ void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)(b )) = *((UINT32*)T5[temp[0][0]]) ^ *((UINT32*)T6[temp[3][1]]) - ^ *((UINT32*)T7[temp[2][2]]) + ^ *((UINT32*)T7[temp[2][2]]) ^ *((UINT32*)T8[temp[1][3]]); *((UINT32*)(b+ 4)) = *((UINT32*)T5[temp[1][0]]) ^ *((UINT32*)T6[temp[0][1]]) - ^ *((UINT32*)T7[temp[3][2]]) + ^ *((UINT32*)T7[temp[3][2]]) ^ *((UINT32*)T8[temp[2][3]]); *((UINT32*)(b+ 8)) = *((UINT32*)T5[temp[2][0]]) ^ *((UINT32*)T6[temp[1][1]]) - ^ *((UINT32*)T7[temp[0][2]]) + ^ *((UINT32*)T7[temp[0][2]]) ^ *((UINT32*)T8[temp[3][3]]); *((UINT32*)(b+12)) = *((UINT32*)T5[temp[3][0]]) ^ *((UINT32*)T6[temp[2][1]]) - ^ *((UINT32*)T7[temp[1][2]]) + ^ *((UINT32*)T7[temp[1][2]]) ^ *((UINT32*)T8[temp[0][3]]); for(r = rijndael->m_uRounds-1; r > 1; r--) { @@ -1756,22 +1765,22 @@ void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)rijndael->m_expandedKey[r][3]); *((UINT32*)(b )) = *((UINT32*)T5[temp[0][0]]) ^ *((UINT32*)T6[temp[3][1]]) - ^ *((UINT32*)T7[temp[2][2]]) + ^ *((UINT32*)T7[temp[2][2]]) ^ *((UINT32*)T8[temp[1][3]]); *((UINT32*)(b+ 4)) = *((UINT32*)T5[temp[1][0]]) ^ *((UINT32*)T6[temp[0][1]]) - ^ *((UINT32*)T7[temp[3][2]]) + ^ *((UINT32*)T7[temp[3][2]]) ^ *((UINT32*)T8[temp[2][3]]); *((UINT32*)(b+ 8)) = *((UINT32*)T5[temp[2][0]]) ^ *((UINT32*)T6[temp[1][1]]) - ^ *((UINT32*)T7[temp[0][2]]) + ^ *((UINT32*)T7[temp[0][2]]) ^ *((UINT32*)T8[temp[3][3]]); *((UINT32*)(b+12)) = *((UINT32*)T5[temp[3][0]]) ^ *((UINT32*)T6[temp[2][1]]) - ^ *((UINT32*)T7[temp[1][2]]) + ^ *((UINT32*)T7[temp[1][2]]) ^ *((UINT32*)T8[temp[0][3]]); } - + *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)rijndael->m_expandedKey[1][0]); *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)rijndael->m_expandedKey[1][1]); *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)rijndael->m_expandedKey[1][2]); @@ -1798,6 +1807,7 @@ void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)(b+12)) ^= *((UINT32*)rijndael->m_expandedKey[0][3]); } +SQLITE_PRIVATE void RijndaelInvalidate(Rijndael* rijndael) { rijndael->m_state = RIJNDAEL_State_Invalid; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.h index f383c0cbb5..837169b286 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.h @@ -18,6 +18,10 @@ #ifndef _RIJNDAEL_H_ #define _RIJNDAEL_H_ +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + /* // File : rijndael.h // Creation date : Sun Nov 5 2000 03:21:05 CEST @@ -116,16 +120,16 @@ typedef unsigned short UINT16; */ typedef struct _Rijndael -{ - int m_state; - int m_mode; - int m_direction; - UINT8 m_initVector[MAX_IV_SIZE]; - UINT32 m_uRounds; - UINT8 m_expandedKey[_MAX_ROUNDS+1][4][4]; +{ + int m_state; + int m_mode; + int m_direction; + UINT8 m_initVector[MAX_IV_SIZE]; + UINT32 m_uRounds; + UINT8 m_expandedKey[_MAX_ROUNDS+1][4][4]; } Rijndael; -void RijndaelCreate(Rijndael* rijndael); +SQLITE_PRIVATE void RijndaelCreate(Rijndael* rijndael); /* ////////////////////////////////////////////////////////////////////////////////////////// @@ -147,7 +151,7 @@ void RijndaelCreate(Rijndael* rijndael); // keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes // initVector: initialization vector, you will usually use 0 here */ -int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, UINT8* initVector); +SQLITE_PRIVATE int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, UINT8* initVector); /* // Encrypts the input array (can be binary data) @@ -158,7 +162,7 @@ int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, // outBuffer must be at least inputLen / 8 bytes long. // Returns the encrypted buffer length in BITS or an error code < 0 in case of error */ -int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); +SQLITE_PRIVATE int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); /* // Encrypts the input array (can be binary data) @@ -167,7 +171,7 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 * // outBuffer must be at least (inputLen + 16) bytes long // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error */ -int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); +SQLITE_PRIVATE int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); /* // Decrypts the input vector @@ -175,7 +179,7 @@ int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 // outBuffer must be at least inputLen / 8 bytes long // Returns the decrypted buffer length in BITS and an error code < 0 in case of error */ -int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); +SQLITE_PRIVATE int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); /* // Decrypts the input vector @@ -183,12 +187,12 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 * // outBuffer must be at least inputLen bytes long // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error */ -int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); - -void RijndaelInvalidate(Rijndael* rijndael); -void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]); -void RijndaelKeyEncToDec(Rijndael* rijndael); -void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); -void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); - +SQLITE_PRIVATE int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); + +SQLITE_PRIVATE void RijndaelInvalidate(Rijndael* rijndael); +SQLITE_PRIVATE void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]); +SQLITE_PRIVATE void RijndaelKeyEncToDec(Rijndael* rijndael); +SQLITE_PRIVATE void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); +SQLITE_PRIVATE void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); + #endif /* _RIJNDAEL_H_ */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/series.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/series.c index 0dfed181f6..694f78ebe6 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/series.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/series.c @@ -90,6 +90,26 @@ ** and a very large cost if either start or stop are unavailable. This ** encourages the query planner to order joins such that the bounds of the ** series are well-defined. +** +** Update on 2024-08-22: +** xBestIndex now also looks for equality and inequality constraints against +** the value column and uses those constraints as additional bounds against +** the sequence range. Thus, a query like this: +** +** SELECT value FROM generate_series($SA,$EA) +** WHERE value BETWEEN $SB AND $EB; +** +** Is logically the same as: +** +** SELECT value FROM generate_series(max($SA,$SB),min($EA,$EB)); +** +** Constraints on the value column can server as substitutes for constraints +** on the hidden start and stop columns. So, the following two queries +** are equivalent: +** +** SELECT value FROM generate_series($S,$E); +** SELECT value FROM generate_series WHERE value BETWEEN $S and $E; +** */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 @@ -131,8 +151,10 @@ static sqlite3_int64 genSeqMember( typedef unsigned char u8; typedef struct SequenceSpec { - sqlite3_int64 iBase; /* Starting value ("start") */ - sqlite3_int64 iTerm; /* Given terminal value ("stop") */ + sqlite3_int64 iOBase; /* Original starting value ("start") */ + sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ + sqlite3_int64 iBase; /* Starting value to actually use */ + sqlite3_int64 iTerm; /* Terminal value to actually use */ sqlite3_int64 iStep; /* Increment ("step") */ sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */ sqlite3_uint64 uSeqIndexNow; /* Current index during generation */ @@ -325,9 +347,9 @@ static int seriesColumn( series_cursor *pCur = (series_cursor*)cur; sqlite3_int64 x = 0; switch( i ){ - case SERIES_COLUMN_START: x = pCur->ss.iBase; break; - case SERIES_COLUMN_STOP: x = pCur->ss.iTerm; break; - case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; + case SERIES_COLUMN_START: x = pCur->ss.iOBase; break; + case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break; + case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; default: x = pCur->ss.iValueNow; break; } sqlite3_result_int64(ctx, x); @@ -335,7 +357,9 @@ static int seriesColumn( } #ifndef LARGEST_UINT64 +#define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) #define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32)) +#define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) #endif /* @@ -376,13 +400,18 @@ static int seriesEof(sqlite3_vtab_cursor *cur){ ** parameter. (idxStr is not used in this implementation.) idxNum ** is a bitmask showing which constraints are available: ** -** 0x01: start=VALUE -** 0x02: stop=VALUE -** 0x04: step=VALUE -** 0x08: descending order -** 0x10: ascending order -** 0x20: LIMIT VALUE -** 0x40: OFFSET VALUE +** 0x0001: start=VALUE +** 0x0002: stop=VALUE +** 0x0004: step=VALUE +** 0x0008: descending order +** 0x0010: ascending order +** 0x0020: LIMIT VALUE +** 0x0040: OFFSET VALUE +** 0x0080: value=VALUE +** 0x0100: value>=VALUE +** 0x0200: value>VALUE +** 0x1000: value<=VALUE +** 0x2000: valuess.iBase = sqlite3_value_int64(argv[i++]); @@ -416,16 +451,98 @@ static int seriesFilter( }else{ pCur->ss.iStep = 1; } + + /* If there are constraints on the value column but there are + ** no constraints on the start, stop, and step columns, then + ** initialize the default range to be the entire range of 64-bit signed + ** integers. This range will contracted by the value column constraints + ** further below. + */ + if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){ + pCur->ss.iBase = SMALLEST_INT64; + } + if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){ + pCur->ss.iTerm = LARGEST_INT64; + } + pCur->ss.iOBase = pCur->ss.iBase; + pCur->ss.iOTerm = pCur->ss.iTerm; + + /* Extract the LIMIT and OFFSET values, but do not apply them yet. + ** The range must first be constrained by the limits on value. + */ if( idxNum & 0x20 ){ - sqlite3_int64 iLimit = sqlite3_value_int64(argv[i++]); - sqlite3_int64 iTerm; + iLimit = sqlite3_value_int64(argv[i++]); if( idxNum & 0x40 ){ - sqlite3_int64 iOffset = sqlite3_value_int64(argv[i++]); - if( iOffset>0 ){ - pCur->ss.iBase += pCur->ss.iStep*iOffset; + iOffset = sqlite3_value_int64(argv[i++]); + } + } + + if( idxNum & 0x3380 ){ + /* Extract the maximum range of output values determined by + ** constraints on the "value" column. + */ + if( idxNum & 0x0080 ){ + iMin = iMax = sqlite3_value_int64(argv[i++]); + }else{ + if( idxNum & 0x0300 ){ + iMin = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x0200 ){ + if( iMin==LARGEST_INT64 ){ + returnNoRows = 1; + }else{ + iMin++; + } + } + } + if( idxNum & 0x3000 ){ + iMax = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x2000 ){ + if( iMax==SMALLEST_INT64 ){ + returnNoRows = 1; + }else{ + iMax--; + } + } + } + if( iMin>iMax ){ + returnNoRows = 1; } } + + /* Try to reduce the range of values to be generated based on + ** constraints on the "value" column. + */ + if( pCur->ss.iStep>0 ){ + sqlite3_int64 szStep = pCur->ss.iStep; + if( pCur->ss.iBasess.iBase; + pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep; + } + if( pCur->ss.iTerm>iMax ){ + sqlite3_uint64 d = pCur->ss.iTerm - iMax; + pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep; + } + }else{ + sqlite3_int64 szStep = -pCur->ss.iStep; + assert( szStep>0 ); + if( pCur->ss.iBase>iMax ){ + sqlite3_uint64 d = pCur->ss.iBase - iMax; + pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep; + } + if( pCur->ss.iTermss.iTerm; + pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep; + } + } + } + + /* Apply LIMIT and OFFSET constraints, if any */ + if( idxNum & 0x20 ){ + if( iOffset>0 ){ + pCur->ss.iBase += pCur->ss.iStep*iOffset; + } if( iLimit>=0 ){ + sqlite3_int64 iTerm; iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep; if( pCur->ss.iStep<0 ){ if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; @@ -434,16 +551,21 @@ static int seriesFilter( } } } + + for(i=0; iss.iBase = 1; - pCur->ss.iTerm = 0; - pCur->ss.iStep = 1; + returnNoRows = 1; break; } } + if( returnNoRows ){ + pCur->ss.iBase = 1; + pCur->ss.iTerm = 0; + pCur->ss.iStep = 1; + } if( idxNum & 0x08 ){ pCur->ss.isReversing = pCur->ss.iStep > 0; }else{ @@ -464,13 +586,35 @@ static int seriesFilter( ** ** The query plan is represented by bits in idxNum: ** -** 0x01 start = $value -- constraint exists -** 0x02 stop = $value -- constraint exists -** 0x04 step = $value -- constraint exists -** 0x08 output is in descending order -** 0x10 output is in ascending order -** 0x20 LIMIT $value -- constraint exists -** 0x40 OFFSET $value -- constraint exists +** 0x0001 start = $num +** 0x0002 stop = $num +** 0x0004 step = $num +** 0x0008 output is in descending order +** 0x0010 output is in ascending order +** 0x0020 LIMIT $num +** 0x0040 OFFSET $num +** 0x0080 value = $num +** 0x0100 value >= $num +** 0x0200 value > $num +** 0x1000 value <= $num +** 0x2000 value < $num +** +** Only one of 0x0100 or 0x0200 will be returned. Similarly, only +** one of 0x1000 or 0x2000 will be returned. If the 0x0080 is set, then +** none of the 0xff00 bits will be set. +** +** The order of parameters passed to xFilter is as follows: +** +** * The argument to start= if bit 0x0001 is in the idxNum mask +** * The argument to stop= if bit 0x0002 is in the idxNum mask +** * The argument to step= if bit 0x0004 is in the idxNum mask +** * The argument to LIMIT if bit 0x0020 is in the idxNum mask +** * The argument to OFFSET if bit 0x0040 is in the idxNum mask +** * The argument to value=, or value>= or value> if any of +** bits 0x0380 are in the idxNum mask +** * The argument to value<= or value< if either of bits 0x3000 +** are in the mask +** */ static int seriesBestIndex( sqlite3_vtab *pVTab, @@ -483,7 +627,9 @@ static int seriesBestIndex( #endif int unusableMask = 0; /* Mask of unusable constraints */ int nArg = 0; /* Number of arguments that seriesFilter() expects */ - int aIdx[5]; /* Constraints on start, stop, step, LIMIT, OFFSET */ + int aIdx[7]; /* Constraints on start, stop, step, LIMIT, OFFSET, + ** and value. aIdx[5] covers value=, value>=, and + ** value>, aIdx[6] covers value<= and value< */ const struct sqlite3_index_constraint *pConstraint; /* This implementation assumes that the start, stop, and step columns @@ -491,7 +637,7 @@ static int seriesBestIndex( assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 ); assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 ); - aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = -1; + aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = aIdx[5] = aIdx[6] = -1; pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ int iCol; /* 0 for start, 1 for stop, 2 for step */ @@ -512,7 +658,58 @@ static int seriesBestIndex( } continue; } - if( pConstraint->iColumniColumniColumn==SERIES_COLUMN_VALUE && pConstraint->usable ){ + switch( op ){ + case SQLITE_INDEX_CONSTRAINT_EQ: + case SQLITE_INDEX_CONSTRAINT_IS: { + idxNum |= 0x0080; + idxNum &= ~0x3300; + aIdx[5] = i; + aIdx[6] = -1; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + bStartSeen = 1; +#endif + break; + } + case SQLITE_INDEX_CONSTRAINT_GE: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x0100; + idxNum &= ~0x0200; + aIdx[5] = i; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + bStartSeen = 1; +#endif + break; + } + case SQLITE_INDEX_CONSTRAINT_GT: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x0200; + idxNum &= ~0x0100; + aIdx[5] = i; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + bStartSeen = 1; +#endif + break; + } + case SQLITE_INDEX_CONSTRAINT_LE: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x1000; + idxNum &= ~0x2000; + aIdx[6] = i; + break; + } + case SQLITE_INDEX_CONSTRAINT_LT: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x2000; + idxNum &= ~0x1000; + aIdx[6] = i; + break; + } + } + } + continue; + } iCol = pConstraint->iColumn - SERIES_COLUMN_START; assert( iCol>=0 && iCol<=2 ); iMask = 1 << iCol; @@ -534,7 +731,7 @@ static int seriesBestIndex( idxNum &= ~0x60; aIdx[4] = 0; } - for(i=0; i<5; i++){ + for(i=0; i<7; i++){ if( (j = aIdx[i])>=0 ){ pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg; pIdxInfo->aConstraintUsage[j].omit = @@ -582,6 +779,9 @@ static int seriesBestIndex( pIdxInfo->estimatedRows = 2147483647; } pIdxInfo->idxNum = idxNum; +#ifdef SQLITE_INDEX_SCAN_HEX + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_HEX; +#endif return SQLITE_OK; } @@ -619,9 +819,10 @@ static sqlite3_module seriesModule = { #endif /* SQLITE_OMIT_VIRTUALTABLE */ -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_series_init( sqlite3 *db, char **pzErrMsg, diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.c index 6a562192d5..c49041cb7f 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.c @@ -13,10 +13,10 @@ Still 100% Public Domain Corrected a problem which generated improper hash values on 16 bit machines Routine SHA1Update changed from - void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len) to - void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned long len) The 'len' parameter was declared an int which works fine on 32 bit machines. @@ -141,6 +141,7 @@ A million repetitions of "a" z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); /* Hash a single 512-bit block. This is the core of the algorithm. */ +SQLITE_PRIVATE void sha1_transform(sha1_ctx *context, const uint8_t buffer[64]) { uint32_t a, b, c, d, e; @@ -205,6 +206,7 @@ void sha1_transform(sha1_ctx *context, const uint8_t buffer[64]) * * @param context SHA1-Context */ +SQLITE_PRIVATE void sha1_init(sha1_ctx *context) { /* SHA1 initialization constants */ @@ -224,6 +226,7 @@ void sha1_init(sha1_ctx *context) * @param p Buffer to run SHA1 on * @param len Number of bytes */ +SQLITE_PRIVATE void sha1_update(sha1_ctx *context, const void *p, size_t len) { const uint8_t *data = p; @@ -259,6 +262,7 @@ void sha1_update(sha1_ctx *context, const void *p, size_t len) * @param digest Generated message digest * @param context SHA1-Context */ +SQLITE_PRIVATE void sha1_final(sha1_ctx *context, uint8_t digest[SHA1_DIGEST_SIZE]) { uint32_t i; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.h index bf2c56aae9..844b607bb1 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.h @@ -4,6 +4,10 @@ #ifndef SHA1_H_ #define SHA1_H_ (1) +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + /** SHA-1 Context */ typedef struct { uint32_t h[5]; @@ -17,12 +21,12 @@ typedef struct { /** SHA-1 Digest size in bytes */ #define SHA1_DIGEST_SIZE 20 -void sha1_init(sha1_ctx *context); +SQLITE_PRIVATE void sha1_init(sha1_ctx *context); -void sha1_update(sha1_ctx *context, const void *p, size_t len); +SQLITE_PRIVATE void sha1_update(sha1_ctx *context, const void *p, size_t len); -void sha1_final(sha1_ctx *context, uint8_t digest[SHA1_DIGEST_SIZE]); +SQLITE_PRIVATE void sha1_final(sha1_ctx *context, uint8_t digest[SHA1_DIGEST_SIZE]); -void sha1_transform(sha1_ctx *context, const uint8_t buffer[64]); +SQLITE_PRIVATE void sha1_transform(sha1_ctx *context, const uint8_t buffer[64]); #endif /* SHA1_H_ */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.c index 587cc39556..cf1300402f 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.c @@ -131,27 +131,27 @@ wv[h] = t1 + t2; \ } -uint32 sha224_h0[8] = +static uint32 sha224_h0[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; -uint32 sha256_h0[8] = +static uint32 sha256_h0[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; -uint64 sha384_h0[8] = +static uint64 sha384_h0[8] = {li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507), li_64(9159015a3070dd17), li_64(152fecd8f70e5939), li_64(67332667ffc00b31), li_64(8eb44a8768581511), li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4)}; -uint64 sha512_h0[8] = +static uint64 sha512_h0[8] = {li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b), li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1), li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f), li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)}; -uint32 sha256_k[64] = +static uint32 sha256_k[64] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, @@ -169,7 +169,7 @@ uint32 sha256_k[64] = 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; -uint64 sha512_k[80] = +static uint64 sha512_k[80] = {li_64(428a2f98d728ae22), li_64(7137449123ef65cd), li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc), li_64(3956c25bf348b538), li_64(59f111f1b605d019), @@ -329,11 +329,13 @@ void sha256_transf(sha256_ctx *ctx, const unsigned char *message, } } +SQLITE_PRIVATE void sha256_transform(sha256_ctx *ctx, const unsigned char *message) { sha256_transf(ctx, message, 1); } +SQLITE_PRIVATE void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) { sha256_ctx ctx; @@ -343,6 +345,7 @@ void sha256(const unsigned char *message, unsigned int len, unsigned char *diges sha256_final(&ctx, digest); } +SQLITE_PRIVATE void sha256_init(sha256_ctx *ctx) { #ifndef UNROLL_LOOPS @@ -361,6 +364,7 @@ void sha256_init(sha256_ctx *ctx) ctx->tot_len = 0; } +SQLITE_PRIVATE void sha256_update(sha256_ctx *ctx, const unsigned char *message, unsigned int len) { @@ -395,6 +399,7 @@ void sha256_update(sha256_ctx *ctx, const unsigned char *message, ctx->tot_len += (block_nb + 1) << 6; } +SQLITE_PRIVATE void sha256_final(sha256_ctx *ctx, unsigned char *digest) { unsigned int block_nb; @@ -531,11 +536,13 @@ void sha512_transf(sha512_ctx *ctx, const unsigned char *message, } } +SQLITE_PRIVATE void sha512_transform(sha512_ctx *ctx, const unsigned char *message) { sha512_transf(ctx, message, 1); } +SQLITE_PRIVATE void sha512(const unsigned char *message, unsigned int len, unsigned char *digest) { @@ -546,6 +553,7 @@ void sha512(const unsigned char *message, unsigned int len, sha512_final(&ctx, digest); } +SQLITE_PRIVATE void sha512_init(sha512_ctx *ctx) { #ifndef UNROLL_LOOPS @@ -564,6 +572,7 @@ void sha512_init(sha512_ctx *ctx) ctx->tot_len = 0; } +SQLITE_PRIVATE void sha512_update(sha512_ctx *ctx, const unsigned char *message, unsigned int len) { @@ -598,6 +607,7 @@ void sha512_update(sha512_ctx *ctx, const unsigned char *message, ctx->tot_len += (block_nb + 1) << 7; } +SQLITE_PRIVATE void sha512_final(sha512_ctx *ctx, unsigned char *digest) { unsigned int block_nb; @@ -638,6 +648,7 @@ void sha512_final(sha512_ctx *ctx, unsigned char *digest) /* SHA-384 functions */ +SQLITE_PRIVATE void sha384(const unsigned char *message, unsigned int len, unsigned char *digest) { @@ -648,6 +659,7 @@ void sha384(const unsigned char *message, unsigned int len, sha384_final(&ctx, digest); } +SQLITE_PRIVATE void sha384_init(sha384_ctx *ctx) { #ifndef UNROLL_LOOPS @@ -666,6 +678,7 @@ void sha384_init(sha384_ctx *ctx) ctx->tot_len = 0; } +SQLITE_PRIVATE void sha384_update(sha384_ctx *ctx, const unsigned char *message, unsigned int len) { @@ -700,6 +713,7 @@ void sha384_update(sha384_ctx *ctx, const unsigned char *message, ctx->tot_len += (block_nb + 1) << 7; } +SQLITE_PRIVATE void sha384_final(sha384_ctx *ctx, unsigned char *digest) { unsigned int block_nb; @@ -738,6 +752,7 @@ void sha384_final(sha384_ctx *ctx, unsigned char *digest) /* SHA-224 functions */ +SQLITE_PRIVATE void sha224(const unsigned char *message, unsigned int len, unsigned char *digest) { @@ -748,6 +763,7 @@ void sha224(const unsigned char *message, unsigned int len, sha224_final(&ctx, digest); } +SQLITE_PRIVATE void sha224_init(sha224_ctx *ctx) { #ifndef UNROLL_LOOPS @@ -766,6 +782,7 @@ void sha224_init(sha224_ctx *ctx) ctx->tot_len = 0; } +SQLITE_PRIVATE void sha224_update(sha224_ctx *ctx, const unsigned char *message, unsigned int len) { @@ -800,6 +817,7 @@ void sha224_update(sha224_ctx *ctx, const unsigned char *message, ctx->tot_len += (block_nb + 1) << 6; } +SQLITE_PRIVATE void sha224_final(sha224_ctx *ctx, unsigned char *digest) { unsigned int block_nb; @@ -963,4 +981,3 @@ int main() } #endif /* TEST_VECTORS */ - diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.h index 4e63b26b0b..07c12c76f4 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.h @@ -34,6 +34,10 @@ #ifndef SHA2_H #define SHA2_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #define SHA224_DIGEST_SIZE ( 224 / 8) #define SHA256_DIGEST_SIZE ( 256 / 8) #define SHA384_DIGEST_SIZE ( 384 / 8) @@ -55,7 +59,7 @@ typedef sqlite3_uint64 uint64; #define li_64(h) 0x##h##ui64 #else #define li_64(h) 0x##h##ull -#endif +#endif #if 0 /* Start of original int64 defines */ @@ -127,35 +131,27 @@ typedef struct { typedef sha512_ctx sha384_ctx; typedef sha256_ctx sha224_ctx; -void sha224_init(sha224_ctx *ctx); -void sha224_update(sha224_ctx *ctx, const unsigned char *message, - unsigned int len); -void sha224_final(sha224_ctx *ctx, unsigned char *digest); -void sha224(const unsigned char *message, unsigned int len, - unsigned char *digest); - -void sha256_init(sha256_ctx * ctx); -void sha256_update(sha256_ctx *ctx, const unsigned char *message, - unsigned int len); -void sha256_final(sha256_ctx *ctx, unsigned char *digest); -void sha256_transform(sha256_ctx *ctx, const unsigned char *message); -void sha256(const unsigned char *message, unsigned int len, - unsigned char *digest); - -void sha384_init(sha384_ctx *ctx); -void sha384_update(sha384_ctx *ctx, const unsigned char *message, - unsigned int len); -void sha384_final(sha384_ctx *ctx, unsigned char *digest); -void sha384(const unsigned char *message, unsigned int len, - unsigned char *digest); - -void sha512_init(sha512_ctx *ctx); -void sha512_update(sha512_ctx *ctx, const unsigned char *message, - unsigned int len); -void sha512_final(sha512_ctx *ctx, unsigned char *digest); -void sha512_transform(sha512_ctx *ctx, const unsigned char *message); -void sha512(const unsigned char *message, unsigned int len, - unsigned char *digest); +SQLITE_PRIVATE void sha224_init(sha224_ctx *ctx); +SQLITE_PRIVATE void sha224_update(sha224_ctx *ctx, const unsigned char *message, unsigned int len); +SQLITE_PRIVATE void sha224_final(sha224_ctx *ctx, unsigned char *digest); +SQLITE_PRIVATE void sha224(const unsigned char *message, unsigned int len, unsigned char *digest); + +SQLITE_PRIVATE void sha256_init(sha256_ctx * ctx); +SQLITE_PRIVATE void sha256_update(sha256_ctx *ctx, const unsigned char *message, unsigned int len); +SQLITE_PRIVATE void sha256_final(sha256_ctx *ctx, unsigned char *digest); +SQLITE_PRIVATE void sha256_transform(sha256_ctx *ctx, const unsigned char *message); +SQLITE_PRIVATE void sha256(const unsigned char *message, unsigned int len, unsigned char *digest); + +SQLITE_PRIVATE void sha384_init(sha384_ctx *ctx); +SQLITE_PRIVATE void sha384_update(sha384_ctx *ctx, const unsigned char *message, unsigned int len); +SQLITE_PRIVATE void sha384_final(sha384_ctx *ctx, unsigned char *digest); +SQLITE_PRIVATE void sha384(const unsigned char *message, unsigned int len, unsigned char *digest); + +SQLITE_PRIVATE void sha512_init(sha512_ctx *ctx); +SQLITE_PRIVATE void sha512_update(sha512_ctx *ctx, const unsigned char *message, unsigned int len); +SQLITE_PRIVATE void sha512_final(sha512_ctx *ctx, unsigned char *digest); +SQLITE_PRIVATE void sha512_transform(sha512_ctx *ctx, const unsigned char *message); +SQLITE_PRIVATE void sha512(const unsigned char *message, unsigned int len, unsigned char *digest); #ifdef __cplusplus } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shathree.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shathree.c index ba3ea581f8..d97995055e 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shathree.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shathree.c @@ -12,13 +12,23 @@ ** ** This SQLite extension implements functions that compute SHA3 hashes ** in the way described by the (U.S.) NIST FIPS 202 SHA-3 Standard. -** Two SQL functions are implemented: +** Three SQL functions are implemented: ** ** sha3(X,SIZE) -** sha3_query(Y,SIZE) +** sha3_agg(Y,SIZE) +** sha3_query(Z,SIZE) ** ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if -** X is NULL. +** X is NULL. If inputs X is text, the UTF-8 rendering of that text is +** used to compute the hash. If X is a BLOB, then the binary data of the +** blob is used to compute the hash. If X is an integer or real number, +** then that number if converted into UTF-8 text and the hash is computed +** over the text. +** +** The sha3_agg(Y) function computes the SHA3 hash of all Y inputs. Since +** order is important for the hash, it is recommended that the Y expression +** by followed by an ORDER BY clause to guarantee that the inputs occur +** in the desired order. ** ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y ** and returns a hash of their results. @@ -26,6 +36,68 @@ ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm ** is used. If SIZE is included it must be one of the integers 224, 256, ** 384, or 512, to determine SHA3 hash variant that is computed. +** +** Because the sha3_agg() and sha3_query() functions compute a hash over +** multiple values, the values are encode to use include type information. +** +** In sha3_agg(), the sequence of bytes that gets hashed for each input +** Y depends on the datatype of Y: +** +** typeof(Y)='null' A single "N" is hashed. (One byte) +** +** typeof(Y)='integer' The data hash is the character "I" followed +** by an 8-byte big-endian binary of the +** 64-bit signed integer. (Nine bytes total.) +** +** typeof(Y)='real' The character "F" followed by an 8-byte +** big-ending binary of the double. (Nine +** bytes total.) +** +** typeof(Y)='text' The hash is over prefix "Tnnn:" followed +** by the UTF8 encoding of the text. The "nnn" +** in the prefix is the minimum-length decimal +** representation of the octet_length of the text. +** Notice the ":" at the end of the prefix, which +** is needed to separate the prefix from the +** content in cases where the content starts +** with a digit. +** +** typeof(Y)='blob' The hash is taken over prefix "Bnnn:" followed +** by the binary content of the blob. The "nnn" +** in the prefix is the mimimum-length decimal +** representation of the byte-length of the blob. +** +** According to the rules above, all of the following SELECT statements +** should return TRUE: +** +** SELECT sha3(1) = sha3('1'); +** +** SELECT sha3('hello') = sha3(x'68656c6c6f'); +** +** WITH a(x) AS (VALUES('xyzzy')) +** SELECT sha3_agg(x) = sha3('T5:xyzzy') FROM a; +** +** WITH a(x) AS (VALUES(x'010203')) +** SELECT sha3_agg(x) = sha3(x'42333a010203') FROM a; +** +** WITH a(x) AS (VALUES(0x123456)) +** SELECT sha3_agg(x) = sha3(x'490000000000123456') FROM a; +** +** WITH a(x) AS (VALUES(100.015625)) +** SELECT sha3_agg(x) = sha3(x'464059010000000000') FROM a; +** +** WITH a(x) AS (VALUES(NULL)) +** SELECT sha3_agg(x) = sha3('N') FROM a; +** +** +** In sha3_query(), individual column values are encoded as with +** sha3_agg(), but with the addition that a single "R" character is +** inserted at the start of each row. +** +** Note that sha3_agg() hashes rows for which Y is NULL. Add a FILTER +** clause if NULL rows should be excluded: +** +** SELECT sha3_agg(x ORDER BY rowid) FILTER(WHERE x NOT NULL) FROM t1; */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 @@ -75,6 +147,7 @@ struct SHA3Context { unsigned nRate; /* Bytes of input accepted per Keccak iteration */ unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ + unsigned iSize; /* 224, 256, 358, or 512 */ }; /* @@ -404,6 +477,7 @@ static void KeccakF1600Step(SHA3Context *p){ */ static void SHA3Init(SHA3Context *p, int iSize){ memset(p, 0, sizeof(*p)); + p->iSize = iSize; if( iSize>=128 && iSize<=512 ){ p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; }else{ @@ -495,7 +569,7 @@ static unsigned char *SHA3Final(SHA3Context *p){ ** Implementation of the sha3(X,SIZE) function. ** ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default -** size is 256. If X is a BLOB, it is hashed as is. +** size is 256. If X is a BLOB, it is hashed as is. ** For all other non-NULL types of input, X is converted into a UTF-8 string ** and the string is hashed without the trailing 0x00 terminator. The hash ** of a NULL value is NULL. @@ -547,6 +621,60 @@ static void sha3_step_vformat( SHA3Update(p, (unsigned char*)zBuf, n); } +/* +** Update a SHA3Context using a single sqlite3_value. +*/ +static void sha3UpdateFromValue(SHA3Context *p, sqlite3_value *pVal){ + switch( sqlite3_value_type(pVal) ){ + case SQLITE_NULL: { + SHA3Update(p, (const unsigned char*)"N",1); + break; + } + case SQLITE_INTEGER: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + sqlite3_int64 v = sqlite3_value_int64(pVal); + memcpy(&u, &v, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + SHA3Update(p, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_value_double(pVal); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + SHA3Update(p,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_value_bytes(pVal); + const unsigned char *z2 = sqlite3_value_text(pVal); + sha3_step_vformat(p,"T%d:",n2); + SHA3Update(p, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_value_bytes(pVal); + const unsigned char *z2 = sqlite3_value_blob(pVal); + sha3_step_vformat(p,"B%d:",n2); + SHA3Update(p, z2, n2); + break; + } + } +} + /* ** Implementation of the sha3_query(SQL,SIZE) function. ** @@ -636,54 +764,7 @@ static void sha3QueryFunc( while( SQLITE_ROW==sqlite3_step(pStmt) ){ SHA3Update(&cx,(const unsigned char*)"R",1); for(i=0; i=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'I'; - SHA3Update(&cx, x, 9); - break; - } - case SQLITE_FLOAT: { - sqlite3_uint64 u; - int j; - unsigned char x[9]; - double r = sqlite3_column_double(pStmt,i); - memcpy(&u, &r, 8); - for(j=8; j>=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'F'; - SHA3Update(&cx,x,9); - break; - } - case SQLITE_TEXT: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_text(pStmt, i); - sha3_step_vformat(&cx,"T%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - case SQLITE_BLOB: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_blob(pStmt, i); - sha3_step_vformat(&cx,"B%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - } + sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i)); } } sqlite3_finalize(pStmt); @@ -691,10 +772,47 @@ static void sha3QueryFunc( sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); } +/* +** xStep function for sha3_agg(). +*/ +static void sha3AggStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA3Context *p; + p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( p->nRate==0 ){ + int sz = 256; + if( argc==2 ){ + sz = sqlite3_value_int(argv[1]); + if( sz!=224 && sz!=384 && sz!=512 ){ + sz = 256; + } + } + SHA3Init(p, sz); + } + sha3UpdateFromValue(p, argv[0]); +} + + +/* +** xFinal function for sha3_agg(). +*/ +static void sha3AggFinal(sqlite3_context *context){ + SHA3Context *p; + p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( p->iSize ){ + sqlite3_result_blob(context, SHA3Final(p), p->iSize/8, SQLITE_TRANSIENT); + } +} -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_shathree_init( sqlite3 *db, char **pzErrMsg, @@ -711,6 +829,16 @@ int sqlite3_shathree_init( SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, 0, sha3Func, 0, 0); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_agg", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, 0, sha3AggStep, sha3AggFinal); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_agg", 2, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, 0, sha3AggStep, sha3AggFinal); + } if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8 | SQLITE_DIRECTONLY, diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shell.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shell.c index dea16bdbd4..ddcf414164 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shell.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shell.c @@ -130,9 +130,6 @@ typedef unsigned short int u16; typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; typedef unsigned char u8; -#if SQLITE_USER_AUTHENTICATION -# include "sqlite3userauth.h" -#endif #include #include @@ -218,8 +215,6 @@ typedef unsigned char u8; # ifndef strdup # define strdup _strdup # endif -# undef popen -# define popen _popen # undef pclose # define pclose _pclose # endif @@ -263,19 +258,9 @@ extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); #endif -/* Use console I/O package as a direct INCLUDE. */ -#define SQLITE_INTERNAL_LINKAGE static - -#ifdef SQLITE_SHELL_FIDDLE -/* Deselect most features from the console I/O package for Fiddle. */ -# define SQLITE_CIO_NO_REDIRECT -# define SQLITE_CIO_NO_CLASSIFY -# define SQLITE_CIO_NO_TRANSLATE -# define SQLITE_CIO_NO_SETMODE -#endif -/************************* Begin ../ext/consio/console_io.h ******************/ +/************************* Begin ../ext/misc/sqlite3_stdio.h ******************/ /* -** 2023 November 1 +** 2024-09-24 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -284,1079 +269,453 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** -******************************************************************************** -** This file exposes various interfaces used for console and other I/O -** by the SQLite project command-line tools. These interfaces are used -** at either source conglomeration time, compilation time, or run time. -** This source provides for either inclusion into conglomerated, -** "single-source" forms or separate compilation then linking. +************************************************************************* +** +** This header file contains definitions of interfaces that provide +** cross-platform I/O for UTF-8 content. ** -** Platform dependencies are "hidden" here by various stratagems so -** that, provided certain conditions are met, the programs using this -** source or object code compiled from it need no explicit conditional -** compilation in their source for their console and stream I/O. +** On most platforms, the interfaces definitions in this file are +** just #defines. For example sqlite3_fopen() is a macro that resolves +** to the standard fopen() in the C-library. ** -** The symbols and functionality exposed here are not a public API. -** This code may change in tandem with other project code as needed. +** But Windows does not have a standard C-library, at least not one that +** can handle UTF-8. So for windows build, the interfaces resolve to new +** C-language routines contained in the separate sqlite3_stdio.c source file. ** -** When this .h file and its companion .c are directly incorporated into -** a source conglomeration (such as shell.c), the preprocessor symbol -** CIO_WIN_WC_XLATE is defined as 0 or 1, reflecting whether console I/O -** translation for Windows is effected for the build. +** So on all non-Windows platforms, simply #include this header file and +** use the interfaces defined herein. Then to run your application on Windows, +** also link in the accompanying sqlite3_stdio.c source file when compiling +** to get compatible interfaces. */ +#ifndef _SQLITE3_STDIO_H_ +#define _SQLITE3_STDIO_H_ 1 +#ifdef _WIN32 +/**** Definitions For Windows ****/ +#include +#include -#ifndef SQLITE_INTERNAL_LINKAGE -# define SQLITE_INTERNAL_LINKAGE extern /* external to translation unit */ -# include -#else -# define SHELL_NO_SYSINC /* Better yet, modify mkshellc.tcl for this. */ -#endif +FILE *sqlite3_fopen(const char *zFilename, const char *zMode); +FILE *sqlite3_popen(const char *zCommand, const char *type); +char *sqlite3_fgets(char *s, int size, FILE *stream); +int sqlite3_fputs(const char *s, FILE *stream); +int sqlite3_fprintf(FILE *stream, const char *format, ...); +void sqlite3_fsetmode(FILE *stream, int mode); -#ifndef SQLITE3_H -/* # include "sqlite3.h" */ -#endif -#ifndef SQLITE_CIO_NO_CLASSIFY +#else +/**** Definitions For All Other Platforms ****/ +#include +#define sqlite3_fopen fopen +#define sqlite3_popen popen +#define sqlite3_fgets fgets +#define sqlite3_fputs fputs +#define sqlite3_fprintf fprintf +#define sqlite3_fsetmode(F,X) /*no-op*/ -/* Define enum for use with following function. */ -typedef enum StreamsAreConsole { - SAC_NoConsole = 0, - SAC_InConsole = 1, SAC_OutConsole = 2, SAC_ErrConsole = 4, - SAC_AnyConsole = 0x7 -} StreamsAreConsole; +#endif +#endif /* _SQLITE3_STDIO_H_ */ +/************************* End ../ext/misc/sqlite3_stdio.h ********************/ +/************************* Begin ../ext/misc/sqlite3_stdio.c ******************/ /* -** Classify the three standard I/O streams according to whether -** they are connected to a console attached to the process. +** 2024-09-24 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: ** -** Returns the bit-wise OR of SAC_{In,Out,Err}Console values, -** or SAC_NoConsole if none of the streams reaches a console. +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. ** -** This function should be called before any I/O is done with -** the given streams. As a side-effect, the given inputs are -** recorded so that later I/O operations on them may be done -** differently than the C library FILE* I/O would be done, -** iff the stream is used for the I/O functions that follow, -** and to support the ones that use an implicit stream. +************************************************************************* ** -** On some platforms, stream or console mode alteration (aka -** "Setup") may be made which is undone by consoleRestore(). +** Implementation of standard I/O interfaces for UTF-8 that are missing +** on Windows. */ -SQLITE_INTERNAL_LINKAGE StreamsAreConsole -consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ); -/* A usual call for convenience: */ -#define SQLITE_STD_CONSOLE_INIT() consoleClassifySetup(stdin,stdout,stderr) +#ifdef _WIN32 /* This file is a no-op on all platforms except Windows */ +#ifndef _SQLITE3_STDIO_H_ +/* #include "sqlite3_stdio.h" */ +#endif +#undef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +/* #include "sqlite3.h" */ +#include +#include +#include +#include /* -** After an initial call to consoleClassifySetup(...), renew -** the same setup it effected. (A call not after is an error.) -** This will restore state altered by consoleRestore(); -** -** Applications which run an inferior (child) process which -** inherits the same I/O streams may call this function after -** such a process exits to guard against console mode changes. -*/ -SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void); +** If the SQLITE_U8TEXT_ONLY option is defined, then use O_U8TEXT +** when appropriate on all output. (Sometimes use O_BINARY when +** rendering ASCII text in cases where NL-to-CRLF expansion would +** not be correct.) +** +** If the SQLITE_U8TEXT_STDIO option is defined, then use O_U8TEXT +** when appropriate when writing to stdout or stderr. Use O_BINARY +** or O_TEXT (depending on things like the .mode and the .crlf setting +** in the CLI, or other context clues in other applications) for all +** other output channels. +** +** The default behavior, if neither of the above is defined is to +** use O_U8TEXT when writing to the Windows console (or anything +** else for which _isatty() returns true) and to use O_BINARY or O_TEXT +** for all other output channels. +*/ +#if defined(SQLITE_U8TEXT_ONLY) +# define UseWtextForOutput(fd) 1 +# define UseWtextForInput(fd) 1 +# define IsConsole(fd) _isatty(_fileno(fd)) +#elif defined(SQLITE_U8TEXT_STDIO) +# define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) +# define UseWtextForInput(fd) ((fd)==stdin) +# define IsConsole(fd) _isatty(_fileno(fd)) +#else +# define UseWtextForOutput(fd) _isatty(_fileno(fd)) +# define UseWtextForInput(fd) _isatty(_fileno(fd)) +# define IsConsole(fd) 1 +#endif /* -** Undo any side-effects left by consoleClassifySetup(...). -** -** This should be called after consoleClassifySetup() and -** before the process terminates normally. It is suitable -** for use with the atexit() C library procedure. After -** this call, no console I/O should be done until one of -** console{Classify or Renew}Setup(...) is called again. -** -** Applications which run an inferior (child) process that -** inherits the same I/O streams might call this procedure -** before so that said process will have a console setup -** however users have configured it or come to expect. +** Global variables determine if simulated O_BINARY mode is to be +** used for stdout or other, respectively. Simulated O_BINARY mode +** means the mode is usually O_BINARY, but switches to O_U8TEXT for +** unicode characters U+0080 or greater (any character that has a +** multi-byte representation in UTF-8). This is the only way we +** have found to render Unicode characters on a Windows console while +** at the same time avoiding undesirable \n to \r\n translation. */ -SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ); +static int simBinaryStdout = 0; +static int simBinaryOther = 0; -#else /* defined(SQLITE_CIO_NO_CLASSIFY) */ -# define consoleClassifySetup(i,o,e) -# define consoleRenewSetup() -# define consoleRestore() -#endif /* defined(SQLITE_CIO_NO_CLASSIFY) */ -#ifndef SQLITE_CIO_NO_REDIRECT /* -** Set stream to be used for the functions below which write -** to "the designated X stream", where X is Output or Error. -** Returns the previous value. -** -** Alternatively, pass the special value, invalidFileStream, -** to get the designated stream value without setting it. -** -** Before the designated streams are set, they default to -** those passed to consoleClassifySetup(...), and before -** that is called they default to stdout and stderr. -** -** It is error to close a stream so designated, then, without -** designating another, use the corresponding {o,e}Emit(...). +** Determine if simulated binary mode should be used for output to fd */ -SQLITE_INTERNAL_LINKAGE FILE *invalidFileStream; -SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf); -# ifdef CONSIO_SET_ERROR_STREAM -SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf); -# endif -#else -# define setOutputStream(pf) -# define setErrorStream(pf) -#endif /* !defined(SQLITE_CIO_NO_REDIRECT) */ +static int UseBinaryWText(FILE *fd){ + if( fd==stdout || fd==stderr ){ + return simBinaryStdout; + }else{ + return simBinaryOther; + } +} -#ifndef SQLITE_CIO_NO_TRANSLATE -/* -** Emit output like fprintf(). If the output is going to the -** console and translation from UTF-8 is necessary, perform -** the needed translation. Otherwise, write formatted output -** to the provided stream almost as-is, possibly with newline -** translation as specified by set{Binary,Text}Mode(). -*/ -SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...); -/* Like fPrintfUtf8 except stream is always the designated output. */ -SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...); -/* Like fPrintfUtf8 except stream is always the designated error. */ -SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...); /* -** Emit output like fputs(). If the output is going to the -** console and translation from UTF-8 is necessary, perform -** the needed translation. Otherwise, write given text to the -** provided stream almost as-is, possibly with newline -** translation as specified by set{Binary,Text}Mode(). +** Work-alike for the fopen() routine from the standard C library. */ -SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO); -/* Like fPutsUtf8 except stream is always the designated output. */ -SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z); -/* Like fPutsUtf8 except stream is always the designated error. */ -SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z); +FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ + FILE *fp = 0; + wchar_t *b1, *b2; + int sz1, sz2; + + sz1 = (int)strlen(zFilename); + sz2 = (int)strlen(zMode); + b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) ); + if( b1 && b2 ){ + sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); + b1[sz1] = 0; + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); + b2[sz2] = 0; + fp = _wfopen(b1, b2); + } + sqlite3_free(b1); + sqlite3_free(b2); + simBinaryOther = 0; + return fp; +} -/* -** Emit output like fPutsUtf8(), except that the length of the -** accepted char or character sequence is limited by nAccept. -** -** Returns the number of accepted char values. -*/ -#ifdef CONSIO_SPUTB -SQLITE_INTERNAL_LINKAGE int -fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept); -#endif -/* Like fPutbUtf8 except stream is always the designated output. */ -SQLITE_INTERNAL_LINKAGE int -oPutbUtf8(const char *cBuf, int nAccept); -/* Like fPutbUtf8 except stream is always the designated error. */ -#ifdef CONSIO_EPUTB -SQLITE_INTERNAL_LINKAGE int -ePutbUtf8(const char *cBuf, int nAccept); -#endif /* -** Collect input like fgets(...) with special provisions for input -** from the console on platforms that require same. Defers to the -** C library fgets() when input is not from the console. Newline -** translation may be done as set by set{Binary,Text}Mode(). As a -** convenience, pfIn==NULL is treated as stdin. +** Work-alike for the popen() routine from the standard C library. */ -SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn); -/* Like fGetsUtf8 except stream is always the designated input. */ -/* SQLITE_INTERNAL_LINKAGE char* iGetsUtf8(char *cBuf, int ncMax); */ +FILE *sqlite3_popen(const char *zCommand, const char *zMode){ + FILE *fp = 0; + wchar_t *b1, *b2; + int sz1, sz2; -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ + sz1 = (int)strlen(zCommand); + sz2 = (int)strlen(zMode); + b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) ); + if( b1 && b2 ){ + sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1); + b1[sz1] = 0; + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); + b2[sz2] = 0; + fp = _wpopen(b1, b2); + } + sqlite3_free(b1); + sqlite3_free(b2); + return fp; +} -#ifndef SQLITE_CIO_NO_SETMODE /* -** Set given stream for binary mode, where newline translation is -** not done, or for text mode where, for some platforms, newlines -** are translated to the platform's conventional char sequence. -** If bFlush true, flush the stream. -** -** An additional side-effect is that if the stream is one passed -** to consoleClassifySetup() as an output, it is flushed first. -** -** Note that binary/text mode has no effect on console I/O -** translation. On all platforms, newline to the console starts -** a new line and CR,LF chars from the console become a newline. +** Work-alike for fgets() from the standard C library. */ -SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *, short bFlush); -SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *, short bFlush); +char *sqlite3_fgets(char *buf, int sz, FILE *in){ + if( UseWtextForInput(in) ){ + /* When reading from the command-prompt in Windows, it is necessary + ** to use _O_WTEXT input mode to read UTF-16 characters, then translate + ** that into UTF-8. Otherwise, non-ASCII characters all get translated + ** into '?'. + */ + wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) ); + if( b1==0 ) return 0; +#ifndef SQLITE_USE_STDIO_FOR_CONSOLE + DWORD nRead = 0; + if( IsConsole(in) + && ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz, &nRead, 0) + ){ + b1[nRead] = 0; + }else #endif - -#ifdef SQLITE_CIO_PROMPTED_IN -typedef struct Prompts { - int numPrompts; - const char **azPrompts; -} Prompts; + { + _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); + if( fgetws(b1, sz/4, in)==0 ){ + sqlite3_free(b1); + return 0; + } + } + WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0); + sqlite3_free(b1); + return buf; + }else{ + /* Reading from a file or other input source, just read bytes without + ** any translation. */ + return fgets(buf, sz, in); + } +} /* -** Macros for use of a line editor. -** -** The following macros define operations involving use of a -** line-editing library or simple console interaction. -** A "T" argument is a text (char *) buffer or filename. -** A "N" argument is an integer. -** -** SHELL_ADD_HISTORY(T) // Record text as line(s) of history. -** SHELL_READ_HISTORY(T) // Read history from file named by T. -** SHELL_WRITE_HISTORY(T) // Write history to file named by T. -** SHELL_STIFLE_HISTORY(N) // Limit history to N entries. -** -** A console program which does interactive console input is -** expected to call: -** SHELL_READ_HISTORY(T) before collecting such input; -** SHELL_ADD_HISTORY(T) as record-worthy input is taken; -** SHELL_STIFLE_HISTORY(N) after console input ceases; then -** SHELL_WRITE_HISTORY(T) before the program exits. +** Send ASCII text as O_BINARY. But for Unicode characters U+0080 and +** greater, switch to O_U8TEXT. */ +static void piecemealOutput(wchar_t *b1, int sz, FILE *out){ + int i; + wchar_t c; + while( sz>0 ){ + for(i=0; i=0x80; i++){} + if( i>0 ){ + c = b1[i]; + b1[i] = 0; + fflush(out); + _setmode(_fileno(out), _O_U8TEXT); + fputws(b1, out); + fflush(out); + b1 += i; + b1[0] = c; + sz -= i; + }else{ + fflush(out); + _setmode(_fileno(out), _O_TEXT); + _setmode(_fileno(out), _O_BINARY); + fwrite(&b1[0], 1, 1, out); + for(i=1; i=0 => char count, nAccept<0 => character - */ -SQLITE_INTERNAL_LINKAGE const char* -zSkipValidUtf8(const char *z, int nAccept, long ccm); - -#endif + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + sqlite3_fputs(z, out); + rc = (int)strlen(z); + sqlite3_free(z); + }else{ + /* Writing to a file or other destination, just write bytes without + ** any translation. */ + va_list ap; + va_start(ap, zFormat); + rc = vfprintf(out, zFormat, ap); + va_end(ap); + } + return rc; +} -/************************* End ../ext/consio/console_io.h ********************/ -/************************* Begin ../ext/consio/console_io.c ******************/ /* -** 2023 November 4 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -******************************************************************************** -** This file implements various interfaces used for console and stream I/O -** by the SQLite project command-line tools, as explained in console_io.h . -** Functions prefixed by "SQLITE_INTERNAL_LINKAGE" behave as described there. +** Set the mode for an output stream. mode argument is typically _O_BINARY or +** _O_TEXT. */ +void sqlite3_fsetmode(FILE *fp, int mode){ + if( !UseWtextForOutput(fp) ){ + fflush(fp); + _setmode(_fileno(fp), mode); + }else if( fp==stdout || fp==stderr ){ + simBinaryStdout = (mode==_O_BINARY); + }else{ + simBinaryOther = (mode==_O_BINARY); + } +} -#ifndef SQLITE_CDECL -# define SQLITE_CDECL -#endif - -#ifndef SHELL_NO_SYSINC -# include -# include -# include -# include -# include -# include "console_io.h" -/* # include "sqlite3.h" */ -#endif +#endif /* defined(_WIN32) */ -#ifndef SQLITE_CIO_NO_TRANSLATE -# if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT -# ifndef SHELL_NO_SYSINC -# include -# include -# undef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# include -# endif -# define CIO_WIN_WC_XLATE 1 /* Use WCHAR Windows APIs for console I/O */ -# else -# ifndef SHELL_NO_SYSINC -# include -# endif -# define CIO_WIN_WC_XLATE 0 /* Use plain C library stream I/O at console */ -# endif -#else -# define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */ -#endif +/************************* End ../ext/misc/sqlite3_stdio.c ********************/ -#if CIO_WIN_WC_XLATE -/* Character used to represent a known-incomplete UTF-8 char group (�) */ -static WCHAR cBadGroup = 0xfffd; -#endif +/* Use console I/O package as a direct INCLUDE. */ +#define SQLITE_INTERNAL_LINKAGE static -#if CIO_WIN_WC_XLATE -static HANDLE handleOfFile(FILE *pf){ - int fileDesc = _fileno(pf); - union { intptr_t osfh; HANDLE fh; } fid = { - (fileDesc>=0)? _get_osfhandle(fileDesc) : (intptr_t)INVALID_HANDLE_VALUE - }; - return fid.fh; -} +#ifdef SQLITE_SHELL_FIDDLE +/* Deselect most features from the console I/O package for Fiddle. */ +# define SQLITE_CIO_NO_REDIRECT +# define SQLITE_CIO_NO_CLASSIFY +# define SQLITE_CIO_NO_TRANSLATE +# define SQLITE_CIO_NO_SETMODE +# define SQLITE_CIO_NO_FLUSH #endif -#ifndef SQLITE_CIO_NO_TRANSLATE -typedef struct PerStreamTags { -# if CIO_WIN_WC_XLATE - HANDLE hx; - DWORD consMode; - char acIncomplete[4]; -# else - short reachesConsole; -# endif - FILE *pf; -} PerStreamTags; - -/* Define NULL-like value for things which can validly be 0. */ -# define SHELL_INVALID_FILE_PTR ((FILE *)~0) -# if CIO_WIN_WC_XLATE -# define SHELL_INVALID_CONS_MODE 0xFFFF0000 -# endif +#define eputz(z) sqlite3_fputs(z,stderr) +#define sputz(fp,z) sqlite3_fputs(z,fp) -# if CIO_WIN_WC_XLATE -# define PST_INITIALIZER { INVALID_HANDLE_VALUE, SHELL_INVALID_CONS_MODE, \ - {0,0,0,0}, SHELL_INVALID_FILE_PTR } -# else -# define PST_INITIALIZER { 0, SHELL_INVALID_FILE_PTR } -# endif +/* True if the timer is enabled */ +static int enableTimer = 0; -/* Quickly say whether a known output is going to the console. */ -# if CIO_WIN_WC_XLATE -static short pstReachesConsole(PerStreamTags *ppst){ - return (ppst->hx != INVALID_HANDLE_VALUE); +/* A version of strcmp() that works with NULL values */ +static int cli_strcmp(const char *a, const char *b){ + if( a==0 ) a = ""; + if( b==0 ) b = ""; + return strcmp(a,b); } -# else -# define pstReachesConsole(ppst) 0 -# endif - -# if CIO_WIN_WC_XLATE -static void restoreConsoleArb(PerStreamTags *ppst){ - if( pstReachesConsole(ppst) ) SetConsoleMode(ppst->hx, ppst->consMode); +static int cli_strncmp(const char *a, const char *b, size_t n){ + if( a==0 ) a = ""; + if( b==0 ) b = ""; + return strncmp(a,b,n); } -# else -# define restoreConsoleArb(ppst) -# endif -/* Say whether FILE* appears to be a console, collect associated info. */ -static short streamOfConsole(FILE *pf, /* out */ PerStreamTags *ppst){ -# if CIO_WIN_WC_XLATE - short rv = 0; - DWORD dwCM = SHELL_INVALID_CONS_MODE; - HANDLE fh = handleOfFile(pf); - ppst->pf = pf; - if( INVALID_HANDLE_VALUE != fh ){ - rv = (GetFileType(fh) == FILE_TYPE_CHAR && GetConsoleMode(fh,&dwCM)); - } - ppst->hx = (rv)? fh : INVALID_HANDLE_VALUE; - ppst->consMode = dwCM; - return rv; -# else - ppst->pf = pf; - ppst->reachesConsole = ( (short)isatty(fileno(pf)) ); - return ppst->reachesConsole; -# endif +/* Return the current wall-clock time */ +static sqlite3_int64 timeOfDay(void){ + static sqlite3_vfs *clockVfs = 0; + sqlite3_int64 t; + if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); + if( clockVfs==0 ) return 0; /* Never actually happens */ + if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ + clockVfs->xCurrentTimeInt64(clockVfs, &t); + }else{ + double r; + clockVfs->xCurrentTime(clockVfs, &r); + t = (sqlite3_int64)(r*86400000.0); + } + return t; } -# if CIO_WIN_WC_XLATE -/* Define console modes for use with the Windows Console API. */ -# define SHELL_CONI_MODE \ - (ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | 0x80 \ - | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT) -# define SHELL_CONO_MODE (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT \ - | ENABLE_VIRTUAL_TERMINAL_PROCESSING) -# endif - -typedef struct ConsoleInfo { - PerStreamTags pstSetup[3]; - PerStreamTags pstDesignated[3]; - StreamsAreConsole sacSetup; -} ConsoleInfo; - -static short isValidStreamInfo(PerStreamTags *ppst){ - return (ppst->pf != SHELL_INVALID_FILE_PTR); -} +#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) +#include +#include -static ConsoleInfo consoleInfo = { - { /* pstSetup */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER }, - { /* pstDesignated[] */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER }, - SAC_NoConsole /* sacSetup */ +/* VxWorks does not support getrusage() as far as we can determine */ +#if defined(_WRS_KERNEL) || defined(__RTP__) +struct rusage { + struct timeval ru_utime; /* user CPU time used */ + struct timeval ru_stime; /* system CPU time used */ }; +#define getrusage(A,B) memset(B,0,sizeof(*B)) +#endif -SQLITE_INTERNAL_LINKAGE FILE* invalidFileStream = (FILE *)~0; -# if CIO_WIN_WC_XLATE -static void maybeSetupAsConsole(PerStreamTags *ppst, short odir){ - if( pstReachesConsole(ppst) ){ - DWORD cm = odir? SHELL_CONO_MODE : SHELL_CONI_MODE; - SetConsoleMode(ppst->hx, cm); - } -} -# else -# define maybeSetupAsConsole(ppst,odir) -# endif +/* Saved resource information for the beginning of an operation */ +static struct rusage sBegin; /* CPU time at start */ +static sqlite3_int64 iBegin; /* Wall-clock time at start */ -SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void){ -# if CIO_WIN_WC_XLATE - int ix = 0; - while( ix < 6 ){ - PerStreamTags *ppst = (ix<3)? - &consoleInfo.pstSetup[ix] : &consoleInfo.pstDesignated[ix-3]; - maybeSetupAsConsole(ppst, (ix % 3)>0); - ++ix; +/* +** Begin timing an operation +*/ +static void beginTimer(void){ + if( enableTimer ){ + getrusage(RUSAGE_SELF, &sBegin); + iBegin = timeOfDay(); } -# endif } -SQLITE_INTERNAL_LINKAGE StreamsAreConsole -consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ){ - StreamsAreConsole rv = SAC_NoConsole; - FILE* apf[3] = { pfIn, pfOut, pfErr }; - int ix; - for( ix = 2; ix >= 0; --ix ){ - PerStreamTags *ppst = &consoleInfo.pstSetup[ix]; - if( streamOfConsole(apf[ix], ppst) ){ - rv |= (SAC_InConsole< 0 ) fflush(apf[ix]); - } - consoleInfo.sacSetup = rv; - consoleRenewSetup(); - return rv; +/* Return the difference of two time_structs in seconds */ +static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ + return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + + (double)(pEnd->tv_sec - pStart->tv_sec); } -SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ){ -# if CIO_WIN_WC_XLATE - static ConsoleInfo *pci = &consoleInfo; - if( pci->sacSetup ){ - int ix; - for( ix=0; ix<3; ++ix ){ - if( pci->sacSetup & (SAC_InConsole<pstSetup[ix]; - SetConsoleMode(ppst->hx, ppst->consMode); - } - } +/* +** Print the timing results. +*/ +static void endTimer(FILE *out){ + if( enableTimer ){ + sqlite3_int64 iEnd = timeOfDay(); + struct rusage sEnd; + getrusage(RUSAGE_SELF, &sEnd); + sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", + (iEnd - iBegin)*0.001, + timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), + timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); } -# endif } -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ -#ifdef SQLITE_CIO_INPUT_REDIR -/* Say whether given FILE* is among those known, via either -** consoleClassifySetup() or set{Output,Error}Stream, as -** readable, and return an associated PerStreamTags pointer -** if so. Otherwise, return 0. -*/ -static PerStreamTags * isKnownReadable(FILE *pf){ - static PerStreamTags *apst[] = { - &consoleInfo.pstDesignated[0], &consoleInfo.pstSetup[0], 0 - }; - int ix = 0; - do { - if( apst[ix]->pf == pf ) break; - } while( apst[++ix] != 0 ); - return apst[ix]; -} -#endif - -#ifndef SQLITE_CIO_NO_TRANSLATE -/* Say whether given FILE* is among those known, via either -** consoleClassifySetup() or set{Output,Error}Stream, as -** writable, and return an associated PerStreamTags pointer -** if so. Otherwise, return 0. -*/ -static PerStreamTags * isKnownWritable(FILE *pf){ - static PerStreamTags *apst[] = { - &consoleInfo.pstDesignated[1], &consoleInfo.pstDesignated[2], - &consoleInfo.pstSetup[1], &consoleInfo.pstSetup[2], 0 - }; - int ix = 0; - do { - if( apst[ix]->pf == pf ) break; - } while( apst[++ix] != 0 ); - return apst[ix]; -} - -static FILE *designateEmitStream(FILE *pf, unsigned chix){ - FILE *rv = consoleInfo.pstDesignated[chix].pf; - if( pf == invalidFileStream ) return rv; - else{ - /* Setting a possibly new output stream. */ - PerStreamTags *ppst = isKnownWritable(pf); - if( ppst != 0 ){ - PerStreamTags pst = *ppst; - consoleInfo.pstDesignated[chix] = pst; - }else streamOfConsole(pf, &consoleInfo.pstDesignated[chix]); - } - return rv; -} - -SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf){ - return designateEmitStream(pf, 1); -} -# ifdef CONSIO_SET_ERROR_STREAM -SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf){ - return designateEmitStream(pf, 2); -} -# endif -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#ifndef SQLITE_CIO_NO_SETMODE -# if CIO_WIN_WC_XLATE -static void setModeFlushQ(FILE *pf, short bFlush, int mode){ - if( bFlush ) fflush(pf); - _setmode(_fileno(pf), mode); -} -# else -# define setModeFlushQ(f, b, m) if(b) fflush(f) -# endif - -SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *pf, short bFlush){ - setModeFlushQ(pf, bFlush, _O_BINARY); -} -SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *pf, short bFlush){ - setModeFlushQ(pf, bFlush, _O_TEXT); -} -# undef setModeFlushQ - -#else /* defined(SQLITE_CIO_NO_SETMODE) */ -# define setBinaryMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0) -# define setTextMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0) -#endif /* defined(SQLITE_CIO_NO_SETMODE) */ - -#ifndef SQLITE_CIO_NO_TRANSLATE -# if CIO_WIN_WC_XLATE -/* Write buffer cBuf as output to stream known to reach console, -** limited to ncTake char's. Return ncTake on success, else 0. */ -static int conZstrEmit(PerStreamTags *ppst, const char *z, int ncTake){ - int rv = 0; - if( z!=NULL ){ - int nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, 0,0); - if( nwc > 0 ){ - WCHAR *zw = sqlite3_malloc64(nwc*sizeof(WCHAR)); - if( zw!=NULL ){ - nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, zw,nwc); - if( nwc > 0 ){ - /* Translation from UTF-8 to UTF-16, then WCHARs out. */ - if( WriteConsoleW(ppst->hx, zw,nwc, 0, NULL) ){ - rv = ncTake; - } - } - sqlite3_free(zw); - } - } - } - return rv; -} - -/* For {f,o,e}PrintfUtf8() when stream is known to reach console. */ -static int conioVmPrintf(PerStreamTags *ppst, const char *zFormat, va_list ap){ - char *z = sqlite3_vmprintf(zFormat, ap); - if( z ){ - int rv = conZstrEmit(ppst, z, (int)strlen(z)); - sqlite3_free(z); - return rv; - }else return 0; -} -# endif /* CIO_WIN_WC_XLATE */ - -# ifdef CONSIO_GET_EMIT_STREAM -static PerStreamTags * getDesignatedEmitStream(FILE *pf, unsigned chix, - PerStreamTags *ppst){ - PerStreamTags *rv = isKnownWritable(pf); - short isValid = (rv!=0)? isValidStreamInfo(rv) : 0; - if( rv != 0 && isValid ) return rv; - streamOfConsole(pf, ppst); - return ppst; -} -# endif - -/* Get stream info, either for designated output or error stream when -** chix equals 1 or 2, or for an arbitrary stream when chix == 0. -** In either case, ppst references a caller-owned PerStreamTags -** struct which may be filled in if none of the known writable -** streams is being held by consoleInfo. The ppf parameter is a -** byref output when chix!=0 and a byref input when chix==0. - */ -static PerStreamTags * -getEmitStreamInfo(unsigned chix, PerStreamTags *ppst, - /* in/out */ FILE **ppf){ - PerStreamTags *ppstTry; - FILE *pfEmit; - if( chix > 0 ){ - ppstTry = &consoleInfo.pstDesignated[chix]; - if( !isValidStreamInfo(ppstTry) ){ - ppstTry = &consoleInfo.pstSetup[chix]; - pfEmit = ppst->pf; - }else pfEmit = ppstTry->pf; - if( !isValidStreamInfo(ppstTry) ){ - pfEmit = (chix > 1)? stderr : stdout; - ppstTry = ppst; - streamOfConsole(pfEmit, ppstTry); - } - *ppf = pfEmit; - }else{ - ppstTry = isKnownWritable(*ppf); - if( ppstTry != 0 ) return ppstTry; - streamOfConsole(*ppf, ppst); - return ppst; - } - return ppstTry; -} - -SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...){ - va_list ap; - int rv; - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - rv = conioVmPrintf(ppst, zFormat, ap); - }else{ -# endif - rv = vfprintf(pfOut, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...){ - va_list ap; - int rv; - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# else - getEmitStreamInfo(2, &pst, &pfErr); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - rv = conioVmPrintf(ppst, zFormat, ap); - }else{ -# endif - rv = vfprintf(pfErr, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...){ - va_list ap; - int rv; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); -# else - getEmitStreamInfo(0, &pst, &pfO); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - maybeSetupAsConsole(ppst, 1); - rv = conioVmPrintf(ppst, zFormat, ap); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - }else{ -# endif - rv = vfprintf(pfO, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO){ - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); -# else - getEmitStreamInfo(0, &pst, &pfO); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - int rv; - maybeSetupAsConsole(ppst, 1); - rv = conZstrEmit(ppst, z, (int)strlen(z)); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - return rv; - }else { -# endif - return (fputs(z, pfO)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z){ - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# else - getEmitStreamInfo(2, &pst, &pfErr); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z)); - else { -# endif - return (fputs(z, pfErr)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z){ - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z)); - else { -# endif - return (fputs(z, pfOut)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#if !(defined(SQLITE_CIO_NO_UTF8SCAN) && defined(SQLITE_CIO_NO_TRANSLATE)) -/* Skip over as much z[] input char sequence as is valid UTF-8, -** limited per nAccept char's or whole characters and containing -** no char cn such that ((1<=0 => char count, nAccept<0 => character - */ -SQLITE_INTERNAL_LINKAGE const char* -zSkipValidUtf8(const char *z, int nAccept, long ccm){ - int ng = (nAccept<0)? -nAccept : 0; - const char *pcLimit = (nAccept>=0)? z+nAccept : 0; - assert(z!=0); - while( (pcLimit)? (z= pcLimit ) return z; - else{ - char ct = *zt++; - if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){ - /* Trailing bytes are too few, too many, or invalid. */ - return z; - } - } - } while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */ - z = zt; - } - } - return z; -} -#endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/ - -#ifndef SQLITE_CIO_NO_TRANSLATE - -#ifdef CONSIO_SPUTB -SQLITE_INTERNAL_LINKAGE int -fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){ - assert(pfO!=0); -# if CIO_WIN_WC_XLATE - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); - if( pstReachesConsole(ppst) ){ - int rv; - maybeSetupAsConsole(ppst, 1); - rv = conZstrEmit(ppst, cBuf, nAccept); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - return rv; - }else { -# endif - return (int)fwrite(cBuf, 1, nAccept, pfO); -# if CIO_WIN_WC_XLATE - } -# endif -} -#endif /* defined(CONSIO_SPUTB) */ - -SQLITE_INTERNAL_LINKAGE int -oPutbUtf8(const char *cBuf, int nAccept){ - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - return conZstrEmit(ppst, cBuf, nAccept); - }else { -# endif - return (int)fwrite(cBuf, 1, nAccept, pfOut); -# if CIO_WIN_WC_XLATE - } -# endif -} - -# ifdef CONSIO_EPUTB -SQLITE_INTERNAL_LINKAGE int -ePutbUtf8(const char *cBuf, int nAccept){ - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - return conZstrEmit(ppst, cBuf, nAccept); - }else { -# endif - return (int)fwrite(cBuf, 1, nAccept, pfErr); -# if CIO_WIN_WC_XLATE - } -# endif -} -# endif /* defined(CONSIO_EPUTB) */ - -SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){ - if( pfIn==0 ) pfIn = stdin; -# if CIO_WIN_WC_XLATE - if( pfIn == consoleInfo.pstSetup[0].pf - && (consoleInfo.sacSetup & SAC_InConsole)!=0 ){ -# if CIO_WIN_WC_XLATE==1 -# define SHELL_GULP 150 /* Count of WCHARS to be gulped at a time */ - WCHAR wcBuf[SHELL_GULP+1]; - int lend = 0, noc = 0; - if( ncMax > 0 ) cBuf[0] = 0; - while( noc < ncMax-8-1 && !lend ){ - /* There is room for at least 2 more characters and a 0-terminator. */ - int na = (ncMax > SHELL_GULP*4+1 + noc)? SHELL_GULP : (ncMax-1 - noc)/4; -# undef SHELL_GULP - DWORD nbr = 0; - BOOL bRC = ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf, na, &nbr, 0); - if( bRC && nbr>0 && (wcBuf[nbr-1]&0xF800)==0xD800 ){ - /* Last WHAR read is first of a UTF-16 surrogate pair. Grab its mate. */ - DWORD nbrx; - bRC &= ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf+nbr, 1, &nbrx, 0); - if( bRC ) nbr += nbrx; - } - if( !bRC || (noc==0 && nbr==0) ) return 0; - if( nbr > 0 ){ - int nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,0,0,0,0); - if( nmb != 0 && noc+nmb <= ncMax ){ - int iseg = noc; - nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,cBuf+noc,nmb,0,0); - noc += nmb; - /* Fixup line-ends as coded by Windows for CR (or "Enter".) - ** This is done without regard for any setMode{Text,Binary}() - ** call that might have been done on the interactive input. - */ - if( noc > 0 ){ - if( cBuf[noc-1]=='\n' ){ - lend = 1; - if( noc > 1 && cBuf[noc-2]=='\r' ) cBuf[--noc-1] = '\n'; - } - } - /* Check for ^Z (anywhere in line) too, to act as EOF. */ - while( iseg < noc ){ - if( cBuf[iseg]=='\x1a' ){ - noc = iseg; /* Chop ^Z and anything following. */ - lend = 1; /* Counts as end of line too. */ - break; - } - ++iseg; - } - }else break; /* Drop apparent garbage in. (Could assert.) */ - }else break; - } - /* If got nothing, (after ^Z chop), must be at end-of-file. */ - if( noc > 0 ){ - cBuf[noc] = 0; - return cBuf; - }else return 0; -# endif - }else{ -# endif - return fgets(cBuf, ncMax, pfIn); -# if CIO_WIN_WC_XLATE - } -# endif -} -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#undef SHELL_INVALID_FILE_PTR - -/************************* End ../ext/consio/console_io.c ********************/ - -#ifndef SQLITE_SHELL_FIDDLE -/* From here onward, fgets() is redirected to the console_io library. */ -# define fgets(b,n,f) fGetsUtf8(b,n,f) -/* - * Define macros for emitting output text in various ways: - * sputz(s, z) => emit 0-terminated string z to given stream s - * sputf(s, f, ...) => emit varargs per format f to given stream s - * oputz(z) => emit 0-terminated string z to default stream - * oputf(f, ...) => emit varargs per format f to default stream - * eputz(z) => emit 0-terminated string z to error stream - * eputf(f, ...) => emit varargs per format f to error stream - * oputb(b, n) => emit char buffer b[0..n-1] to default stream - * - * Note that the default stream is whatever has been last set via: - * setOutputStream(FILE *pf) - * This is normally the stream that CLI normal output goes to. - * For the stand-alone CLI, it is stdout with no .output redirect. - */ -# define sputz(s,z) fPutsUtf8(z,s) -# define sputf fPrintfUtf8 -# define oputz(z) oPutsUtf8(z) -# define oputf oPrintfUtf8 -# define eputz(z) ePutsUtf8(z) -# define eputf ePrintfUtf8 -# define oputb(buf,na) oPutbUtf8(buf,na) -#else -/* For Fiddle, all console handling and emit redirection is omitted. */ -# define sputz(fp,z) fputs(z,fp) -# define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__) -# define oputz(z) fputs(z,stdout) -# define oputf(fmt, ...) printf(fmt,__VA_ARGS__) -# define eputz(z) fputs(z,stderr) -# define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__) -# define oputb(buf,na) fwrite(buf,1,na,stdout) -#endif - -/* True if the timer is enabled */ -static int enableTimer = 0; - -/* A version of strcmp() that works with NULL values */ -static int cli_strcmp(const char *a, const char *b){ - if( a==0 ) a = ""; - if( b==0 ) b = ""; - return strcmp(a,b); -} -static int cli_strncmp(const char *a, const char *b, size_t n){ - if( a==0 ) a = ""; - if( b==0 ) b = ""; - return strncmp(a,b,n); -} - -/* Return the current wall-clock time */ -static sqlite3_int64 timeOfDay(void){ - static sqlite3_vfs *clockVfs = 0; - sqlite3_int64 t; - if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); - if( clockVfs==0 ) return 0; /* Never actually happens */ - if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ - clockVfs->xCurrentTimeInt64(clockVfs, &t); - }else{ - double r; - clockVfs->xCurrentTime(clockVfs, &r); - t = (sqlite3_int64)(r*86400000.0); - } - return t; -} - -#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) -#include -#include - -/* VxWorks does not support getrusage() as far as we can determine */ -#if defined(_WRS_KERNEL) || defined(__RTP__) -struct rusage { - struct timeval ru_utime; /* user CPU time used */ - struct timeval ru_stime; /* system CPU time used */ -}; -#define getrusage(A,B) memset(B,0,sizeof(*B)) -#endif - -/* Saved resource information for the beginning of an operation */ -static struct rusage sBegin; /* CPU time at start */ -static sqlite3_int64 iBegin; /* Wall-clock time at start */ - -/* -** Begin timing an operation -*/ -static void beginTimer(void){ - if( enableTimer ){ - getrusage(RUSAGE_SELF, &sBegin); - iBegin = timeOfDay(); - } -} - -/* Return the difference of two time_structs in seconds */ -static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ - return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + - (double)(pEnd->tv_sec - pStart->tv_sec); -} - -/* -** Print the timing results. -*/ -static void endTimer(void){ - if( enableTimer ){ - sqlite3_int64 iEnd = timeOfDay(); - struct rusage sEnd; - getrusage(RUSAGE_SELF, &sEnd); - oputf("Run Time: real %.3f user %f sys %f\n", - (iEnd - iBegin)*0.001, - timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), - timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); - } -} - -#define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() -#define HAS_TIMER 1 +#define BEGIN_TIMER beginTimer() +#define END_TIMER(X) endTimer(X) +#define HAS_TIMER 1 #elif (defined(_WIN32) || defined(WIN32)) @@ -1421,12 +780,12 @@ static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ /* ** Print the timing results. */ -static void endTimer(void){ +static void endTimer(FILE *out){ if( enableTimer && getProcessTimesAddr){ FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; sqlite3_int64 ftWallEnd = timeOfDay(); getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); - oputf("Run Time: real %.3f user %f sys %f\n", + sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", (ftWallEnd - ftWallBegin)*0.001, timeDiff(&ftUserBegin, &ftUserEnd), timeDiff(&ftKernelBegin, &ftKernelEnd)); @@ -1434,12 +793,12 @@ static void endTimer(void){ } #define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() +#define END_TIMER(X) endTimer(X) #define HAS_TIMER hasTimer() #else #define BEGIN_TIMER -#define END_TIMER +#define END_TIMER(X) /*no-op*/ #define HAS_TIMER 0 #endif @@ -1512,6 +871,14 @@ static char *shell_strncpy(char *dest, const char *src, size_t n){ return dest; } +/* +** strcpy() workalike to squelch an unwarranted link-time warning +** from OpenBSD. +*/ +static void shell_strcpy(char *dest, const char *src){ + while( (*(dest++) = *(src++))!=0 ){} +} + /* ** Optionally disable dynamic continuation prompt. ** Unless disabled, the continuation prompt shows open SQL lexemes if any, @@ -1577,7 +944,7 @@ static char *dynamicContinuePrompt(void){ size_t ncp = strlen(continuePrompt); size_t ndp = strlen(dynPrompt.zScannerAwaits); if( ndp > ncp-3 ) return continuePrompt; - strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits); + shell_strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits); while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' '; shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3, PROMPT_LEN_MAX-4); @@ -1632,37 +999,212 @@ static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); va_end(ap); - sputf(iotrace, "%s", z); + sqlite3_fprintf(iotrace, "%s", z); sqlite3_free(z); } #endif +/* Lookup table to estimate the number of columns consumed by a Unicode +** character. +*/ +static const struct { + unsigned char w; /* Width of the character in columns */ + int iFirst; /* First character in a span having this width */ +} aUWidth[] = { + /* {1, 0x00000}, */ + {0, 0x00300}, {1, 0x00370}, {0, 0x00483}, {1, 0x00487}, {0, 0x00488}, + {1, 0x0048a}, {0, 0x00591}, {1, 0x005be}, {0, 0x005bf}, {1, 0x005c0}, + {0, 0x005c1}, {1, 0x005c3}, {0, 0x005c4}, {1, 0x005c6}, {0, 0x005c7}, + {1, 0x005c8}, {0, 0x00600}, {1, 0x00604}, {0, 0x00610}, {1, 0x00616}, + {0, 0x0064b}, {1, 0x0065f}, {0, 0x00670}, {1, 0x00671}, {0, 0x006d6}, + {1, 0x006e5}, {0, 0x006e7}, {1, 0x006e9}, {0, 0x006ea}, {1, 0x006ee}, + {0, 0x0070f}, {1, 0x00710}, {0, 0x00711}, {1, 0x00712}, {0, 0x00730}, + {1, 0x0074b}, {0, 0x007a6}, {1, 0x007b1}, {0, 0x007eb}, {1, 0x007f4}, + {0, 0x00901}, {1, 0x00903}, {0, 0x0093c}, {1, 0x0093d}, {0, 0x00941}, + {1, 0x00949}, {0, 0x0094d}, {1, 0x0094e}, {0, 0x00951}, {1, 0x00955}, + {0, 0x00962}, {1, 0x00964}, {0, 0x00981}, {1, 0x00982}, {0, 0x009bc}, + {1, 0x009bd}, {0, 0x009c1}, {1, 0x009c5}, {0, 0x009cd}, {1, 0x009ce}, + {0, 0x009e2}, {1, 0x009e4}, {0, 0x00a01}, {1, 0x00a03}, {0, 0x00a3c}, + {1, 0x00a3d}, {0, 0x00a41}, {1, 0x00a43}, {0, 0x00a47}, {1, 0x00a49}, + {0, 0x00a4b}, {1, 0x00a4e}, {0, 0x00a70}, {1, 0x00a72}, {0, 0x00a81}, + {1, 0x00a83}, {0, 0x00abc}, {1, 0x00abd}, {0, 0x00ac1}, {1, 0x00ac6}, + {0, 0x00ac7}, {1, 0x00ac9}, {0, 0x00acd}, {1, 0x00ace}, {0, 0x00ae2}, + {1, 0x00ae4}, {0, 0x00b01}, {1, 0x00b02}, {0, 0x00b3c}, {1, 0x00b3d}, + {0, 0x00b3f}, {1, 0x00b40}, {0, 0x00b41}, {1, 0x00b44}, {0, 0x00b4d}, + {1, 0x00b4e}, {0, 0x00b56}, {1, 0x00b57}, {0, 0x00b82}, {1, 0x00b83}, + {0, 0x00bc0}, {1, 0x00bc1}, {0, 0x00bcd}, {1, 0x00bce}, {0, 0x00c3e}, + {1, 0x00c41}, {0, 0x00c46}, {1, 0x00c49}, {0, 0x00c4a}, {1, 0x00c4e}, + {0, 0x00c55}, {1, 0x00c57}, {0, 0x00cbc}, {1, 0x00cbd}, {0, 0x00cbf}, + {1, 0x00cc0}, {0, 0x00cc6}, {1, 0x00cc7}, {0, 0x00ccc}, {1, 0x00cce}, + {0, 0x00ce2}, {1, 0x00ce4}, {0, 0x00d41}, {1, 0x00d44}, {0, 0x00d4d}, + {1, 0x00d4e}, {0, 0x00dca}, {1, 0x00dcb}, {0, 0x00dd2}, {1, 0x00dd5}, + {0, 0x00dd6}, {1, 0x00dd7}, {0, 0x00e31}, {1, 0x00e32}, {0, 0x00e34}, + {1, 0x00e3b}, {0, 0x00e47}, {1, 0x00e4f}, {0, 0x00eb1}, {1, 0x00eb2}, + {0, 0x00eb4}, {1, 0x00eba}, {0, 0x00ebb}, {1, 0x00ebd}, {0, 0x00ec8}, + {1, 0x00ece}, {0, 0x00f18}, {1, 0x00f1a}, {0, 0x00f35}, {1, 0x00f36}, + {0, 0x00f37}, {1, 0x00f38}, {0, 0x00f39}, {1, 0x00f3a}, {0, 0x00f71}, + {1, 0x00f7f}, {0, 0x00f80}, {1, 0x00f85}, {0, 0x00f86}, {1, 0x00f88}, + {0, 0x00f90}, {1, 0x00f98}, {0, 0x00f99}, {1, 0x00fbd}, {0, 0x00fc6}, + {1, 0x00fc7}, {0, 0x0102d}, {1, 0x01031}, {0, 0x01032}, {1, 0x01033}, + {0, 0x01036}, {1, 0x01038}, {0, 0x01039}, {1, 0x0103a}, {0, 0x01058}, + {1, 0x0105a}, {2, 0x01100}, {0, 0x01160}, {1, 0x01200}, {0, 0x0135f}, + {1, 0x01360}, {0, 0x01712}, {1, 0x01715}, {0, 0x01732}, {1, 0x01735}, + {0, 0x01752}, {1, 0x01754}, {0, 0x01772}, {1, 0x01774}, {0, 0x017b4}, + {1, 0x017b6}, {0, 0x017b7}, {1, 0x017be}, {0, 0x017c6}, {1, 0x017c7}, + {0, 0x017c9}, {1, 0x017d4}, {0, 0x017dd}, {1, 0x017de}, {0, 0x0180b}, + {1, 0x0180e}, {0, 0x018a9}, {1, 0x018aa}, {0, 0x01920}, {1, 0x01923}, + {0, 0x01927}, {1, 0x01929}, {0, 0x01932}, {1, 0x01933}, {0, 0x01939}, + {1, 0x0193c}, {0, 0x01a17}, {1, 0x01a19}, {0, 0x01b00}, {1, 0x01b04}, + {0, 0x01b34}, {1, 0x01b35}, {0, 0x01b36}, {1, 0x01b3b}, {0, 0x01b3c}, + {1, 0x01b3d}, {0, 0x01b42}, {1, 0x01b43}, {0, 0x01b6b}, {1, 0x01b74}, + {0, 0x01dc0}, {1, 0x01dcb}, {0, 0x01dfe}, {1, 0x01e00}, {0, 0x0200b}, + {1, 0x02010}, {0, 0x0202a}, {1, 0x0202f}, {0, 0x02060}, {1, 0x02064}, + {0, 0x0206a}, {1, 0x02070}, {0, 0x020d0}, {1, 0x020f0}, {2, 0x02329}, + {1, 0x0232b}, {2, 0x02e80}, {0, 0x0302a}, {2, 0x03030}, {1, 0x0303f}, + {2, 0x03040}, {0, 0x03099}, {2, 0x0309b}, {1, 0x0a4d0}, {0, 0x0a806}, + {1, 0x0a807}, {0, 0x0a80b}, {1, 0x0a80c}, {0, 0x0a825}, {1, 0x0a827}, + {2, 0x0ac00}, {1, 0x0d7a4}, {2, 0x0f900}, {1, 0x0fb00}, {0, 0x0fb1e}, + {1, 0x0fb1f}, {0, 0x0fe00}, {2, 0x0fe10}, {1, 0x0fe1a}, {0, 0x0fe20}, + {1, 0x0fe24}, {2, 0x0fe30}, {1, 0x0fe70}, {0, 0x0feff}, {2, 0x0ff00}, + {1, 0x0ff61}, {2, 0x0ffe0}, {1, 0x0ffe7}, {0, 0x0fff9}, {1, 0x0fffc}, + {0, 0x10a01}, {1, 0x10a04}, {0, 0x10a05}, {1, 0x10a07}, {0, 0x10a0c}, + {1, 0x10a10}, {0, 0x10a38}, {1, 0x10a3b}, {0, 0x10a3f}, {1, 0x10a40}, + {0, 0x1d167}, {1, 0x1d16a}, {0, 0x1d173}, {1, 0x1d183}, {0, 0x1d185}, + {1, 0x1d18c}, {0, 0x1d1aa}, {1, 0x1d1ae}, {0, 0x1d242}, {1, 0x1d245}, + {2, 0x20000}, {1, 0x2fffe}, {2, 0x30000}, {1, 0x3fffe}, {0, 0xe0001}, + {1, 0xe0002}, {0, 0xe0020}, {1, 0xe0080}, {0, 0xe0100}, {1, 0xe01f0} +}; + /* -** Output string zUtf to Out stream as w characters. If w is negative, -** then right-justify the text. W is the width in UTF-8 characters, not -** in bytes. This is different from the %*.*s specification in printf -** since with %*.*s the width is measured in bytes, not characters. +** Return an estimate of the width, in columns, for the single Unicode +** character c. For normal characters, the answer is always 1. But the +** estimate might be 0 or 2 for zero-width and double-width characters. +** +** Different display devices display unicode using different widths. So +** it is impossible to know that true display width with 100% accuracy. +** Inaccuracies in the width estimates might cause columns to be misaligned. +** Unfortunately, there is nothing we can do about that. */ -static void utf8_width_print(int w, const char *zUtf){ - int i; - int n; +int cli_wcwidth(int c){ + int iFirst, iLast; + + /* Fast path for common characters */ + if( c<=0x300 ) return 1; + + /* The general case */ + iFirst = 0; + iLast = sizeof(aUWidth)/sizeof(aUWidth[0]) - 1; + while( iFirst c ){ + iLast = iMid - 1; + }else{ + return aUWidth[iMid].w; + } + } + if( aUWidth[iLast].iFirst > c ) return aUWidth[iFirst].w; + return aUWidth[iLast].w; +} + +/* +** Compute the value and length of a multi-byte UTF-8 character that +** begins at z[0]. Return the length. Write the Unicode value into *pU. +** +** This routine only works for *multi-byte* UTF-8 characters. +*/ +static int decodeUtf8(const unsigned char *z, int *pU){ + if( (z[0] & 0xe0)==0xc0 && (z[1] & 0xc0)==0x80 ){ + *pU = ((z[0] & 0x1f)<<6) | (z[1] & 0x3f); + return 2; + } + if( (z[0] & 0xf0)==0xe0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 ){ + *pU = ((z[0] & 0x0f)<<12) | ((z[1] & 0x3f)<<6) | (z[2] & 0x3f); + return 3; + } + if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 + && (z[3] & 0xc0)==0x80 + ){ + *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6 + | (z[4] & 0x3f); + return 4; + } + *pU = 0; + return 1; +} + + +#if 0 /* NOT USED */ +/* +** Return the width, in display columns, of a UTF-8 string. +** +** Each normal character counts as 1. Zero-width characters count +** as zero, and double-width characters count as 2. +*/ +int cli_wcswidth(const char *z){ + const unsigned char *a = (const unsigned char*)z; + int n = 0; + int i = 0; + unsigned char c; + while( (c = a[i])!=0 ){ + if( c>=0xc0 ){ + int u; + int len = decodeUtf8(&a[i], &u); + i += len; + n += cli_wcwidth(u); + }else if( c>=' ' ){ + n++; + i++; + }else{ + i++; + } + } + return n; +} +#endif + +/* +** Output string zUtf to stdout as w characters. If w is negative, +** then right-justify the text. W is the width in UTF-8 characters, not +** in bytes. This is different from the %*.*s specification in printf +** since with %*.*s the width is measured in bytes, not characters. +** +** Take into account zero-width and double-width Unicode characters. +** In other words, a zero-width character does not count toward the +** the w limit. A double-width character counts as two. +*/ +static void utf8_width_print(FILE *out, int w, const char *zUtf){ + const unsigned char *a = (const unsigned char*)zUtf; + unsigned char c; + int i = 0; + int n = 0; int aw = w<0 ? -w : w; if( zUtf==0 ) zUtf = ""; - for(i=n=0; zUtf[i]; i++){ - if( (zUtf[i]&0xc0)!=0x80 ){ - n++; - if( n==aw ){ - do{ i++; }while( (zUtf[i]&0xc0)==0x80 ); + while( (c = a[i])!=0 ){ + if( (c&0xc0)==0xc0 ){ + int u; + int len = decodeUtf8(a+i, &u); + int x = cli_wcwidth(u); + if( x+n>aw ){ break; } + i += len; + n += x; + }else if( n>=aw ){ + break; + }else{ + n++; + i++; } } if( n>=aw ){ - oputf("%.*s", i, zUtf); + sqlite3_fprintf(out, "%.*s", i, zUtf); }else if( w<0 ){ - oputf("%*s%s", aw-n, "", zUtf); + sqlite3_fprintf(out, "%*s%s", aw-n, "", zUtf); }else{ - oputf("%s%*s", zUtf, aw-n, ""); + sqlite3_fprintf(out, "%s%*s", zUtf, aw-n, ""); } } @@ -1723,14 +1265,14 @@ static int strlenChar(const char *z){ */ static FILE * openChrSource(const char *zFile){ #if defined(_WIN32) || defined(WIN32) - struct _stat x = {0}; + struct __stat64 x = {0}; # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0) /* On Windows, open first, then check the stream nature. This order ** is necessary because _stat() and sibs, when checking a named pipe, ** effectively break the pipe as its supplier sees it. */ - FILE *rv = fopen(zFile, "rb"); + FILE *rv = sqlite3_fopen(zFile, "rb"); if( rv==0 ) return 0; - if( _fstat(_fileno(rv), &x) != 0 + if( _fstat64(_fileno(rv), &x) != 0 || !STAT_CHR_SRC(x.st_mode)){ fclose(rv); rv = 0; @@ -1742,7 +1284,7 @@ static FILE * openChrSource(const char *zFile){ # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) if( rc!=0 ) return 0; if( STAT_CHR_SRC(x.st_mode) ){ - return fopen(zFile, "rb"); + return sqlite3_fopen(zFile, "rb"); }else{ return 0; } @@ -1769,7 +1311,7 @@ static char *local_getline(char *zLine, FILE *in){ zLine = realloc(zLine, nLine); shell_check_oom(zLine); } - if( fgets(&zLine[n], nLine - n, in)==0 ){ + if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){ if( n==0 ){ free(zLine); return 0; @@ -2835,13 +2377,23 @@ int sqlite3PcacheTraceDeactivate(void){ ** ** This SQLite extension implements functions that compute SHA3 hashes ** in the way described by the (U.S.) NIST FIPS 202 SHA-3 Standard. -** Two SQL functions are implemented: +** Three SQL functions are implemented: ** ** sha3(X,SIZE) -** sha3_query(Y,SIZE) +** sha3_agg(Y,SIZE) +** sha3_query(Z,SIZE) ** ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if -** X is NULL. +** X is NULL. If inputs X is text, the UTF-8 rendering of that text is +** used to compute the hash. If X is a BLOB, then the binary data of the +** blob is used to compute the hash. If X is an integer or real number, +** then that number if converted into UTF-8 text and the hash is computed +** over the text. +** +** The sha3_agg(Y) function computes the SHA3 hash of all Y inputs. Since +** order is important for the hash, it is recommended that the Y expression +** by followed by an ORDER BY clause to guarantee that the inputs occur +** in the desired order. ** ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y ** and returns a hash of their results. @@ -2849,6 +2401,68 @@ int sqlite3PcacheTraceDeactivate(void){ ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm ** is used. If SIZE is included it must be one of the integers 224, 256, ** 384, or 512, to determine SHA3 hash variant that is computed. +** +** Because the sha3_agg() and sha3_query() functions compute a hash over +** multiple values, the values are encode to use include type information. +** +** In sha3_agg(), the sequence of bytes that gets hashed for each input +** Y depends on the datatype of Y: +** +** typeof(Y)='null' A single "N" is hashed. (One byte) +** +** typeof(Y)='integer' The data hash is the character "I" followed +** by an 8-byte big-endian binary of the +** 64-bit signed integer. (Nine bytes total.) +** +** typeof(Y)='real' The character "F" followed by an 8-byte +** big-ending binary of the double. (Nine +** bytes total.) +** +** typeof(Y)='text' The hash is over prefix "Tnnn:" followed +** by the UTF8 encoding of the text. The "nnn" +** in the prefix is the minimum-length decimal +** representation of the octet_length of the text. +** Notice the ":" at the end of the prefix, which +** is needed to separate the prefix from the +** content in cases where the content starts +** with a digit. +** +** typeof(Y)='blob' The hash is taken over prefix "Bnnn:" followed +** by the binary content of the blob. The "nnn" +** in the prefix is the mimimum-length decimal +** representation of the byte-length of the blob. +** +** According to the rules above, all of the following SELECT statements +** should return TRUE: +** +** SELECT sha3(1) = sha3('1'); +** +** SELECT sha3('hello') = sha3(x'68656c6c6f'); +** +** WITH a(x) AS (VALUES('xyzzy')) +** SELECT sha3_agg(x) = sha3('T5:xyzzy') FROM a; +** +** WITH a(x) AS (VALUES(x'010203')) +** SELECT sha3_agg(x) = sha3(x'42333a010203') FROM a; +** +** WITH a(x) AS (VALUES(0x123456)) +** SELECT sha3_agg(x) = sha3(x'490000000000123456') FROM a; +** +** WITH a(x) AS (VALUES(100.015625)) +** SELECT sha3_agg(x) = sha3(x'464059010000000000') FROM a; +** +** WITH a(x) AS (VALUES(NULL)) +** SELECT sha3_agg(x) = sha3('N') FROM a; +** +** +** In sha3_query(), individual column values are encoded as with +** sha3_agg(), but with the addition that a single "R" character is +** inserted at the start of each row. +** +** Note that sha3_agg() hashes rows for which Y is NULL. Add a FILTER +** clause if NULL rows should be excluded: +** +** SELECT sha3_agg(x ORDER BY rowid) FILTER(WHERE x NOT NULL) FROM t1; */ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 @@ -2898,6 +2512,7 @@ struct SHA3Context { unsigned nRate; /* Bytes of input accepted per Keccak iteration */ unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ + unsigned iSize; /* 224, 256, 358, or 512 */ }; /* @@ -3227,6 +2842,7 @@ static void KeccakF1600Step(SHA3Context *p){ */ static void SHA3Init(SHA3Context *p, int iSize){ memset(p, 0, sizeof(*p)); + p->iSize = iSize; if( iSize>=128 && iSize<=512 ){ p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; }else{ @@ -3370,6 +2986,60 @@ static void sha3_step_vformat( SHA3Update(p, (unsigned char*)zBuf, n); } +/* +** Update a SHA3Context using a single sqlite3_value. +*/ +static void sha3UpdateFromValue(SHA3Context *p, sqlite3_value *pVal){ + switch( sqlite3_value_type(pVal) ){ + case SQLITE_NULL: { + SHA3Update(p, (const unsigned char*)"N",1); + break; + } + case SQLITE_INTEGER: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + sqlite3_int64 v = sqlite3_value_int64(pVal); + memcpy(&u, &v, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + SHA3Update(p, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_value_double(pVal); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + SHA3Update(p,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_value_bytes(pVal); + const unsigned char *z2 = sqlite3_value_text(pVal); + sha3_step_vformat(p,"T%d:",n2); + SHA3Update(p, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_value_bytes(pVal); + const unsigned char *z2 = sqlite3_value_blob(pVal); + sha3_step_vformat(p,"B%d:",n2); + SHA3Update(p, z2, n2); + break; + } + } +} + /* ** Implementation of the sha3_query(SQL,SIZE) function. ** @@ -3459,54 +3129,7 @@ static void sha3QueryFunc( while( SQLITE_ROW==sqlite3_step(pStmt) ){ SHA3Update(&cx,(const unsigned char*)"R",1); for(i=0; i=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'I'; - SHA3Update(&cx, x, 9); - break; - } - case SQLITE_FLOAT: { - sqlite3_uint64 u; - int j; - unsigned char x[9]; - double r = sqlite3_column_double(pStmt,i); - memcpy(&u, &r, 8); - for(j=8; j>=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'F'; - SHA3Update(&cx,x,9); - break; - } - case SQLITE_TEXT: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_text(pStmt, i); - sha3_step_vformat(&cx,"T%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - case SQLITE_BLOB: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_blob(pStmt, i); - sha3_step_vformat(&cx,"B%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - } + sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i)); } } sqlite3_finalize(pStmt); @@ -3514,6 +3137,44 @@ static void sha3QueryFunc( sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); } +/* +** xStep function for sha3_agg(). +*/ +static void sha3AggStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA3Context *p; + p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( p->nRate==0 ){ + int sz = 256; + if( argc==2 ){ + sz = sqlite3_value_int(argv[1]); + if( sz!=224 && sz!=384 && sz!=512 ){ + sz = 256; + } + } + SHA3Init(p, sz); + } + sha3UpdateFromValue(p, argv[0]); +} + + +/* +** xFinal function for sha3_agg(). +*/ +static void sha3AggFinal(sqlite3_context *context){ + SHA3Context *p; + p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( p->iSize ){ + sqlite3_result_blob(context, SHA3Final(p), p->iSize/8, SQLITE_TRANSIENT); + } +} + + #ifdef _WIN32 @@ -3534,6 +3195,16 @@ int sqlite3_shathree_init( SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, 0, sha3Func, 0, 0); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_agg", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, 0, sha3AggStep, sha3AggFinal); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_agg", 2, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, 0, sha3AggStep, sha3AggFinal); + } if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8 | SQLITE_DIRECTONLY, @@ -3548,9 +3219,9 @@ int sqlite3_shathree_init( } /************************* End ../ext/misc/shathree.c ********************/ -/************************* Begin ../ext/misc/uint.c ******************/ +/************************* Begin ../ext/misc/sha1.c ******************/ /* -** 2020-04-14 +** 2017-01-27 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -3561,90 +3232,502 @@ int sqlite3_shathree_init( ** ****************************************************************************** ** -** This SQLite extension implements the UINT collating sequence. -** -** UINT works like BINARY for text, except that embedded strings -** of digits compare in numeric order. +** This SQLite extension implements functions that compute SHA1 hashes. +** Two SQL functions are implemented: ** -** * Leading zeros are handled properly, in the sense that -** they do not mess of the maginitude comparison of embedded -** strings of digits. "x00123y" is equal to "x123y". +** sha1(X) +** sha1_query(Y) ** -** * Only unsigned integers are recognized. Plus and minus -** signs are ignored. Decimal points and exponential notation -** are ignored. +** The sha1(X) function computes the SHA1 hash of the input X, or NULL if +** X is NULL. ** -** * Embedded integers can be of arbitrary length. Comparison -** is *not* limited integers that can be expressed as a -** 64-bit machine integer. +** The sha1_query(Y) function evalutes all queries in the SQL statements of Y +** and returns a hash of their results. */ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #include #include -#include +#include -/* -** Compare text in lexicographic order, except strings of digits -** compare in numeric order. +/****************************************************************************** +** The Hash Engine */ -static int uintCollFunc( - void *notUsed, - int nKey1, const void *pKey1, - int nKey2, const void *pKey2 +/* Context for the SHA1 hash */ +typedef struct SHA1Context SHA1Context; +struct SHA1Context { + unsigned int state[5]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) +#define rol(x,k) SHA_ROT(x,k,32-(k)) +#define ror(x,k) SHA_ROT(x,32-(k),k) + +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ + |(rol(block[i],8)&0x00FF00FF)) +#define blk0be(i) block[i] +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + * + * Rl0() for little-endian and Rb0() for big-endian. Endianness is + * determined at run-time. + */ +#define Rl0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define Rb0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R1(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R2(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); +#define R3(v,w,x,y,z,i) \ + z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); +#define R4(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ + unsigned int qq[5]; /* a, b, c, d, e; */ + static int one = 1; + unsigned int block[16]; + memcpy(block, buffer, 64); + memcpy(qq,state,5*sizeof(unsigned int)); + +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + + /* Copy p->state[] to working vars */ + /* + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + */ + + /* 4 rounds of 20 operations each. Loop unrolled. */ + if( 1 == *(unsigned char*)&one ){ + Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); + Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); + Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); + Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); + }else{ + Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); + Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); + Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); + Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); + } + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + +#undef a +#undef b +#undef c +#undef d +#undef e +} + + +/* Initialize a SHA1 context */ +static void hash_init(SHA1Context *p){ + /* SHA1 initialization constants */ + p->state[0] = 0x67452301; + p->state[1] = 0xEFCDAB89; + p->state[2] = 0x98BADCFE; + p->state[3] = 0x10325476; + p->state[4] = 0xC3D2E1F0; + p->count[0] = p->count[1] = 0; +} + +/* Add new content to the SHA1 hash */ +static void hash_step( + SHA1Context *p, /* Add content to this context */ + const unsigned char *data, /* Data to be added */ + unsigned int len /* Number of bytes in data */ ){ - const unsigned char *zA = (const unsigned char*)pKey1; - const unsigned char *zB = (const unsigned char*)pKey2; - int i=0, j=0, x; - (void)notUsed; - while( icount[0]; + if( (p->count[0] += len << 3) < j ){ + p->count[1] += (len>>29)+1; + } + j = (j >> 3) & 63; + if( (j + len) > 63 ){ + (void)memcpy(&p->buffer[j], data, (i = 64-j)); + SHA1Transform(p->state, p->buffer); + for(; i + 63 < len; i += 64){ + SHA1Transform(p->state, &data[i]); } + j = 0; + }else{ + i = 0; } - return (nKey1 - i) - (nKey2 - j); + (void)memcpy(&p->buffer[j], &data[i], len - i); } -#ifdef _WIN32 - -#endif -int sqlite3_uint_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi +/* Compute a string using sqlite3_vsnprintf() and hash it */ +static void hash_step_vformat( + SHA1Context *p, /* Add content to this context */ + const char *zFormat, + ... ){ - SQLITE_EXTENSION_INIT2(pApi); - (void)pzErrMsg; /* Unused parameter */ - return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc); + va_list ap; + int n; + char zBuf[50]; + va_start(ap, zFormat); + sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); + va_end(ap); + n = (int)strlen(zBuf); + hash_step(p, (unsigned char*)zBuf, n); } -/************************* End ../ext/misc/uint.c ********************/ -/************************* Begin ../ext/misc/decimal.c ******************/ -/* + +/* Add padding and compute the message digest. Render the +** message digest as lower-case hexadecimal and put it into +** zOut[]. zOut[] must be at least 41 bytes long. */ +static void hash_finish( + SHA1Context *p, /* The SHA1 context to finish and render */ + char *zOut, /* Store hex or binary hash here */ + int bAsBinary /* 1 for binary hash, 0 for hex hash */ +){ + unsigned int i; + unsigned char finalcount[8]; + unsigned char digest[20]; + static const char zEncode[] = "0123456789abcdef"; + + for (i = 0; i < 8; i++){ + finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + hash_step(p, (const unsigned char *)"\200", 1); + while ((p->count[0] & 504) != 448){ + hash_step(p, (const unsigned char *)"\0", 1); + } + hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++){ + digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + if( bAsBinary ){ + memcpy(zOut, digest, 20); + }else{ + for(i=0; i<20; i++){ + zOut[i*2] = zEncode[(digest[i]>>4)&0xf]; + zOut[i*2+1] = zEncode[digest[i] & 0xf]; + } + zOut[i*2]= 0; + } +} +/* End of the hashing logic +*****************************************************************************/ + +/* +** Implementation of the sha1(X) function. +** +** Return a lower-case hexadecimal rendering of the SHA1 hash of the +** argument X. If X is a BLOB, it is hashed as is. For all other +** types of input, X is converted into a UTF-8 string and the string +** is hash without the trailing 0x00 terminator. The hash of a NULL +** value is NULL. +*/ +static void sha1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA1Context cx; + int eType = sqlite3_value_type(argv[0]); + int nByte = sqlite3_value_bytes(argv[0]); + char zOut[44]; + + assert( argc==1 ); + if( eType==SQLITE_NULL ) return; + hash_init(&cx); + if( eType==SQLITE_BLOB ){ + hash_step(&cx, sqlite3_value_blob(argv[0]), nByte); + }else{ + hash_step(&cx, sqlite3_value_text(argv[0]), nByte); + } + if( sqlite3_user_data(context)!=0 ){ + hash_finish(&cx, zOut, 1); + sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT); + }else{ + hash_finish(&cx, zOut, 0); + sqlite3_result_blob(context, zOut, 40, SQLITE_TRANSIENT); + } +} + +/* +** Implementation of the sha1_query(SQL) function. +** +** This function compiles and runs the SQL statement(s) given in the +** argument. The results are hashed using SHA1 and that hash is returned. +** +** The original SQL text is included as part of the hash. +** +** The hash is not just a concatenation of the outputs. Each query +** is delimited and each row and value within the query is delimited, +** with all values being marked with their datatypes. +*/ +static void sha1QueryFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + sqlite3_stmt *pStmt = 0; + int nCol; /* Number of columns in the result set */ + int i; /* Loop counter */ + int rc; + int n; + const char *z; + SHA1Context cx; + char zOut[44]; + + assert( argc==1 ); + if( zSql==0 ) return; + hash_init(&cx); + while( zSql[0] ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); + if( rc ){ + char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", + zSql, sqlite3_errmsg(db)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + if( !sqlite3_stmt_readonly(pStmt) ){ + char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + nCol = sqlite3_column_count(pStmt); + z = sqlite3_sql(pStmt); + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + hash_step(&cx,(unsigned char*)z,n); + + /* Compute a hash over the result of the query */ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + hash_step(&cx,(const unsigned char*)"R",1); + for(i=0; i=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + hash_step(&cx, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_column_double(pStmt,i); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + hash_step(&cx,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_text(pStmt, i); + hash_step_vformat(&cx,"T%d:",n2); + hash_step(&cx, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_blob(pStmt, i); + hash_step_vformat(&cx,"B%d:",n2); + hash_step(&cx, z2, n2); + break; + } + } + } + } + sqlite3_finalize(pStmt); + } + hash_finish(&cx, zOut, 0); + sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); +} + + +#ifdef _WIN32 + +#endif +int sqlite3_sha_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + static int one = 1; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "sha1", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, sha1Func, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha1b", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + (void*)&one, sha1Func, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha1_query", 1, + SQLITE_UTF8|SQLITE_DIRECTONLY, 0, + sha1QueryFunc, 0, 0); + } + return rc; +} + +/************************* End ../ext/misc/sha1.c ********************/ +/************************* Begin ../ext/misc/uint.c ******************/ +/* +** 2020-04-14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This SQLite extension implements the UINT collating sequence. +** +** UINT works like BINARY for text, except that embedded strings +** of digits compare in numeric order. +** +** * Leading zeros are handled properly, in the sense that +** they do not mess of the maginitude comparison of embedded +** strings of digits. "x00123y" is equal to "x123y". +** +** * Only unsigned integers are recognized. Plus and minus +** signs are ignored. Decimal points and exponential notation +** are ignored. +** +** * Embedded integers can be of arbitrary length. Comparison +** is *not* limited integers that can be expressed as a +** 64-bit machine integer. +*/ +/* #include "sqlite3ext.h" */ +SQLITE_EXTENSION_INIT1 +#include +#include +#include + +/* +** Compare text in lexicographic order, except strings of digits +** compare in numeric order. +*/ +static int uintCollFunc( + void *notUsed, + int nKey1, const void *pKey1, + int nKey2, const void *pKey2 +){ + const unsigned char *zA = (const unsigned char*)pKey1; + const unsigned char *zB = (const unsigned char*)pKey2; + int i=0, j=0, x; + (void)notUsed; + while( i +#include +#include + +/* The following object is the group context for a single percentile() +** aggregate. Remember all input Y values until the very end. +** Those values are accumulated in the Percentile.a[] array. +*/ +typedef struct Percentile Percentile; +struct Percentile { + unsigned nAlloc; /* Number of slots allocated for a[] */ + unsigned nUsed; /* Number of slots actually used in a[] */ + char bSorted; /* True if a[] is already in sorted order */ + char bKeepSorted; /* True if advantageous to keep a[] sorted */ + char bPctValid; /* True if rPct is valid */ + double rPct; /* Fraction. 0.0 to 1.0 */ + double *a; /* Array of Y values */ +}; + +/* Details of each function in the percentile family */ +typedef struct PercentileFunc PercentileFunc; +struct PercentileFunc { + const char *zName; /* Function name */ + char nArg; /* Number of arguments */ + char mxFrac; /* Maximum value of the "fraction" input */ + char bDiscrete; /* True for percentile_disc() */ +}; +static const PercentileFunc aPercentFunc[] = { + { "median", 1, 1, 0 }, + { "percentile", 2, 100, 0 }, + { "percentile_cont", 2, 1, 0 }, + { "percentile_disc", 2, 1, 1 }, +}; + +/* +** Return TRUE if the input floating-point number is an infinity. +*/ +static int percentIsInfinity(double r){ + sqlite3_uint64 u; + assert( sizeof(u)==sizeof(r) ); + memcpy(&u, &r, sizeof(u)); + return ((u>>52)&0x7ff)==0x7ff; +} + +/* +** Return TRUE if two doubles differ by 0.001 or less. +*/ +static int percentSameValue(double a, double b){ + a -= b; + return a>=-0.001 && a<=0.001; +} + +/* +** Search p (which must have p->bSorted) looking for an entry with +** value y. Return the index of that entry. +** +** If bExact is true, return -1 if the entry is not found. +** +** If bExact is false, return the index at which a new entry with +** value y should be insert in order to keep the values in sorted +** order. The smallest return value in this case will be 0, and +** the largest return value will be p->nUsed. +*/ +static int percentBinarySearch(Percentile *p, double y, int bExact){ + int iFirst = 0; /* First element of search range */ + int iLast = p->nUsed - 1; /* Last element of search range */ + while( iLast>=iFirst ){ + int iMid = (iFirst+iLast)/2; + double x = p->a[iMid]; + if( xy ){ + iLast = iMid - 1; + }else{ + return iMid; + } + } + if( bExact ) return -1; + return iFirst; +} + +/* +** Generate an error for a percentile function. +** +** The error format string must have exactly one occurrance of "%%s()" +** (with two '%' characters). That substring will be replaced by the name +** of the function. +*/ +static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){ + PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); + char *zMsg1; + char *zMsg2; + va_list ap; + + va_start(ap, zFormat); + zMsg1 = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, pFunc->zName) : 0; + sqlite3_result_error(pCtx, zMsg2, -1); + sqlite3_free(zMsg1); + sqlite3_free(zMsg2); +} + +/* +** The "step" function for percentile(Y,P) is called once for each +** input row. +*/ +static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ + Percentile *p; + double rPct; + int eType; + double y; + assert( argc==2 || argc==1 ); + + if( argc==1 ){ + /* Requirement 13: median(Y) is the same as percentile(Y,50). */ + rPct = 0.5; + }else{ + /* Requirement 3: P must be a number between 0 and 100 */ + PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); + eType = sqlite3_value_numeric_type(argv[1]); + rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac; + if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) + || rPct<0.0 || rPct>1.0 + ){ + percentError(pCtx, "the fraction argument to %%s()" + " is not between 0.0 and %.1f", + (double)pFunc->mxFrac); + return; + } + } + + /* Allocate the session context. */ + p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p==0 ) return; + + /* Remember the P value. Throw an error if the P value is different + ** from any prior row, per Requirement (2). */ + if( !p->bPctValid ){ + p->rPct = rPct; + p->bPctValid = 1; + }else if( !percentSameValue(p->rPct,rPct) ){ + percentError(pCtx, "the fraction argument to %%s()" + " is not the same for all input rows"); + return; + } + + /* Ignore rows for which Y is NULL */ + eType = sqlite3_value_type(argv[0]); + if( eType==SQLITE_NULL ) return; + + /* If not NULL, then Y must be numeric. Otherwise throw an error. + ** Requirement 4 */ + if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ + percentError(pCtx, "input to %%s() is not numeric"); + return; + } + + /* Throw an error if the Y value is infinity or NaN */ + y = sqlite3_value_double(argv[0]); + if( percentIsInfinity(y) ){ + percentError(pCtx, "Inf input to %%s()"); + return; + } + + /* Allocate and store the Y */ + if( p->nUsed>=p->nAlloc ){ + unsigned n = p->nAlloc*2 + 250; + double *a = sqlite3_realloc64(p->a, sizeof(double)*n); + if( a==0 ){ + sqlite3_free(p->a); + memset(p, 0, sizeof(*p)); + sqlite3_result_error_nomem(pCtx); + return; + } + p->nAlloc = n; + p->a = a; + } + if( p->nUsed==0 ){ + p->a[p->nUsed++] = y; + p->bSorted = 1; + }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){ + p->a[p->nUsed++] = y; + }else if( p->bKeepSorted ){ + int i; + i = percentBinarySearch(p, y, 0); + if( i<(int)p->nUsed ){ + memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0])); + } + p->a[i] = y; + p->nUsed++; + }else{ + p->a[p->nUsed++] = y; + p->bSorted = 0; + } +} + +/* +** Interchange two doubles. +*/ +#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;} + +/* +** Sort an array of doubles. +** +** Algorithm: quicksort +** +** This is implemented separately rather than using the qsort() routine +** from the standard library because: +** +** (1) To avoid a dependency on qsort() +** (2) To avoid the function call to the comparison routine for each +** comparison. +*/ +static void percentSort(double *a, unsigned int n){ + int iLt; /* Entries before a[iLt] are less than rPivot */ + int iGt; /* Entries at or after a[iGt] are greater than rPivot */ + int i; /* Loop counter */ + double rPivot; /* The pivot value */ + + assert( n>=2 ); + if( a[0]>a[n-1] ){ + SWAP_DOUBLE(a[0],a[n-1]) + } + if( n==2 ) return; + iGt = n-1; + i = n/2; + if( a[0]>a[i] ){ + SWAP_DOUBLE(a[0],a[i]) + }else if( a[i]>a[iGt] ){ + SWAP_DOUBLE(a[i],a[iGt]) + } + if( n==3 ) return; + rPivot = a[i]; + iLt = i = 1; + do{ + if( a[i]iLt ) SWAP_DOUBLE(a[i],a[iLt]) + iLt++; + i++; + }else if( a[i]>rPivot ){ + do{ + iGt--; + }while( iGt>i && a[iGt]>rPivot ); + SWAP_DOUBLE(a[i],a[iGt]) + }else{ + i++; + } + }while( i=2 ) percentSort(a, iLt); + if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); + +/* Uncomment for testing */ +#if 0 + for(i=0; ibSorted==0 ){ + assert( p->nUsed>1 ); + percentSort(p->a, p->nUsed); + p->bSorted = 1; + } + p->bKeepSorted = 1; + + /* Find and remove the row */ + i = percentBinarySearch(p, y, 1); + if( i>=0 ){ + p->nUsed--; + if( i<(int)p->nUsed ){ + memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0])); + } + } +} + +/* +** Compute the final output of percentile(). Clean up all allocated +** memory if and only if bIsFinal is true. +*/ +static void percentCompute(sqlite3_context *pCtx, int bIsFinal){ + Percentile *p; + PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); + unsigned i1, i2; + double v1, v2; + double ix, vx; + p = (Percentile*)sqlite3_aggregate_context(pCtx, 0); + if( p==0 ) return; + if( p->a==0 ) return; + if( p->nUsed ){ + if( p->bSorted==0 ){ + assert( p->nUsed>1 ); + percentSort(p->a, p->nUsed); + p->bSorted = 1; + } + ix = p->rPct*(p->nUsed-1); + i1 = (unsigned)ix; + if( pFunc->bDiscrete ){ + vx = p->a[i1]; + }else{ + i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; + v1 = p->a[i1]; + v2 = p->a[i2]; + vx = v1 + (v2-v1)*(ix-i1); + } + sqlite3_result_double(pCtx, vx); + } + if( bIsFinal ){ + sqlite3_free(p->a); + memset(p, 0, sizeof(*p)); + }else{ + p->bKeepSorted = 1; + } +} +static void percentFinal(sqlite3_context *pCtx){ + percentCompute(pCtx, 1); +} +static void percentValue(sqlite3_context *pCtx){ + percentCompute(pCtx, 0); +} + +#if defined(_WIN32) && !defined(SQLITE3_H) && !defined(SQLITE_STATIC_PERCENTILE) + +#endif +int sqlite3_percentile_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + unsigned int i; +#ifdef SQLITE3EXT_H + SQLITE_EXTENSION_INIT2(pApi); +#else + (void)pApi; /* Unused parameter */ +#endif + (void)pzErrMsg; /* Unused parameter */ + for(i=0; i>8) & 0xff; + deliberate_fall_through; /* FALLTHRU */ case 1: pOut[0] = (qv>>16) & 0xff; + deliberate_fall_through; /* FALLTHRU */ } pOut += nbo; } @@ -5065,12 +5657,16 @@ static u8* fromBase85( char *pIn, int ncIn, u8 *pOut ){ switch( nbo ){ case 4: *pOut++ = (qv >> 24)&0xff; + /* FALLTHRU */ case 3: *pOut++ = (qv >> 16)&0xff; + /* FALLTHRU */ case 2: *pOut++ = (qv >> 8)&0xff; + /* FALLTHRU */ case 1: *pOut++ = qv&0xff; + /* FALLTHRU */ case 0: break; } @@ -5703,6 +6299,26 @@ int sqlite3_ieee_init( ** and a very large cost if either start or stop are unavailable. This ** encourages the query planner to order joins such that the bounds of the ** series are well-defined. +** +** Update on 2024-08-22: +** xBestIndex now also looks for equality and inequality constraints against +** the value column and uses those constraints as additional bounds against +** the sequence range. Thus, a query like this: +** +** SELECT value FROM generate_series($SA,$EA) +** WHERE value BETWEEN $SB AND $EB; +** +** Is logically the same as: +** +** SELECT value FROM generate_series(max($SA,$SB),min($EA,$EB)); +** +** Constraints on the value column can server as substitutes for constraints +** on the hidden start and stop columns. So, the following two queries +** are equivalent: +** +** SELECT value FROM generate_series($S,$E); +** SELECT value FROM generate_series WHERE value BETWEEN $S and $E; +** */ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 @@ -5716,16 +6332,20 @@ SQLITE_EXTENSION_INIT1 ** index is ix. The 0th member is given by smBase. The sequence members ** progress per ix increment by smStep. */ -static sqlite3_int64 genSeqMember(sqlite3_int64 smBase, - sqlite3_int64 smStep, - sqlite3_uint64 ix){ - if( ix>=(sqlite3_uint64)LLONG_MAX ){ +static sqlite3_int64 genSeqMember( + sqlite3_int64 smBase, + sqlite3_int64 smStep, + sqlite3_uint64 ix +){ + static const sqlite3_uint64 mxI64 = + ((sqlite3_uint64)0x7fffffff)<<32 | 0xffffffff; + if( ix>=mxI64 ){ /* Get ix into signed i64 range. */ - ix -= (sqlite3_uint64)LLONG_MAX; + ix -= mxI64; /* With 2's complement ALU, this next can be 1 step, but is split into * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */ - smBase += (LLONG_MAX/2) * smStep; - smBase += (LLONG_MAX - LLONG_MAX/2) * smStep; + smBase += (mxI64/2) * smStep; + smBase += (mxI64 - mxI64/2) * smStep; } /* Under UBSAN (or on 1's complement machines), must do this last term * in steps to avoid the dreaded (and harmless) signed multiply overlow. */ @@ -5740,8 +6360,10 @@ static sqlite3_int64 genSeqMember(sqlite3_int64 smBase, /* typedef unsigned char u8; */ typedef struct SequenceSpec { - sqlite3_int64 iBase; /* Starting value ("start") */ - sqlite3_int64 iTerm; /* Given terminal value ("stop") */ + sqlite3_int64 iOBase; /* Original starting value ("start") */ + sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ + sqlite3_int64 iBase; /* Starting value to actually use */ + sqlite3_int64 iTerm; /* Terminal value to actually use */ sqlite3_int64 iStep; /* Increment ("step") */ sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */ sqlite3_uint64 uSeqIndexNow; /* Current index during generation */ @@ -5934,9 +6556,9 @@ static int seriesColumn( series_cursor *pCur = (series_cursor*)cur; sqlite3_int64 x = 0; switch( i ){ - case SERIES_COLUMN_START: x = pCur->ss.iBase; break; - case SERIES_COLUMN_STOP: x = pCur->ss.iTerm; break; - case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; + case SERIES_COLUMN_START: x = pCur->ss.iOBase; break; + case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break; + case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; default: x = pCur->ss.iValueNow; break; } sqlite3_result_int64(ctx, x); @@ -5944,7 +6566,9 @@ static int seriesColumn( } #ifndef LARGEST_UINT64 +#define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) #define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32)) +#define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) #endif /* @@ -5985,13 +6609,18 @@ static int seriesEof(sqlite3_vtab_cursor *cur){ ** parameter. (idxStr is not used in this implementation.) idxNum ** is a bitmask showing which constraints are available: ** -** 1: start=VALUE -** 2: stop=VALUE -** 4: step=VALUE -** -** Also, if bit 8 is set, that means that the series should be output -** in descending order rather than in ascending order. If bit 16 is -** set, then output must appear in ascending order. +** 0x0001: start=VALUE +** 0x0002: stop=VALUE +** 0x0004: step=VALUE +** 0x0008: descending order +** 0x0010: ascending order +** 0x0020: LIMIT VALUE +** 0x0040: OFFSET VALUE +** 0x0080: value=VALUE +** 0x0100: value>=VALUE +** 0x0200: value>VALUE +** 0x1000: value<=VALUE +** 0x2000: valuess.iBase = sqlite3_value_int64(argv[i++]); }else{ pCur->ss.iBase = 0; } - if( idxNum & 2 ){ + if( idxNum & 0x02 ){ pCur->ss.iTerm = sqlite3_value_int64(argv[i++]); }else{ pCur->ss.iTerm = 0xffffffff; } - if( idxNum & 4 ){ + if( idxNum & 0x04 ){ pCur->ss.iStep = sqlite3_value_int64(argv[i++]); if( pCur->ss.iStep==0 ){ pCur->ss.iStep = 1; }else if( pCur->ss.iStep<0 ){ - if( (idxNum & 16)==0 ) idxNum |= 8; + if( (idxNum & 0x10)==0 ) idxNum |= 0x08; } }else{ pCur->ss.iStep = 1; } + + /* If there are constraints on the value column but there are + ** no constraints on the start, stop, and step columns, then + ** initialize the default range to be the entire range of 64-bit signed + ** integers. This range will contracted by the value column constraints + ** further below. + */ + if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){ + pCur->ss.iBase = SMALLEST_INT64; + } + if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){ + pCur->ss.iTerm = LARGEST_INT64; + } + pCur->ss.iOBase = pCur->ss.iBase; + pCur->ss.iOTerm = pCur->ss.iTerm; + + /* Extract the LIMIT and OFFSET values, but do not apply them yet. + ** The range must first be constrained by the limits on value. + */ + if( idxNum & 0x20 ){ + iLimit = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x40 ){ + iOffset = sqlite3_value_int64(argv[i++]); + } + } + + if( idxNum & 0x3380 ){ + /* Extract the maximum range of output values determined by + ** constraints on the "value" column. + */ + if( idxNum & 0x0080 ){ + iMin = iMax = sqlite3_value_int64(argv[i++]); + }else{ + if( idxNum & 0x0300 ){ + iMin = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x0200 ){ + if( iMin==LARGEST_INT64 ){ + returnNoRows = 1; + }else{ + iMin++; + } + } + } + if( idxNum & 0x3000 ){ + iMax = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x2000 ){ + if( iMax==SMALLEST_INT64 ){ + returnNoRows = 1; + }else{ + iMax--; + } + } + } + if( iMin>iMax ){ + returnNoRows = 1; + } + } + + /* Try to reduce the range of values to be generated based on + ** constraints on the "value" column. + */ + if( pCur->ss.iStep>0 ){ + sqlite3_int64 szStep = pCur->ss.iStep; + if( pCur->ss.iBasess.iBase; + pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep; + } + if( pCur->ss.iTerm>iMax ){ + sqlite3_uint64 d = pCur->ss.iTerm - iMax; + pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep; + } + }else{ + sqlite3_int64 szStep = -pCur->ss.iStep; + assert( szStep>0 ); + if( pCur->ss.iBase>iMax ){ + sqlite3_uint64 d = pCur->ss.iBase - iMax; + pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep; + } + if( pCur->ss.iTermss.iTerm; + pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep; + } + } + } + + /* Apply LIMIT and OFFSET constraints, if any */ + if( idxNum & 0x20 ){ + if( iOffset>0 ){ + pCur->ss.iBase += pCur->ss.iStep*iOffset; + } + if( iLimit>=0 ){ + sqlite3_int64 iTerm; + iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep; + if( pCur->ss.iStep<0 ){ + if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; + }else{ + if( iTermss.iTerm ) pCur->ss.iTerm = iTerm; + } + } + } + + for(i=0; iss.iBase = 1; - pCur->ss.iTerm = 0; - pCur->ss.iStep = 1; + returnNoRows = 1; break; } } - if( idxNum & 8 ){ + if( returnNoRows ){ + pCur->ss.iBase = 1; + pCur->ss.iTerm = 0; + pCur->ss.iStep = 1; + } + if( idxNum & 0x08 ){ pCur->ss.isReversing = pCur->ss.iStep > 0; }else{ pCur->ss.isReversing = pCur->ss.iStep < 0; @@ -6055,10 +6795,35 @@ static int seriesFilter( ** ** The query plan is represented by bits in idxNum: ** -** (1) start = $value -- constraint exists -** (2) stop = $value -- constraint exists -** (4) step = $value -- constraint exists -** (8) output in descending order +** 0x0001 start = $num +** 0x0002 stop = $num +** 0x0004 step = $num +** 0x0008 output is in descending order +** 0x0010 output is in ascending order +** 0x0020 LIMIT $num +** 0x0040 OFFSET $num +** 0x0080 value = $num +** 0x0100 value >= $num +** 0x0200 value > $num +** 0x1000 value <= $num +** 0x2000 value < $num +** +** Only one of 0x0100 or 0x0200 will be returned. Similarly, only +** one of 0x1000 or 0x2000 will be returned. If the 0x0080 is set, then +** none of the 0xff00 bits will be set. +** +** The order of parameters passed to xFilter is as follows: +** +** * The argument to start= if bit 0x0001 is in the idxNum mask +** * The argument to stop= if bit 0x0002 is in the idxNum mask +** * The argument to step= if bit 0x0004 is in the idxNum mask +** * The argument to LIMIT if bit 0x0020 is in the idxNum mask +** * The argument to OFFSET if bit 0x0040 is in the idxNum mask +** * The argument to value=, or value>= or value> if any of +** bits 0x0380 are in the idxNum mask +** * The argument to value<= or value< if either of bits 0x3000 +** are in the mask +** */ static int seriesBestIndex( sqlite3_vtab *pVTab, @@ -6066,10 +6831,14 @@ static int seriesBestIndex( ){ int i, j; /* Loop over constraints */ int idxNum = 0; /* The query plan bitmask */ +#ifndef ZERO_ARGUMENT_GENERATE_SERIES int bStartSeen = 0; /* EQ constraint seen on the START column */ +#endif int unusableMask = 0; /* Mask of unusable constraints */ int nArg = 0; /* Number of arguments that seriesFilter() expects */ - int aIdx[3]; /* Constraints on start, stop, and step */ + int aIdx[7]; /* Constraints on start, stop, step, LIMIT, OFFSET, + ** and value. aIdx[5] covers value=, value>=, and + ** value>, aIdx[6] covers value<= and value< */ const struct sqlite3_index_constraint *pConstraint; /* This implementation assumes that the start, stop, and step columns @@ -6077,28 +6846,105 @@ static int seriesBestIndex( assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 ); assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 ); - aIdx[0] = aIdx[1] = aIdx[2] = -1; + aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = aIdx[5] = aIdx[6] = -1; pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ int iCol; /* 0 for start, 1 for stop, 2 for step */ int iMask; /* bitmask for those column */ - if( pConstraint->iColumniColumn - SERIES_COLUMN_START; - assert( iCol>=0 && iCol<=2 ); - iMask = 1 << iCol; - if( iCol==0 ) bStartSeen = 1; - if( pConstraint->usable==0 ){ - unusableMask |= iMask; - continue; - }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ - idxNum |= iMask; + int op = pConstraint->op; + if( op>=SQLITE_INDEX_CONSTRAINT_LIMIT + && op<=SQLITE_INDEX_CONSTRAINT_OFFSET + ){ + if( pConstraint->usable==0 ){ + /* do nothing */ + }else if( op==SQLITE_INDEX_CONSTRAINT_LIMIT ){ + aIdx[3] = i; + idxNum |= 0x20; + }else{ + assert( op==SQLITE_INDEX_CONSTRAINT_OFFSET ); + aIdx[4] = i; + idxNum |= 0x40; + } + continue; + } + if( pConstraint->iColumniColumn==SERIES_COLUMN_VALUE && pConstraint->usable ){ + switch( op ){ + case SQLITE_INDEX_CONSTRAINT_EQ: + case SQLITE_INDEX_CONSTRAINT_IS: { + idxNum |= 0x0080; + idxNum &= ~0x3300; + aIdx[5] = i; + aIdx[6] = -1; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + bStartSeen = 1; +#endif + break; + } + case SQLITE_INDEX_CONSTRAINT_GE: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x0100; + idxNum &= ~0x0200; + aIdx[5] = i; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + bStartSeen = 1; +#endif + break; + } + case SQLITE_INDEX_CONSTRAINT_GT: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x0200; + idxNum &= ~0x0100; + aIdx[5] = i; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + bStartSeen = 1; +#endif + break; + } + case SQLITE_INDEX_CONSTRAINT_LE: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x1000; + idxNum &= ~0x2000; + aIdx[6] = i; + break; + } + case SQLITE_INDEX_CONSTRAINT_LT: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x2000; + idxNum &= ~0x1000; + aIdx[6] = i; + break; + } + } + } + continue; + } + iCol = pConstraint->iColumn - SERIES_COLUMN_START; + assert( iCol>=0 && iCol<=2 ); + iMask = 1 << iCol; +#ifndef ZERO_ARGUMENT_GENERATE_SERIES + if( iCol==0 && op==SQLITE_INDEX_CONSTRAINT_EQ ){ + bStartSeen = 1; + } +#endif + if( pConstraint->usable==0 ){ + unusableMask |= iMask; + continue; + }else if( op==SQLITE_INDEX_CONSTRAINT_EQ ){ + idxNum |= iMask; aIdx[iCol] = i; } } - for(i=0; i<3; i++){ + if( aIdx[3]==0 ){ + /* Ignore OFFSET if LIMIT is omitted */ + idxNum &= ~0x60; + aIdx[4] = 0; + } + for(i=0; i<7; i++){ if( (j = aIdx[i])>=0 ){ pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg; - pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY; + pIdxInfo->aConstraintUsage[j].omit = + !SQLITE_SERIES_CONSTRAINT_VERIFY || i>=3; } } /* The current generate_column() implementation requires at least one @@ -6119,19 +6965,22 @@ static int seriesBestIndex( ** this plan is unusable */ return SQLITE_CONSTRAINT; } - if( (idxNum & 3)==3 ){ + if( (idxNum & 0x03)==0x03 ){ /* Both start= and stop= boundaries are available. This is the ** the preferred case */ pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); pIdxInfo->estimatedRows = 1000; if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){ if( pIdxInfo->aOrderBy[0].desc ){ - idxNum |= 8; + idxNum |= 0x08; }else{ - idxNum |= 16; + idxNum |= 0x10; } pIdxInfo->orderByConsumed = 1; } + }else if( (idxNum & 0x21)==0x21 ){ + /* We have start= and LIMIT */ + pIdxInfo->estimatedRows = 2500; }else{ /* If either boundary is missing, we have to generate a huge span ** of numbers. Make this case very expensive so that the query @@ -6139,6 +6988,9 @@ static int seriesBestIndex( pIdxInfo->estimatedRows = 2147483647; } pIdxInfo->idxNum = idxNum; +#ifdef SQLITE_INDEX_SCAN_HEX + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_HEX; +#endif return SQLITE_OK; } @@ -6857,7 +7709,8 @@ static const char *re_subcompile_string(ReCompiled *p){ ** regular expression. Applications should invoke this routine once ** for every call to re_compile() to avoid memory leaks. */ -static void re_free(ReCompiled *pRe){ +static void re_free(void *p){ + ReCompiled *pRe = (ReCompiled*)p; if( pRe ){ sqlite3_free(pRe->aOp); sqlite3_free(pRe->aArg); @@ -7126,7 +7979,7 @@ int sqlite3_regexp_init( ** modification-time of the target file is set to this value before ** returning. ** -** If three or more arguments are passed to this function and an +** If five or more arguments are passed to this function and an ** error is encountered, an exception is raised. ** ** READFILE(FILE): @@ -7196,6 +8049,13 @@ SQLITE_EXTENSION_INIT1 #include #include +/* When used as part of the CLI, the sqlite3_stdio.h module will have +** been included before this one. In that case use the sqlite3_stdio.h +** #defines. If not, create our own for fopen(). +*/ +#ifndef _SQLITE3_STDIO_H_ +# define sqlite3_fopen fopen +#endif /* ** Structure of the fsdir() table-valued function @@ -7228,7 +8088,7 @@ static void readFileContents(sqlite3_context *ctx, const char *zName){ sqlite3 *db; int mxBlob; - in = fopen(zName, "rb"); + in = sqlite3_fopen(zName, "rb"); if( in==0 ){ /* File does not exist or is unreadable. Leave the result set to NULL. */ return; @@ -7458,7 +8318,9 @@ static int writeFile( #if !defined(_WIN32) && !defined(WIN32) if( S_ISLNK(mode) ){ const char *zTo = (const char*)sqlite3_value_text(pData); - if( zTo==0 || symlink(zTo, zFile)<0 ) return 1; + if( zTo==0 ) return 1; + unlink(zFile); + if( symlink(zTo, zFile)<0 ) return 1; }else #endif { @@ -7481,7 +8343,7 @@ static int writeFile( sqlite3_int64 nWrite = 0; const char *z; int rc = 0; - FILE *out = fopen(zFile, "wb"); + FILE *out = sqlite3_fopen(zFile, "wb"); if( out==0 ) return 1; z = (const char*)sqlite3_value_blob(pData); if( z ){ @@ -7514,7 +8376,7 @@ static int writeFile( GetSystemTime(¤tTime); SystemTimeToFileTime(¤tTime, &lastAccess); - intervals = Int32x32To64(mtime, 10000000) + 116444736000000000; + intervals = (mtime*10000000) + 116444736000000000; lastWrite.dwLowDateTime = (DWORD)intervals; lastWrite.dwHighDateTime = intervals >> 32; zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); @@ -7544,13 +8406,19 @@ static int writeFile( return 1; } #else - /* Legacy unix */ - struct timeval times[2]; - times[0].tv_usec = times[1].tv_usec = 0; - times[0].tv_sec = time(0); - times[1].tv_sec = mtime; - if( utimes(zFile, times) ){ - return 1; + /* Legacy unix. + ** + ** Do not use utimes() on a symbolic link - it sees through the link and + ** modifies the timestamps on the target. Or fails if the target does + ** not exist. */ + if( 0==S_ISLNK(mode) ){ + struct timeval times[2]; + times[0].tv_usec = times[1].tv_usec = 0; + times[0].tv_sec = time(0); + times[1].tv_sec = mtime; + if( utimes(zFile, times) ){ + return 1; + } } #endif } @@ -8371,7 +9239,7 @@ static int completionNext(sqlite3_vtab_cursor *cur){ zSql = sqlite3_mprintf( "%z%s" "SELECT pti.name FROM \"%w\".sqlite_schema AS sm" - " JOIN pragma_table_info(sm.name,%Q) AS pti" + " JOIN pragma_table_xinfo(sm.name,%Q) AS pti" " WHERE sm.type='table'", zSql, zSep, zDb, zDb ); @@ -9331,10 +10199,20 @@ SQLITE_EXTENSION_INIT1 #include #include #include -#include +#ifndef SQLITE_NO_STDINT +# include +#endif #include "zlibwrap.h" +/* When used as part of the CLI, the sqlite3_stdio.h module will have +** been included before this one. In that case use the sqlite3_stdio.h +** #defines. If not, create our own for fopen(). +*/ +#ifndef _SQLITE3_STDIO_H_ +# define sqlite3_fopen fopen +#endif + #ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_AMALGAMATION @@ -10591,7 +11469,7 @@ static int zipfileFilter( } if( 0==pTab->pWriteFd && 0==bInMemory ){ - pCsr->pFile = zFile ? fopen(zFile, "rb") : 0; + pCsr->pFile = zFile ? sqlite3_fopen(zFile, "rb") : 0; if( pCsr->pFile==0 ){ zipfileCursorErr(pCsr, "cannot open file: %s", zFile); rc = SQLITE_ERROR; @@ -10781,7 +11659,7 @@ static int zipfileBegin(sqlite3_vtab *pVtab){ ** structure into memory. During the transaction any new file data is ** appended to the archive file, but the central directory is accumulated ** in main-memory until the transaction is committed. */ - pTab->pWriteFd = fopen(pTab->zFile, "ab+"); + pTab->pWriteFd = sqlite3_fopen(pTab->zFile, "ab+"); if( pTab->pWriteFd==0 ){ pTab->base.zErrMsg = sqlite3_mprintf( "zipfile: failed to open file %s for writing", pTab->zFile @@ -11622,7 +12500,7 @@ static void sqlarUncompressFunc( sqlite3_value **argv ){ uLong nData; - uLongf sz; + sqlite3_int64 sz; assert( argc==2 ); sz = sqlite3_value_int(argv[1]); @@ -11630,14 +12508,15 @@ static void sqlarUncompressFunc( if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){ sqlite3_result_value(context, argv[0]); }else{ + uLongf szf = sz; const Bytef *pData= sqlite3_value_blob(argv[0]); Bytef *pOut = sqlite3_malloc(sz); if( pOut==0 ){ sqlite3_result_error_nomem(context); - }else if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){ + }else if( Z_OK!=uncompress(pOut, &szf, pData, nData) ){ sqlite3_result_error(context, "error in uncompress()", -1); }else{ - sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT); + sqlite3_result_blob(context, pOut, szf, SQLITE_TRANSIENT); } sqlite3_free(pOut); } @@ -12467,7 +13346,7 @@ static int expertFilter( pCsr->pData = 0; if( rc==SQLITE_OK ){ rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, - "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName + "SELECT * FROM main.%Q WHERE sqlite_expert_sample()", pVtab->pTab->zName ); } @@ -13233,6 +14112,66 @@ static int idxProcessTriggers(sqlite3expert *p, char **pzErr){ return rc; } +/* +** This function tests if the schema of the main database of database handle +** db contains an object named zTab. Assuming no error occurs, output parameter +** (*pbContains) is set to true if zTab exists, or false if it does not. +** +** Or, if an error occurs, an SQLite error code is returned. The final value +** of (*pbContains) is undefined in this case. +*/ +static int expertDbContainsObject( + sqlite3 *db, + const char *zTab, + int *pbContains /* OUT: True if object exists */ +){ + const char *zSql = "SELECT 1 FROM sqlite_schema WHERE name = ?"; + sqlite3_stmt *pSql = 0; + int rc = SQLITE_OK; + int ret = 0; + + rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_text(pSql, 1, zTab, -1, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pSql) ){ + ret = 1; + } + rc = sqlite3_finalize(pSql); + } + + *pbContains = ret; + return rc; +} + +/* +** Execute SQL command zSql using database handle db. If no error occurs, +** set (*pzErr) to NULL and return SQLITE_OK. +** +** If an error does occur, return an SQLite error code and set (*pzErr) to +** point to a buffer containing an English language error message. Except, +** if the error message begins with "no such module:", then ignore the +** error and return as if the SQL statement had succeeded. +** +** This is used to copy as much of the database schema as possible while +** ignoring any errors related to missing virtual table modules. +*/ +static int expertSchemaSql(sqlite3 *db, const char *zSql, char **pzErr){ + int rc = SQLITE_OK; + char *zErr = 0; + + rc = sqlite3_exec(db, zSql, 0, 0, &zErr); + if( rc!=SQLITE_OK && zErr ){ + int nErr = STRLEN(zErr); + if( nErr>=15 && memcmp(zErr, "no such module:", 15)==0 ){ + sqlite3_free(zErr); + rc = SQLITE_OK; + zErr = 0; + } + } + + *pzErr = zErr; + return rc; +} static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ int rc = idxRegisterVtab(p); @@ -13244,26 +14183,35 @@ static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ ** 2) Create the equivalent virtual table in dbv. */ rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg, - "SELECT type, name, sql, 1 FROM sqlite_schema " - "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' " + "SELECT type, name, sql, 1, " + " substr(sql,1,14)=='create virtual' COLLATE nocase " + "FROM sqlite_schema " + "WHERE type IN ('table','view') AND " + " substr(name,1,7)!='sqlite_' COLLATE nocase " " UNION ALL " - "SELECT type, name, sql, 2 FROM sqlite_schema " + "SELECT type, name, sql, 2, 0 FROM sqlite_schema " "WHERE type = 'trigger'" " AND tbl_name IN(SELECT name FROM sqlite_schema WHERE type = 'view') " - "ORDER BY 4, 1" + "ORDER BY 4, 5 DESC, 1" ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){ const char *zType = (const char*)sqlite3_column_text(pSchema, 0); const char *zName = (const char*)sqlite3_column_text(pSchema, 1); const char *zSql = (const char*)sqlite3_column_text(pSchema, 2); + int bVirtual = sqlite3_column_int(pSchema, 4); + int bExists = 0; if( zType==0 || zName==0 ) continue; - if( zType[0]=='v' || zType[1]=='r' ){ - if( zSql ) rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg); + rc = expertDbContainsObject(p->dbv, zName, &bExists); + if( rc || bExists ) continue; + + if( zType[0]=='v' || zType[1]=='r' || bVirtual ){ + /* A view. Or a trigger on a view. */ + if( zSql ) rc = expertSchemaSql(p->dbv, zSql, pzErrmsg); }else{ IdxTable *pTab; rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg); - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && ALWAYS(pTab!=0) ){ int i; char *zInner = 0; char *zOuter = 0; @@ -13341,7 +14289,7 @@ struct IdxRemCtx { }; /* -** Implementation of scalar function rem(). +** Implementation of scalar function sqlite_expert_rem(). */ static void idxRemFunc( sqlite3_context *pCtx, @@ -13354,7 +14302,7 @@ static void idxRemFunc( assert( argc==2 ); iSlot = sqlite3_value_int(argv[0]); - assert( iSlot<=p->nSlot ); + assert( iSlotnSlot ); pSlot = &p->aSlot[iSlot]; switch( pSlot->eType ){ @@ -13464,8 +14412,15 @@ static int idxPopulateOneStat1( const char *zComma = zCols==0 ? "" : ", "; const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); + if( zName==0 ){ + /* This index contains an expression. Ignore it. */ + sqlite3_free(zCols); + sqlite3_free(zOrder); + return sqlite3_reset(pIndexXInfo); + } zCols = idxAppendText(&rc, zCols, - "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl + "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s", + zComma, zName, nCol, zName, zColl ); zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol); } @@ -13598,13 +14553,13 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ if( rc==SQLITE_OK ){ sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); - rc = sqlite3_create_function( - dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 + rc = sqlite3_create_function(dbrem, "sqlite_expert_rem", + 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 ); } if( rc==SQLITE_OK ){ - rc = sqlite3_create_function( - p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 + rc = sqlite3_create_function(p->db, "sqlite_expert_sample", + 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 ); } @@ -13656,6 +14611,9 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); } + sqlite3_create_function(p->db, "sqlite_expert_rem", 2, SQLITE_UTF8, 0,0,0,0); + sqlite3_create_function(p->db, "sqlite_expert_sample", 0,SQLITE_UTF8,0,0,0,0); + sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); return rc; } @@ -13788,12 +14746,18 @@ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ if( rc==SQLITE_OK ){ sqlite3_stmt *pSql = 0; rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, - "SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'" - " AND sql NOT LIKE 'CREATE VIRTUAL %%'" + "SELECT sql, name, substr(sql,1,14)=='create virtual' COLLATE nocase" + " FROM sqlite_schema WHERE substr(name,1,7)!='sqlite_' COLLATE nocase" + " ORDER BY 3 DESC, rowid" ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ const char *zSql = (const char*)sqlite3_column_text(pSql, 0); - if( zSql ) rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg); + const char *zName = (const char*)sqlite3_column_text(pSql, 1); + int bExists = 0; + rc = expertDbContainsObject(pNew->dbm, zName, &bExists); + if( rc==SQLITE_OK && zSql && bExists==0 ){ + rc = expertSchemaSql(pNew->dbm, zSql, pzErrmsg); + } } idxFinalize(&rc, pSql); } @@ -13971,25 +14935,2456 @@ const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){ } /* -** Free an sqlite3expert object. +** Free an sqlite3expert object. +*/ +void sqlite3_expert_destroy(sqlite3expert *p){ + if( p ){ + sqlite3_close(p->dbm); + sqlite3_close(p->dbv); + idxScanFree(p->pScan, 0); + idxStatementFree(p->pStatement, 0); + idxTableFree(p->pTable); + idxWriteFree(p->pWrite); + idxHashClear(&p->hIdx); + sqlite3_free(p->zCandidates); + sqlite3_free(p); + } +} + +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + +/************************* End ../ext/expert/sqlite3expert.c ********************/ +/************************* Begin ../ext/intck/sqlite3intck.h ******************/ +/* +** 2024-02-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +/* +** Incremental Integrity-Check Extension +** ------------------------------------- +** +** This module contains code to check whether or not an SQLite database +** is well-formed or corrupt. This is the same task as performed by SQLite's +** built-in "PRAGMA integrity_check" command. This module differs from +** "PRAGMA integrity_check" in that: +** +** + It is less thorough - this module does not detect certain types +** of corruption that are detected by the PRAGMA command. However, +** it does detect all kinds of corruption that are likely to cause +** errors in SQLite applications. +** +** + It is slower. Sometimes up to three times slower. +** +** + It allows integrity-check operations to be split into multiple +** transactions, so that the database does not need to be read-locked +** for the duration of the integrity-check. +** +** One way to use the API to run integrity-check on the "main" database +** of handle db is: +** +** int rc = SQLITE_OK; +** sqlite3_intck *p = 0; +** +** sqlite3_intck_open(db, "main", &p); +** while( SQLITE_OK==sqlite3_intck_step(p) ){ +** const char *zMsg = sqlite3_intck_message(p); +** if( zMsg ) printf("corruption: %s\n", zMsg); +** } +** rc = sqlite3_intck_error(p, &zErr); +** if( rc!=SQLITE_OK ){ +** printf("error occured (rc=%d), (errmsg=%s)\n", rc, zErr); +** } +** sqlite3_intck_close(p); +** +** Usually, the sqlite3_intck object opens a read transaction within the +** first call to sqlite3_intck_step() and holds it open until the +** integrity-check is complete. However, if sqlite3_intck_unlock() is +** called, the read transaction is ended and a new read transaction opened +** by the subsequent call to sqlite3_intck_step(). +*/ + +#ifndef _SQLITE_INTCK_H +#define _SQLITE_INTCK_H + +/* #include "sqlite3.h" */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** An ongoing incremental integrity-check operation is represented by an +** opaque pointer of the following type. +*/ +typedef struct sqlite3_intck sqlite3_intck; + +/* +** Open a new incremental integrity-check object. If successful, populate +** output variable (*ppOut) with the new object handle and return SQLITE_OK. +** Or, if an error occurs, set (*ppOut) to NULL and return an SQLite error +** code (e.g. SQLITE_NOMEM). +** +** The integrity-check will be conducted on database zDb (which must be "main", +** "temp", or the name of an attached database) of database handle db. Once +** this function has been called successfully, the caller should not use +** database handle db until the integrity-check object has been destroyed +** using sqlite3_intck_close(). +*/ +int sqlite3_intck_open( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Database name ("main", "temp" etc.) */ + sqlite3_intck **ppOut /* OUT: New sqlite3_intck handle */ +); + +/* +** Close and release all resources associated with a handle opened by an +** earlier call to sqlite3_intck_open(). The results of using an +** integrity-check handle after it has been passed to this function are +** undefined. +*/ +void sqlite3_intck_close(sqlite3_intck *pCk); + +/* +** Do the next step of the integrity-check operation specified by the handle +** passed as the only argument. This function returns SQLITE_DONE if the +** integrity-check operation is finished, or an SQLite error code if +** an error occurs, or SQLITE_OK if no error occurs but the integrity-check +** is not finished. It is not considered an error if database corruption +** is encountered. +** +** Following a successful call to sqlite3_intck_step() (one that returns +** SQLITE_OK), sqlite3_intck_message() returns a non-NULL value if +** corruption was detected in the db. +** +** If an error occurs and a value other than SQLITE_OK or SQLITE_DONE is +** returned, then the integrity-check handle is placed in an error state. +** In this state all subsequent calls to sqlite3_intck_step() or +** sqlite3_intck_unlock() will immediately return the same error. The +** sqlite3_intck_error() method may be used to obtain an English language +** error message in this case. +*/ +int sqlite3_intck_step(sqlite3_intck *pCk); + +/* +** If the previous call to sqlite3_intck_step() encountered corruption +** within the database, then this function returns a pointer to a buffer +** containing a nul-terminated string describing the corruption in +** English. If the previous call to sqlite3_intck_step() did not encounter +** corruption, or if there was no previous call, this function returns +** NULL. +*/ +const char *sqlite3_intck_message(sqlite3_intck *pCk); + +/* +** Close any read-transaction opened by an earlier call to +** sqlite3_intck_step(). Any subsequent call to sqlite3_intck_step() will +** open a new transaction. Return SQLITE_OK if successful, or an SQLite error +** code otherwise. +** +** If an error occurs, then the integrity-check handle is placed in an error +** state. In this state all subsequent calls to sqlite3_intck_step() or +** sqlite3_intck_unlock() will immediately return the same error. The +** sqlite3_intck_error() method may be used to obtain an English language +** error message in this case. +*/ +int sqlite3_intck_unlock(sqlite3_intck *pCk); + +/* +** If an error has occurred in an earlier call to sqlite3_intck_step() +** or sqlite3_intck_unlock(), then this method returns the associated +** SQLite error code. Additionally, if pzErr is not NULL, then (*pzErr) +** may be set to point to a nul-terminated string containing an English +** language error message. Or, if no error message is available, to +** NULL. +** +** If no error has occurred within sqlite3_intck_step() or +** sqlite_intck_unlock() calls on the handle passed as the first argument, +** then SQLITE_OK is returned and (*pzErr) set to NULL. +*/ +int sqlite3_intck_error(sqlite3_intck *pCk, const char **pzErr); + +/* +** This API is used for testing only. It returns the full-text of an SQL +** statement used to test object zObj, which may be a table or index. +** The returned buffer is valid until the next call to either this function +** or sqlite3_intck_close() on the same sqlite3_intck handle. +*/ +const char *sqlite3_intck_test_sql(sqlite3_intck *pCk, const char *zObj); + + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE_INTCK_H */ + +/************************* End ../ext/intck/sqlite3intck.h ********************/ +/************************* Begin ../ext/intck/sqlite3intck.c ******************/ +/* +** 2024-02-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +/* #include "sqlite3intck.h" */ +#include +#include + +#include +#include + +/* +** nKeyVal: +** The number of values that make up the 'key' for the current pCheck +** statement. +** +** rc: +** Error code returned by most recent sqlite3_intck_step() or +** sqlite3_intck_unlock() call. This is set to SQLITE_DONE when +** the integrity-check operation is finished. +** +** zErr: +** If the object has entered the error state, this is the error message. +** Is freed using sqlite3_free() when the object is deleted. +** +** zTestSql: +** The value returned by the most recent call to sqlite3_intck_testsql(). +** Each call to testsql() frees the previous zTestSql value (using +** sqlite3_free()) and replaces it with the new value it will return. +*/ +struct sqlite3_intck { + sqlite3 *db; + const char *zDb; /* Copy of zDb parameter to _open() */ + char *zObj; /* Current object. Or NULL. */ + + sqlite3_stmt *pCheck; /* Current check statement */ + char *zKey; + int nKeyVal; + + char *zMessage; + int bCorruptSchema; + + int rc; /* Error code */ + char *zErr; /* Error message */ + char *zTestSql; /* Returned by sqlite3_intck_test_sql() */ +}; + + +/* +** Some error has occurred while using database p->db. Save the error message +** and error code currently held by the database handle in p->rc and p->zErr. +*/ +static void intckSaveErrmsg(sqlite3_intck *p){ + p->rc = sqlite3_errcode(p->db); + sqlite3_free(p->zErr); + p->zErr = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); +} + +/* +** If the handle passed as the first argument is already in the error state, +** then this function is a no-op (returns NULL immediately). Otherwise, if an +** error occurs within this function, it leaves an error in said handle. +** +** Otherwise, this function attempts to prepare SQL statement zSql and +** return the resulting statement handle to the user. +*/ +static sqlite3_stmt *intckPrepare(sqlite3_intck *p, const char *zSql){ + sqlite3_stmt *pRet = 0; + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_prepare_v2(p->db, zSql, -1, &pRet, 0); + if( p->rc!=SQLITE_OK ){ + intckSaveErrmsg(p); + assert( pRet==0 ); + } + } + return pRet; +} + +/* +** If the handle passed as the first argument is already in the error state, +** then this function is a no-op (returns NULL immediately). Otherwise, if an +** error occurs within this function, it leaves an error in said handle. +** +** Otherwise, this function treats argument zFmt as a printf() style format +** string. It formats it according to the trailing arguments and then +** attempts to prepare the results and return the resulting prepared +** statement. +*/ +static sqlite3_stmt *intckPrepareFmt(sqlite3_intck *p, const char *zFmt, ...){ + sqlite3_stmt *pRet = 0; + va_list ap; + char *zSql = 0; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK && zSql==0 ){ + p->rc = SQLITE_NOMEM; + } + pRet = intckPrepare(p, zSql); + sqlite3_free(zSql); + va_end(ap); + return pRet; +} + +/* +** Finalize SQL statement pStmt. If an error occurs and the handle passed +** as the first argument does not already contain an error, store the +** error in the handle. +*/ +static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){ + int rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ + intckSaveErrmsg(p); + } +} + +/* +** If there is already an error in handle p, return it. Otherwise, call +** sqlite3_step() on the statement handle and return that value. +*/ +static int intckStep(sqlite3_intck *p, sqlite3_stmt *pStmt){ + if( p->rc ) return p->rc; + return sqlite3_step(pStmt); +} + +/* +** Execute SQL statement zSql. There is no way to obtain any results +** returned by the statement. This function uses the sqlite3_intck error +** code convention. +*/ +static void intckExec(sqlite3_intck *p, const char *zSql){ + sqlite3_stmt *pStmt = 0; + pStmt = intckPrepare(p, zSql); + intckStep(p, pStmt); + intckFinalize(p, pStmt); +} + +/* +** A wrapper around sqlite3_mprintf() that uses the sqlite3_intck error +** code convention. +*/ +static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){ + va_list ap; + char *zRet = 0; + va_start(ap, zFmt); + zRet = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK ){ + if( zRet==0 ){ + p->rc = SQLITE_NOMEM; + } + }else{ + sqlite3_free(zRet); + zRet = 0; + } + return zRet; +} + +/* +** This is used by sqlite3_intck_unlock() to save the vector key value +** required to restart the current pCheck query as a nul-terminated string +** in p->zKey. +*/ +static void intckSaveKey(sqlite3_intck *p){ + int ii; + char *zSql = 0; + sqlite3_stmt *pStmt = 0; + sqlite3_stmt *pXinfo = 0; + const char *zDir = 0; + + assert( p->pCheck ); + assert( p->zKey==0 ); + + pXinfo = intckPrepareFmt(p, + "SELECT group_concat(desc, '') FROM %Q.sqlite_schema s, " + "pragma_index_xinfo(%Q, %Q) " + "WHERE s.type='index' AND s.name=%Q", + p->zDb, p->zObj, p->zDb, p->zObj + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXinfo) ){ + zDir = (const char*)sqlite3_column_text(pXinfo, 0); + } + + if( zDir==0 ){ + /* Object is a table, not an index. This is the easy case,as there are + ** no DESC columns or NULL values in a primary key. */ + const char *zSep = "SELECT '(' || "; + for(ii=0; iinKeyVal; ii++){ + zSql = intckMprintf(p, "%z%squote(?)", zSql, zSep); + zSep = " || ', ' || "; + } + zSql = intckMprintf(p, "%z || ')'", zSql); + }else{ + + /* Object is an index. */ + assert( p->nKeyVal>1 ); + for(ii=p->nKeyVal; ii>0; ii--){ + int bLastIsDesc = zDir[ii-1]=='1'; + int bLastIsNull = sqlite3_column_type(p->pCheck, ii)==SQLITE_NULL; + const char *zLast = sqlite3_column_name(p->pCheck, ii); + char *zLhs = 0; + char *zRhs = 0; + char *zWhere = 0; + + if( bLastIsNull ){ + if( bLastIsDesc ) continue; + zWhere = intckMprintf(p, "'%s IS NOT NULL'", zLast); + }else{ + const char *zOp = bLastIsDesc ? "<" : ">"; + zWhere = intckMprintf(p, "'%s %s ' || quote(?%d)", zLast, zOp, ii); + } + + if( ii>1 ){ + const char *zLhsSep = ""; + const char *zRhsSep = ""; + int jj; + for(jj=0; jjpCheck,jj+1); + zLhs = intckMprintf(p, "%z%s%s", zLhs, zLhsSep, zAlias); + zRhs = intckMprintf(p, "%z%squote(?%d)", zRhs, zRhsSep, jj+1); + zLhsSep = ","; + zRhsSep = " || ',' || "; + } + + zWhere = intckMprintf(p, + "'(%z) IS (' || %z || ') AND ' || %z", + zLhs, zRhs, zWhere); + } + zWhere = intckMprintf(p, "'WHERE ' || %z", zWhere); + + zSql = intckMprintf(p, "%z%s(quote( %z ) )", + zSql, + (zSql==0 ? "VALUES" : ",\n "), + zWhere + ); + } + zSql = intckMprintf(p, + "WITH wc(q) AS (\n%z\n)" + "SELECT 'VALUES' || group_concat('(' || q || ')', ',\n ') FROM wc" + , zSql + ); + } + + pStmt = intckPrepare(p, zSql); + if( p->rc==SQLITE_OK ){ + for(ii=0; iinKeyVal; ii++){ + sqlite3_bind_value(pStmt, ii+1, sqlite3_column_value(p->pCheck, ii+1)); + } + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + p->zKey = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0)); + } + intckFinalize(p, pStmt); + } + + sqlite3_free(zSql); + intckFinalize(p, pXinfo); +} + +/* +** Find the next database object (table or index) to check. If successful, +** set sqlite3_intck.zObj to point to a nul-terminated buffer containing +** the object's name before returning. +*/ +static void intckFindObject(sqlite3_intck *p){ + sqlite3_stmt *pStmt = 0; + char *zPrev = p->zObj; + p->zObj = 0; + + assert( p->rc==SQLITE_OK ); + assert( p->pCheck==0 ); + + pStmt = intckPrepareFmt(p, + "WITH tables(table_name) AS (" + " SELECT name" + " FROM %Q.sqlite_schema WHERE (type='table' OR type='index') AND rootpage" + " UNION ALL " + " SELECT 'sqlite_schema'" + ")" + "SELECT table_name FROM tables " + "WHERE ?1 IS NULL OR table_name%s?1 " + "ORDER BY 1" + , p->zDb, (p->zKey ? ">=" : ">") + ); + + if( p->rc==SQLITE_OK ){ + sqlite3_bind_text(pStmt, 1, zPrev, -1, SQLITE_TRANSIENT); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + p->zObj = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0)); + } + } + intckFinalize(p, pStmt); + + /* If this is a new object, ensure the previous key value is cleared. */ + if( sqlite3_stricmp(p->zObj, zPrev) ){ + sqlite3_free(p->zKey); + p->zKey = 0; + } + + sqlite3_free(zPrev); +} + +/* +** Return the size in bytes of the first token in nul-terminated buffer z. +** For the purposes of this call, a token is either: +** +** * a quoted SQL string, +* * a contiguous series of ascii alphabet characters, or +* * any other single byte. +*/ +static int intckGetToken(const char *z){ + char c = z[0]; + int iRet = 1; + if( c=='\'' || c=='"' || c=='`' ){ + while( 1 ){ + if( z[iRet]==c ){ + iRet++; + if( z[iRet]!=c ) break; + } + iRet++; + } + } + else if( c=='[' ){ + while( z[iRet++]!=']' && z[iRet] ); + } + else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){ + while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){ + iRet++; + } + } + + return iRet; +} + +/* +** Return true if argument c is an ascii whitespace character. +*/ +static int intckIsSpace(char c){ + return (c==' ' || c=='\t' || c=='\n' || c=='\r'); +} + +/* +** Argument z points to the text of a CREATE INDEX statement. This function +** identifies the part of the text that contains either the index WHERE +** clause (if iCol<0) or the iCol'th column of the index. +** +** If (iCol<0), the identified fragment does not include the "WHERE" keyword, +** only the expression that follows it. If (iCol>=0) then the identified +** fragment does not include any trailing sort-order keywords - "ASC" or +** "DESC". +** +** If the CREATE INDEX statement does not contain the requested field or +** clause, NULL is returned and (*pnByte) is set to 0. Otherwise, a pointer to +** the identified fragment is returned and output parameter (*pnByte) set +** to its size in bytes. +*/ +static const char *intckParseCreateIndex(const char *z, int iCol, int *pnByte){ + int iOff = 0; + int iThisCol = 0; + int iStart = 0; + int nOpen = 0; + + const char *zRet = 0; + int nRet = 0; + + int iEndOfCol = 0; + + /* Skip forward until the first "(" token */ + while( z[iOff]!='(' ){ + iOff += intckGetToken(&z[iOff]); + if( z[iOff]=='\0' ) return 0; + } + assert( z[iOff]=='(' ); + + nOpen = 1; + iOff++; + iStart = iOff; + while( z[iOff] ){ + const char *zToken = &z[iOff]; + int nToken = 0; + + /* Check if this is the end of the current column - either a "," or ")" + ** when nOpen==1. */ + if( nOpen==1 ){ + if( z[iOff]==',' || z[iOff]==')' ){ + if( iCol==iThisCol ){ + int iEnd = iEndOfCol ? iEndOfCol : iOff; + nRet = (iEnd - iStart); + zRet = &z[iStart]; + break; + } + iStart = iOff+1; + while( intckIsSpace(z[iStart]) ) iStart++; + iThisCol++; + } + if( z[iOff]==')' ) break; + } + if( z[iOff]=='(' ) nOpen++; + if( z[iOff]==')' ) nOpen--; + nToken = intckGetToken(zToken); + + if( (nToken==3 && 0==sqlite3_strnicmp(zToken, "ASC", nToken)) + || (nToken==4 && 0==sqlite3_strnicmp(zToken, "DESC", nToken)) + ){ + iEndOfCol = iOff; + }else if( 0==intckIsSpace(zToken[0]) ){ + iEndOfCol = 0; + } + + iOff += nToken; + } + + /* iStart is now the byte offset of 1 byte passed the final ')' in the + ** CREATE INDEX statement. Try to find a WHERE clause to return. */ + while( zRet==0 && z[iOff] ){ + int n = intckGetToken(&z[iOff]); + if( n==5 && 0==sqlite3_strnicmp(&z[iOff], "where", 5) ){ + zRet = &z[iOff+5]; + nRet = (int)strlen(zRet); + } + iOff += n; + } + + /* Trim any whitespace from the start and end of the returned string. */ + if( zRet ){ + while( intckIsSpace(zRet[0]) ){ + nRet--; + zRet++; + } + while( nRet>0 && intckIsSpace(zRet[nRet-1]) ) nRet--; + } + + *pnByte = nRet; + return zRet; +} + +/* +** User-defined SQL function wrapper for intckParseCreateIndex(): +** +** SELECT parse_create_index(, ); +*/ +static void intckParseCreateIndexFunc( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + const char *zSql = (const char*)sqlite3_value_text(apVal[0]); + int idx = sqlite3_value_int(apVal[1]); + const char *zRes = 0; + int nRes = 0; + + assert( nVal==2 ); + if( zSql ){ + zRes = intckParseCreateIndex(zSql, idx, &nRes); + } + sqlite3_result_text(pCtx, zRes, nRes, SQLITE_TRANSIENT); +} + +/* +** Return true if sqlite3_intck.db has automatic indexes enabled, false +** otherwise. +*/ +static int intckGetAutoIndex(sqlite3_intck *p){ + int bRet = 0; + sqlite3_stmt *pStmt = 0; + pStmt = intckPrepare(p, "PRAGMA automatic_index"); + if( SQLITE_ROW==intckStep(p, pStmt) ){ + bRet = sqlite3_column_int(pStmt, 0); + } + intckFinalize(p, pStmt); + return bRet; +} + +/* +** Return true if zObj is an index, or false otherwise. +*/ +static int intckIsIndex(sqlite3_intck *p, const char *zObj){ + int bRet = 0; + sqlite3_stmt *pStmt = 0; + pStmt = intckPrepareFmt(p, + "SELECT 1 FROM %Q.sqlite_schema WHERE name=%Q AND type='index'", + p->zDb, zObj + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + bRet = 1; + } + intckFinalize(p, pStmt); + return bRet; +} + +/* +** Return a pointer to a nul-terminated buffer containing the SQL statement +** used to check database object zObj (a table or index) for corruption. +** If parameter zPrev is not NULL, then it must be a string containing the +** vector key required to restart the check where it left off last time. +** If pnKeyVal is not NULL, then (*pnKeyVal) is set to the number of +** columns in the vector key value for the specified object. +** +** This function uses the sqlite3_intck error code convention. +*/ +static char *intckCheckObjectSql( + sqlite3_intck *p, /* Integrity check object */ + const char *zObj, /* Object (table or index) to scan */ + const char *zPrev, /* Restart key vector, if any */ + int *pnKeyVal /* OUT: Number of key-values for this scan */ +){ + char *zRet = 0; + sqlite3_stmt *pStmt = 0; + int bAutoIndex = 0; + int bIsIndex = 0; + + const char *zCommon = + /* Relation without_rowid also contains just one row. Column "b" is + ** set to true if the table being examined is a WITHOUT ROWID table, + ** or false otherwise. */ + ", without_rowid(b) AS (" + " SELECT EXISTS (" + " SELECT 1 FROM tabname, pragma_index_list(tab, db) AS l" + " WHERE origin='pk' " + " AND NOT EXISTS (SELECT 1 FROM sqlite_schema WHERE name=l.name)" + " )" + ")" + "" + /* Table idx_cols contains 1 row for each column in each index on the + ** table being checked. Columns are: + ** + ** idx_name: Name of the index. + ** idx_ispk: True if this index is the PK of a WITHOUT ROWID table. + ** col_name: Name of indexed column, or NULL for index on expression. + ** col_expr: Indexed expression, including COLLATE clause. + ** col_alias: Alias used for column in 'intck_wrapper' table. + */ + ", idx_cols(idx_name, idx_ispk, col_name, col_expr, col_alias) AS (" + " SELECT l.name, (l.origin=='pk' AND w.b), i.name, COALESCE((" + " SELECT parse_create_index(sql, i.seqno) FROM " + " sqlite_schema WHERE name = l.name" + " ), format('\"%w\"', i.name) || ' COLLATE ' || quote(i.coll))," + " 'c' || row_number() OVER ()" + " FROM " + " tabname t," + " without_rowid w," + " pragma_index_list(t.tab, t.db) l," + " pragma_index_xinfo(l.name) i" + " WHERE i.key" + " UNION ALL" + " SELECT '', 1, '_rowid_', '_rowid_', 'r1' FROM without_rowid WHERE b=0" + ")" + "" + "" + /* + ** For a PK declared as "PRIMARY KEY(a, b) ... WITHOUT ROWID", where + ** the intck_wrapper aliases of "a" and "b" are "c1" and "c2": + ** + ** o_pk: "o.c1, o.c2" + ** i_pk: "i.'a', i.'b'" + ** ... + ** n_pk: 2 + */ + ", tabpk(db, tab, idx, o_pk, i_pk, q_pk, eq_pk, ps_pk, pk_pk, n_pk) AS (" + " WITH pkfields(f, a) AS (" + " SELECT i.col_name, i.col_alias FROM idx_cols i WHERE i.idx_ispk" + " )" + " SELECT t.db, t.tab, t.idx, " + " group_concat(a, ', '), " + " group_concat('i.'||quote(f), ', '), " + " group_concat('quote(o.'||a||')', ' || '','' || '), " + " format('(%s)==(%s)'," + " group_concat('o.'||a, ', '), " + " group_concat(format('\"%w\"', f), ', ')" + " )," + " group_concat('%s', ',')," + " group_concat('quote('||a||')', ', '), " + " count(*)" + " FROM tabname t, pkfields" + ")" + "" + ", idx(name, match_expr, partial, partial_alias, idx_ps, idx_idx) AS (" + " SELECT idx_name," + " format('(%s,%s) IS (%s,%s)', " + " group_concat(i.col_expr, ', '), i_pk," + " group_concat('o.'||i.col_alias, ', '), o_pk" + " ), " + " parse_create_index(" + " (SELECT sql FROM sqlite_schema WHERE name=idx_name), -1" + " )," + " 'cond' || row_number() OVER ()" + " , group_concat('%s', ',')" + " , group_concat('quote('||i.col_alias||')', ', ')" + " FROM tabpk t, " + " without_rowid w," + " idx_cols i" + " WHERE i.idx_ispk==0 " + " GROUP BY idx_name" + ")" + "" + ", wrapper_with(s) AS (" + " SELECT 'intck_wrapper AS (\n SELECT\n ' || (" + " WITH f(a, b) AS (" + " SELECT col_expr, col_alias FROM idx_cols" + " UNION ALL " + " SELECT partial, partial_alias FROM idx WHERE partial IS NOT NULL" + " )" + " SELECT group_concat(format('%s AS %s', a, b), ',\n ') FROM f" + " )" + " || format('\n FROM %Q.%Q ', t.db, t.tab)" + /* If the object being checked is a table, append "NOT INDEXED". + ** Otherwise, append "INDEXED BY ", and then, if the index + ** is a partial index " WHERE ". */ + " || CASE WHEN t.idx IS NULL THEN " + " 'NOT INDEXED'" + " ELSE" + " format('INDEXED BY %Q%s', t.idx, ' WHERE '||i.partial)" + " END" + " || '\n)'" + " FROM tabname t LEFT JOIN idx i ON (i.name=t.idx)" + ")" + "" + ; + + bAutoIndex = intckGetAutoIndex(p); + if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 0"); + + bIsIndex = intckIsIndex(p, zObj); + if( bIsIndex ){ + pStmt = intckPrepareFmt(p, + /* Table idxname contains a single row. The first column, "db", contains + ** the name of the db containing the table (e.g. "main") and the second, + ** "tab", the name of the table itself. */ + "WITH tabname(db, tab, idx) AS (" + " SELECT %Q, (SELECT tbl_name FROM %Q.sqlite_schema WHERE name=%Q), %Q " + ")" + "" + ", whereclause(w_c) AS (%s)" + "" + "%s" /* zCommon */ + "" + ", case_statement(c) AS (" + " SELECT " + " 'CASE WHEN (' || group_concat(col_alias, ', ') || ', 1) IS (\n' " + " || ' SELECT ' || group_concat(col_expr, ', ') || ', 1 FROM '" + " || format('%%Q.%%Q NOT INDEXED WHERE %%s\n', t.db, t.tab, p.eq_pk)" + " || ' )\n THEN NULL\n '" + " || 'ELSE format(''surplus entry ('" + " || group_concat('%%s', ',') || ',' || p.ps_pk" + " || ') in index ' || t.idx || ''', ' " + " || group_concat('quote('||i.col_alias||')', ', ') || ', ' || p.pk_pk" + " || ')'" + " || '\n END AS error_message'" + " FROM tabname t, tabpk p, idx_cols i WHERE i.idx_name=t.idx" + ")" + "" + ", thiskey(k, n) AS (" + " SELECT group_concat(i.col_alias, ', ') || ', ' || p.o_pk, " + " count(*) + p.n_pk " + " FROM tabpk p, idx_cols i WHERE i.idx_name=p.idx" + ")" + "" + ", main_select(m, n) AS (" + " SELECT format(" + " 'WITH %%s\n' ||" + " ', idx_checker AS (\n' ||" + " ' SELECT %%s,\n' ||" + " ' %%s\n' || " + " ' FROM intck_wrapper AS o\n' ||" + " ')\n'," + " ww.s, c, t.k" + " ), t.n" + " FROM case_statement, wrapper_with ww, thiskey t" + ")" + + "SELECT m || " + " group_concat('SELECT * FROM idx_checker ' || w_c, ' UNION ALL '), n" + " FROM " + "main_select, whereclause " + , p->zDb, p->zDb, zObj, zObj + , zPrev ? zPrev : "VALUES('')", zCommon + ); + }else{ + pStmt = intckPrepareFmt(p, + /* Table tabname contains a single row. The first column, "db", contains + ** the name of the db containing the table (e.g. "main") and the second, + ** "tab", the name of the table itself. */ + "WITH tabname(db, tab, idx, prev) AS (SELECT %Q, %Q, NULL, %Q)" + "" + "%s" /* zCommon */ + + /* expr(e) contains one row for each index on table zObj. Value e + ** is set to an expression that evaluates to NULL if the required + ** entry is present in the index, or an error message otherwise. */ + ", expr(e, p) AS (" + " SELECT format('CASE WHEN EXISTS \n" + " (SELECT 1 FROM %%Q.%%Q AS i INDEXED BY %%Q WHERE %%s%%s)\n" + " THEN NULL\n" + " ELSE format(''entry (%%s,%%s) missing from index %%s'', %%s, %%s)\n" + " END\n'" + " , t.db, t.tab, i.name, i.match_expr, ' AND (' || partial || ')'," + " i.idx_ps, t.ps_pk, i.name, i.idx_idx, t.pk_pk)," + " CASE WHEN partial IS NULL THEN NULL ELSE i.partial_alias END" + " FROM tabpk t, idx i" + ")" + + ", numbered(ii, cond, e) AS (" + " SELECT 0, 'n.ii=0', 'NULL'" + " UNION ALL " + " SELECT row_number() OVER ()," + " '(n.ii='||row_number() OVER ()||COALESCE(' AND '||p||')', ')'), e" + " FROM expr" + ")" + + ", counter_with(w) AS (" + " SELECT 'WITH intck_counter(ii) AS (\n ' || " + " group_concat('SELECT '||ii, ' UNION ALL\n ') " + " || '\n)' FROM numbered" + ")" + "" + ", case_statement(c) AS (" + " SELECT 'CASE ' || " + " group_concat(format('\n WHEN %%s THEN (%%s)', cond, e), '') ||" + " '\nEND AS error_message'" + " FROM numbered" + ")" + "" + + /* This table contains a single row consisting of a single value - + ** the text of an SQL expression that may be used by the main SQL + ** statement to output an SQL literal that can be used to resume + ** the scan if it is suspended. e.g. for a rowid table, an expression + ** like: + ** + ** format('(%d,%d)', _rowid_, n.ii) + */ + ", thiskey(k, n) AS (" + " SELECT o_pk || ', ii', n_pk+1 FROM tabpk" + ")" + "" + ", whereclause(w_c) AS (" + " SELECT CASE WHEN prev!='' THEN " + " '\nWHERE (' || o_pk ||', n.ii) > ' || prev" + " ELSE ''" + " END" + " FROM tabpk, tabname" + ")" + "" + ", main_select(m, n) AS (" + " SELECT format(" + " '%%s, %%s\nSELECT %%s,\n%%s\nFROM intck_wrapper AS o" + ", intck_counter AS n%%s\nORDER BY %%s', " + " w, ww.s, c, thiskey.k, whereclause.w_c, t.o_pk" + " ), thiskey.n" + " FROM case_statement, tabpk t, counter_with, " + " wrapper_with ww, thiskey, whereclause" + ")" + + "SELECT m, n FROM main_select", + p->zDb, zObj, zPrev, zCommon + ); + } + + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + zRet = intckMprintf(p, "%s", (const char*)sqlite3_column_text(pStmt, 0)); + if( pnKeyVal ){ + *pnKeyVal = sqlite3_column_int(pStmt, 1); + } + } + intckFinalize(p, pStmt); + + if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1"); + return zRet; +} + +/* +** Open a new integrity-check object. +*/ +int sqlite3_intck_open( + sqlite3 *db, /* Database handle to operate on */ + const char *zDbArg, /* "main", "temp" etc. */ + sqlite3_intck **ppOut /* OUT: New integrity-check handle */ +){ + sqlite3_intck *pNew = 0; + int rc = SQLITE_OK; + const char *zDb = zDbArg ? zDbArg : "main"; + int nDb = (int)strlen(zDb); + + pNew = (sqlite3_intck*)sqlite3_malloc(sizeof(*pNew) + nDb + 1); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pNew, 0, sizeof(*pNew)); + pNew->db = db; + pNew->zDb = (const char*)&pNew[1]; + memcpy(&pNew[1], zDb, nDb+1); + rc = sqlite3_create_function(db, "parse_create_index", + 2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0 + ); + if( rc!=SQLITE_OK ){ + sqlite3_intck_close(pNew); + pNew = 0; + } + } + + *ppOut = pNew; + return rc; +} + +/* +** Free the integrity-check object. +*/ +void sqlite3_intck_close(sqlite3_intck *p){ + if( p ){ + sqlite3_finalize(p->pCheck); + sqlite3_create_function( + p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0 + ); + sqlite3_free(p->zObj); + sqlite3_free(p->zKey); + sqlite3_free(p->zTestSql); + sqlite3_free(p->zErr); + sqlite3_free(p->zMessage); + sqlite3_free(p); + } +} + +/* +** Step the integrity-check object. +*/ +int sqlite3_intck_step(sqlite3_intck *p){ + if( p->rc==SQLITE_OK ){ + + if( p->zMessage ){ + sqlite3_free(p->zMessage); + p->zMessage = 0; + } + + if( p->bCorruptSchema ){ + p->rc = SQLITE_DONE; + }else + if( p->pCheck==0 ){ + intckFindObject(p); + if( p->rc==SQLITE_OK ){ + if( p->zObj ){ + char *zSql = 0; + zSql = intckCheckObjectSql(p, p->zObj, p->zKey, &p->nKeyVal); + p->pCheck = intckPrepare(p, zSql); + sqlite3_free(zSql); + sqlite3_free(p->zKey); + p->zKey = 0; + }else{ + p->rc = SQLITE_DONE; + } + }else if( p->rc==SQLITE_CORRUPT ){ + p->rc = SQLITE_OK; + p->zMessage = intckMprintf(p, "%s", + "corruption found while reading database schema" + ); + p->bCorruptSchema = 1; + } + } + + if( p->pCheck ){ + assert( p->rc==SQLITE_OK ); + if( sqlite3_step(p->pCheck)==SQLITE_ROW ){ + /* Normal case, do nothing. */ + }else{ + intckFinalize(p, p->pCheck); + p->pCheck = 0; + p->nKeyVal = 0; + if( p->rc==SQLITE_CORRUPT ){ + p->rc = SQLITE_OK; + p->zMessage = intckMprintf(p, + "corruption found while scanning database object %s", p->zObj + ); + } + } + } + } + + return p->rc; +} + +/* +** Return a message describing the corruption encountered by the most recent +** call to sqlite3_intck_step(), or NULL if no corruption was encountered. +*/ +const char *sqlite3_intck_message(sqlite3_intck *p){ + assert( p->pCheck==0 || p->zMessage==0 ); + if( p->zMessage ){ + return p->zMessage; + } + if( p->pCheck ){ + return (const char*)sqlite3_column_text(p->pCheck, 0); + } + return 0; +} + +/* +** Return the error code and message. +*/ +int sqlite3_intck_error(sqlite3_intck *p, const char **pzErr){ + if( pzErr ) *pzErr = p->zErr; + return (p->rc==SQLITE_DONE ? SQLITE_OK : p->rc); +} + +/* +** Close any read transaction the integrity-check object is holding open +** on the database. +*/ +int sqlite3_intck_unlock(sqlite3_intck *p){ + if( p->rc==SQLITE_OK && p->pCheck ){ + assert( p->zKey==0 && p->nKeyVal>0 ); + intckSaveKey(p); + intckFinalize(p, p->pCheck); + p->pCheck = 0; + } + return p->rc; +} + +/* +** Return the SQL statement used to check object zObj. Or, if zObj is +** NULL, the current SQL statement. +*/ +const char *sqlite3_intck_test_sql(sqlite3_intck *p, const char *zObj){ + sqlite3_free(p->zTestSql); + if( zObj ){ + p->zTestSql = intckCheckObjectSql(p, zObj, 0, 0); + }else{ + if( p->zObj ){ + p->zTestSql = intckCheckObjectSql(p, p->zObj, p->zKey, 0); + }else{ + sqlite3_free(p->zTestSql); + p->zTestSql = 0; + } + } + return p->zTestSql; +} + +/************************* End ../ext/intck/sqlite3intck.c ********************/ +/************************* Begin ../ext/misc/stmtrand.c ******************/ +/* +** 2024-05-24 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** An SQL function that return pseudo-random non-negative integers. +** +** SELECT stmtrand(123); +** +** A special feature of this function is that the same sequence of random +** integers is returned for each invocation of the statement. This makes +** the results repeatable, and hence useful for testing. The argument is +** an integer which is the seed for the random number sequence. The seed +** is used by the first invocation of this function only and is ignored +** for all subsequent calls within the same statement. +** +** Resetting a statement (sqlite3_reset()) also resets the random number +** sequence. +*/ +/* #include "sqlite3ext.h" */ +SQLITE_EXTENSION_INIT1 +#include +#include + +/* State of the pseudo-random number generator */ +typedef struct Stmtrand { + unsigned int x, y; +} Stmtrand; + +/* auxdata key */ +#define STMTRAND_KEY (-4418371) + +/* +** Function: stmtrand(SEED) +** +** Return a pseudo-random number. +*/ +static void stmtrandFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Stmtrand *p; + + p = (Stmtrand*)sqlite3_get_auxdata(context, STMTRAND_KEY); + if( p==0 ){ + unsigned int seed; + p = sqlite3_malloc( sizeof(*p) ); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + if( argc>=1 ){ + seed = (unsigned int)sqlite3_value_int(argv[0]); + }else{ + seed = 0; + } + p->x = seed | 1; + p->y = seed; + sqlite3_set_auxdata(context, STMTRAND_KEY, p, sqlite3_free); + p = (Stmtrand*)sqlite3_get_auxdata(context, STMTRAND_KEY); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + } + p->x = (p->x>>1) ^ ((1+~(p->x&1)) & 0xd0000001); + p->y = p->y*1103515245 + 12345; + sqlite3_result_int(context, (int)((p->x ^ p->y)&0x7fffffff)); +} + +#ifdef _WIN32 + +#endif +int sqlite3_stmtrand_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "stmtrand", 1, SQLITE_UTF8, 0, + stmtrandFunc, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "stmtrand", 0, SQLITE_UTF8, 0, + stmtrandFunc, 0, 0); + } + return rc; +} + +/************************* End ../ext/misc/stmtrand.c ********************/ +/************************* Begin ../ext/misc/vfstrace.c ******************/ +/* +** 2011 March 16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code implements a VFS shim that writes diagnostic +** output for each VFS call, similar to "strace". +** +** USAGE: +** +** This source file exports a single symbol which is the name of a +** function: +** +** int vfstrace_register( +** const char *zTraceName, // Name of the newly constructed VFS +** const char *zOldVfsName, // Name of the underlying VFS +** int (*xOut)(const char*,void*), // Output routine. ex: fputs +** void *pOutArg, // 2nd argument to xOut. ex: stderr +** int makeDefault // Make the new VFS the default +** ); +** +** Applications that want to trace their VFS usage must provide a callback +** function with this prototype: +** +** int traceOutput(const char *zMessage, void *pAppData); +** +** This function will "output" the trace messages, where "output" can +** mean different things to different applications. The traceOutput function +** for the command-line shell (see shell.c) is "fputs" from the standard +** library, which means that all trace output is written on the stream +** specified by the second argument. In the case of the command-line shell +** the second argument is stderr. Other applications might choose to output +** trace information to a file, over a socket, or write it into a buffer. +** +** The vfstrace_register() function creates a new "shim" VFS named by +** the zTraceName parameter. A "shim" VFS is an SQLite backend that does +** not really perform the duties of a true backend, but simply filters or +** interprets VFS calls before passing them off to another VFS which does +** the actual work. In this case the other VFS - the one that does the +** real work - is identified by the second parameter, zOldVfsName. If +** the 2nd parameter is NULL then the default VFS is used. The common +** case is for the 2nd parameter to be NULL. +** +** The third and fourth parameters are the pointer to the output function +** and the second argument to the output function. For the SQLite +** command-line shell, when the -vfstrace option is used, these parameters +** are fputs and stderr, respectively. +** +** The fifth argument is true (non-zero) to cause the newly created VFS +** to become the default VFS. The common case is for the fifth parameter +** to be true. +** +** The call to vfstrace_register() simply creates the shim VFS that does +** tracing. The application must also arrange to use the new VFS for +** all database connections that are created and for which tracing is +** desired. This can be done by specifying the trace VFS using URI filename +** notation, or by specifying the trace VFS as the 4th parameter to +** sqlite3_open_v2() or by making the trace VFS be the default (by setting +** the 5th parameter of vfstrace_register() to 1). +** +** +** ENABLING VFSTRACE IN A COMMAND-LINE SHELL +** +** The SQLite command line shell implemented by the shell.c source file +** can be used with this module. To compile in -vfstrace support, first +** gather this file (test_vfstrace.c), the shell source file (shell.c), +** and the SQLite amalgamation source files (sqlite3.c, sqlite3.h) into +** the working directory. Then compile using a command like the following: +** +** gcc -o sqlite3 -Os -I. -DSQLITE_ENABLE_VFSTRACE \ +** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \ +** -DHAVE_READLINE -DHAVE_USLEEP=1 \ +** shell.c test_vfstrace.c sqlite3.c -ldl -lreadline -lncurses +** +** The gcc command above works on Linux and provides (in addition to the +** -vfstrace option) support for FTS3 and FTS4, RTREE, and command-line +** editing using the readline library. The command-line shell does not +** use threads so we added -DSQLITE_THREADSAFE=0 just to make the code +** run a little faster. For compiling on a Mac, you'll probably need +** to omit the -DHAVE_READLINE, the -lreadline, and the -lncurses options. +** The compilation could be simplified to just this: +** +** gcc -DSQLITE_ENABLE_VFSTRACE \ +** shell.c test_vfstrace.c sqlite3.c -ldl -lpthread +** +** In this second example, all unnecessary options have been removed +** Note that since the code is now threadsafe, we had to add the -lpthread +** option to pull in the pthreads library. +** +** To cross-compile for windows using MinGW, a command like this might +** work: +** +** /opt/mingw/bin/i386-mingw32msvc-gcc -o sqlite3.exe -Os -I \ +** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_VFSTRACE \ +** shell.c test_vfstrace.c sqlite3.c +** +** Similar compiler commands will work on different systems. The key +** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that +** the shell.c source file will know to include the -vfstrace command-line +** option and (2) you must compile and link the three source files +** shell,c, test_vfstrace.c, and sqlite3.c. +** +** RUNTIME CONTROL OF VFSTRACE OUTPUT +** +** The application can use the "vfstrace" pragma to control which VFS +** APIs are traced. To disable all output: +** +** PRAGMA vfstrace('-all'); +** +** To enable all output (which is the default setting): +** +** PRAGMA vfstrace('+all'); +** +** Individual APIs can be enabled or disabled by name, with or without +** the initial "x" character. For example, to set up for tracing lock +** primatives only: +** +** PRAGMA vfstrace('-all, +Lock,Unlock,ShmLock'); +** +** The argument to the vfstrace pragma ignores capitalization and any +** characters other than alphabetics, '+', and '-'. +*/ +#include +#include +/* #include "sqlite3.h" */ + +/* +** An instance of this structure is attached to the each trace VFS to +** provide auxiliary information. +*/ +typedef struct vfstrace_info vfstrace_info; +struct vfstrace_info { + sqlite3_vfs *pRootVfs; /* The underlying real VFS */ + int (*xOut)(const char*, void*); /* Send output here */ + unsigned int mTrace; /* Mask of interfaces to trace */ + u8 bOn; /* Tracing on/off */ + void *pOutArg; /* First argument to xOut */ + const char *zVfsName; /* Name of this trace-VFS */ + sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */ +}; + +/* +** The sqlite3_file object for the trace VFS +*/ +typedef struct vfstrace_file vfstrace_file; +struct vfstrace_file { + sqlite3_file base; /* Base class. Must be first */ + vfstrace_info *pInfo; /* The trace-VFS to which this file belongs */ + const char *zFName; /* Base name of the file */ + sqlite3_file *pReal; /* The real underlying file */ +}; + +/* +** Bit values for vfstrace_info.mTrace. +*/ +#define VTR_CLOSE 0x00000001 +#define VTR_READ 0x00000002 +#define VTR_WRITE 0x00000004 +#define VTR_TRUNC 0x00000008 +#define VTR_SYNC 0x00000010 +#define VTR_FSIZE 0x00000020 +#define VTR_LOCK 0x00000040 +#define VTR_UNLOCK 0x00000080 +#define VTR_CRL 0x00000100 +#define VTR_FCTRL 0x00000200 +#define VTR_SECSZ 0x00000400 +#define VTR_DEVCHAR 0x00000800 +#define VTR_SHMLOCK 0x00001000 +#define VTR_SHMMAP 0x00002000 +#define VTR_SHMBAR 0x00004000 +#define VTR_SHMUNMAP 0x00008000 +#define VTR_OPEN 0x00010000 +#define VTR_DELETE 0x00020000 +#define VTR_ACCESS 0x00040000 +#define VTR_FULLPATH 0x00080000 +#define VTR_DLOPEN 0x00100000 +#define VTR_DLERR 0x00200000 +#define VTR_DLSYM 0x00400000 +#define VTR_DLCLOSE 0x00800000 +#define VTR_RAND 0x01000000 +#define VTR_SLEEP 0x02000000 +#define VTR_CURTIME 0x04000000 +#define VTR_LASTERR 0x08000000 +#define VTR_FETCH 0x10000000 /* Also coverse xUnfetch */ + +/* +** Method declarations for vfstrace_file. +*/ +static int vfstraceClose(sqlite3_file*); +static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int vfstraceWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64); +static int vfstraceTruncate(sqlite3_file*, sqlite3_int64 size); +static int vfstraceSync(sqlite3_file*, int flags); +static int vfstraceFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int vfstraceLock(sqlite3_file*, int); +static int vfstraceUnlock(sqlite3_file*, int); +static int vfstraceCheckReservedLock(sqlite3_file*, int *); +static int vfstraceFileControl(sqlite3_file*, int op, void *pArg); +static int vfstraceSectorSize(sqlite3_file*); +static int vfstraceDeviceCharacteristics(sqlite3_file*); +static int vfstraceShmLock(sqlite3_file*,int,int,int); +static int vfstraceShmMap(sqlite3_file*,int,int,int, void volatile **); +static void vfstraceShmBarrier(sqlite3_file*); +static int vfstraceShmUnmap(sqlite3_file*,int); + +/* +** Method declarations for vfstrace_vfs. +*/ +static int vfstraceOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +static int vfstraceDelete(sqlite3_vfs*, const char *zName, int syncDir); +static int vfstraceAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int vfstraceFullPathname(sqlite3_vfs*, const char *zName, int, char *); +static void *vfstraceDlOpen(sqlite3_vfs*, const char *zFilename); +static void vfstraceDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*vfstraceDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void); +static void vfstraceDlClose(sqlite3_vfs*, void*); +static int vfstraceRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int vfstraceSleep(sqlite3_vfs*, int microseconds); +static int vfstraceCurrentTime(sqlite3_vfs*, double*); +static int vfstraceGetLastError(sqlite3_vfs*, int, char*); +static int vfstraceCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); +static int vfstraceSetSystemCall(sqlite3_vfs*,const char*, sqlite3_syscall_ptr); +static sqlite3_syscall_ptr vfstraceGetSystemCall(sqlite3_vfs*, const char *); +static const char *vfstraceNextSystemCall(sqlite3_vfs*, const char *zName); + +/* +** Return a pointer to the tail of the pathname. Examples: +** +** /home/drh/xyzzy.txt -> xyzzy.txt +** xyzzy.txt -> xyzzy.txt +*/ +static const char *fileTail(const char *z){ + size_t i; + if( z==0 ) return 0; + i = strlen(z)-1; + while( i>0 && z[i-1]!='/' ){ i--; } + return &z[i]; +} + +/* +** Send trace output defined by zFormat and subsequent arguments. +*/ +static void vfstrace_printf( + vfstrace_info *pInfo, + const char *zFormat, + ... +){ + va_list ap; + char *zMsg; + if( pInfo->bOn ){ + va_start(ap, zFormat); + zMsg = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + pInfo->xOut(zMsg, pInfo->pOutArg); + sqlite3_free(zMsg); + } +} + +/* +** Try to convert an error code into a symbolic name for that error code. +*/ +static const char *vfstrace_errcode_name(int rc ){ + const char *zVal = 0; + switch( rc ){ + case SQLITE_OK: zVal = "SQLITE_OK"; break; + case SQLITE_INTERNAL: zVal = "SQLITE_INTERNAL"; break; + case SQLITE_ERROR: zVal = "SQLITE_ERROR"; break; + case SQLITE_PERM: zVal = "SQLITE_PERM"; break; + case SQLITE_ABORT: zVal = "SQLITE_ABORT"; break; + case SQLITE_BUSY: zVal = "SQLITE_BUSY"; break; + case SQLITE_LOCKED: zVal = "SQLITE_LOCKED"; break; + case SQLITE_NOMEM: zVal = "SQLITE_NOMEM"; break; + case SQLITE_READONLY: zVal = "SQLITE_READONLY"; break; + case SQLITE_INTERRUPT: zVal = "SQLITE_INTERRUPT"; break; + case SQLITE_IOERR: zVal = "SQLITE_IOERR"; break; + case SQLITE_CORRUPT: zVal = "SQLITE_CORRUPT"; break; + case SQLITE_NOTFOUND: zVal = "SQLITE_NOTFOUND"; break; + case SQLITE_FULL: zVal = "SQLITE_FULL"; break; + case SQLITE_CANTOPEN: zVal = "SQLITE_CANTOPEN"; break; + case SQLITE_PROTOCOL: zVal = "SQLITE_PROTOCOL"; break; + case SQLITE_EMPTY: zVal = "SQLITE_EMPTY"; break; + case SQLITE_SCHEMA: zVal = "SQLITE_SCHEMA"; break; + case SQLITE_TOOBIG: zVal = "SQLITE_TOOBIG"; break; + case SQLITE_CONSTRAINT: zVal = "SQLITE_CONSTRAINT"; break; + case SQLITE_MISMATCH: zVal = "SQLITE_MISMATCH"; break; + case SQLITE_MISUSE: zVal = "SQLITE_MISUSE"; break; + case SQLITE_NOLFS: zVal = "SQLITE_NOLFS"; break; + case SQLITE_IOERR_READ: zVal = "SQLITE_IOERR_READ"; break; + case SQLITE_IOERR_SHORT_READ: zVal = "SQLITE_IOERR_SHORT_READ"; break; + case SQLITE_IOERR_WRITE: zVal = "SQLITE_IOERR_WRITE"; break; + case SQLITE_IOERR_FSYNC: zVal = "SQLITE_IOERR_FSYNC"; break; + case SQLITE_IOERR_DIR_FSYNC: zVal = "SQLITE_IOERR_DIR_FSYNC"; break; + case SQLITE_IOERR_TRUNCATE: zVal = "SQLITE_IOERR_TRUNCATE"; break; + case SQLITE_IOERR_FSTAT: zVal = "SQLITE_IOERR_FSTAT"; break; + case SQLITE_IOERR_UNLOCK: zVal = "SQLITE_IOERR_UNLOCK"; break; + case SQLITE_IOERR_RDLOCK: zVal = "SQLITE_IOERR_RDLOCK"; break; + case SQLITE_IOERR_DELETE: zVal = "SQLITE_IOERR_DELETE"; break; + case SQLITE_IOERR_BLOCKED: zVal = "SQLITE_IOERR_BLOCKED"; break; + case SQLITE_IOERR_NOMEM: zVal = "SQLITE_IOERR_NOMEM"; break; + case SQLITE_IOERR_ACCESS: zVal = "SQLITE_IOERR_ACCESS"; break; + case SQLITE_IOERR_CHECKRESERVEDLOCK: + zVal = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; + case SQLITE_IOERR_LOCK: zVal = "SQLITE_IOERR_LOCK"; break; + case SQLITE_IOERR_CLOSE: zVal = "SQLITE_IOERR_CLOSE"; break; + case SQLITE_IOERR_DIR_CLOSE: zVal = "SQLITE_IOERR_DIR_CLOSE"; break; + case SQLITE_IOERR_SHMOPEN: zVal = "SQLITE_IOERR_SHMOPEN"; break; + case SQLITE_IOERR_SHMSIZE: zVal = "SQLITE_IOERR_SHMSIZE"; break; + case SQLITE_IOERR_SHMLOCK: zVal = "SQLITE_IOERR_SHMLOCK"; break; + case SQLITE_IOERR_SHMMAP: zVal = "SQLITE_IOERR_SHMMAP"; break; + case SQLITE_IOERR_SEEK: zVal = "SQLITE_IOERR_SEEK"; break; + case SQLITE_IOERR_GETTEMPPATH: zVal = "SQLITE_IOERR_GETTEMPPATH"; break; + case SQLITE_IOERR_CONVPATH: zVal = "SQLITE_IOERR_CONVPATH"; break; + case SQLITE_READONLY_DBMOVED: zVal = "SQLITE_READONLY_DBMOVED"; break; + case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break; + case SQLITE_BUSY_RECOVERY: zVal = "SQLITE_BUSY_RECOVERY"; break; + case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break; + } + return zVal; +} + +/* +** Convert value rc into a string and print it using zFormat. zFormat +** should have exactly one %s +*/ +static void vfstrace_print_errcode( + vfstrace_info *pInfo, + const char *zFormat, + int rc +){ + const char *zVal; + char zBuf[50]; + zVal = vfstrace_errcode_name(rc); + if( zVal==0 ){ + zVal = vfstrace_errcode_name(rc&0xff); + if( zVal ){ + sqlite3_snprintf(sizeof(zBuf), zBuf, "%s | 0x%x", zVal, rc&0xffff00); + }else{ + sqlite3_snprintf(sizeof(zBuf), zBuf, "%d (0x%x)", rc, rc); + } + zVal = zBuf; + } + vfstrace_printf(pInfo, zFormat, zVal); +} + +/* +** Append to a buffer. +*/ +static void strappend(char *z, int *pI, const char *zAppend){ + int i = *pI; + while( zAppend[0] ){ z[i++] = *(zAppend++); } + z[i] = 0; + *pI = i; +} + +/* +** Turn tracing output on or off according to mMask. +*/ +static void vfstraceOnOff(vfstrace_info *pInfo, unsigned int mMask){ + pInfo->bOn = (pInfo->mTrace & mMask)!=0; +} + +/* +** Close an vfstrace-file. +*/ +static int vfstraceClose(sqlite3_file *pFile){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_CLOSE); + vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xClose(p->pReal); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + if( rc==SQLITE_OK ){ + sqlite3_free((void*)p->base.pMethods); + p->base.pMethods = 0; + } + return rc; +} + +/* +** Read data from an vfstrace-file. +*/ +static int vfstraceRead( + sqlite3_file *pFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_READ); + vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)", + pInfo->zVfsName, p->zFName, iAmt, iOfst); + rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Write data to an vfstrace-file. +*/ +static int vfstraceWrite( + sqlite3_file *pFile, + const void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_WRITE); + vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)", + pInfo->zVfsName, p->zFName, iAmt, iOfst); + rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Truncate an vfstrace-file. +*/ +static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_TRUNC); + vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName, + size); + rc = p->pReal->pMethods->xTruncate(p->pReal, size); + vfstrace_printf(pInfo, " -> %d\n", rc); + return rc; +} + +/* +** Sync an vfstrace-file. +*/ +static int vfstraceSync(sqlite3_file *pFile, int flags){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + int i; + char zBuf[100]; + memcpy(zBuf, "|0", 3); + i = 0; + if( flags & SQLITE_SYNC_FULL ) strappend(zBuf, &i, "|FULL"); + else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL"); + if( flags & SQLITE_SYNC_DATAONLY ) strappend(zBuf, &i, "|DATAONLY"); + if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){ + sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags); + } + vfstraceOnOff(pInfo, VTR_SYNC); + vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName, + &zBuf[1]); + rc = p->pReal->pMethods->xSync(p->pReal, flags); + vfstrace_printf(pInfo, " -> %d\n", rc); + return rc; +} + +/* +** Return the current file-size of an vfstrace-file. +*/ +static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_FSIZE); + vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); + vfstrace_print_errcode(pInfo, " -> %s,", rc); + vfstrace_printf(pInfo, " size=%lld\n", *pSize); + return rc; +} + +/* +** Return the name of a lock. +*/ +static const char *lockName(int eLock){ + const char *azLockNames[] = { + "NONE", "SHARED", "RESERVED", "PENDING", "EXCLUSIVE" + }; + if( eLock<0 || eLock>=(int)(sizeof(azLockNames)/sizeof(azLockNames[0])) ){ + return "???"; + }else{ + return azLockNames[eLock]; + } +} + +/* +** Lock an vfstrace-file. +*/ +static int vfstraceLock(sqlite3_file *pFile, int eLock){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_LOCK); + vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName, + lockName(eLock)); + rc = p->pReal->pMethods->xLock(p->pReal, eLock); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Unlock an vfstrace-file. +*/ +static int vfstraceUnlock(sqlite3_file *pFile, int eLock){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_UNLOCK); + vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName, + lockName(eLock)); + rc = p->pReal->pMethods->xUnlock(p->pReal, eLock); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Check if another file-handle holds a RESERVED lock on an vfstrace-file. +*/ +static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_CRL); + vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)", + pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut); + vfstrace_print_errcode(pInfo, " -> %s", rc); + vfstrace_printf(pInfo, ", out=%d\n", *pResOut); + return rc; +} + +/* +** File control method. For custom operations on an vfstrace-file. +*/ +static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + char zBuf[100]; + char zBuf2[100]; + char *zOp; + char *zRVal = 0; + vfstraceOnOff(pInfo, VTR_FCTRL); + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break; + case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break; + case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break; + case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break; + case SQLITE_FCNTL_SIZE_HINT: { + sqlite3_snprintf(sizeof(zBuf), zBuf, "SIZE_HINT,%lld", + *(sqlite3_int64*)pArg); + zOp = zBuf; + break; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + sqlite3_snprintf(sizeof(zBuf), zBuf, "CHUNK_SIZE,%d", *(int*)pArg); + zOp = zBuf; + break; + } + case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break; + case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break; + case SQLITE_FCNTL_PERSIST_WAL: { + sqlite3_snprintf(sizeof(zBuf), zBuf, "PERSIST_WAL,%d", *(int*)pArg); + zOp = zBuf; + break; + } + case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break; + case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break; + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break; + case SQLITE_FCNTL_PRAGMA: { + const char *const* a = (const char*const*)pArg; + if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){ + const u8 *zArg = (const u8*)a[2]; + if( zArg[0]>='0' && zArg[0]<=9 ){ + pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0); + }else{ + static const struct { + const char *z; + unsigned int m; + } aKw[] = { + { "all", 0xffffffff }, + { "close", VTR_CLOSE }, + { "read", VTR_READ }, + { "write", VTR_WRITE }, + { "truncate", VTR_TRUNC }, + { "sync", VTR_SYNC }, + { "filesize", VTR_FSIZE }, + { "lock", VTR_LOCK }, + { "unlock", VTR_UNLOCK }, + { "checkreservedlock", VTR_CRL }, + { "filecontrol", VTR_FCTRL }, + { "sectorsize", VTR_SECSZ }, + { "devicecharacteristics", VTR_DEVCHAR }, + { "shmlock", VTR_SHMLOCK }, + { "shmmap", VTR_SHMMAP }, + { "shmummap", VTR_SHMUNMAP }, + { "shmbarrier", VTR_SHMBAR }, + { "open", VTR_OPEN }, + { "delete", VTR_DELETE }, + { "access", VTR_ACCESS }, + { "fullpathname", VTR_FULLPATH }, + { "dlopen", VTR_DLOPEN }, + { "dlerror", VTR_DLERR }, + { "dlsym", VTR_DLSYM }, + { "dlclose", VTR_DLCLOSE }, + { "randomness", VTR_RAND }, + { "sleep", VTR_SLEEP }, + { "currenttime", VTR_CURTIME }, + { "currenttimeint64", VTR_CURTIME }, + { "getlasterror", VTR_LASTERR }, + { "fetch", VTR_FETCH }, + }; + int onOff = 1; + while( zArg[0] ){ + int jj, n; + while( zArg[0]!=0 && zArg[0]!='-' && zArg[0]!='+' + && !isalpha(zArg[0]) ) zArg++; + if( zArg[0]==0 ) break; + if( zArg[0]=='-' ){ + onOff = 0; + zArg++; + }else if( zArg[0]=='+' ){ + onOff = 1; + zArg++; + } + while( !isalpha(zArg[0]) ){ + if( zArg[0]==0 ) break; + zArg++; + } + if( zArg[0]=='x' && isalpha(zArg[1]) ) zArg++; + for(n=0; isalpha(zArg[n]); n++){} + for(jj=0; jj<(int)(sizeof(aKw)/sizeof(aKw[0])); jj++){ + if( sqlite3_strnicmp(aKw[jj].z,(const char*)zArg,n)==0 ){ + if( onOff ){ + pInfo->mTrace |= aKw[jj].m; + }else{ + pInfo->mTrace &= ~aKw[jj].m; + } + break; + } + } + zArg += n; + } + } + } + sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]); + zOp = zBuf; + break; + } + case SQLITE_FCNTL_BUSYHANDLER: zOp = "BUSYHANDLER"; break; + case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break; + case SQLITE_FCNTL_MMAP_SIZE: { + sqlite3_int64 iMMap = *(sqlite3_int64*)pArg; + sqlite3_snprintf(sizeof(zBuf), zBuf, "MMAP_SIZE,%lld",iMMap); + zOp = zBuf; + break; + } + case SQLITE_FCNTL_TRACE: zOp = "TRACE"; break; + case SQLITE_FCNTL_HAS_MOVED: zOp = "HAS_MOVED"; break; + case SQLITE_FCNTL_SYNC: zOp = "SYNC"; break; + case SQLITE_FCNTL_COMMIT_PHASETWO: zOp = "COMMIT_PHASETWO"; break; + case SQLITE_FCNTL_WIN32_SET_HANDLE: zOp = "WIN32_SET_HANDLE"; break; + case SQLITE_FCNTL_WAL_BLOCK: zOp = "WAL_BLOCK"; break; + case SQLITE_FCNTL_ZIPVFS: zOp = "ZIPVFS"; break; + case SQLITE_FCNTL_RBU: zOp = "RBU"; break; + case SQLITE_FCNTL_VFS_POINTER: zOp = "VFS_POINTER"; break; + case SQLITE_FCNTL_JOURNAL_POINTER: zOp = "JOURNAL_POINTER"; break; + case SQLITE_FCNTL_WIN32_GET_HANDLE: zOp = "WIN32_GET_HANDLE"; break; + case SQLITE_FCNTL_PDB: zOp = "PDB"; break; + case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: zOp = "BEGIN_ATOMIC_WRITE"; break; + case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: zOp = "COMMIT_ATOMIC_WRITE"; break; + case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: { + zOp = "ROLLBACK_ATOMIC_WRITE"; + break; + } + case SQLITE_FCNTL_LOCK_TIMEOUT: { + sqlite3_snprintf(sizeof(zBuf), zBuf, "LOCK_TIMEOUT,%d", *(int*)pArg); + zOp = zBuf; + break; + } + case SQLITE_FCNTL_DATA_VERSION: zOp = "DATA_VERSION"; break; + case SQLITE_FCNTL_SIZE_LIMIT: zOp = "SIZE_LIMIT"; break; + case SQLITE_FCNTL_CKPT_DONE: zOp = "CKPT_DONE"; break; + case SQLITE_FCNTL_RESERVE_BYTES: zOp = "RESERVED_BYTES"; break; + case SQLITE_FCNTL_CKPT_START: zOp = "CKPT_START"; break; + case SQLITE_FCNTL_EXTERNAL_READER: zOp = "EXTERNAL_READER"; break; + case SQLITE_FCNTL_CKSM_FILE: zOp = "CKSM_FILE"; break; + case SQLITE_FCNTL_RESET_CACHE: zOp = "RESET_CACHE"; break; + case 0xca093fa0: zOp = "DB_UNCHANGED"; break; + default: { + sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op); + zOp = zBuf; + break; + } + } + vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)", + pInfo->zVfsName, p->zFName, zOp); + rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); + if( rc==SQLITE_OK ){ + switch( op ){ + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z", + pInfo->zVfsName, *(char**)pArg); + zRVal = *(char**)pArg; + break; + } + case SQLITE_FCNTL_MMAP_SIZE: { + sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%lld", *(sqlite3_int64*)pArg); + zRVal = zBuf2; + break; + } + case SQLITE_FCNTL_HAS_MOVED: + case SQLITE_FCNTL_PERSIST_WAL: { + sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%d", *(int*)pArg); + zRVal = zBuf2; + break; + } + case SQLITE_FCNTL_PRAGMA: + case SQLITE_FCNTL_TEMPFILENAME: { + zRVal = *(char**)pArg; + break; + } + } + } + if( zRVal ){ + vfstrace_print_errcode(pInfo, " -> %s", rc); + vfstrace_printf(pInfo, ", %s\n", zRVal); + }else{ + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + } + return rc; +} + +/* +** Return the sector-size in bytes for an vfstrace-file. +*/ +static int vfstraceSectorSize(sqlite3_file *pFile){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_SECSZ); + vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xSectorSize(p->pReal); + vfstrace_printf(pInfo, " -> %d\n", rc); + return rc; +} + +/* +** Return the device characteristic flags supported by an vfstrace-file. +*/ +static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_DEVCHAR); + vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)", + pInfo->zVfsName, p->zFName); + rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal); + vfstrace_printf(pInfo, " -> 0x%08x\n", rc); + return rc; +} + +/* +** Shared-memory operations. +*/ +static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ + static const char *azLockName[] = { + "WRITE", + "CKPT", + "RECOVER", + "READ0", + "READ1", + "READ2", + "READ3", + "READ4", + }; + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + char zLck[100]; + int i = 0; + vfstraceOnOff(pInfo, VTR_SHMLOCK); + memcpy(zLck, "|0", 3); + if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK"); + if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK"); + if( flags & SQLITE_SHM_SHARED ) strappend(zLck, &i, "|SHARED"); + if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE"); + if( flags & ~(0xf) ){ + sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags); + } + if( ofst>=0 && ofst<(int)(sizeof(azLockName)/sizeof(azLockName[0])) ){ + vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d(%s),n=%d,%s)", + pInfo->zVfsName, p->zFName, ofst, azLockName[ofst], + n, &zLck[1]); + }else{ + vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=5d,n=%d,%s)", + pInfo->zVfsName, p->zFName, ofst, + n, &zLck[1]); + } + rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} +static int vfstraceShmMap( + sqlite3_file *pFile, + int iRegion, + int szRegion, + int isWrite, + void volatile **pp +){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_SHMMAP); + vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)", + pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite); + rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} +static void vfstraceShmBarrier(sqlite3_file *pFile){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + vfstraceOnOff(pInfo, VTR_SHMBAR); + vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName); + p->pReal->pMethods->xShmBarrier(p->pReal); +} +static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_SHMUNMAP); + vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)", + pInfo->zVfsName, p->zFName, delFlag); + rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} +static int vfstraceFetch(sqlite3_file *pFile, i64 iOff, int nAmt, void **pptr){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_FETCH); + vfstrace_printf(pInfo, "%s.xFetch(%s,iOff=%lld,nAmt=%d,p=%p)", + pInfo->zVfsName, p->zFName, iOff, nAmt, *pptr); + rc = p->pReal->pMethods->xFetch(p->pReal, iOff, nAmt, pptr); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} +static int vfstraceUnfetch(sqlite3_file *pFile, i64 iOff, void *ptr){ + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = p->pInfo; + int rc; + vfstraceOnOff(pInfo, VTR_FETCH); + vfstrace_printf(pInfo, "%s.xUnfetch(%s,iOff=%lld,p=%p)", + pInfo->zVfsName, p->zFName, iOff, ptr); + rc = p->pReal->pMethods->xUnfetch(p->pReal, iOff, ptr); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + + +/* +** Open an vfstrace file handle. +*/ +static int vfstraceOpen( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_file *pFile, + int flags, + int *pOutFlags +){ + int rc; + vfstrace_file *p = (vfstrace_file *)pFile; + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + p->pInfo = pInfo; + p->zFName = zName ? fileTail(zName) : ""; + p->pReal = (sqlite3_file *)&p[1]; + rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags); + vfstraceOnOff(pInfo, VTR_OPEN); + vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)", + pInfo->zVfsName, p->zFName, flags); + if( p->pReal->pMethods ){ + sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) ); + const sqlite3_io_methods *pSub = p->pReal->pMethods; + memset(pNew, 0, sizeof(*pNew)); + pNew->iVersion = pSub->iVersion; + pNew->xClose = vfstraceClose; + pNew->xRead = vfstraceRead; + pNew->xWrite = vfstraceWrite; + pNew->xTruncate = vfstraceTruncate; + pNew->xSync = vfstraceSync; + pNew->xFileSize = vfstraceFileSize; + pNew->xLock = vfstraceLock; + pNew->xUnlock = vfstraceUnlock; + pNew->xCheckReservedLock = vfstraceCheckReservedLock; + pNew->xFileControl = vfstraceFileControl; + pNew->xSectorSize = vfstraceSectorSize; + pNew->xDeviceCharacteristics = vfstraceDeviceCharacteristics; + if( pNew->iVersion>=2 ){ + pNew->xShmMap = pSub->xShmMap ? vfstraceShmMap : 0; + pNew->xShmLock = pSub->xShmLock ? vfstraceShmLock : 0; + pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0; + pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0; + } + if( pNew->iVersion>=3 ){ + pNew->xFetch = pSub->xFetch ? vfstraceFetch : 0; + pNew->xUnfetch = pSub->xUnfetch ? vfstraceUnfetch : 0; + } + pFile->pMethods = pNew; + } + vfstrace_print_errcode(pInfo, " -> %s", rc); + if( pOutFlags ){ + vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags); + }else{ + vfstrace_printf(pInfo, "\n"); + } + return rc; +} + +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstraceOnOff(pInfo, VTR_DELETE); + vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)", + pInfo->zVfsName, zPath, dirSync); + rc = pRoot->xDelete(pRoot, zPath, dirSync); + vfstrace_print_errcode(pInfo, " -> %s\n", rc); + return rc; +} + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +*/ +static int vfstraceAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstraceOnOff(pInfo, VTR_ACCESS); + vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)", + pInfo->zVfsName, zPath, flags); + rc = pRoot->xAccess(pRoot, zPath, flags, pResOut); + vfstrace_print_errcode(pInfo, " -> %s", rc); + vfstrace_printf(pInfo, ", out=%d\n", *pResOut); + return rc; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (DEVSYM_MAX_PATHNAME+1) bytes. +*/ +static int vfstraceFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstraceOnOff(pInfo, VTR_FULLPATH); + vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")", + pInfo->zVfsName, zPath); + rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut); + vfstrace_print_errcode(pInfo, " -> %s", rc); + vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut); + return rc; +} + +/* +** Open the dynamic library located at zPath and return a handle. +*/ +static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_DLOPEN); + vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath); + return pRoot->xDlOpen(pRoot, zPath); +} + +/* +** Populate the buffer zErrMsg (size nByte bytes) with a human readable +** utf-8 string describing the most recent error encountered associated +** with dynamic libraries. +*/ +static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_DLERR); + vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte); + pRoot->xDlError(pRoot, nByte, zErrMsg); + vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg); +} + +/* +** Return a pointer to the symbol zSymbol in the dynamic library pHandle. +*/ +static void (*vfstraceDlSym(sqlite3_vfs *pVfs,void *p,const char *zSym))(void){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstrace_printf(pInfo, "%s.xDlSym(\"%s\")\n", pInfo->zVfsName, zSym); + return pRoot->xDlSym(pRoot, p, zSym); +} + +/* +** Close the dynamic library handle pHandle. +*/ +static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_DLCLOSE); + vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName); + pRoot->xDlClose(pRoot, pHandle); +} + +/* +** Populate the buffer pointed to by zBufOut with nByte bytes of +** random data. +*/ +static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_RAND); + vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte); + return pRoot->xRandomness(pRoot, nByte, zBufOut); +} + +/* +** Sleep for nMicro microseconds. Return the number of microseconds +** actually slept. +*/ +static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + vfstraceOnOff(pInfo, VTR_SLEEP); + vfstrace_printf(pInfo, "%s.xSleep(%d)\n", pInfo->zVfsName, nMicro); + return pRoot->xSleep(pRoot, nMicro); +} + +/* +** Return the current time as a Julian Day number in *pTimeOut. */ -void sqlite3_expert_destroy(sqlite3expert *p){ - if( p ){ - sqlite3_close(p->dbm); - sqlite3_close(p->dbv); - idxScanFree(p->pScan, 0); - idxStatementFree(p->pStatement, 0); - idxTableFree(p->pTable); - idxWriteFree(p->pWrite); - idxHashClear(&p->hIdx); - sqlite3_free(p->zCandidates); - sqlite3_free(p); - } +static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstraceOnOff(pInfo, VTR_CURTIME); + vfstrace_printf(pInfo, "%s.xCurrentTime()", pInfo->zVfsName); + rc = pRoot->xCurrentTime(pRoot, pTimeOut); + vfstrace_printf(pInfo, " -> %.17g\n", *pTimeOut); + return rc; +} +static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstraceOnOff(pInfo, VTR_CURTIME); + vfstrace_printf(pInfo, "%s.xCurrentTimeInt64()", pInfo->zVfsName); + rc = pRoot->xCurrentTimeInt64(pRoot, pTimeOut); + vfstrace_printf(pInfo, " -> %lld\n", *pTimeOut); + return rc; } -#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ +/* +** Return the most recent error code and message +*/ +static int vfstraceGetLastError(sqlite3_vfs *pVfs, int nErr, char *zErr){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + int rc; + vfstraceOnOff(pInfo, VTR_LASTERR); + vfstrace_printf(pInfo, "%s.xGetLastError(%d,zBuf)", pInfo->zVfsName, nErr); + if( nErr ) zErr[0] = 0; + rc = pRoot->xGetLastError(pRoot, nErr, zErr); + vfstrace_printf(pInfo, " -> zBuf[] = \"%s\", rc = %d\n", nErr?zErr:"", rc); + return rc; +} -/************************* End ../ext/expert/sqlite3expert.c ********************/ +/* +** Override system calls. +*/ +static int vfstraceSetSystemCall( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_syscall_ptr pFunc +){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xSetSystemCall(pRoot, zName, pFunc); +} +static sqlite3_syscall_ptr vfstraceGetSystemCall( + sqlite3_vfs *pVfs, + const char *zName +){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xGetSystemCall(pRoot, zName); +} +static const char *vfstraceNextSystemCall(sqlite3_vfs *pVfs, const char *zName){ + vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; + sqlite3_vfs *pRoot = pInfo->pRootVfs; + return pRoot->xNextSystemCall(pRoot, zName); +} + + +/* +** Clients invoke this routine to construct a new trace-vfs shim. +** +** Return SQLITE_OK on success. +** +** SQLITE_NOMEM is returned in the case of a memory allocation error. +** SQLITE_NOTFOUND is returned if zOldVfsName does not exist. +*/ +int vfstrace_register( + const char *zTraceName, /* Name of the newly constructed VFS */ + const char *zOldVfsName, /* Name of the underlying VFS */ + int (*xOut)(const char*,void*), /* Output routine. ex: fputs */ + void *pOutArg, /* 2nd argument to xOut. ex: stderr */ + int makeDefault /* True to make the new VFS the default */ +){ + sqlite3_vfs *pNew; + sqlite3_vfs *pRoot; + vfstrace_info *pInfo; + size_t nName; + size_t nByte; + + pRoot = sqlite3_vfs_find(zOldVfsName); + if( pRoot==0 ) return SQLITE_NOTFOUND; + nName = strlen(zTraceName); + nByte = sizeof(*pNew) + sizeof(*pInfo) + nName + 1; + pNew = sqlite3_malloc64( nByte ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, nByte); + pInfo = (vfstrace_info*)&pNew[1]; + pNew->iVersion = pRoot->iVersion; + pNew->szOsFile = pRoot->szOsFile + sizeof(vfstrace_file); + pNew->mxPathname = pRoot->mxPathname; + pNew->zName = (char*)&pInfo[1]; + memcpy((char*)&pInfo[1], zTraceName, nName+1); + pNew->pAppData = pInfo; + pNew->xOpen = vfstraceOpen; + pNew->xDelete = vfstraceDelete; + pNew->xAccess = vfstraceAccess; + pNew->xFullPathname = vfstraceFullPathname; + pNew->xDlOpen = pRoot->xDlOpen==0 ? 0 : vfstraceDlOpen; + pNew->xDlError = pRoot->xDlError==0 ? 0 : vfstraceDlError; + pNew->xDlSym = pRoot->xDlSym==0 ? 0 : vfstraceDlSym; + pNew->xDlClose = pRoot->xDlClose==0 ? 0 : vfstraceDlClose; + pNew->xRandomness = vfstraceRandomness; + pNew->xSleep = vfstraceSleep; + pNew->xCurrentTime = vfstraceCurrentTime; + pNew->xGetLastError = pRoot->xGetLastError==0 ? 0 : vfstraceGetLastError; + if( pNew->iVersion>=2 ){ + pNew->xCurrentTimeInt64 = pRoot->xCurrentTimeInt64==0 ? 0 : + vfstraceCurrentTimeInt64; + if( pNew->iVersion>=3 ){ + pNew->xSetSystemCall = pRoot->xSetSystemCall==0 ? 0 : + vfstraceSetSystemCall; + pNew->xGetSystemCall = pRoot->xGetSystemCall==0 ? 0 : + vfstraceGetSystemCall; + pNew->xNextSystemCall = pRoot->xNextSystemCall==0 ? 0 : + vfstraceNextSystemCall; + } + } + pInfo->pRootVfs = pRoot; + pInfo->xOut = xOut; + pInfo->pOutArg = pOutArg; + pInfo->zVfsName = pNew->zName; + pInfo->pTraceVfs = pNew; + pInfo->mTrace = 0xffffffff; + pInfo->bOn = 1; + vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n", + pInfo->zVfsName, pRoot->zName); + return sqlite3_vfs_register(pNew, makeDefault); +} + +/* +** Look for the named VFS. If it is a TRACEVFS, then unregister it +** and delete it. +*/ +void vfstrace_unregister(const char *zTraceName){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(zTraceName); + if( pVfs==0 ) return; + if( pVfs->xOpen!=vfstraceOpen ) return; + sqlite3_vfs_unregister(pVfs); + sqlite3_free(pVfs); +} + +/************************* End ../ext/misc/vfstrace.c ********************/ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) #define SQLITE_SHELL_HAVE_RECOVER 1 @@ -14341,6 +17736,15 @@ int sqlite3_recover_finish(sqlite3_recover*); typedef struct DbdataTable DbdataTable; typedef struct DbdataCursor DbdataCursor; +typedef struct DbdataBuffer DbdataBuffer; + +/* +** Buffer type. +*/ +struct DbdataBuffer { + u8 *aBuf; + sqlite3_int64 nBuf; +}; /* Cursor object */ struct DbdataCursor { @@ -14357,7 +17761,7 @@ struct DbdataCursor { sqlite3_int64 iRowid; /* Only for the sqlite_dbdata table */ - u8 *pRec; /* Buffer containing current record */ + DbdataBuffer rec; sqlite3_int64 nRec; /* Size of pRec[] in bytes */ sqlite3_int64 nHdr; /* Size of header in bytes */ int iField; /* Current field number */ @@ -14402,6 +17806,31 @@ struct DbdataTable { " schema TEXT HIDDEN" \ ")" +/* +** Ensure the buffer passed as the first argument is at least nMin bytes +** in size. If an error occurs while attempting to resize the buffer, +** SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. +*/ +static int dbdataBufferSize(DbdataBuffer *pBuf, sqlite3_int64 nMin){ + if( nMin>pBuf->nBuf ){ + sqlite3_int64 nNew = nMin+16384; + u8 *aNew = (u8*)sqlite3_realloc64(pBuf->aBuf, nNew); + + if( aNew==0 ) return SQLITE_NOMEM; + pBuf->aBuf = aNew; + pBuf->nBuf = nNew; + } + return SQLITE_OK; +} + +/* +** Release the allocation managed by buffer pBuf. +*/ +static void dbdataBufferFree(DbdataBuffer *pBuf){ + sqlite3_free(pBuf->aBuf); + memset(pBuf, 0, sizeof(*pBuf)); +} + /* ** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual ** table. @@ -14542,9 +17971,9 @@ static void dbdataResetCursor(DbdataCursor *pCsr){ pCsr->iField = 0; pCsr->bOnePage = 0; sqlite3_free(pCsr->aPage); - sqlite3_free(pCsr->pRec); - pCsr->pRec = 0; + dbdataBufferFree(&pCsr->rec); pCsr->aPage = 0; + pCsr->nRec = 0; } /* @@ -14686,67 +18115,88 @@ static void dbdataValue( u8 *pData, sqlite3_int64 nData ){ - if( eType>=0 && dbdataValueBytes(eType)<=nData ){ - switch( eType ){ - case 0: - case 10: - case 11: - sqlite3_result_null(pCtx); - break; - - case 8: - sqlite3_result_int(pCtx, 0); - break; - case 9: - sqlite3_result_int(pCtx, 1); - break; - - case 1: case 2: case 3: case 4: case 5: case 6: case 7: { - sqlite3_uint64 v = (signed char)pData[0]; - pData++; - switch( eType ){ - case 7: - case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; - case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; - case 4: v = (v<<8) + pData[0]; pData++; - case 3: v = (v<<8) + pData[0]; pData++; - case 2: v = (v<<8) + pData[0]; pData++; - } - - if( eType==7 ){ - double r; - memcpy(&r, &v, sizeof(r)); - sqlite3_result_double(pCtx, r); - }else{ - sqlite3_result_int64(pCtx, (sqlite3_int64)v); + if( eType>=0 ){ + if( dbdataValueBytes(eType)<=nData ){ + switch( eType ){ + case 0: + case 10: + case 11: + sqlite3_result_null(pCtx); + break; + + case 8: + sqlite3_result_int(pCtx, 0); + break; + case 9: + sqlite3_result_int(pCtx, 1); + break; + + case 1: case 2: case 3: case 4: case 5: case 6: case 7: { + sqlite3_uint64 v = (signed char)pData[0]; + pData++; + switch( eType ){ + case 7: + case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 4: v = (v<<8) + pData[0]; pData++; + case 3: v = (v<<8) + pData[0]; pData++; + case 2: v = (v<<8) + pData[0]; pData++; + } + + if( eType==7 ){ + double r; + memcpy(&r, &v, sizeof(r)); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_int64(pCtx, (sqlite3_int64)v); + } + break; } - break; - } - - default: { - int n = ((eType-12) / 2); - if( eType % 2 ){ - switch( enc ){ -#ifndef SQLITE_OMIT_UTF16 - case SQLITE_UTF16BE: - sqlite3_result_text16be(pCtx, (void*)pData, n, SQLITE_TRANSIENT); - break; - case SQLITE_UTF16LE: - sqlite3_result_text16le(pCtx, (void*)pData, n, SQLITE_TRANSIENT); - break; -#endif - default: - sqlite3_result_text(pCtx, (char*)pData, n, SQLITE_TRANSIENT); - break; + + default: { + int n = ((eType-12) / 2); + if( eType % 2 ){ + switch( enc ){ + #ifndef SQLITE_OMIT_UTF16 + case SQLITE_UTF16BE: + sqlite3_result_text16be(pCtx, (void*)pData, n, SQLITE_TRANSIENT); + break; + case SQLITE_UTF16LE: + sqlite3_result_text16le(pCtx, (void*)pData, n, SQLITE_TRANSIENT); + break; + #endif + default: + sqlite3_result_text(pCtx, (char*)pData, n, SQLITE_TRANSIENT); + break; + } + }else{ + sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); } - }else{ - sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); } } + }else{ + if( eType==7 ){ + sqlite3_result_double(pCtx, 0.0); + }else if( eType<7 ){ + sqlite3_result_int(pCtx, 0); + }else if( eType%2 ){ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + }else{ + sqlite3_result_blob(pCtx, "", 0, SQLITE_STATIC); + } } } } +/* This macro is a copy of the MX_CELL() macro in the SQLite core. Given +** a page-size, it returns the maximum number of cells that may be present +** on the page. */ +#define DBDATA_MX_CELL(pgsz) ((pgsz-8)/6) + +/* Maximum number of fields that may appear in a single record. This is +** the "hard-limit", according to comments in sqliteLimit.h. */ +#define DBDATA_MX_FIELD 32676 + /* ** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry. */ @@ -14775,6 +18225,9 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ assert( iOff+3+2<=pCsr->nPage ); pCsr->iCell = pTab->bPtr ? -2 : 0; pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]); + if( pCsr->nCell>DBDATA_MX_CELL(pCsr->nPage) ){ + pCsr->nCell = DBDATA_MX_CELL(pCsr->nPage); + } } if( pTab->bPtr ){ @@ -14792,7 +18245,8 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ } }else{ /* If there is no record loaded, load it now. */ - if( pCsr->pRec==0 ){ + assert( pCsr->rec.aBuf!=0 || pCsr->nRec==0 ); + if( pCsr->nRec==0 ){ int bHasRowid = 0; int nPointer = 0; sqlite3_int64 nPayload = 0; @@ -14819,22 +18273,24 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ if( pCsr->iCell>=pCsr->nCell ){ bNextPage = 1; }else{ + int iCellPtr = iOff + 8 + nPointer + pCsr->iCell*2; - iOff += 8 + nPointer + pCsr->iCell*2; - if( iOff>pCsr->nPage ){ + if( iCellPtr>pCsr->nPage ){ bNextPage = 1; }else{ - iOff = get_uint16(&pCsr->aPage[iOff]); + iOff = get_uint16(&pCsr->aPage[iCellPtr]); } /* For an interior node cell, skip past the child-page number */ iOff += nPointer; /* Load the "byte of payload including overflow" field */ - if( bNextPage || iOff>pCsr->nPage ){ + if( bNextPage || iOff>pCsr->nPage || iOff<=iCellPtr ){ bNextPage = 1; }else{ iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload); + if( nPayload>0x7fffff00 ) nPayload &= 0x3fff; + if( nPayload==0 ) nPayload = 1; } /* If this is a leaf intkey cell, load the rowid */ @@ -14869,13 +18325,13 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ /* Allocate space for payload. And a bit more to catch small buffer ** overruns caused by attempting to read a varint or similar from ** near the end of a corrupt record. */ - pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES); - if( pCsr->pRec==0 ) return SQLITE_NOMEM; - memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES); - pCsr->nRec = nPayload; + rc = dbdataBufferSize(&pCsr->rec, nPayload+DBDATA_PADDING_BYTES); + if( rc!=SQLITE_OK ) return rc; + assert( pCsr->rec.aBuf!=0 ); + assert( nPayload!=0 ); /* Load the nLocal bytes of payload */ - memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal); + memcpy(pCsr->rec.aBuf, &pCsr->aPage[iOff], nLocal); iOff += nLocal; /* Load content from overflow pages */ @@ -14893,19 +18349,22 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ nCopy = U-4; if( nCopy>nRem ) nCopy = nRem; - memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); + memcpy(&pCsr->rec.aBuf[nPayload-nRem], &aOvfl[4], nCopy); nRem -= nCopy; pgnoOvfl = get_uint32(aOvfl); sqlite3_free(aOvfl); } + nPayload -= nRem; } + memset(&pCsr->rec.aBuf[nPayload], 0, DBDATA_PADDING_BYTES); + pCsr->nRec = nPayload; - iHdr = dbdataGetVarintU32(pCsr->pRec, &nHdr); + iHdr = dbdataGetVarintU32(pCsr->rec.aBuf, &nHdr); if( nHdr>nPayload ) nHdr = 0; pCsr->nHdr = nHdr; - pCsr->pHdrPtr = &pCsr->pRec[iHdr]; - pCsr->pPtr = &pCsr->pRec[pCsr->nHdr]; + pCsr->pHdrPtr = &pCsr->rec.aBuf[iHdr]; + pCsr->pPtr = &pCsr->rec.aBuf[pCsr->nHdr]; pCsr->iField = (bHasRowid ? -1 : 0); } } @@ -14913,14 +18372,16 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ pCsr->iField++; if( pCsr->iField>0 ){ sqlite3_int64 iType; - if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){ + if( pCsr->pHdrPtr>=&pCsr->rec.aBuf[pCsr->nRec] + || pCsr->iField>=DBDATA_MX_FIELD + ){ bNextPage = 1; }else{ int szField = 0; pCsr->pHdrPtr += dbdataGetVarintU32(pCsr->pHdrPtr, &iType); szField = dbdataValueBytes(iType); - if( (pCsr->nRec - (pCsr->pPtr - pCsr->pRec))pPtr = &pCsr->pRec[pCsr->nRec]; + if( (pCsr->nRec - (pCsr->pPtr - pCsr->rec.aBuf))pPtr = &pCsr->rec.aBuf[pCsr->nRec]; }else{ pCsr->pPtr += szField; } @@ -14930,20 +18391,18 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ if( bNextPage ){ sqlite3_free(pCsr->aPage); - sqlite3_free(pCsr->pRec); pCsr->aPage = 0; - pCsr->pRec = 0; + pCsr->nRec = 0; if( pCsr->bOnePage ) return SQLITE_OK; pCsr->iPgno++; }else{ - if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){ + if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->rec.aBuf[pCsr->nHdr] ){ return SQLITE_OK; } /* Advance to the next cell. The next iteration of the loop will load ** the record and so on. */ - sqlite3_free(pCsr->pRec); - pCsr->pRec = 0; + pCsr->nRec = 0; pCsr->iCell++; } } @@ -15133,12 +18592,12 @@ static int dbdataColumn( case DBDATA_COLUMN_VALUE: { if( pCsr->iField<0 ){ sqlite3_result_int64(ctx, pCsr->iIntkey); - }else if( &pCsr->pRec[pCsr->nRec] >= pCsr->pPtr ){ + }else if( &pCsr->rec.aBuf[pCsr->nRec] >= pCsr->pPtr ){ sqlite3_int64 iType; dbdataGetVarintU32(pCsr->pHdrPtr, &iType); dbdataValue( ctx, pCsr->enc, iType, pCsr->pPtr, - &pCsr->pRec[pCsr->nRec] - pCsr->pPtr + &pCsr->rec.aBuf[pCsr->nRec] - pCsr->pPtr ); } break; @@ -15575,8 +19034,8 @@ static int recoverError( va_start(ap, zFmt); if( zFmt ){ z = sqlite3_vmprintf(zFmt, ap); - va_end(ap); } + va_end(ap); sqlite3_free(p->zErrMsg); p->zErrMsg = z; p->errCode = errCode; @@ -15956,7 +19415,7 @@ static const char *recoverUnusedString( } /* -** Implementation of scalar SQL function "escape_crnl". The argument passed to +** Implementation of scalar SQL function "escape_crlf". The argument passed to ** this function is the output of built-in function quote(). If the first ** character of the input is "'", indicating that the value passed to quote() ** was a text value, then this function searches the input for "\n" and "\r" @@ -15967,7 +19426,7 @@ static const char *recoverUnusedString( ** Or, if the first character of the input is not "'", then a copy of the input ** is returned. */ -static void recoverEscapeCrnl( +static void recoverEscapeCrlf( sqlite3_context *context, int argc, sqlite3_value **argv @@ -16182,7 +19641,7 @@ static int recoverOpenOutput(sqlite3_recover *p){ { "getpage", 1, recoverGetPage }, { "page_is_used", 1, recoverPageIsUsed }, { "read_i32", 2, recoverReadI32 }, - { "escape_crnl", 1, recoverEscapeCrnl }, + { "escape_crlf", 1, recoverEscapeCrlf }, }; const int flags = SQLITE_OPEN_URI|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE; @@ -16401,7 +19860,7 @@ static int recoverWriteSchema1(sqlite3_recover *p){ if( bTable && !bVirtual ){ if( SQLITE_ROW==sqlite3_step(pTblname) ){ const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0); - recoverAddTable(p, zTbl, iRoot); + if( zTbl ) recoverAddTable(p, zTbl, iRoot); } recoverReset(p, pTblname); } @@ -16535,7 +19994,7 @@ static sqlite3_stmt *recoverInsertStmt( if( bSql ){ zBind = recoverMPrintf(p, - "%z%sescape_crnl(quote(?%d))", zBind, zSqlSep, pTab->aCol[ii].iBind + "%z%sescape_crlf(quote(?%d))", zBind, zSqlSep, pTab->aCol[ii].iBind ); zSqlSep = "||', '||"; }else{ @@ -17037,6 +20496,8 @@ static int recoverWriteDataStep(sqlite3_recover *p){ recoverError(p, SQLITE_NOMEM, 0); } p1->nVal = iField+1; + }else if( pTab->nCol==0 ){ + p1->nVal = pTab->nCol; } p1->iPrevCell = iCell; p1->iPrevPage = iPage; @@ -18151,6 +21612,8 @@ struct ShellState { u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ u8 bSafeMode; /* True to prohibit unsafe operations */ u8 bSafeModePersist; /* The long-term value of bSafeMode */ + u8 eRestoreState; /* See comments above doAutoDetectRestore() */ + u8 crlfMode; /* Do NL-to-CRLF translations when enabled (maybe) */ ColModeOpts cmOpts; /* Option values affecting columnar mode output */ unsigned statsOn; /* True to display memory stats before each finalize */ unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */ @@ -18296,6 +21759,7 @@ static ShellState shellState; #define MODE_Count 17 /* Output only a count of the rows of output */ #define MODE_Off 18 /* No query output shown */ #define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */ +#define MODE_Www 20 /* Full web-page output */ static const char *modeDescr[] = { "line", @@ -18316,7 +21780,9 @@ static const char *modeDescr[] = { "table", "box", "count", - "off" + "off", + "scanexp", + "www", }; /* @@ -18344,7 +21810,7 @@ static const char *modeDescr[] = { static void shellLog(void *pArg, int iErrCode, const char *zMsg){ ShellState *p = (ShellState*)pArg; if( p->pLog==0 ) return; - sputf(p->pLog, "(%d) %s\n", iErrCode, zMsg); + sqlite3_fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); fflush(p->pLog); } @@ -18359,9 +21825,9 @@ static void shellPutsFunc( int nVal, sqlite3_value **apVal ){ - /* Unused: (ShellState*)sqlite3_user_data(pCtx); */ + ShellState *p = (ShellState*)sqlite3_user_data(pCtx); (void)nVal; - oputf("%s\n", sqlite3_value_text(apVal[0])); + sqlite3_fprintf(p->out, "%s\n", sqlite3_value_text(apVal[0])); sqlite3_result_value(pCtx, apVal[0]); } @@ -18380,7 +21846,7 @@ static void failIfSafeMode( va_start(ap, zErrMsg); zMsg = sqlite3_vmprintf(zErrMsg, ap); va_end(ap); - eputf("line %d: %s\n", p->lineno, zMsg); + sqlite3_fprintf(stderr, "line %d: %s\n", p->lineno, zMsg); exit(1); } } @@ -18413,7 +21879,7 @@ static void editFunc( char *zCmd = 0; int bBin; int rc; - int hasCRNL = 0; + int hasCRLF = 0; FILE *f = 0; sqlite3_int64 sz; sqlite3_int64 x; @@ -18447,7 +21913,7 @@ static void editFunc( bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; /* When writing the file to be edited, do \n to \r\n conversions on systems ** that want \r\n line endings */ - f = fopen(zTempFile, bBin ? "wb" : "w"); + f = sqlite3_fopen(zTempFile, bBin ? "wb" : "w"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot open temp file", -1); goto edit_func_end; @@ -18458,7 +21924,7 @@ static void editFunc( }else{ const char *z = (const char*)sqlite3_value_text(argv[0]); /* Remember whether or not the value originally contained \r\n */ - if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1; + if( z && strstr(z,"\r\n")!=0 ) hasCRLF = 1; x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f); } fclose(f); @@ -18478,7 +21944,7 @@ static void editFunc( sqlite3_result_error(context, "EDITOR returned non-zero", -1); goto edit_func_end; } - f = fopen(zTempFile, "rb"); + f = sqlite3_fopen(zTempFile, "rb"); if( f==0 ){ sqlite3_result_error(context, "edit() cannot reopen temp file after edit", -1); @@ -18503,7 +21969,7 @@ static void editFunc( sqlite3_result_blob64(context, p, sz, sqlite3_free); }else{ sqlite3_int64 i, j; - if( hasCRNL ){ + if( hasCRLF ){ /* If the original contains \r\n then do no conversions back to \n */ }else{ /* If the file did not originally contain \r\n then convert any new @@ -18545,10 +22011,25 @@ static void outputModePop(ShellState *p){ memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator)); } +/* +** Set output mode to text or binary for Windows. +*/ +static void setCrlfMode(ShellState *p){ +#ifdef _WIN32 + if( p->crlfMode ){ + sqlite3_fsetmode(p->out, _O_TEXT); + }else{ + sqlite3_fsetmode(p->out, _O_BINARY); + } +#else + UNUSED_PARAMETER(p); +#endif +} + /* ** Output the given string as a hex-encoded blob (eg. X'1234' ) */ -static void output_hex_blob(const void *pBlob, int nBlob){ +static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ int i; unsigned char *aBlob = (unsigned char*)pBlob; @@ -18565,7 +22046,7 @@ static void output_hex_blob(const void *pBlob, int nBlob){ } zStr[i*2] = '\0'; - oputf("X'%s'", zStr); + sqlite3_fprintf(out, "X'%s'", zStr); sqlite3_free(zStr); } @@ -18595,28 +22076,26 @@ static const char *unused_string( ** ** See also: output_quoted_escaped_string() */ -static void output_quoted_string(const char *z){ +static void output_quoted_string(ShellState *p, const char *z){ int i; char c; -#ifndef SQLITE_SHELL_FIDDLE - FILE *pfO = setOutputStream(invalidFileStream); - setBinaryMode(pfO, 1); -#endif + FILE *out = p->out; + sqlite3_fsetmode(out, _O_BINARY); if( z==0 ) return; for(i=0; (c = z[i])!=0 && c!='\''; i++){} if( c==0 ){ - oputf("'%s'",z); + sqlite3_fprintf(out, "'%s'",z); }else{ - oputz("'"); + sqlite3_fputs("'", out); while( *z ){ for(i=0; (c = z[i])!=0 && c!='\''; i++){} if( c=='\'' ) i++; if( i ){ - oputf("%.*s", i, z); + sqlite3_fprintf(out, "%.*s", i, z); z += i; } if( c=='\'' ){ - oputz("'"); + sqlite3_fputs("'", out); continue; } if( c==0 ){ @@ -18624,13 +22103,9 @@ static void output_quoted_string(const char *z){ } z++; } - oputz("'"); + sqlite3_fputs("'", out); } -#ifndef SQLITE_SHELL_FIDDLE - setTextMode(pfO, 1); -#else - setTextMode(stdout, 1); -#endif + setCrlfMode(p); } /* @@ -18642,16 +22117,14 @@ static void output_quoted_string(const char *z){ ** This is like output_quoted_string() but with the addition of the \r\n ** escape mechanism. */ -static void output_quoted_escaped_string(const char *z){ +static void output_quoted_escaped_string(ShellState *p, const char *z){ int i; char c; -#ifndef SQLITE_SHELL_FIDDLE - FILE *pfO = setOutputStream(invalidFileStream); - setBinaryMode(pfO, 1); -#endif + FILE *out = p->out; + sqlite3_fsetmode(out, _O_BINARY); for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} if( c==0 ){ - oputf("'%s'",z); + sqlite3_fprintf(out, "'%s'",z); }else{ const char *zNL = 0; const char *zCR = 0; @@ -18663,23 +22136,23 @@ static void output_quoted_escaped_string(const char *z){ if( z[i]=='\r' ) nCR++; } if( nNL ){ - oputz("replace("); + sqlite3_fputs("replace(", out); zNL = unused_string(z, "\\n", "\\012", zBuf1); } if( nCR ){ - oputz("replace("); + sqlite3_fputs("replace(", out); zCR = unused_string(z, "\\r", "\\015", zBuf2); } - oputz("'"); + sqlite3_fputs("'", out); while( *z ){ for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} if( c=='\'' ) i++; if( i ){ - oputf("%.*s", i, z); + sqlite3_fprintf(out, "%.*s", i, z); z += i; } if( c=='\'' ){ - oputz("'"); + sqlite3_fputs("'", out); continue; } if( c==0 ){ @@ -18687,24 +22160,20 @@ static void output_quoted_escaped_string(const char *z){ } z++; if( c=='\n' ){ - oputz(zNL); + sqlite3_fputs(zNL, out); continue; } - oputz(zCR); + sqlite3_fputs(zCR, out); } - oputz("'"); + sqlite3_fputs("'", out); if( nCR ){ - oputf(",'%s',char(13))", zCR); + sqlite3_fprintf(out, ",'%s',char(13))", zCR); } if( nNL ){ - oputf(",'%s',char(10))", zNL); + sqlite3_fprintf(out, ",'%s',char(10))", zNL); } } -#ifndef SQLITE_SHELL_FIDDLE - setTextMode(pfO, 1); -#else - setTextMode(stdout, 1); -#endif + setCrlfMode(p); } /* @@ -18724,22 +22193,60 @@ static const char *anyOfInStr(const char *s, const char *zAny, size_t ns){ } return pcFirst; } + +/* Skip over as much z[] input char sequence as is valid UTF-8, +** limited per nAccept char's or whole characters and containing +** no char cn such that ((1<=0 => char count, nAccept<0 => character + */ +const char *zSkipValidUtf8(const char *z, int nAccept, long ccm){ + int ng = (nAccept<0)? -nAccept : 0; + const char *pcLimit = (nAccept>=0)? z+nAccept : 0; + assert(z!=0); + while( (pcLimit)? (z= pcLimit ) return z; + else{ + char ct = *zt++; + if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){ + /* Trailing bytes are too few, too many, or invalid. */ + return z; + } + } + } while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */ + z = zt; + } + } + return z; +} + + /* ** Output the given string as a quoted according to C or TCL quoting rules. */ -static void output_c_string(const char *z){ +static void output_c_string(FILE *out, const char *z){ char c; static const char *zq = "\""; static long ctrlMask = ~0L; static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */ char ace[3] = "\\?"; char cbsSay; - oputz(zq); + sqlite3_fputs(zq, out); while( *z!=0 ){ const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0); const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask); const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast; - if( pcEnd > z ) oputb(z, (int)(pcEnd-z)); + if( pcEnd > z ){ + sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z); + } if( (c = *pcEnd)==0 ) break; ++pcEnd; switch( c ){ @@ -18754,23 +22261,23 @@ static void output_c_string(const char *z){ } if( cbsSay ){ ace[1] = cbsSay; - oputz(ace); + sqlite3_fputs(ace, out); }else if( !isprint(c&0xff) ){ - oputf("\\%03o", c&0xff); + sqlite3_fprintf(out, "\\%03o", c&0xff); }else{ ace[1] = (char)c; - oputz(ace+1); + sqlite3_fputs(ace+1, out); } z = pcEnd; } - oputz(zq); + sqlite3_fputs(zq, out); } /* -** Output the given string as a quoted according to JSON quoting rules. +** Output the given string as quoted according to JSON quoting rules. */ -static void output_json_string(const char *z, i64 n){ - char c; +static void output_json_string(FILE *out, const char *z, i64 n){ + unsigned char c; static const char *zq = "\""; static long ctrlMask = ~0L; static const char *zDQBS = "\"\\"; @@ -18780,17 +22287,17 @@ static void output_json_string(const char *z, i64 n){ if( z==0 ) z = ""; pcLimit = z + ((n<0)? strlen(z) : (size_t)n); - oputz(zq); + sqlite3_fputs(zq, out); while( z < pcLimit ){ const char *pcDQBS = anyOfInStr(z, zDQBS, pcLimit-z); const char *pcPast = zSkipValidUtf8(z, (int)(pcLimit-z), ctrlMask); const char *pcEnd = (pcDQBS && pcDQBS < pcPast)? pcDQBS : pcPast; if( pcEnd > z ){ - oputb(z, (int)(pcEnd-z)); + sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z); z = pcEnd; } if( z >= pcLimit ) break; - c = *(z++); + c = (unsigned char)*(z++); switch( c ){ case '"': case '\\': cbsSay = (char)c; @@ -18804,22 +22311,22 @@ static void output_json_string(const char *z, i64 n){ } if( cbsSay ){ ace[1] = cbsSay; - oputz(ace); - }else if( c<=0x1f ){ - oputf("u%04x", c); + sqlite3_fputs(ace, out); + }else if( c<=0x1f || c>=0x7f ){ + sqlite3_fprintf(out, "\\u%04x", c); }else{ ace[1] = (char)c; - oputz(ace+1); + sqlite3_fputs(ace+1, out); } } - oputz(zq); + sqlite3_fputs(zq, out); } /* ** Output the given string with characters that are special to ** HTML escaped. */ -static void output_html_string(const char *z){ +static void output_html_string(FILE *out, const char *z){ int i; if( z==0 ) z = ""; while( *z ){ @@ -18831,18 +22338,18 @@ static void output_html_string(const char *z){ && z[i]!='\''; i++){} if( i>0 ){ - oputf("%.*s",i,z); + sqlite3_fprintf(out, "%.*s",i,z); } if( z[i]=='<' ){ - oputz("<"); + sqlite3_fputs("<", out); }else if( z[i]=='&' ){ - oputz("&"); + sqlite3_fputs("&", out); }else if( z[i]=='>' ){ - oputz(">"); + sqlite3_fputs(">", out); }else if( z[i]=='\"' ){ - oputz("""); + sqlite3_fputs(""", out); }else if( z[i]=='\'' ){ - oputz("'"); + sqlite3_fputs("'", out); }else{ break; } @@ -18881,7 +22388,7 @@ static const char needCsvQuote[] = { */ static void output_csv(ShellState *p, const char *z, int bSep){ if( z==0 ){ - oputf("%s",p->nullValue); + sqlite3_fprintf(p->out, "%s",p->nullValue); }else{ unsigned i; for(i=0; z[i]; i++){ @@ -18893,14 +22400,14 @@ static void output_csv(ShellState *p, const char *z, int bSep){ if( i==0 || strstr(z, p->colSeparator)!=0 ){ char *zQuoted = sqlite3_mprintf("\"%w\"", z); shell_check_oom(zQuoted); - oputz(zQuoted); + sqlite3_fputs(zQuoted, p->out); sqlite3_free(zQuoted); }else{ - oputz(z); + sqlite3_fputs(z, p->out); } } if( bSep ){ - oputz(p->colSeparator); + sqlite3_fputs(p->colSeparator, p->out); } } @@ -19008,16 +22515,16 @@ static int shellAuth( az[1] = zA2; az[2] = zA3; az[3] = zA4; - oputf("authorizer: %s", azAction[op]); + sqlite3_fprintf(p->out, "authorizer: %s", azAction[op]); for(i=0; i<4; i++){ - oputz(" "); + sqlite3_fputs(" ", p->out); if( az[i] ){ - output_c_string(az[i]); + output_c_string(p->out, az[i]); }else{ - oputz("NULL"); + sqlite3_fputs("NULL", p->out); } } - oputz("\n"); + sqlite3_fputs("\n", p->out); if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4); return SQLITE_OK; } @@ -19033,7 +22540,7 @@ static int shellAuth( ** sqlite3_complete() returns false, try to terminate the comment before ** printing the result. https://sqlite.org/forum/forumpost/d7be961c5c */ -static void printSchemaLine(const char *z, const char *zTail){ +static void printSchemaLine(FILE *out, const char *z, const char *zTail){ char *zToFree = 0; if( z==0 ) return; if( zTail==0 ) return; @@ -19055,16 +22562,16 @@ static void printSchemaLine(const char *z, const char *zTail){ } } if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ - oputf("CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); + sqlite3_fprintf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); }else{ - oputf("%s%s", z, zTail); + sqlite3_fprintf(out, "%s%s", z, zTail); } sqlite3_free(zToFree); } -static void printSchemaLineN(char *z, int n, const char *zTail){ +static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ char c = z[n]; z[n] = 0; - printSchemaLine(z, zTail); + printSchemaLine(out, z, zTail); z[n] = c; } @@ -19092,7 +22599,7 @@ static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){ if( zText==0 ) return; nText = strlen(zText); if( p->autoEQPtest ){ - oputf("%d,%d,%s\n", iEqpId, p2, zText); + sqlite3_fprintf(p->out, "%d,%d,%s\n", iEqpId, p2, zText); } pNew = sqlite3_malloc64( sizeof(*pNew) + nText ); shell_check_oom(pNew); @@ -19140,7 +22647,8 @@ static void eqp_render_level(ShellState *p, int iEqpId){ for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ pNext = eqp_next_row(p, iEqpId, pRow); z = pRow->zText; - oputf("%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z); + sqlite3_fprintf(p->out, "%s%s%s\n", p->sGraph.zPrefix, + pNext ? "|--" : "`--", z); if( n<(i64)sizeof(p->sGraph.zPrefix)-7 ){ memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4); eqp_render_level(p, pRow->iEqpId); @@ -19160,13 +22668,13 @@ static void eqp_render(ShellState *p, i64 nCycle){ eqp_reset(p); return; } - oputf("%s\n", pRow->zText+3); + sqlite3_fprintf(p->out, "%s\n", pRow->zText+3); p->sGraph.pRow = pRow->pNext; sqlite3_free(pRow); }else if( nCycle>0 ){ - oputf("QUERY PLAN (cycles=%lld [100%%])\n", nCycle); + sqlite3_fprintf(p->out, "QUERY PLAN (cycles=%lld [100%%])\n", nCycle); }else{ - oputz("QUERY PLAN\n"); + sqlite3_fputs("QUERY PLAN\n", p->out); } p->sGraph.zPrefix[0] = 0; eqp_render_level(p, 0); @@ -19182,13 +22690,13 @@ static int progress_handler(void *pClientData) { ShellState *p = (ShellState*)pClientData; p->nProgress++; if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){ - oputf("Progress limit reached (%u)\n", p->nProgress); + sqlite3_fprintf(p->out, "Progress limit reached (%u)\n", p->nProgress); if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0; return 1; } if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){ - oputf("Progress %u\n", p->nProgress); + sqlite3_fprintf(p->out, "Progress %u\n", p->nProgress); } return 0; } @@ -19197,14 +22705,14 @@ static int progress_handler(void *pClientData) { /* ** Print N dashes */ -static void print_dashes(int N){ +static void print_dashes(FILE *out, int N){ const char zDash[] = "--------------------------------------------------"; const int nDash = sizeof(zDash) - 1; while( N>nDash ){ - oputz(zDash); + sqlite3_fputs(zDash, out); N -= nDash; } - oputf("%.*s", N, zDash); + sqlite3_fprintf(out, "%.*s", N, zDash); } /* @@ -19217,15 +22725,15 @@ static void print_row_separator( ){ int i; if( nArg>0 ){ - oputz(zSep); - print_dashes(p->actualWidth[0]+2); + sqlite3_fputs(zSep, p->out); + print_dashes(p->out, p->actualWidth[0]+2); for(i=1; iactualWidth[i]+2); + sqlite3_fputs(zSep, p->out); + print_dashes(p->out, p->actualWidth[i]+2); } - oputz(zSep); + sqlite3_fputs(zSep, p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); } /* @@ -19255,9 +22763,9 @@ static int shell_callback( int len = strlen30(azCol[i] ? azCol[i] : ""); if( len>w ) w = len; } - if( p->cnt++>0 ) oputz(p->rowSeparator); + if( p->cnt++>0 ) sqlite3_fputs(p->rowSeparator, p->out); for(i=0; iout, "%*s = %s%s", w, azCol[i], azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); } break; @@ -19266,7 +22774,7 @@ static int shell_callback( case MODE_Explain: { static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13}; static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 }; - static const int aScanExpWidth[] = {4, 6, 6, 13, 4, 4, 4, 13, 2, 13}; + static const int aScanExpWidth[] = {4, 15, 6, 13, 4, 4, 4, 13, 2, 13}; static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 }; const int *aWidth = aExplainWidth; @@ -19285,12 +22793,12 @@ static int shell_callback( /* If this is the first row seen, print out the headers */ if( p->cnt++==0 ){ for(i=0; iout, aWidth[i], azCol[ aMap[i] ]); + sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out); } for(i=0; iout, aWidth[i]); + sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out); } } @@ -19308,17 +22816,17 @@ static int shell_callback( } if( i==iIndent && p->aiIndent && p->pStmt ){ if( p->iIndentnIndent ){ - oputf("%*.s", p->aiIndent[p->iIndent], ""); + sqlite3_fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); } p->iIndent++; } - utf8_width_print(w, zVal ? zVal : p->nullValue); - oputz(i==nArg-1 ? "\n" : zSep); + utf8_width_print(p->out, w, zVal ? zVal : p->nullValue); + sqlite3_fputs(i==nArg-1 ? "\n" : zSep, p->out); } break; } case MODE_Semi: { /* .schema and .fullschema output */ - printSchemaLine(azArg[0], ";\n"); + printSchemaLine(p->out, azArg[0], ";\n"); break; } case MODE_Pretty: { /* .schema and .fullschema with --indent */ @@ -19333,7 +22841,7 @@ static int shell_callback( if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 ){ - oputf("%s;\n", azArg[0]); + sqlite3_fprintf(p->out, "%s;\n", azArg[0]); break; } z = sqlite3_mprintf("%s", azArg[0]); @@ -19366,7 +22874,7 @@ static int shell_callback( }else if( c==')' ){ nParen--; if( nLine>0 && nParen==0 && j>0 ){ - printSchemaLineN(z, j, "\n"); + printSchemaLineN(p->out, z, j, "\n"); j = 0; } } @@ -19375,7 +22883,7 @@ static int shell_callback( && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1))) ){ if( c=='\n' ) j--; - printSchemaLineN(z, j, "\n "); + printSchemaLineN(p->out, z, j, "\n "); j = 0; nLine++; while( IsSpace(z[i+1]) ){ i++; } @@ -19383,118 +22891,128 @@ static int shell_callback( } z[j] = 0; } - printSchemaLine(z, ";\n"); + printSchemaLine(p->out, z, ";\n"); sqlite3_free(z); break; } case MODE_List: { if( p->cnt++==0 && p->showHeader ){ for(i=0; irowSeparator : p->colSeparator); + sqlite3_fprintf(p->out, "%s%s", azCol[i], + i==nArg-1 ? p->rowSeparator : p->colSeparator); } } if( azArg==0 ) break; for(i=0; inullValue; - oputz(z); - oputz((icolSeparator : p->rowSeparator); + sqlite3_fputs(z, p->out); + sqlite3_fputs((icolSeparator : p->rowSeparator, p->out); } break; } + case MODE_Www: case MODE_Html: { - if( p->cnt++==0 && p->showHeader ){ - oputz(""); + if( p->cnt==0 && p->cMode==MODE_Www ){ + sqlite3_fputs( + "\n" + "\n" + ,p->out + ); + } + if( p->cnt==0 && (p->showHeader || p->cMode==MODE_Www) ){ + sqlite3_fputs("", p->out); for(i=0; i"); - output_html_string(azCol[i]); - oputz("\n"); + sqlite3_fputs("\n", p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); } + p->cnt++; if( azArg==0 ) break; - oputz(""); + sqlite3_fputs("", p->out); for(i=0; i"); - output_html_string(azArg[i] ? azArg[i] : p->nullValue); - oputz("\n"); + sqlite3_fputs("\n", p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); break; } case MODE_Tcl: { if( p->cnt++==0 && p->showHeader ){ for(i=0; icolSeparator); + output_c_string(p->out, azCol[i] ? azCol[i] : ""); + if(icolSeparator, p->out); } - oputz(p->rowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); } if( azArg==0 ) break; for(i=0; inullValue); - if(icolSeparator); + output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); + if(icolSeparator, p->out); } - oputz(p->rowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); break; } case MODE_Csv: { - setBinaryMode(p->out, 1); + sqlite3_fsetmode(p->out, _O_BINARY); if( p->cnt++==0 && p->showHeader ){ for(i=0; irowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); } if( nArg>0 ){ for(i=0; irowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); } - setTextMode(p->out, 1); + setCrlfMode(p); break; } case MODE_Insert: { if( azArg==0 ) break; - oputf("INSERT INTO %s",p->zDestTable); + sqlite3_fprintf(p->out, "INSERT INTO %s",p->zDestTable); if( p->showHeader ){ - oputz("("); + sqlite3_fputs("(", p->out); for(i=0; i0 ) oputz(","); + if( i>0 ) sqlite3_fputs(",", p->out); if( quoteChar(azCol[i]) ){ char *z = sqlite3_mprintf("\"%w\"", azCol[i]); shell_check_oom(z); - oputz(z); + sqlite3_fputs(z, p->out); sqlite3_free(z); }else{ - oputf("%s", azCol[i]); + sqlite3_fprintf(p->out, "%s", azCol[i]); } } - oputz(")"); + sqlite3_fputs(")", p->out); } p->cnt++; for(i=0; i0 ? "," : " VALUES("); + sqlite3_fputs(i>0 ? "," : " VALUES(", p->out); if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - oputz("NULL"); + sqlite3_fputs("NULL", p->out); }else if( aiType && aiType[i]==SQLITE_TEXT ){ if( ShellHasFlag(p, SHFLG_Newlines) ){ - output_quoted_string(azArg[i]); + output_quoted_string(p, azArg[i]); }else{ - output_quoted_escaped_string(azArg[i]); + output_quoted_escaped_string(p, azArg[i]); } }else if( aiType && aiType[i]==SQLITE_INTEGER ){ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); }else if( aiType && aiType[i]==SQLITE_FLOAT ){ char z[50]; double r = sqlite3_column_double(p->pStmt, i); sqlite3_uint64 ur; memcpy(&ur,&r,sizeof(r)); if( ur==0x7ff0000000000000LL ){ - oputz("9.0e+999"); + sqlite3_fputs("9.0e+999", p->out); }else if( ur==0xfff0000000000000LL ){ - oputz("-9.0e+999"); + sqlite3_fputs("-9.0e+999", p->out); }else{ sqlite3_int64 ir = (sqlite3_int64)r; if( r==(double)ir ){ @@ -19502,115 +23020,115 @@ static int shell_callback( }else{ sqlite3_snprintf(50,z,"%!.20g", r); } - oputz(z); + sqlite3_fputs(z, p->out); } }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); - output_hex_blob(pBlob, nBlob); + output_hex_blob(p->out, pBlob, nBlob); }else if( isNumber(azArg[i], 0) ){ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); }else if( ShellHasFlag(p, SHFLG_Newlines) ){ - output_quoted_string(azArg[i]); + output_quoted_string(p, azArg[i]); }else{ - output_quoted_escaped_string(azArg[i]); + output_quoted_escaped_string(p, azArg[i]); } } - oputz(");\n"); + sqlite3_fputs(");\n", p->out); break; } case MODE_Json: { if( azArg==0 ) break; if( p->cnt==0 ){ - fputs("[{", p->out); + sqlite3_fputs("[{", p->out); }else{ - fputs(",\n{", p->out); + sqlite3_fputs(",\n{", p->out); } p->cnt++; for(i=0; iout, azCol[i], -1); + sqlite3_fputs(":", p->out); if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - oputz("null"); + sqlite3_fputs("null", p->out); }else if( aiType && aiType[i]==SQLITE_FLOAT ){ char z[50]; double r = sqlite3_column_double(p->pStmt, i); sqlite3_uint64 ur; memcpy(&ur,&r,sizeof(r)); if( ur==0x7ff0000000000000LL ){ - oputz("9.0e+999"); + sqlite3_fputs("9.0e+999", p->out); }else if( ur==0xfff0000000000000LL ){ - oputz("-9.0e+999"); + sqlite3_fputs("-9.0e+999", p->out); }else{ sqlite3_snprintf(50,z,"%!.20g", r); - oputz(z); + sqlite3_fputs(z, p->out); } }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); - output_json_string(pBlob, nBlob); + output_json_string(p->out, pBlob, nBlob); }else if( aiType && aiType[i]==SQLITE_TEXT ){ - output_json_string(azArg[i], -1); + output_json_string(p->out, azArg[i], -1); }else{ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); } if( iout); } } - oputz("}"); + sqlite3_fputs("}", p->out); break; } case MODE_Quote: { if( azArg==0 ) break; if( p->cnt==0 && p->showHeader ){ for(i=0; i0 ) fputs(p->colSeparator, p->out); - output_quoted_string(azCol[i]); + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); + output_quoted_string(p, azCol[i]); } - fputs(p->rowSeparator, p->out); + sqlite3_fputs(p->rowSeparator, p->out); } p->cnt++; for(i=0; i0 ) fputs(p->colSeparator, p->out); + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - oputz("NULL"); + sqlite3_fputs("NULL", p->out); }else if( aiType && aiType[i]==SQLITE_TEXT ){ - output_quoted_string(azArg[i]); + output_quoted_string(p, azArg[i]); }else if( aiType && aiType[i]==SQLITE_INTEGER ){ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); }else if( aiType && aiType[i]==SQLITE_FLOAT ){ char z[50]; double r = sqlite3_column_double(p->pStmt, i); sqlite3_snprintf(50,z,"%!.20g", r); - oputz(z); + sqlite3_fputs(z, p->out); }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); - output_hex_blob(pBlob, nBlob); + output_hex_blob(p->out, pBlob, nBlob); }else if( isNumber(azArg[i], 0) ){ - oputz(azArg[i]); + sqlite3_fputs(azArg[i], p->out); }else{ - output_quoted_string(azArg[i]); + output_quoted_string(p, azArg[i]); } } - fputs(p->rowSeparator, p->out); + sqlite3_fputs(p->rowSeparator, p->out); break; } case MODE_Ascii: { if( p->cnt++==0 && p->showHeader ){ for(i=0; i0 ) oputz(p->colSeparator); - oputz(azCol[i] ? azCol[i] : ""); + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); + sqlite3_fputs(azCol[i] ? azCol[i] : "", p->out); } - oputz(p->rowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); } if( azArg==0 ) break; for(i=0; i0 ) oputz(p->colSeparator); - oputz(azArg[i] ? azArg[i] : p->nullValue); + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); + sqlite3_fputs(azArg[i] ? azArg[i] : p->nullValue, p->out); } - oputz(p->rowSeparator); + sqlite3_fputs(p->rowSeparator, p->out); break; } case MODE_EQP: { @@ -19689,7 +23207,7 @@ static void createSelftestTable(ShellState *p){ "DROP TABLE [_shell$self];" ,0,0,&zErrMsg); if( zErrMsg ){ - eputf("SELFTEST initialization failure: %s\n", zErrMsg); + sqlite3_fprintf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg); sqlite3_free(zErrMsg); } sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0); @@ -19792,7 +23310,7 @@ static int run_table_dump_query( rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); if( rc!=SQLITE_OK || !pSelect ){ char *zContext = shell_error_context(zSelect, p->db); - oputf("/**** ERROR: (%d) %s *****/\n%s", + sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n%s", rc, sqlite3_errmsg(p->db), zContext); sqlite3_free(zContext); if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; @@ -19802,22 +23320,23 @@ static int run_table_dump_query( nResult = sqlite3_column_count(pSelect); while( rc==SQLITE_ROW ){ z = (const char*)sqlite3_column_text(pSelect, 0); - oputf("%s", z); + sqlite3_fprintf(p->out, "%s", z); for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); } if( z==0 ) z = ""; while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; if( z[0] ){ - oputz("\n;\n"); + sqlite3_fputs("\n;\n", p->out); }else{ - oputz(";\n"); + sqlite3_fputs(";\n", p->out); } rc = sqlite3_step(pSelect); } rc = sqlite3_finalize(pSelect); if( rc!=SQLITE_OK ){ - oputf("/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); + sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", + rc, sqlite3_errmsg(p->db)); if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; } return rc; @@ -19853,13 +23372,13 @@ static char *save_err_msg( /* ** Attempt to display I/O stats on Linux using /proc/PID/io */ -static void displayLinuxIoStats(void){ +static void displayLinuxIoStats(FILE *out){ FILE *in; char z[200]; sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); - in = fopen(z, "rb"); + in = sqlite3_fopen(z, "rb"); if( in==0 ) return; - while( fgets(z, sizeof(z), in)!=0 ){ + while( sqlite3_fgets(z, sizeof(z), in)!=0 ){ static const struct { const char *zPattern; const char *zDesc; @@ -19876,7 +23395,7 @@ static void displayLinuxIoStats(void){ for(i=0; iout==0 ) return 0; + out = pArg->out; if( pArg->pStmt && pArg->statsOn==2 ){ int nCol, i, x; sqlite3_stmt *pStmt = pArg->pStmt; char z[100]; nCol = sqlite3_column_count(pStmt); - oputf("%-36s %d\n", "Number of output columns:", nCol); + sqlite3_fprintf(out, "%-36s %d\n", "Number of output columns:", nCol); for(i=0; istatsOn==3 ){ if( pArg->pStmt ){ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset); - oputf("VM-steps: %d\n", iCur); + sqlite3_fprintf(out, "VM-steps: %d\n", iCur); } return 0; } - displayStatLine("Memory Used:", + displayStatLine(out, "Memory Used:", "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); - displayStatLine("Number of Outstanding Allocations:", + displayStatLine(out, "Number of Outstanding Allocations:", "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); if( pArg->shellFlgs & SHFLG_Pagecache ){ - displayStatLine("Number of Pcache Pages Used:", + displayStatLine(out, "Number of Pcache Pages Used:", "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); } - displayStatLine("Number of Pcache Overflow Bytes:", + displayStatLine(out, "Number of Pcache Overflow Bytes:", "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); - displayStatLine("Largest Allocation:", + displayStatLine(out, "Largest Allocation:", "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); - displayStatLine("Largest Pcache Allocation:", + displayStatLine(out, "Largest Pcache Allocation:", "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); #ifdef YYTRACKMAXSTACKDEPTH - displayStatLine("Deepest Parser Stack:", + displayStatLine(out, "Deepest Parser Stack:", "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); #endif @@ -19978,68 +23501,87 @@ static int display_stats( iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset); - oputf("Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); + sqlite3_fprintf(out, + "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset); - oputf("Successful lookaside attempts: %d\n", iHiwtr); + sqlite3_fprintf(out, + "Successful lookaside attempts: %d\n", iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset); - oputf("Lookaside failures due to size: %d\n", iHiwtr); + sqlite3_fprintf(out, + "Lookaside failures due to size: %d\n", iHiwtr); sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset); - oputf("Lookaside failures due to OOM: %d\n", iHiwtr); + sqlite3_fprintf(out, + "Lookaside failures due to OOM: %d\n", iHiwtr); } iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); - oputf("Pager Heap Usage: %d bytes\n", iCur); + sqlite3_fprintf(out, + "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); - oputf("Page cache hits: %d\n", iCur); + sqlite3_fprintf(out, + "Page cache hits: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); - oputf("Page cache misses: %d\n", iCur); + sqlite3_fprintf(out, + "Page cache misses: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - oputf("Page cache writes: %d\n", iCur); + sqlite3_fprintf(out, + "Page cache writes: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); - oputf("Page cache spills: %d\n", iCur); + sqlite3_fprintf(out, + "Page cache spills: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); - oputf("Schema Heap Usage: %d bytes\n", iCur); + sqlite3_fprintf(out, + "Schema Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); - oputf("Statement Heap/Lookaside Usage: %d bytes\n", iCur); + sqlite3_fprintf(out, + "Statement Heap/Lookaside Usage: %d bytes\n", iCur); } if( pArg->pStmt ){ int iHit, iMiss; iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset); - oputf("Fullscan Steps: %d\n", iCur); + sqlite3_fprintf(out, + "Fullscan Steps: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); - oputf("Sort Operations: %d\n", iCur); + sqlite3_fprintf(out, + "Sort Operations: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); - oputf("Autoindex Inserts: %d\n", iCur); + sqlite3_fprintf(out, + "Autoindex Inserts: %d\n", iCur); iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, bReset); iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, bReset); if( iHit || iMiss ){ - oputf("Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss); + sqlite3_fprintf(out, + "Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss); } iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); - oputf("Virtual Machine Steps: %d\n", iCur); + sqlite3_fprintf(out, + "Virtual Machine Steps: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset); - oputf("Reprepare operations: %d\n", iCur); + sqlite3_fprintf(out, + "Reprepare operations: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); - oputf("Number of times run: %d\n", iCur); + sqlite3_fprintf(out, + "Number of times run: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset); - oputf("Memory used by prepared stmt: %d\n", iCur); + sqlite3_fprintf(out, + "Memory used by prepared stmt: %d\n", iCur); } #ifdef __linux__ - displayLinuxIoStats(); + displayLinuxIoStats(pArg->out); #endif /* Do not remove this machine readable comment: extra-stats-output-here */ @@ -20276,7 +23818,13 @@ static void display_scanstats( if( pArg->scanstatsOn==3 ){ const char *zSql = " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec," - " round(ncycle*100.0 / (sum(ncycle) OVER ()), 2)||'%' AS cycles" + " format('% 6s (%.2f%%)'," + " CASE WHEN ncycle<100_000 THEN ncycle || ' '" + " WHEN ncycle<100_000_000 THEN (ncycle/1_000) || 'K'" + " WHEN ncycle<100_000_000_000 THEN (ncycle/1_000_000) || 'M'" + " ELSE (ncycle/1000_000_000) || 'G' END," + " ncycle*100.0/(sum(ncycle) OVER ())" + " ) AS cycles" " FROM bytecode(?)"; int rc = SQLITE_OK; @@ -20384,6 +23932,15 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){ }else if( sqlite3_strlike("_INF", zVar, 0)==0 ){ sqlite3_bind_double(pStmt, i, INFINITY); #endif + }else if( strncmp(zVar, "$int_", 5)==0 ){ + sqlite3_bind_int(pStmt, i, atoi(&zVar[5])); + }else if( strncmp(zVar, "$text_", 6)==0 ){ + size_t szVar = strlen(zVar); + char *zBuf = sqlite3_malloc64( szVar-5 ); + if( zBuf ){ + memcpy(zBuf, &zVar[6], szVar-5); + sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8); + } }else{ sqlite3_bind_null(pStmt, i); } @@ -20420,17 +23977,17 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){ /* Draw horizontal line N characters long using unicode box ** characters */ -static void print_box_line(int N){ +static void print_box_line(FILE *out, int N){ const char zDash[] = BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24; const int nDash = sizeof(zDash) - 1; N *= 3; while( N>nDash ){ - oputz(zDash); + sqlite3_fputs(zDash, out); N -= nDash; } - oputf("%.*s", N, zDash); + sqlite3_fprintf(out, "%.*s", N, zDash); } /* @@ -20445,15 +24002,15 @@ static void print_box_row_separator( ){ int i; if( nArg>0 ){ - oputz(zSep1); - print_box_line(p->actualWidth[0]+2); + sqlite3_fputs(zSep1, p->out); + print_box_line(p->out, p->actualWidth[0]+2); for(i=1; iactualWidth[i]+2); + sqlite3_fputs(zSep2, p->out); + print_box_line(p->out, p->actualWidth[i]+2); } - oputz(zSep3); + sqlite3_fputs(zSep3, p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); } /* @@ -20487,12 +24044,22 @@ static char *translateForDisplayAndDup( if( mxWidth==0 ) mxWidth = 1000000; i = j = n = 0; while( n=' ' ){ + unsigned char c = z[i]; + if( c>=0xc0 ){ + int u; + int len = decodeUtf8(&z[i], &u); + i += len; + j += len; + n += cli_wcwidth(u); + continue; + } + if( c>=' ' ){ n++; - do{ i++; j++; }while( (z[i]&0xc0)==0x80 ); + i++; + j++; continue; } - if( z[i]=='\t' ){ + if( c=='\t' ){ do{ n++; j++; @@ -20534,9 +24101,17 @@ static char *translateForDisplayAndDup( shell_check_oom(zOut); i = j = n = 0; while( i=' ' ){ + unsigned char c = z[i]; + if( c>=0xc0 ){ + int u; + int len = decodeUtf8(&z[i], &u); + do{ zOut[j++] = z[i++]; }while( (--len)>0 ); + n += cli_wcwidth(u); + continue; + } + if( c>=' ' ){ n++; - do{ zOut[j++] = z[i++]; }while( (z[i]&0xc0)==0x80 ); + zOut[j++] = z[i++]; continue; } if( z[i]=='\t' ){ @@ -20622,6 +24197,7 @@ static void exec_prepared_stmt_columnar( rc = sqlite3_step(pStmt); if( rc!=SQLITE_ROW ) return; nColumn = sqlite3_column_count(pStmt); + if( nColumn==0 ) goto columnar_end; nAlloc = nColumn*4; if( nAlloc<=0 ) nAlloc = 1; azData = sqlite3_malloc64( nAlloc*sizeof(char*) ); @@ -20707,7 +24283,6 @@ static void exec_prepared_stmt_columnar( if( n>p->actualWidth[j] ) p->actualWidth[j] = n; } if( seenInterrupt ) goto columnar_end; - if( nColumn==0 ) goto columnar_end; switch( p->cMode ){ case MODE_Column: { colSep = " "; @@ -20716,12 +24291,12 @@ static void exec_prepared_stmt_columnar( for(i=0; iactualWidth[i]; if( p->colWidth[i]<0 ) w = -w; - utf8_width_print(w, azData[i]); - fputs(i==nColumn-1?"\n":" ", p->out); + utf8_width_print(p->out, w, azData[i]); + sqlite3_fputs(i==nColumn-1?"\n":" ", p->out); } for(i=0; iactualWidth[i]); - fputs(i==nColumn-1?"\n":" ", p->out); + print_dashes(p->out, p->actualWidth[i]); + sqlite3_fputs(i==nColumn-1?"\n":" ", p->out); } } break; @@ -20730,12 +24305,13 @@ static void exec_prepared_stmt_columnar( colSep = " | "; rowSep = " |\n"; print_row_separator(p, nColumn, "+"); - fputs("| ", p->out); + sqlite3_fputs("| ", p->out); for(i=0; iactualWidth[i]; n = strlenChar(azData[i]); - oputf("%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, ""); - oputz(i==nColumn-1?" |\n":" | "); + sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "", + azData[i], (w-n+1)/2, ""); + sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out); } print_row_separator(p, nColumn, "+"); break; @@ -20743,12 +24319,13 @@ static void exec_prepared_stmt_columnar( case MODE_Markdown: { colSep = " | "; rowSep = " |\n"; - fputs("| ", p->out); + sqlite3_fputs("| ", p->out); for(i=0; iactualWidth[i]; n = strlenChar(azData[i]); - oputf("%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, ""); - oputz(i==nColumn-1?" |\n":" | "); + sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "", + azData[i], (w-n+1)/2, ""); + sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out); } print_row_separator(p, nColumn, "|"); break; @@ -20757,11 +24334,11 @@ static void exec_prepared_stmt_columnar( colSep = " " BOX_13 " "; rowSep = " " BOX_13 "\n"; print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34); - oputz(BOX_13 " "); + sqlite3_fputs(BOX_13 " ", p->out); for(i=0; iactualWidth[i]; n = strlenChar(azData[i]); - oputf("%*s%s%*s%s", + sqlite3_fprintf(p->out, "%*s%s%*s%s", (w-n)/2, "", azData[i], (w-n+1)/2, "", i==nColumn-1?" "BOX_13"\n":" "BOX_13" "); } @@ -20771,28 +24348,28 @@ static void exec_prepared_stmt_columnar( } for(i=nColumn, j=0; icMode!=MODE_Column ){ - oputz(p->cMode==MODE_Box?BOX_13" ":"| "); + sqlite3_fputs(p->cMode==MODE_Box?BOX_13" ":"| ", p->out); } z = azData[i]; if( z==0 ) z = p->nullValue; w = p->actualWidth[j]; if( p->colWidth[j]<0 ) w = -w; - utf8_width_print(w, z); + utf8_width_print(p->out, w, z); if( j==nColumn-1 ){ - oputz(rowSep); + sqlite3_fputs(rowSep, p->out); if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1cMode==MODE_Table ){ print_row_separator(p, nColumn, "+"); }else if( p->cMode==MODE_Box ){ print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134); }else if( p->cMode==MODE_Column ){ - oputz("\n"); + sqlite3_fputs("\n", p->out); } } j = -1; if( seenInterrupt ) goto columnar_end; }else{ - oputz(colSep); + sqlite3_fputs(colSep, p->out); } } if( p->cMode==MODE_Table ){ @@ -20802,7 +24379,7 @@ static void exec_prepared_stmt_columnar( } columnar_end: if( seenInterrupt ){ - oputz("Interrupt\n"); + sqlite3_fputs("Interrupt\n", p->out); } nData = (nRow+1)*nColumn; for(i=0; icMode==MODE_Json ){ - fputs("]\n", pArg->out); + sqlite3_fputs("]\n", pArg->out); + }else if( pArg->cMode==MODE_Www ){ + sqlite3_fputs("
            ", p->out); + output_html_string(p->out, azCol[i]); + sqlite3_fputs("
            ", p->out); + output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); + sqlite3_fputs("
            \n
            \n", pArg->out);
                   }else if( pArg->cMode==MODE_Count ){
                     char zBuf[200];
                     sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n",
            @@ -20938,6 +24517,7 @@ static int expertFinish(
             ){
               int rc = SQLITE_OK;
               sqlite3expert *p = pState->expert.pExpert;
            +  FILE *out = pState->out;
               assert( p );
               assert( bCancel || pzErr==0 || *pzErr==0 );
               if( bCancel==0 ){
            @@ -20950,8 +24530,8 @@ static int expertFinish(
             
                   if( bVerbose ){
                     const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
            -        oputz("-- Candidates -----------------------------\n");
            -        oputf("%s\n", zCand);
            +        sqlite3_fputs("-- Candidates -----------------------------\n", out);
            +        sqlite3_fprintf(out, "%s\n", zCand);
                   }
                   for(i=0; i=2 && 0==cli_strncmp(z, "-sample", n) ){
                   if( i==(nArg-1) ){
            -        eputf("option requires an argument: %s\n", z);
            +        sqlite3_fprintf(stderr, "option requires an argument: %s\n", z);
                     rc = SQLITE_ERROR;
                   }else{
                     iSample = (int)integerValue(azArg[++i]);
                     if( iSample<0 || iSample>100 ){
            -          eputf("value out of range: %s\n", azArg[i]);
            +          sqlite3_fprintf(stderr,"value out of range: %s\n", azArg[i]);
                       rc = SQLITE_ERROR;
                     }
                   }
                 }
                 else{
            -      eputf("unknown option: %s\n", z);
            +      sqlite3_fprintf(stderr,"unknown option: %s\n", z);
                   rc = SQLITE_ERROR;
                 }
               }
            @@ -21017,7 +24598,8 @@ static int expertDotCommand(
               if( rc==SQLITE_OK ){
                 pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
                 if( pState->expert.pExpert==0 ){
            -      eputf("sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory");
            +      sqlite3_fprintf(stderr,
            +          "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory");
                   rc = SQLITE_ERROR;
                 }else{
                   sqlite3_expert_config(
            @@ -21099,6 +24681,7 @@ static int shell_exec(
                     sqlite3_reset(pExplain);
                     rc = sqlite3_stmt_explain(pExplain, 2);
                     if( rc==SQLITE_OK ){
            +          bind_prepared_stmt(pArg, pExplain);
                       while( sqlite3_step(pExplain)==SQLITE_ROW ){
                         const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
                         int iEqpId = sqlite3_column_int(pExplain, 0);
            @@ -21116,6 +24699,7 @@ static int shell_exec(
                       if( rc==SQLITE_OK ){
                         pArg->cMode = MODE_Explain;
                         assert( sqlite3_stmt_isexplain(pExplain)==1 );
            +            bind_prepared_stmt(pArg, pExplain);
                         explain_data_prepare(pArg, pExplain);
                         exec_prepared_stmt(pArg, pExplain);
                         explain_data_delete(pArg);
            @@ -21344,9 +24928,9 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
               noSys    = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
             
               if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
            -    if( !dataOnly ) oputz("DELETE FROM sqlite_sequence;\n");
            +    /* no-op */
               }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
            -    if( !dataOnly ) oputz("ANALYZE sqlite_schema;\n");
            +    if( !dataOnly ) sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out);
               }else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){
                 return 0;
               }else if( dataOnly ){
            @@ -21354,7 +24938,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
               }else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
                 char *zIns;
                 if( !p->writableSchema ){
            -      oputz("PRAGMA writable_schema=ON;\n");
            +      sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out);
                   p->writableSchema = 1;
                 }
                 zIns = sqlite3_mprintf(
            @@ -21362,11 +24946,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
                    "VALUES('table','%q','%q',0,'%q');",
                    zTable, zTable, zSql);
                 shell_check_oom(zIns);
            -    oputf("%s\n", zIns);
            +    sqlite3_fprintf(p->out, "%s\n", zIns);
                 sqlite3_free(zIns);
                 return 0;
               }else{
            -    printSchemaLine(zSql, ";\n");
            +    printSchemaLine(p->out, zSql, ";\n");
               }
             
               if( cli_strcmp(zType, "table")==0 ){
            @@ -21424,7 +25008,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
                 p->mode = p->cMode = MODE_Insert;
                 rc = shell_exec(p, sSelect.z, 0);
                 if( (rc&0xff)==SQLITE_CORRUPT ){
            -      oputz("/****** CORRUPTION ERROR *******/\n");
            +      sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
                   toggleSelectOrder(p->db);
                   shell_exec(p, sSelect.z, 0);
                   toggleSelectOrder(p->db);
            @@ -21455,9 +25039,9 @@ static int run_schema_dump_query(
               if( rc==SQLITE_CORRUPT ){
                 char *zQ2;
                 int len = strlen30(zQuery);
            -    oputz("/****** CORRUPTION ERROR *******/\n");
            +    sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
                 if( zErr ){
            -      oputf("/****** %s ******/\n", zErr);
            +      sqlite3_fprintf(p->out, "/****** %s ******/\n", zErr);
                   sqlite3_free(zErr);
                   zErr = 0;
                 }
            @@ -21466,13 +25050,13 @@ static int run_schema_dump_query(
                 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
                 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
                 if( rc ){
            -      oputf("/****** ERROR: %s ******/\n", zErr);
            +      sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
                 }else{
                   rc = SQLITE_CORRUPT;
                 }
            -    sqlite3_free(zErr);
                 free(zQ2);
               }
            +  sqlite3_free(zErr);
               return rc;
             }
             
            @@ -21529,14 +25113,13 @@ static const char *(azHelp[]) = {
               ".clone NEWDB             Clone data into NEWDB from the existing database",
             #endif
               ".connection [close] [#]  Open or close an auxiliary database connection",
            -#if defined(_WIN32) || defined(WIN32)
            -  ".crnl on|off             Translate \\n to \\r\\n.  Default ON",
            -#endif
            +  ".crlf ?on|off?           Whether or not to use \\r\\n line endings",
               ".databases               List names and files of attached databases",
               ".dbconfig ?op? ?val?     List or change sqlite3_db_config() options",
             #if SQLITE_SHELL_HAVE_RECOVER
               ".dbinfo ?DB?             Show status information about the database",
             #endif
            +  ".dbtotxt                 Hex dump of the database file",
               ".dump ?OBJECTS?          Render database content as SQL",
               "   Options:",
               "     --data-only            Output only INSERT statements",
            @@ -21590,6 +25173,7 @@ static const char *(azHelp[]) = {
               ".indexes ?TABLE?         Show names of indexes",
               "                           If TABLE is specified, only show indexes for",
               "                           tables matching TABLE using the LIKE operator.",
            +  ".intck ?STEPS_PER_UNLOCK?  Run an incremental integrity check on the db",
             #ifdef SQLITE_ENABLE_IOTRACE
               ",iotrace FILE            Enable I/O diagnostic logging to FILE",
             #endif
            @@ -21636,9 +25220,11 @@ static const char *(azHelp[]) = {
             #ifndef SQLITE_SHELL_FIDDLE
               ".once ?OPTIONS? ?FILE?   Output for the next SQL command only to FILE",
               "     If FILE begins with '|' then open as a pipe",
            -  "       --bom  Put a UTF8 byte-order mark at the beginning",
            -  "       -e     Send output to the system text editor",
            -  "       -x     Send output as CSV to a spreadsheet (same as \".excel\")",
            +  "       --bom    Put a UTF8 byte-order mark at the beginning",
            +  "       -e       Send output to the system text editor",
            +  "       --plain  Use text/plain output instead of HTML for -w option",
            +  "       -w       Send output as HTML to a web browser (same as \".www\")",
            +  "       -x       Send output as CSV to a spreadsheet (same as \".excel\")",
               /* Note that .open is (partially) available in WASM builds but is
               ** currently only intended to be used by the fiddle tool, not
               ** end users, so is "undocumented." */
            @@ -21661,6 +25247,8 @@ static const char *(azHelp[]) = {
               "   Options:",
               "     --bom                 Prefix output with a UTF8 byte-order mark",
               "     -e                    Send output to the system text editor",
            +  "     --plain               Use text/plain for -w option",
            +  "     -w                    Send output to a web browser",
               "     -x                    Send output as CSV to a spreadsheet",
             #endif
               ".parameter CMD ...       Manage SQL parameter bindings",
            @@ -21774,6 +25362,10 @@ static const char *(azHelp[]) = {
               ".vfsname ?AUX?           Print the name of the VFS stack",
               ".width NUM1 NUM2 ...     Set minimum column widths for columnar output",
               "     Negative values right-justify",
            +#ifndef SQLITE_SHELL_FIDDLE
            +  ".www                     Display output of the next command in web browser",
            +  "    --plain                 Show results as text/plain, not as HTML",
            +#endif
             };
             
             /*
            @@ -21822,10 +25414,10 @@ static int showHelp(FILE *out, const char *zPattern){
                   }
                   if( ((hw^hh)&HH_Undoc)==0 ){
                     if( (hh&HH_Summary)!=0 ){
            -          sputf(out, ".%s\n", azHelp[i]+1);
            +          sqlite3_fprintf(out, ".%s\n", azHelp[i]+1);
                       ++n;
                     }else if( (hw&HW_SummaryOnly)==0 ){
            -          sputf(out, "%s\n", azHelp[i]);
            +          sqlite3_fprintf(out, "%s\n", azHelp[i]);
                     }
                   }
                 }
            @@ -21835,7 +25427,7 @@ static int showHelp(FILE *out, const char *zPattern){
                 shell_check_oom(zPat);
                 for(i=0; i65536 || (pgsz & (pgsz-1))!=0 ){
            -    eputz("invalid pagesize\n");
            +    sqlite3_fputs("invalid pagesize\n", stderr);
                 goto readHexDb_error;
               }
            -  for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){
            +  for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
                 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
                 if( rc==2 ){
                   iOffset = k;
            @@ -22097,14 +25689,14 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){
               if( in!=p->in ){
                 fclose(in);
               }else{
            -    while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
            +    while( sqlite3_fgets(zLine, sizeof(zLine), p->in)!=0 ){
                   nLine++;
                   if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
                 }
                 p->lineno = nLine;
               }
               sqlite3_free(a);
            -  eputf("Error on line %d of --hexdb input\n", nLine);
            +  sqlite3_fprintf(stderr,"Error on line %d of --hexdb input\n", nLine);
               return 0;
             }
             #endif /* SQLITE_OMIT_DESERIALIZE */
            @@ -22178,9 +25770,8 @@ static void open_db(ShellState *p, int openFlags){
                     break;
                   }
                 }
            -    globalDb = p->db;
                 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
            -      eputf("Error: unable to open database \"%s\": %s\n",
            +      sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
                         zDbFilename, sqlite3_errmsg(p->db));
                   if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
                     exit(1);
            @@ -22188,13 +25779,16 @@ static void open_db(ShellState *p, int openFlags){
                   sqlite3_close(p->db);
                   sqlite3_open(":memory:", &p->db);
                   if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
            -        eputz("Also: unable to open substitute in-memory database.\n");
            +        sqlite3_fputs("Also: unable to open substitute in-memory database.\n",
            +                      stderr);
                     exit(1);
                   }else{
            -        eputf("Notice: using substitute in-memory database instead of \"%s\"\n",
            +        sqlite3_fprintf(stderr,
            +              "Notice: using substitute in-memory database instead of \"%s\"\n",
                           zDbFilename);
                   }
                 }
            +    globalDb = p->db;
                 sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0);
             
                 /* Reflect the use or absence of --unsafe-testing invocation. */
            @@ -22207,9 +25801,12 @@ static void open_db(ShellState *p, int openFlags){
             #ifndef SQLITE_OMIT_LOAD_EXTENSION
                 sqlite3_enable_load_extension(p->db, 1);
             #endif
            +    sqlite3_sha_init(p->db, 0, 0);
                 sqlite3_shathree_init(p->db, 0, 0);
                 sqlite3_uint_init(p->db, 0, 0);
            +    sqlite3_stmtrand_init(p->db, 0, 0);
                 sqlite3_decimal_init(p->db, 0, 0);
            +    sqlite3_percentile_init(p->db, 0, 0);
                 sqlite3_base64_init(p->db, 0, 0);
                 sqlite3_base85_init(p->db, 0, 0);
                 sqlite3_regexp_init(p->db, 0, 0);
            @@ -22299,7 +25896,7 @@ static void open_db(ShellState *p, int openFlags){
                                SQLITE_DESERIALIZE_RESIZEABLE |
                                SQLITE_DESERIALIZE_FREEONCLOSE);
                   if( rc ){
            -        eputf("Error: sqlite3_deserialize() returns %d\n", rc);
            +        sqlite3_fprintf(stderr,"Error: sqlite3_deserialize() returns %d\n", rc);
                   }
                   if( p->szMax>0 ){
                     sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
            @@ -22323,11 +25920,13 @@ static void open_db(ShellState *p, int openFlags){
             void close_db(sqlite3 *db){
               int rc = sqlite3_close(db);
               if( rc ){
            -    eputf("Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db));
            +    sqlite3_fprintf(stderr,
            +        "Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db));
               }
             }
             
            -#if HAVE_READLINE || HAVE_EDITLINE
            +#if (HAVE_READLINE || HAVE_EDITLINE) \
            +  && !defined(SQLITE_OMIT_READLINE_COMPLETION)
             /*
             ** Readline completion callbacks
             */
            @@ -22362,15 +25961,25 @@ static char **readline_completion(const char *zText, int iStart, int iEnd){
             
             #elif HAVE_LINENOISE
             /*
            -** Linenoise completion callback
            +** Linenoise completion callback. Note that the 3rd argument is from
            +** the "msteveb" version of linenoise, not the "antirez" version.
             */
            -static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
            +static void linenoise_completion(
            +  const char *zLine,
            +  linenoiseCompletions *lc
            +#if HAVE_LINENOISE==2
            +  ,void *pUserData
            +#endif
            +){
               i64 nLine = strlen(zLine);
               i64 i, iStart;
               sqlite3_stmt *pStmt = 0;
               char *zSql;
               char zBuf[1000];
             
            +#if HAVE_LINENOISE==2
            +  UNUSED_PARAMETER(pUserData);
            +#endif
               if( nLine>(i64)sizeof(zBuf)-30 ) return;
               if( zLine[0]=='.' || zLine[0]=='#') return;
               for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
            @@ -22484,7 +26093,8 @@ static int booleanValue(const char *zArg){
               if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
                 return 0;
               }
            -  eputf("ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg);
            +  sqlite3_fprintf(stderr,
            +       "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg);
               return 0;
             }
             
            @@ -22511,7 +26121,7 @@ static void output_file_close(FILE *f){
             ** recognized and do the right thing.  NULL is returned if the output
             ** filename is "off".
             */
            -static FILE *output_file_open(const char *zFile, int bTextMode){
            +static FILE *output_file_open(const char *zFile){
               FILE *f;
               if( cli_strcmp(zFile,"stdout")==0 ){
                 f = stdout;
            @@ -22520,9 +26130,9 @@ static FILE *output_file_open(const char *zFile, int bTextMode){
               }else if( cli_strcmp(zFile, "off")==0 ){
                 f = 0;
               }else{
            -    f = fopen(zFile, bTextMode ? "w" : "wb");
            +    f = sqlite3_fopen(zFile, "w");
                 if( f==0 ){
            -      eputf("Error: cannot open \"%s\"\n", zFile);
            +      sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile);
                 }
               }
               return f;
            @@ -22575,12 +26185,13 @@ static int sql_trace_callback(
               switch( mType ){
                 case SQLITE_TRACE_ROW:
                 case SQLITE_TRACE_STMT: {
            -      sputf(p->traceOut, "%.*s;\n", (int)nSql, zSql);
            +      sqlite3_fprintf(p->traceOut, "%.*s;\n", (int)nSql, zSql);
                   break;
                 }
                 case SQLITE_TRACE_PROFILE: {
                   sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0;
            -      sputf(p->traceOut, "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec);
            +      sqlite3_fprintf(p->traceOut,
            +                      "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec);
                   break;
                 }
               }
            @@ -22687,10 +26298,11 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
                     break;
                   }
                   if( pc==cQuote && c!='\r' ){
            -        eputf("%s:%d: unescaped %c character\n", p->zFile, p->nLine, cQuote);
            +        sqlite3_fprintf(stderr,"%s:%d: unescaped %c character\n", 
            +                        p->zFile, p->nLine, cQuote);
                   }
                   if( c==EOF ){
            -        eputf("%s:%d: unterminated %c-quoted field\n",
            +        sqlite3_fprintf(stderr,"%s:%d: unterminated %c-quoted field\n",
                           p->zFile, startLine, cQuote);
                     p->cTerm = c;
                     break;
            @@ -22789,7 +26401,7 @@ static void tryToCloneData(
               shell_check_oom(zQuery);
               rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
               if( rc ){
            -    eputf("Error %d: %s on [%s]\n",
            +    sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n",
                       sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
                 goto end_data_xfer;
               }
            @@ -22806,7 +26418,7 @@ static void tryToCloneData(
               memcpy(zInsert+i, ");", 3);
               rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
               if( rc ){
            -    eputf("Error %d: %s on [%s]\n",
            +    sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n",
                       sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zInsert);
                 goto end_data_xfer;
               }
            @@ -22842,7 +26454,7 @@ static void tryToCloneData(
                   } /* End for */
                   rc = sqlite3_step(pInsert);
                   if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
            -        eputf("Error %d: %s\n",
            +        sqlite3_fprintf(stderr,"Error %d: %s\n",
                           sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb));
                   }
                   sqlite3_reset(pInsert);
            @@ -22860,7 +26472,7 @@ static void tryToCloneData(
                 shell_check_oom(zQuery);
                 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
                 if( rc ){
            -      eputf("Warning: cannot step \"%s\" backwards", zTable);
            +      sqlite3_fprintf(stderr,"Warning: cannot step \"%s\" backwards", zTable);
                   break;
                 }
               } /* End for(k=0...) */
            @@ -22897,7 +26509,8 @@ static void tryToCloneSchema(
               shell_check_oom(zQuery);
               rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
               if( rc ){
            -    eputf("Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db),
            +    sqlite3_fprintf(stderr,
            +          "Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db),
                       sqlite3_errmsg(p->db), zQuery);
                 goto end_schema_xfer;
               }
            @@ -22906,10 +26519,10 @@ static void tryToCloneSchema(
                 zSql = sqlite3_column_text(pQuery, 1);
                 if( zName==0 || zSql==0 ) continue;
                 if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){
            -      sputf(stdout, "%s... ", zName); fflush(stdout);
            +      sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout);
                   sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
                   if( zErrMsg ){
            -        eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
            +        sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
                     sqlite3_free(zErrMsg);
                     zErrMsg = 0;
                   }
            @@ -22927,7 +26540,7 @@ static void tryToCloneSchema(
                 shell_check_oom(zQuery);
                 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
                 if( rc ){
            -      eputf("Error: (%d) %s on [%s]\n",
            +      sqlite3_fprintf(stderr,"Error: (%d) %s on [%s]\n",
                         sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
                   goto end_schema_xfer;
                 }
            @@ -22936,10 +26549,10 @@ static void tryToCloneSchema(
                   zSql = sqlite3_column_text(pQuery, 1);
                   if( zName==0 || zSql==0 ) continue;
                   if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue;
            -      sputf(stdout, "%s... ", zName); fflush(stdout);
            +      sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout);
                   sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
                   if( zErrMsg ){
            -        eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
            +        sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
                     sqlite3_free(zErrMsg);
                     zErrMsg = 0;
                   }
            @@ -22963,12 +26576,13 @@ static void tryToClone(ShellState *p, const char *zNewDb){
               int rc;
               sqlite3 *newDb = 0;
               if( access(zNewDb,0)==0 ){
            -    eputf("File \"%s\" already exists.\n", zNewDb);
            +    sqlite3_fprintf(stderr,"File \"%s\" already exists.\n", zNewDb);
                 return;
               }
               rc = sqlite3_open(zNewDb, &newDb);
               if( rc ){
            -    eputf("Cannot create output database: %s\n", sqlite3_errmsg(newDb));
            +    sqlite3_fprintf(stderr,
            +        "Cannot create output database: %s\n", sqlite3_errmsg(newDb));
               }else{
                 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
                 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
            @@ -22985,10 +26599,18 @@ static void tryToClone(ShellState *p, const char *zNewDb){
             ** Change the output stream (file or pipe or console) to something else.
             */
             static void output_redir(ShellState *p, FILE *pfNew){
            -  if( p->out != stdout ) eputz("Output already redirected.\n");
            -  else{
            +  if( p->out != stdout ){
            +    sqlite3_fputs("Output already redirected.\n", stderr);
            +  }else{
                 p->out = pfNew;
            -    setOutputStream(pfNew);
            +    setCrlfMode(p);
            +    if( p->mode==MODE_Www ){
            +      sqlite3_fputs(
            +        "\n"
            +        "
            \n",
            +        p->out
            +      );
            +    }
               }
             }
             
            @@ -23005,6 +26627,9 @@ static void output_reset(ShellState *p){
                 pclose(p->out);
             #endif
               }else{
            +    if( p->mode==MODE_Www ){
            +      sqlite3_fputs("
            \n", p->out); + } output_file_close(p->out); #ifndef SQLITE_NOHAVE_SYSTEM if( p->doXdgOpen ){ @@ -23019,7 +26644,7 @@ static void output_reset(ShellState *p){ char *zCmd; zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile); if( system(zCmd) ){ - eputf("Failed: [%s]\n", zCmd); + sqlite3_fprintf(stderr,"Failed: [%s]\n", zCmd); }else{ /* Give the start/open/xdg-open command some time to get ** going before we continue, and potential delete the @@ -23034,7 +26659,7 @@ static void output_reset(ShellState *p){ } p->outfile[0] = 0; p->out = stdout; - setOutputStream(stdout); + setCrlfMode(p); } #else # define output_redir(SS,pfO) @@ -23044,14 +26669,20 @@ static void output_reset(ShellState *p){ /* ** Run an SQL command and return the single integer result. */ -static int db_int(sqlite3 *db, const char *zSql){ +static int db_int(sqlite3 *db, const char *zSql, ...){ sqlite3_stmt *pStmt; int res = 0; - sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + char *z; + va_list ap; + va_start(ap, zSql); + z = sqlite3_vmprintf(zSql, ap); + va_end(ap); + sqlite3_prepare_v2(db, z, -1, &pStmt, 0); if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ res = sqlite3_column_int(pStmt,0); } sqlite3_finalize(pStmt); + sqlite3_free(z); return res; } @@ -23110,7 +26741,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1", -1, &pStmt, 0); if( rc ){ - eputf("error: %s\n", sqlite3_errmsg(p->db)); + sqlite3_fprintf(stderr,"error: %s\n", sqlite3_errmsg(p->db)); sqlite3_finalize(pStmt); return 1; } @@ -23123,28 +26754,28 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ memcpy(aHdr, pb, 100); sqlite3_finalize(pStmt); }else{ - eputz("unable to read database header\n"); + sqlite3_fputs("unable to read database header\n", stderr); sqlite3_finalize(pStmt); return 1; } i = get2byteInt(aHdr+16); if( i==1 ) i = 65536; - oputf("%-20s %d\n", "database page size:", i); - oputf("%-20s %d\n", "write format:", aHdr[18]); - oputf("%-20s %d\n", "read format:", aHdr[19]); - oputf("%-20s %d\n", "reserved bytes:", aHdr[20]); + sqlite3_fprintf(p->out, "%-20s %d\n", "database page size:", i); + sqlite3_fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); + sqlite3_fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); + sqlite3_fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); for(i=0; iout, "%-20s %u", aField[i].zName, val); switch( ofst ){ case 56: { - if( val==1 ) oputz(" (utf8)"); - if( val==2 ) oputz(" (utf16le)"); - if( val==3 ) oputz(" (utf16be)"); + if( val==1 ) sqlite3_fputs(" (utf8)", p->out); + if( val==2 ) sqlite3_fputs(" (utf16le)", p->out); + if( val==3 ) sqlite3_fputs(" (utf16be)", p->out); } } - oputz("\n"); + sqlite3_fputs("\n", p->out); } if( zDb==0 ){ zSchemaTab = sqlite3_mprintf("main.sqlite_schema"); @@ -23154,24 +26785,120 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb); } for(i=0; idb, zSql); - sqlite3_free(zSql); - oputf("%-20s %d\n", aQuery[i].zName, val); + int val = db_int(p->db, aQuery[i].zSql, zSchemaTab); + sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); } sqlite3_free(zSchemaTab); sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion); - oputf("%-20s %u\n", "data version", iDataVersion); + sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion); return 0; } #endif /* SQLITE_SHELL_HAVE_RECOVER */ +/* +** Implementation of the ".dbtotxt" command. +** +** Return 1 on error, 2 to exit, and 0 otherwise. +*/ +static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){ + sqlite3_stmt *pStmt = 0; + sqlite3_int64 nPage = 0; + int pgSz = 0; + const char *zTail; + char *zName = 0; + int rc, i, j; + unsigned char bShow[256]; /* Characters ok to display */ + + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(azArg); + memset(bShow, '.', sizeof(bShow)); + for(i=' '; i<='~'; i++){ + if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i; + } + rc = sqlite3_prepare_v2(p->db, "PRAGMA page_size", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; + pgSz = sqlite3_column_int(pStmt, 0); + sqlite3_finalize(pStmt); + pStmt = 0; + if( pgSz<512 || pgSz>65536 || (pgSz&(pgSz-1))!=0 ) goto dbtotxt_error; + rc = sqlite3_prepare_v2(p->db, "PRAGMA page_count", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + rc = 0; + if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; + nPage = sqlite3_column_int64(pStmt, 0); + sqlite3_finalize(pStmt); + pStmt = 0; + if( nPage<1 ) goto dbtotxt_error; + rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + if( sqlite3_step(pStmt)!=SQLITE_ROW ){ + zTail = "unk.db"; + }else{ + const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2); + if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; + zTail = strrchr(zFilename, '/'); +#if defined(_WIN32) + if( zTail==0 ) zTail = strrchr(zFilename, '\\'); +#endif + } + zName = strdup(zTail); + shell_check_oom(zName); + sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n", + nPage*pgSz, pgSz, zName); + sqlite3_finalize(pStmt); + pStmt = 0; + rc = sqlite3_prepare_v2(p->db, + "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0); + if( rc ) goto dbtotxt_error; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0); + const u8 *aData = sqlite3_column_blob(pStmt, 1); + int seenPageLabel = 0; + for(i=0; iout, "| page %lld offset %lld\n", pgno, pgno*pgSz); + seenPageLabel = 1; + } + sqlite3_fprintf(p->out, "| %5d:", i); + for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]); + sqlite3_fprintf(p->out, " "); + for(j=0; j<16; j++){ + unsigned char c = (unsigned char)aLine[j]; + sqlite3_fprintf(p->out, "%c", bShow[c]); + } + sqlite3_fprintf(p->out, "\n"); + } + } + sqlite3_finalize(pStmt); + sqlite3_fprintf(p->out, "| end %s\n", zName); + free(zName); + return 0; + +dbtotxt_error: + if( rc ){ + sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db)); + } + sqlite3_finalize(pStmt); + free(zName); + return 1; +} + +/* +** Print the given string as an error message. +*/ +static void shellEmitError(const char *zErr){ + sqlite3_fprintf(stderr,"Error: %s\n", zErr); +} /* ** Print the current sqlite3_errmsg() value to stderr and return 1. */ static int shellDatabaseError(sqlite3 *db){ - const char *zErr = sqlite3_errmsg(db); - eputf("Error: %s\n", zErr); + shellEmitError(sqlite3_errmsg(db)); return 1; } @@ -23412,6 +27139,7 @@ static int lintFkeyIndexes( const char *zIndent = ""; /* How much to indent CREATE INDEX by */ int rc; /* Return code */ sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ + FILE *out = pState->out; /* Send output here */ /* ** This SELECT statement returns one row for each foreign key constraint @@ -23487,7 +27215,8 @@ static int lintFkeyIndexes( zIndent = " "; } else{ - eputf("Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); + sqlite3_fprintf(stderr, + "Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); return SQLITE_ERROR; } } @@ -23531,22 +27260,23 @@ static int lintFkeyIndexes( if( rc!=SQLITE_OK ) break; if( res<0 ){ - eputz("Error: internal error"); + sqlite3_fputs("Error: internal error", stderr); break; }else{ if( bGroupByParent && (bVerbose || res==0) && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) ){ - oputf("-- Parent table %s\n", zParent); + sqlite3_fprintf(out, "-- Parent table %s\n", zParent); sqlite3_free(zPrev); zPrev = sqlite3_mprintf("%s", zParent); } if( res==0 ){ - oputf("%s%s --> %s\n", zIndent, zCI, zTarget); + sqlite3_fprintf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); }else if( bVerbose ){ - oputf("%s/* no extra indexes required for %s -> %s */\n", + sqlite3_fprintf(out, + "%s/* no extra indexes required for %s -> %s */\n", zIndent, zFrom, zTarget ); } @@ -23555,16 +27285,16 @@ static int lintFkeyIndexes( sqlite3_free(zPrev); if( rc!=SQLITE_OK ){ - eputf("%s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); } rc2 = sqlite3_finalize(pSql); if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ rc = rc2; - eputf("%s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); } }else{ - eputf("%s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); } return rc; @@ -23584,13 +27314,12 @@ static int lintDotCommand( return lintFkeyIndexes(pState, azArg, nArg); usage: - eputf("Usage %s sub-command ?switches...?\n", azArg[0]); - eputz("Where sub-commands are:\n"); - eputz(" fkey-indexes\n"); + sqlite3_fprintf(stderr,"Usage %s sub-command ?switches...?\n", azArg[0]); + sqlite3_fprintf(stderr, "Where sub-commands are:\n"); + sqlite3_fprintf(stderr, " fkey-indexes\n"); return SQLITE_ERROR; } -#if !defined SQLITE_OMIT_VIRTUALTABLE static void shellPrepare( sqlite3 *db, int *pRc, @@ -23601,7 +27330,8 @@ static void shellPrepare( if( *pRc==SQLITE_OK ){ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); if( rc!=SQLITE_OK ){ - eputf("sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); + sqlite3_fprintf(stderr, + "sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); *pRc = rc; } } @@ -23609,12 +27339,8 @@ static void shellPrepare( /* ** Create a prepared statement using printf-style arguments for the SQL. -** -** This routine is could be marked "static". But it is not always used, -** depending on compile-time options. By omitting the "static", we avoid -** nuisance compiler warnings about "defined but not used". */ -void shellPreparePrintf( +static void shellPreparePrintf( sqlite3 *db, int *pRc, sqlite3_stmt **ppStmt, @@ -23637,13 +27363,10 @@ void shellPreparePrintf( } } -/* Finalize the prepared statement created using shellPreparePrintf(). -** -** This routine is could be marked "static". But it is not always used, -** depending on compile-time options. By omitting the "static", we avoid -** nuisance compiler warnings about "defined but not used". +/* +** Finalize the prepared statement created using shellPreparePrintf(). */ -void shellFinalize( +static void shellFinalize( int *pRc, sqlite3_stmt *pStmt ){ @@ -23652,13 +27375,14 @@ void shellFinalize( int rc = sqlite3_finalize(pStmt); if( *pRc==SQLITE_OK ){ if( rc!=SQLITE_OK ){ - eputf("SQL error: %s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db)); } *pRc = rc; } } } +#if !defined SQLITE_OMIT_VIRTUALTABLE /* Reset the prepared statement created using shellPreparePrintf(). ** ** This routine is could be marked "static". But it is not always used, @@ -23673,7 +27397,7 @@ void shellReset( if( *pRc==SQLITE_OK ){ if( rc!=SQLITE_OK ){ sqlite3 *db = sqlite3_db_handle(pStmt); - eputf("SQL error: %s\n", sqlite3_errmsg(db)); + sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db)); } *pRc = rc; } @@ -23702,6 +27426,7 @@ struct ArCommand { const char *zDir; /* --directory argument, or NULL */ char **azArg; /* Array of command arguments */ ShellState *p; /* Shell state */ + FILE *out; /* Output to this stream */ sqlite3 *db; /* Database containing the archive */ }; @@ -23723,11 +27448,11 @@ static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){ va_start(ap, zFmt); z = sqlite3_vmprintf(zFmt, ap); va_end(ap); - eputf("Error: %s\n", z); + shellEmitError(z); if( pAr->fromCmdLine ){ - eputz("Use \"-A\" for more help\n"); + sqlite3_fputs("Use \"-A\" for more help\n", stderr); }else{ - eputz("Use \".archive --help\" for more help\n"); + sqlite3_fputs("Use \".archive --help\" for more help\n", stderr); } sqlite3_free(z); return SQLITE_ERROR; @@ -23780,7 +27505,7 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){ break; case AR_SWITCH_APPEND: pAr->bAppend = 1; - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ case AR_SWITCH_FILE: pAr->zFile = zArg; break; @@ -23827,7 +27552,7 @@ static int arParseCommand( struct ArSwitch *pEnd = &aSwitch[nSwitch]; if( nArg<=1 ){ - eputz("Wrong number of arguments. Usage:\n"); + sqlite3_fprintf(stderr, "Wrong number of arguments. Usage:\n"); return arUsage(stderr); }else{ char *z = azArg[1]; @@ -23933,7 +27658,7 @@ static int arParseCommand( } } if( pAr->eCmd==0 ){ - eputz("Required argument missing. Usage:\n"); + sqlite3_fprintf(stderr, "Required argument missing. Usage:\n"); return arUsage(stderr); } return SQLITE_OK; @@ -23976,7 +27701,7 @@ static int arCheckEntries(ArCommand *pAr){ } shellReset(&rc, pTest); if( rc==SQLITE_OK && bOk==0 ){ - eputf("not found in archive: %s\n", z); + sqlite3_fprintf(stderr,"not found in archive: %s\n", z); rc = SQLITE_ERROR; } } @@ -24043,15 +27768,15 @@ static int arListCommand(ArCommand *pAr){ shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose], pAr->zSrcTable, zWhere); if( pAr->bDryRun ){ - oputf("%s\n", sqlite3_sql(pSql)); + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql)); }else{ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ if( pAr->bVerbose ){ - oputf("%s % 10d %s %s\n", + sqlite3_fprintf(pAr->out, "%s % 10d %s %s\n", sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1), sqlite3_column_text(pSql, 2),sqlite3_column_text(pSql, 3)); }else{ - oputf("%s\n", sqlite3_column_text(pSql, 0)); + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0)); } } } @@ -24078,7 +27803,7 @@ static int arRemoveCommand(ArCommand *pAr){ zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;", pAr->zSrcTable, zWhere); if( pAr->bDryRun ){ - oputf("%s\n", zSql); + sqlite3_fprintf(pAr->out, "%s\n", zSql); }else{ char *zErr = 0; rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0); @@ -24091,7 +27816,7 @@ static int arRemoveCommand(ArCommand *pAr){ } } if( zErr ){ - sputf(stdout, "ERROR: %s\n", zErr); /* stdout? */ + sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); /* stdout? */ sqlite3_free(zErr); } } @@ -24155,11 +27880,11 @@ static int arExtractCommand(ArCommand *pAr){ j = sqlite3_bind_parameter_index(pSql, "$dirOnly"); sqlite3_bind_int(pSql, j, i); if( pAr->bDryRun ){ - oputf("%s\n", sqlite3_sql(pSql)); + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql)); }else{ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ if( i==0 && pAr->bVerbose ){ - oputf("%s\n", sqlite3_column_text(pSql, 0)); + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0)); } } } @@ -24179,13 +27904,13 @@ static int arExtractCommand(ArCommand *pAr){ static int arExecSql(ArCommand *pAr, const char *zSql){ int rc; if( pAr->bDryRun ){ - oputf("%s\n", zSql); + sqlite3_fprintf(pAr->out, "%s\n", zSql); rc = SQLITE_OK; }else{ char *zErr = 0; rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); if( zErr ){ - sputf(stdout, "ERROR: %s\n", zErr); + sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); sqlite3_free(zErr); } } @@ -24334,6 +28059,7 @@ static int arDotCommand( if( rc==SQLITE_OK ){ int eDbType = SHELL_OPEN_UNSPEC; cmd.p = pState; + cmd.out = pState->out; cmd.db = pState->db; if( cmd.zFile ){ eDbType = deduceDatabaseType(cmd.zFile, 1); @@ -24360,13 +28086,14 @@ static int arDotCommand( } cmd.db = 0; if( cmd.bDryRun ){ - oputf("-- open database '%s'%s\n", cmd.zFile, + sqlite3_fprintf(cmd.out, "-- open database '%s'%s\n", cmd.zFile, eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : ""); } rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); if( rc!=SQLITE_OK ){ - eputf("cannot open file: %s (%s)\n", cmd.zFile, sqlite3_errmsg(cmd.db)); + sqlite3_fprintf(stderr, "cannot open file: %s (%s)\n", + cmd.zFile, sqlite3_errmsg(cmd.db)); goto end_ar_command; } sqlite3_fileio_init(cmd.db, 0, 0); @@ -24379,7 +28106,7 @@ static int arDotCommand( if( cmd.eCmd!=AR_CMD_CREATE && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0) ){ - eputz("database does not contain an 'sqlar' table\n"); + sqlite3_fprintf(stderr, "database does not contain an 'sqlar' table\n"); rc = SQLITE_ERROR; goto end_ar_command; } @@ -24437,7 +28164,7 @@ static int arDotCommand( */ static int recoverSqlCb(void *pCtx, const char *zSql){ ShellState *pState = (ShellState*)pCtx; - sputf(pState->out, "%s;\n", zSql); + sqlite3_fprintf(pState->out, "%s;\n", zSql); return SQLITE_OK; } @@ -24480,7 +28207,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ bRowids = 0; } else{ - eputf("unexpected option: %s\n", azArg[i]); + sqlite3_fprintf(stderr,"unexpected option: %s\n", azArg[i]); showHelp(pState->out, azArg[0]); return 1; } @@ -24499,13 +28226,47 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ if( sqlite3_recover_errcode(p)!=SQLITE_OK ){ const char *zErr = sqlite3_recover_errmsg(p); int errCode = sqlite3_recover_errcode(p); - eputf("sql error: %s (%d)\n", zErr, errCode); + sqlite3_fprintf(stderr,"sql error: %s (%d)\n", zErr, errCode); } rc = sqlite3_recover_finish(p); return rc; } #endif /* SQLITE_SHELL_HAVE_RECOVER */ +/* +** Implementation of ".intck STEPS_PER_UNLOCK" command. +*/ +static int intckDatabaseCmd(ShellState *pState, i64 nStepPerUnlock){ + sqlite3_intck *p = 0; + int rc = SQLITE_OK; + + rc = sqlite3_intck_open(pState->db, "main", &p); + if( rc==SQLITE_OK ){ + i64 nStep = 0; + i64 nError = 0; + const char *zErr = 0; + while( SQLITE_OK==sqlite3_intck_step(p) ){ + const char *zMsg = sqlite3_intck_message(p); + if( zMsg ){ + sqlite3_fprintf(pState->out, "%s\n", zMsg); + nError++; + } + nStep++; + if( nStepPerUnlock && (nStep % nStepPerUnlock)==0 ){ + sqlite3_intck_unlock(p); + } + } + rc = sqlite3_intck_error(p, &zErr); + if( zErr ){ + sqlite3_fprintf(stderr,"%s\n", zErr); + } + sqlite3_intck_close(p); + + sqlite3_fprintf(pState->out, "%lld steps, %lld errors\n", nStep, nError); + } + + return rc; +} /* * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it. @@ -24524,7 +28285,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ #define rc_err_oom_die(rc) \ if( rc==SQLITE_NOMEM ) shell_check_oom(0); \ else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \ - eputf("E:%d\n",rc), assert(0) + sqlite3_fprintf(stderr,"E:%d\n",rc), assert(0) #else static void rc_err_oom_die(int rc){ if( rc==SQLITE_NOMEM ) shell_check_oom(0); @@ -24682,8 +28443,8 @@ FROM (\ }else{ /* Formulate the columns spec, close the DB, zero *pDb. */ char *zColsSpec = 0; - int hasDupes = db_int(*pDb, zHasDupes); - int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0; + int hasDupes = db_int(*pDb, "%s", zHasDupes); + int nDigits = (hasDupes)? db_int(*pDb, "%s", zColDigits) : 0; if( hasDupes ){ #ifdef SHELL_COLUMN_RENAME_CLEAN rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0); @@ -24698,7 +28459,7 @@ FROM (\ sqlite3_finalize(pStmt); if( rc!=SQLITE_DONE ) rc_err_oom_die(SQLITE_NOMEM); } - assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */ + assert(db_int(*pDb, "%s", zHasDupes)==0); /* Consider: remove this */ rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0); rc_err_oom_die(rc); rc = sqlite3_step(pStmt); @@ -24718,11 +28479,77 @@ FROM (\ *pzRenamed = 0; } } - sqlite3_finalize(pStmt); - sqlite3_close(*pDb); - *pDb = 0; - return zColsSpec; + sqlite3_finalize(pStmt); + sqlite3_close(*pDb); + *pDb = 0; + return zColsSpec; + } +} + +/* +** Check if the sqlite_schema table contains one or more virtual tables. If +** parameter zLike is not NULL, then it is an SQL expression that the +** sqlite_schema row must also match. If one or more such rows are found, +** print the following warning to the output: +** +** WARNING: Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled +*/ +static int outputDumpWarning(ShellState *p, const char *zLike){ + int rc = SQLITE_OK; + sqlite3_stmt *pStmt = 0; + shellPreparePrintf(p->db, &rc, &pStmt, + "SELECT 1 FROM sqlite_schema o WHERE " + "sql LIKE 'CREATE VIRTUAL TABLE%%' AND %s", zLike ? zLike : "true" + ); + if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ + sqlite3_fputs("/* WARNING: " + "Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n", + p->out + ); + } + shellFinalize(&rc, pStmt); + return rc; +} + +/* +** Fault-Simulator state and logic. +*/ +static struct { + int iId; /* ID that triggers a simulated fault. -1 means "any" */ + int iErr; /* The error code to return on a fault */ + int iCnt; /* Trigger the fault only if iCnt is already zero */ + int iInterval; /* Reset iCnt to this value after each fault */ + int eVerbose; /* When to print output */ + int nHit; /* Number of hits seen so far */ + int nRepeat; /* Turn off after this many hits. 0 for never */ + int nSkip; /* Skip this many before first fault */ +} faultsim_state = {-1, 0, 0, 0, 0, 0, 0, 0}; + +/* +** This is the fault-sim callback +*/ +static int faultsim_callback(int iArg){ + if( faultsim_state.iId>0 && faultsim_state.iId!=iArg ){ + return SQLITE_OK; + } + if( faultsim_state.iCnt ){ + if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--; + if( faultsim_state.eVerbose>=2 ){ + sqlite3_fprintf(stdout, + "FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt); + } + return SQLITE_OK; + } + if( faultsim_state.eVerbose>=1 ){ + sqlite3_fprintf(stdout, + "FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr); } + faultsim_state.iCnt = faultsim_state.iInterval; + faultsim_state.nHit++; + if( faultsim_state.nRepeat>0 && faultsim_state.nRepeat<=faultsim_state.nHit ){ + faultsim_state.iCnt = -1; + } + return faultsim_state.iErr; } /* @@ -24778,7 +28605,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifndef SQLITE_OMIT_AUTHORIZATION if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){ if( nArg!=2 ){ - eputz("Usage: .auth ON|OFF\n"); + sqlite3_fprintf(stderr, "Usage: .auth ON|OFF\n"); rc = 1; goto meta_command_exit; } @@ -24825,7 +28652,7 @@ static int do_meta_command(char *zLine, ShellState *p){ bAsync = 1; }else { - eputf("unknown option: %s\n", azArg[j]); + sqlite3_fprintf(stderr,"unknown option: %s\n", azArg[j]); return 1; } }else if( zDestFile==0 ){ @@ -24834,19 +28661,19 @@ static int do_meta_command(char *zLine, ShellState *p){ zDb = zDestFile; zDestFile = azArg[j]; }else{ - eputz("Usage: .backup ?DB? ?OPTIONS? FILENAME\n"); + sqlite3_fprintf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n"); return 1; } } if( zDestFile==0 ){ - eputz("missing FILENAME argument on .backup\n"); + sqlite3_fprintf(stderr, "missing FILENAME argument on .backup\n"); return 1; } if( zDb==0 ) zDb = "main"; rc = sqlite3_open_v2(zDestFile, &pDest, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs); if( rc!=SQLITE_OK ){ - eputf("Error: cannot open \"%s\"\n", zDestFile); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zDestFile); close_db(pDest); return 1; } @@ -24857,7 +28684,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); if( pBackup==0 ){ - eputf("Error: %s\n", sqlite3_errmsg(pDest)); + shellDatabaseError(pDest); close_db(pDest); return 1; } @@ -24866,7 +28693,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( rc==SQLITE_DONE ){ rc = 0; }else{ - eputf("Error: %s\n", sqlite3_errmsg(pDest)); + shellDatabaseError(pDest); rc = 1; } close_db(pDest); @@ -24882,19 +28709,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - /* Undocumented. Legacy only. See "crnl" below */ + /* Undocumented. Legacy only. See "crlf" below */ if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){ - if( nArg==2 ){ - if( booleanValue(azArg[1]) ){ - setBinaryMode(p->out, 1); - }else{ - setTextMode(p->out, 1); - } - }else{ - eputz("The \".binary\" command is deprecated. Use \".crnl\" instead.\n" - "Usage: .binary on|off\n"); - rc = 1; - } + eputz("The \".binary\" command is deprecated.\n"); + rc = 1; }else /* The undocumented ".breakpoint" command causes a call to the no-op @@ -24916,7 +28734,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = chdir(azArg[1]); #endif if( rc ){ - eputf("Cannot change to directory \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Cannot change to directory \"%s\"\n", azArg[1]); rc = 1; } }else{ @@ -24949,11 +28767,12 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ rc = 2; }else if( testcase_glob(azArg[1],zRes)==0 ){ - eputf("testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", + sqlite3_fprintf(stderr, + "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", p->zTestcase, azArg[1], zRes); rc = 1; }else{ - oputf("testcase-%s ok\n", p->zTestcase); + sqlite3_fprintf(p->out, "testcase-%s ok\n", p->zTestcase); p->nCheck++; } sqlite3_free(zRes); @@ -24986,9 +28805,9 @@ static int do_meta_command(char *zLine, ShellState *p){ zFile = "(temporary-file)"; } if( p->pAuxDb == &p->aAuxDb[i] ){ - sputf(stdout, "ACTIVE %d: %s\n", i, zFile); + sqlite3_fprintf(stdout, "ACTIVE %d: %s\n", i, zFile); }else if( p->aAuxDb[i].db!=0 ){ - sputf(stdout, " %d: %s\n", i, zFile); + sqlite3_fprintf(stdout, " %d: %s\n", i, zFile); } } }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){ @@ -25018,20 +28837,18 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - if( c=='c' && n==4 && cli_strncmp(azArg[0], "crnl", n)==0 ){ + if( c=='c' && n==4 + && (cli_strncmp(azArg[0], "crlf", n)==0 + || cli_strncmp(azArg[0], "crnl",n)==0) + ){ if( nArg==2 ){ - if( booleanValue(azArg[1]) ){ - setTextMode(p->out, 1); - }else{ - setBinaryMode(p->out, 1); - } - }else{ -#if !defined(_WIN32) && !defined(WIN32) - eputz("The \".crnl\" is a no-op on non-Windows machines.\n"); +#ifdef _WIN32 + p->crlfMode = booleanValue(azArg[1]); +#else + p->crlfMode = 0; #endif - eputz("Usage: .crnl on|off\n"); - rc = 1; } + sqlite3_fprintf(stderr, "crlf is %s\n", p->crlfMode ? "ON" : "OFF"); }else if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){ @@ -25042,7 +28859,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); if( rc ){ - eputf("Error: %s\n", sqlite3_errmsg(p->db)); + shellDatabaseError(p->db); rc = 1; }else{ while( sqlite3_step(pStmt)==SQLITE_ROW ){ @@ -25061,7 +28878,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int eTxn = sqlite3_txn_state(p->db, azName[i*2]); int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]); const char *z = azName[i*2+1]; - oputf("%s: %s %s%s\n", + sqlite3_fprintf(p->out, "%s: %s %s%s\n", azName[i*2], z && z[0] ? z : "\"\"", bRdonly ? "r/o" : "r/w", eTxn==SQLITE_TXN_NONE ? "" : eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn"); @@ -25103,11 +28920,12 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); } sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); - oputf("%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); + sqlite3_fprintf(p->out, "%19s %s\n", + aDbConfig[ii].zName, v ? "on" : "off"); if( nArg>1 ) break; } if( nArg>1 && ii==ArraySize(aDbConfig) ){ - eputf("Error: unknown dbconfig \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Error: unknown dbconfig \"%s\"\n", azArg[1]); eputz("Enter \".dbconfig\" with no arguments for a list\n"); } }else @@ -25157,7 +28975,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ShellSetFlag(p, SHFLG_DumpNoSys); }else { - eputf("Unknown option \"%s\" on \".dump\"\n", azArg[i]); + sqlite3_fprintf(stderr, + "Unknown option \"%s\" on \".dump\"\n", azArg[i]); rc = 1; sqlite3_free(zLike); goto meta_command_exit; @@ -25187,12 +29006,13 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); + outputDumpWarning(p, zLike); if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ - oputz("PRAGMA foreign_keys=OFF;\n"); - oputz("BEGIN TRANSACTION;\n"); + sqlite3_fputs("PRAGMA foreign_keys=OFF;\n", p->out); + sqlite3_fputs("BEGIN TRANSACTION;\n", p->out); } p->writableSchema = 0; p->showHeader = 0; @@ -25215,7 +29035,8 @@ static int do_meta_command(char *zLine, ShellState *p){ zSql = sqlite3_mprintf( "SELECT sql FROM sqlite_schema AS o " "WHERE (%s) AND sql NOT NULL" - " AND type IN ('index','trigger','view')", + " AND type IN ('index','trigger','view') " + "ORDER BY type COLLATE NOCASE DESC", zLike ); run_table_dump_query(p, zSql); @@ -25223,13 +29044,13 @@ static int do_meta_command(char *zLine, ShellState *p){ } sqlite3_free(zLike); if( p->writableSchema ){ - oputz("PRAGMA writable_schema=OFF;\n"); + sqlite3_fputs("PRAGMA writable_schema=OFF;\n", p->out); p->writableSchema = 0; } sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ - oputz(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n"); + sqlite3_fputs(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n", p->out); } p->showHeader = savedShowHeader; p->shellFlgs = savedShellFlags; @@ -25244,6 +29065,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){ + rc = shell_dbtotxt_command(p, nArg, azArg); + }else + if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){ if( nArg==2 ){ p->autoEQPtest = 0; @@ -25309,7 +29134,8 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifndef SQLITE_OMIT_VIRTUALTABLE if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ if( p->bSafeMode ){ - eputf("Cannot run experimental commands such as \"%s\" in safe mode\n", + sqlite3_fprintf(stderr, + "Cannot run experimental commands such as \"%s\" in safe mode\n", azArg[0]); rc = 1; }else{ @@ -25366,9 +29192,10 @@ static int do_meta_command(char *zLine, ShellState *p){ /* --help lists all file-controls */ if( cli_strcmp(zCmd,"help")==0 ){ - oputz("Available file-controls:\n"); + sqlite3_fputs("Available file-controls:\n", p->out); for(i=0; iout, + " .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); } rc = 1; goto meta_command_exit; @@ -25383,7 +29210,7 @@ static int do_meta_command(char *zLine, ShellState *p){ filectrl = aCtrl[i].ctrlCode; iCtrl = i; }else{ - eputf("Error: ambiguous file-control: \"%s\"\n" + sqlite3_fprintf(stderr,"Error: ambiguous file-control: \"%s\"\n" "Use \".filectrl --help\" for help\n", zCmd); rc = 1; goto meta_command_exit; @@ -25391,7 +29218,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( filectrl<0 ){ - eputf("Error: unknown file-control: %s\n" + sqlite3_fprintf(stderr,"Error: unknown file-control: %s\n" "Use \".filectrl --help\" for help\n", zCmd); }else{ switch(filectrl){ @@ -25435,7 +29262,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg!=2 ) break; sqlite3_file_control(p->db, zSchema, filectrl, &z); if( z ){ - oputf("%s\n", z); + sqlite3_fprintf(p->out, "%s\n", z); sqlite3_free(z); } isOk = 2; @@ -25449,19 +29276,20 @@ static int do_meta_command(char *zLine, ShellState *p){ } x = -1; sqlite3_file_control(p->db, zSchema, filectrl, &x); - oputf("%d\n", x); + sqlite3_fprintf(p->out, "%d\n", x); isOk = 2; break; } } } if( isOk==0 && iCtrl>=0 ){ - oputf("Usage: .filectrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); + sqlite3_fprintf(p->out, "Usage: .filectrl %s %s\n", + zCmd, aCtrl[iCtrl].zUsage); rc = 1; }else if( isOk==1 ){ char zBuf[100]; sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes); - oputf("%s\n", zBuf); + sqlite3_fprintf(p->out, "%s\n", zBuf); } }else @@ -25502,15 +29330,15 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( doStats==0 ){ - oputz("/* No STAT tables available */\n"); + sqlite3_fputs("/* No STAT tables available */\n", p->out); }else{ - oputz("ANALYZE sqlite_schema;\n"); + sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); data.cMode = data.mode = MODE_Insert; data.zDestTable = "sqlite_stat1"; shell_exec(&data, "SELECT * FROM sqlite_stat1", 0); data.zDestTable = "sqlite_stat4"; shell_exec(&data, "SELECT * FROM sqlite_stat4", 0); - oputz("ANALYZE sqlite_schema;\n"); + sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); } }else @@ -25528,7 +29356,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg>=2 ){ n = showHelp(p->out, azArg[1]); if( n==0 ){ - oputf("Nothing matches '%s'\n", azArg[1]); + sqlite3_fprintf(p->out, "Nothing matches '%s'\n", azArg[1]); } }else{ showHelp(p->out, 0); @@ -25538,16 +29366,15 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifndef SQLITE_SHELL_FIDDLE if( c=='i' && cli_strncmp(azArg[0], "import", n)==0 ){ char *zTable = 0; /* Insert data into this table */ - char *zSchema = 0; /* within this schema (may default to "main") */ + char *zSchema = 0; /* Schema of zTable */ char *zFile = 0; /* Name of file to extra content from */ sqlite3_stmt *pStmt = NULL; /* A statement */ int nCol; /* Number of columns in the table */ - int nByte; /* Number of bytes in an SQL string */ + i64 nByte; /* Number of bytes in an SQL string */ int i, j; /* Loop counters */ int needCommit; /* True to COMMIT or ROLLBACK at end */ int nSep; /* Number of bytes in p->colSeparator[] */ - char *zSql; /* An SQL statement */ - char *zFullTabName; /* Table name with schema if applicable */ + char *zSql = 0; /* An SQL statement */ ImportCtx sCtx; /* Reader context */ char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ int eVerbose = 0; /* Larger for more console output */ @@ -25572,7 +29399,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( zTable==0 ){ zTable = z; }else{ - oputf("ERROR: extra argument: \"%s\". Usage:\n", z); + sqlite3_fprintf(p->out, "ERROR: extra argument: \"%s\". Usage:\n",z); showHelp(p->out, "import"); goto meta_command_exit; } @@ -25593,13 +29420,13 @@ static int do_meta_command(char *zLine, ShellState *p){ xRead = csv_read_one_field; useOutputMode = 0; }else{ - oputf("ERROR: unknown option: \"%s\". Usage:\n", z); + sqlite3_fprintf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z); showHelp(p->out, "import"); goto meta_command_exit; } } if( zTable==0 ){ - oputf("ERROR: missing %s argument. Usage:\n", + sqlite3_fprintf(p->out, "ERROR: missing %s argument. Usage:\n", zFile==0 ? "FILE" : "TABLE"); showHelp(p->out, "import"); goto meta_command_exit; @@ -25649,28 +29476,28 @@ static int do_meta_command(char *zLine, ShellState *p){ eputz("Error: pipes are not supported in this OS\n"); goto meta_command_exit; #else - sCtx.in = popen(sCtx.zFile+1, "r"); + sCtx.in = sqlite3_popen(sCtx.zFile+1, "r"); sCtx.zFile = ""; sCtx.xCloser = pclose; #endif }else{ - sCtx.in = fopen(sCtx.zFile, "rb"); + sCtx.in = sqlite3_fopen(sCtx.zFile, "rb"); sCtx.xCloser = fclose; } if( sCtx.in==0 ){ - eputf("Error: cannot open \"%s\"\n", zFile); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile); goto meta_command_exit; } if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){ char zSep[2]; zSep[1] = 0; zSep[0] = sCtx.cColSep; - oputz("Column separator "); - output_c_string(zSep); - oputz(", row separator "); + sqlite3_fputs("Column separator ", p->out); + output_c_string(p->out, zSep); + sqlite3_fputs(", row separator ", p->out); zSep[0] = sCtx.cRowSep; - output_c_string(zSep); - oputz("\n"); + output_c_string(p->out, zSep); + sqlite3_fputs("\n", p->out); } sCtx.z = sqlite3_malloc64(120); if( sCtx.z==0 ){ @@ -25681,75 +29508,98 @@ static int do_meta_command(char *zLine, ShellState *p){ while( (nSkip--)>0 ){ while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){} } - if( zSchema!=0 ){ - zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable); - }else{ - zFullTabName = sqlite3_mprintf("\"%w\"", zTable); - } - zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName); - if( zSql==0 || zFullTabName==0 ){ - import_cleanup(&sCtx); - shell_out_of_memory(); - } - nByte = strlen30(zSql); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ - if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){ + if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0) + && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema" + " WHERE name=%Q AND type='view'", + zSchema ? zSchema : "main", zTable) + ){ + /* Table does not exist. Create it. */ sqlite3 *dbCols = 0; char *zRenames = 0; char *zColDefs; - zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName); + zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"", + zSchema ? zSchema : "main", zTable); while( xRead(&sCtx) ){ zAutoColumn(sCtx.z, &dbCols, 0); if( sCtx.cTerm!=sCtx.cColSep ) break; } zColDefs = zAutoColumn(0, &dbCols, &zRenames); if( zRenames!=0 ){ - sputf((stdin_is_interactive && p->in==stdin)? p->out : stderr, + sqlite3_fprintf((stdin_is_interactive && p->in==stdin)? p->out : stderr, "Columns renamed during .import %s due to duplicates:\n" "%s\n", sCtx.zFile, zRenames); sqlite3_free(zRenames); } assert(dbCols==0); if( zColDefs==0 ){ - eputf("%s: empty file\n", sCtx.zFile); - import_fail: - sqlite3_free(zCreate); - sqlite3_free(zSql); - sqlite3_free(zFullTabName); + sqlite3_fprintf(stderr,"%s: empty file\n", sCtx.zFile); import_cleanup(&sCtx); rc = 1; + sqlite3_free(zCreate); goto meta_command_exit; } zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs); + if( zCreate==0 ){ + import_cleanup(&sCtx); + shell_out_of_memory(); + } if( eVerbose>=1 ){ - oputf("%s\n", zCreate); + sqlite3_fprintf(p->out, "%s\n", zCreate); } rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); if( rc ){ - eputf("%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); - goto import_fail; + sqlite3_fprintf(stderr, + "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); } sqlite3_free(zCreate); zCreate = 0; - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + if( rc ){ + import_cleanup(&sCtx); + rc = 1; + goto meta_command_exit; + } + } + zSql = sqlite3_mprintf("SELECT count(*) FROM pragma_table_info(%Q,%Q);", + zTable, zSchema); + if( zSql==0 ){ + import_cleanup(&sCtx); + shell_out_of_memory(); } + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + zSql = 0; if( rc ){ if (pStmt) sqlite3_finalize(pStmt); - eputf("Error: %s\n", sqlite3_errmsg(p->db)); - goto import_fail; + shellDatabaseError(p->db); + import_cleanup(&sCtx); + rc = 1; + goto meta_command_exit; + } + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + nCol = sqlite3_column_int(pStmt, 0); + }else{ + nCol = 0; } - sqlite3_free(zSql); - nCol = sqlite3_column_count(pStmt); sqlite3_finalize(pStmt); pStmt = 0; if( nCol==0 ) return 0; /* no columns, no error */ - zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); + + nByte = 64 /* space for "INSERT INTO", "VALUES(", ")\0" */ + + (zSchema ? strlen(zSchema)*2 + 2: 0) /* Quoted schema name */ + + strlen(zTable)*2 + 2 /* Quoted table name */ + + nCol*2; /* Space for ",?" for each column */ + zSql = sqlite3_malloc64( nByte ); if( zSql==0 ){ import_cleanup(&sCtx); shell_out_of_memory(); } - sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName); + if( zSchema ){ + sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?", + zSchema, zTable); + }else{ + sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); + } j = strlen30(zSql); for(i=1; i=2 ){ - oputf("Insert using: %s\n", zSql); + sqlite3_fprintf(p->out, "Insert using: %s\n", zSql); } rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + zSql = 0; if( rc ){ - eputf("Error: %s\n", sqlite3_errmsg(p->db)); + shellDatabaseError(p->db); if (pStmt) sqlite3_finalize(pStmt); - goto import_fail; + import_cleanup(&sCtx); + rc = 1; + goto meta_command_exit; } - sqlite3_free(zSql); - sqlite3_free(zFullTabName); needCommit = sqlite3_get_autocommit(p->db); if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); do{ @@ -25795,7 +29648,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); if( i=nCol ){ sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); if( rc!=SQLITE_OK ){ - eputf("%s:%d: INSERT failed: %s\n", + sqlite3_fprintf(stderr,"%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, sqlite3_errmsg(p->db)); sCtx.nErr++; }else{ @@ -25827,7 +29681,8 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_finalize(pStmt); if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); if( eVerbose>0 ){ - oputf("Added %d rows with %d errors using %d lines of input\n", + sqlite3_fprintf(p->out, + "Added %d rows with %d errors using %d lines of input\n", sCtx.nRow, sCtx.nErr, sCtx.nLine-1); } }else @@ -25843,7 +29698,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ int i; if( !ShellHasFlag(p,SHFLG_TestingMode) ){ - eputf(".%s unavailable without --unsafe-testing\n", + sqlite3_fprintf(stderr,".%s unavailable without --unsafe-testing\n", "imposter"); rc = 1; goto meta_command_exit; @@ -25909,7 +29764,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } sqlite3_finalize(pStmt); if( i==0 || tnum==0 ){ - eputf("no such index: \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"no such index: \"%s\"\n", azArg[1]); rc = 1; sqlite3_free(zCollist); goto meta_command_exit; @@ -25924,20 +29779,37 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); if( rc ){ - eputf("Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); + sqlite3_fprintf(stderr, + "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); }else{ - sputf(stdout, "%s;\n", zSql); - sputf(stdout, "WARNING: writing to an imposter table will corrupt" + sqlite3_fprintf(stdout, "%s;\n", zSql); + sqlite3_fprintf(stdout, + "WARNING: writing to an imposter table will corrupt" " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index"); } }else{ - eputf("SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); + sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); rc = 1; } sqlite3_free(zSql); }else #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ + if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){ + i64 iArg = 0; + if( nArg==2 ){ + iArg = integerValue(azArg[1]); + if( iArg==0 ) iArg = -1; + } + if( (nArg!=1 && nArg!=2) || iArg<0 ){ + sqlite3_fprintf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + rc = intckDatabaseCmd(p, iArg); + }else + #ifdef SQLITE_ENABLE_IOTRACE if( c=='i' && cli_strncmp(azArg[0], "iotrace", n)==0 ){ SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); @@ -25949,9 +29821,9 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3IoTrace = iotracePrintf; iotrace = stdout; }else{ - iotrace = fopen(azArg[1], "w"); + iotrace = sqlite3_fopen(azArg[1], "w"); if( iotrace==0 ){ - eputf("Error: cannot open \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); sqlite3IoTrace = 0; rc = 1; }else{ @@ -25983,7 +29855,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); if( nArg==1 ){ for(i=0; idb, aLimit[i].limitCode, -1)); } }else if( nArg>3 ){ @@ -25998,14 +29870,14 @@ static int do_meta_command(char *zLine, ShellState *p){ if( iLimit<0 ){ iLimit = i; }else{ - eputf("ambiguous limit: \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"ambiguous limit: \"%s\"\n", azArg[1]); rc = 1; goto meta_command_exit; } } } if( iLimit<0 ){ - eputf("unknown limit: \"%s\"\n" + sqlite3_fprintf(stderr,"unknown limit: \"%s\"\n" "enter \".limits\" with no arguments for a list.\n", azArg[1]); rc = 1; @@ -26015,7 +29887,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_limit(p->db, aLimit[iLimit].limitCode, (int)integerValue(azArg[2])); } - sputf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName, + sqlite3_fprintf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName, sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); } }else @@ -26041,7 +29913,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); if( rc!=SQLITE_OK ){ - eputf("Error: %s\n", zErrMsg); + shellEmitError(zErrMsg); sqlite3_free(zErrMsg); rc = 1; } @@ -26064,7 +29936,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } output_file_close(p->pLog); if( cli_strcmp(zFile,"on")==0 ) zFile = "stdout"; - p->pLog = output_file_open(zFile, 0); + p->pLog = output_file_open(zFile); } }else @@ -26098,7 +29970,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( zTabname==0 ){ zTabname = z; }else if( z[0]=='-' ){ - eputf("unknown option: %s\n", z); + sqlite3_fprintf(stderr,"unknown option: %s\n", z); eputz("options:\n" " --noquote\n" " --quote\n" @@ -26108,7 +29980,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; }else{ - eputf("extra argument: \"%s\"\n", z); + sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z); rc = 1; goto meta_command_exit; } @@ -26117,12 +29989,14 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->mode==MODE_Column || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) ){ - oputf("current output mode: %s --wrap %d --wordwrap %s --%squote\n", + sqlite3_fprintf(p->out, + "current output mode: %s --wrap %d --wordwrap %s --%squote\n", modeDescr[p->mode], p->cmOpts.iWrap, p->cmOpts.bWordWrap ? "on" : "off", p->cmOpts.bQuote ? "" : "no"); }else{ - oputf("current output mode: %s\n", modeDescr[p->mode]); + sqlite3_fprintf(p->out, + "current output mode: %s\n", modeDescr[p->mode]); } zMode = modeDescr[p->mode]; } @@ -26195,7 +30069,7 @@ static int do_meta_command(char *zLine, ShellState *p){ eputz("Usage: .nonce NONCE\n"); rc = 1; }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){ - eputf("line %d: incorrect nonce: \"%s\"\n", + sqlite3_fprintf(stderr,"line %d: incorrect nonce: \"%s\"\n", p->lineno, azArg[1]); exit(1); }else{ @@ -26250,11 +30124,11 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif /* !SQLITE_SHELL_FIDDLE */ if( z[0]=='-' ){ - eputf("unknown option: %s\n", z); + sqlite3_fprintf(stderr,"unknown option: %s\n", z); rc = 1; goto meta_command_exit; }else if( zFN ){ - eputf("extra argument: \"%s\"\n", z); + sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z); rc = 1; goto meta_command_exit; }else{ @@ -26296,7 +30170,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->pAuxDb->zDbFilename = zNewFilename; open_db(p, OPEN_DB_KEEPALIVE); if( p->db==0 ){ - eputf("Error: cannot open '%s'\n", zNewFilename); + sqlite3_fprintf(stderr,"Error: cannot open '%s'\n", zNewFilename); sqlite3_free(zNewFilename); }else{ p->pAuxDb->zFreeOnClose = zNewFilename; @@ -26314,19 +30188,23 @@ static int do_meta_command(char *zLine, ShellState *p){ && (cli_strncmp(azArg[0], "output", n)==0 || cli_strncmp(azArg[0], "once", n)==0)) || (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0) + || (c=='w' && n==3 && cli_strcmp(azArg[0],"www")==0) ){ char *zFile = 0; - int bTxtMode = 0; int i; int eMode = 0; - int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */ - static const char *zBomUtf8 = "\xef\xbb\xbf"; + int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */ + int bPlain = 0; /* --plain option */ + static const char *zBomUtf8 = "\357\273\277"; const char *zBom = 0; failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]); if( c=='e' ){ eMode = 'x'; bOnce = 2; + }else if( c=='w' ){ + eMode = 'w'; + bOnce = 2; }else if( cli_strncmp(azArg[0],"once",n)==0 ){ bOnce = 1; } @@ -26336,24 +30214,30 @@ static int do_meta_command(char *zLine, ShellState *p){ if( z[1]=='-' ) z++; if( cli_strcmp(z,"-bom")==0 ){ zBom = zBomUtf8; - }else if( c!='e' && cli_strcmp(z,"-x")==0 ){ + }else if( cli_strcmp(z,"-plain")==0 ){ + bPlain = 1; + }else if( c=='o' && cli_strcmp(z,"-x")==0 ){ eMode = 'x'; /* spreadsheet */ - }else if( c!='e' && cli_strcmp(z,"-e")==0 ){ + }else if( c=='o' && cli_strcmp(z,"-e")==0 ){ eMode = 'e'; /* text editor */ + }else if( c=='o' && cli_strcmp(z,"-w")==0 ){ + eMode = 'w'; /* Web browser */ }else{ - oputf("ERROR: unknown option: \"%s\". Usage:\n", azArg[i]); + sqlite3_fprintf(p->out, + "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; goto meta_command_exit; } - }else if( zFile==0 && eMode!='e' && eMode!='x' ){ + }else if( zFile==0 && eMode==0 ){ zFile = sqlite3_mprintf("%s", z); if( zFile && zFile[0]=='|' ){ while( i+1out, + "ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; sqlite3_free(zFile); @@ -26363,6 +30247,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zFile==0 ){ zFile = sqlite3_mprintf("stdout"); } + shell_check_oom(zFile); if( bOnce ){ p->outCount = 2; }else{ @@ -26370,7 +30255,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } output_reset(p); #ifndef SQLITE_NOHAVE_SYSTEM - if( eMode=='e' || eMode=='x' ){ + if( eMode=='e' || eMode=='x' || eMode=='w' ){ p->doXdgOpen = 1; outputModePush(p); if( eMode=='x' ){ @@ -26380,10 +30265,17 @@ static int do_meta_command(char *zLine, ShellState *p){ p->mode = MODE_Csv; sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); +#ifdef _WIN32 + zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does + ** not work without it. */ +#endif + }else if( eMode=='w' ){ + /* web-browser mode. */ + newTempFile(p, "html"); + if( !bPlain ) p->mode = MODE_Www; }else{ /* text editor mode */ newTempFile(p, "txt"); - bTxtMode = 1; } sqlite3_free(zFile); zFile = sqlite3_mprintf("%s", p->zTempFile); @@ -26396,26 +30288,34 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; output_redir(p, stdout); #else - FILE *pfPipe = popen(zFile + 1, "w"); + FILE *pfPipe = sqlite3_popen(zFile + 1, "w"); if( pfPipe==0 ){ - eputf("Error: cannot open pipe \"%s\"\n", zFile + 1); + assert( stderr!=NULL ); + sqlite3_fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); rc = 1; }else{ output_redir(p, pfPipe); - if( zBom ) oputz(zBom); + if( zBom ) sqlite3_fputs(zBom, pfPipe); sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } #endif }else{ - FILE *pfFile = output_file_open(zFile, bTxtMode); + FILE *pfFile = output_file_open(zFile); if( pfFile==0 ){ if( cli_strcmp(zFile,"off")!=0 ){ - eputf("Error: cannot write to \"%s\"\n", zFile); + assert( stderr!=NULL ); + sqlite3_fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile); } rc = 1; } else { output_redir(p, pfFile); - if( zBom ) oputz(zBom); + if( zBom ) sqlite3_fputs(zBom, pfFile); + if( bPlain && eMode=='w' ){ + sqlite3_fputs( + "\n\n\n", + pfFile + ); + } sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } @@ -26456,7 +30356,8 @@ static int do_meta_command(char *zLine, ShellState *p){ "SELECT key, quote(value) " "FROM temp.sqlite_parameters;", -1, &pStmt, 0); while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ - oputf("%-*s %s\n", len, sqlite3_column_text(pStmt,0), + sqlite3_fprintf(p->out, + "%-*s %s\n", len, sqlite3_column_text(pStmt,0), sqlite3_column_text(pStmt,1)); } sqlite3_finalize(pStmt); @@ -26501,12 +30402,13 @@ static int do_meta_command(char *zLine, ShellState *p){ rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rx!=SQLITE_OK ){ - oputf("Error: %s\n", sqlite3_errmsg(p->db)); + sqlite3_fprintf(p->out, "Error: %s\n", sqlite3_errmsg(p->db)); sqlite3_finalize(pStmt); pStmt = 0; rc = 1; } } + bind_prepared_stmt(p, pStmt); sqlite3_step(pStmt); sqlite3_finalize(pStmt); }else @@ -26530,10 +30432,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){ int i; for(i=1; i<nArg; i++){ - if( i>1 ) oputz(" "); - oputz(azArg[i]); + if( i>1 ) sqlite3_fputs(" ", p->out); + sqlite3_fputs(azArg[i], p->out); } - oputz("\n"); + sqlite3_fputs("\n", p->out); }else #ifndef SQLITE_OMIT_PROGRESS_CALLBACK @@ -26570,7 +30472,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } continue; } - eputf("Error: unknown option: \"%s\"\n", azArg[i]); + sqlite3_fprintf(stderr,"Error: unknown option: \"%s\"\n", azArg[i]); rc = 1; goto meta_command_exit; }else{ @@ -26611,11 +30513,10 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifdef SQLITE_OMIT_POPEN eputz("Error: pipes are not supported in this OS\n"); rc = 1; - p->out = stdout; #else - p->in = popen(azArg[1]+1, "r"); + p->in = sqlite3_popen(azArg[1]+1, "r"); if( p->in==0 ){ - eputf("Error: cannot open \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; }else{ rc = process_input(p); @@ -26623,7 +30524,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } #endif }else if( (p->in = openChrSource(azArg[1]))==0 ){ - eputf("Error: cannot open \"%s\"\n", azArg[1]); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; }else{ rc = process_input(p); @@ -26656,14 +30557,14 @@ static int do_meta_command(char *zLine, ShellState *p){ } rc = sqlite3_open(zSrcFile, &pSrc); if( rc!=SQLITE_OK ){ - eputf("Error: cannot open \"%s\"\n", zSrcFile); + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zSrcFile); close_db(pSrc); return 1; } open_db(p, 0); pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); if( pBackup==0 ){ - eputf("Error: %s\n", sqlite3_errmsg(p->db)); + shellDatabaseError(p->db); close_db(pSrc); return 1; } @@ -26681,14 +30582,17 @@ static int do_meta_command(char *zLine, ShellState *p){ eputz("Error: source database is busy\n"); rc = 1; }else{ - eputf("Error: %s\n", sqlite3_errmsg(p->db)); + shellDatabaseError(p->db); rc = 1; } close_db(pSrc); }else #endif /* !defined(SQLITE_SHELL_FIDDLE) */ - if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){ + if( c=='s' && + (cli_strncmp(azArg[0], "scanstats", n)==0 || + cli_strncmp(azArg[0], "scanstatus", n)==0) + ){ if( nArg==2 ){ if( cli_strcmp(azArg[1], "vm")==0 ){ p->scanstatsOn = 3; @@ -26739,7 +30643,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( optionMatch(azArg[ii],"nosys") ){ bNoSystemTabs = 1; }else if( azArg[ii][0]=='-' ){ - eputf("Unknown option: \"%s\"\n", azArg[ii]); + sqlite3_fprintf(stderr,"Unknown option: \"%s\"\n", azArg[ii]); rc = 1; goto meta_command_exit; }else if( zName==0 ){ @@ -26778,7 +30682,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list", -1, &pStmt, 0); if( rc ){ - eputf("Error: %s\n", sqlite3_errmsg(p->db)); + shellDatabaseError(p->db); sqlite3_finalize(pStmt); rc = 1; goto meta_command_exit; @@ -26840,14 +30744,14 @@ static int do_meta_command(char *zLine, ShellState *p){ appendText(&sSelect, "sql IS NOT NULL" " ORDER BY snum, rowid", 0); if( bDebug ){ - oputf("SQL: %s;\n", sSelect.z); + sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z); }else{ rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); } freeText(&sSelect); } if( zErrMsg ){ - eputf("Error: %s\n", zErrMsg); + shellEmitError(zErrMsg); sqlite3_free(zErrMsg); rc = 1; }else if( rc != SQLITE_OK ){ @@ -26901,7 +30805,8 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ rc = sqlite3session_attach(pSession->p, azCmd[1]); if( rc ){ - eputf("ERROR: sqlite3session_attach() returns %d\n",rc); + sqlite3_fprintf(stderr, + "ERROR: sqlite3session_attach() returns %d\n",rc); rc = 0; } } @@ -26918,9 +30823,9 @@ static int do_meta_command(char *zLine, ShellState *p){ failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]); if( nCmd!=2 ) goto session_syntax_error; if( pSession->p==0 ) goto session_not_open; - out = fopen(azCmd[1], "wb"); + out = sqlite3_fopen(azCmd[1], "wb"); if( out==0 ){ - eputf("ERROR: cannot open \"%s\" for writing\n", + sqlite3_fprintf(stderr,"ERROR: cannot open \"%s\" for writing\n", azCmd[1]); }else{ int szChng; @@ -26931,12 +30836,13 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); } if( rc ){ - sputf(stdout, "Error: error code %d\n", rc); + sqlite3_fprintf(stdout, "Error: error code %d\n", rc); rc = 0; } if( pChng && fwrite(pChng, szChng, 1, out)!=1 ){ - eputf("ERROR: Failed to write entire %d-byte output\n", szChng); + sqlite3_fprintf(stderr, + "ERROR: Failed to write entire %d-byte output\n", szChng); } sqlite3_free(pChng); fclose(out); @@ -26963,7 +30869,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( pAuxDb->nSession ){ ii = sqlite3session_enable(pSession->p, ii); - oputf("session %s enable flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, + "session %s enable flag = %d\n", pSession->zName, ii); } }else @@ -26998,7 +30905,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( pAuxDb->nSession ){ ii = sqlite3session_indirect(pSession->p, ii); - oputf("session %s indirect flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, + "session %s indirect flag = %d\n", pSession->zName, ii); } }else @@ -27010,7 +30918,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCmd!=1 ) goto session_syntax_error; if( pAuxDb->nSession ){ ii = sqlite3session_isempty(pSession->p); - oputf("session %s isempty flag = %d\n", pSession->zName, ii); + sqlite3_fprintf(p->out, + "session %s isempty flag = %d\n", pSession->zName, ii); } }else @@ -27019,7 +30928,7 @@ static int do_meta_command(char *zLine, ShellState *p){ */ if( cli_strcmp(azCmd[0],"list")==0 ){ for(i=0; i<pAuxDb->nSession; i++){ - oputf("%d %s\n", i, pAuxDb->aSession[i].zName); + sqlite3_fprintf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName); } }else @@ -27034,18 +30943,19 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zName[0]==0 ) goto session_syntax_error; for(i=0; i<pAuxDb->nSession; i++){ if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){ - eputf("Session \"%s\" already exists\n", zName); + sqlite3_fprintf(stderr,"Session \"%s\" already exists\n", zName); goto meta_command_exit; } } if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){ - eputf("Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); + sqlite3_fprintf(stderr, + "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); goto meta_command_exit; } pSession = &pAuxDb->aSession[pAuxDb->nSession]; rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); if( rc ){ - eputf("Cannot open session: error code=%d\n", rc); + sqlite3_fprintf(stderr,"Cannot open session: error code=%d\n", rc); rc = 0; goto meta_command_exit; } @@ -27069,7 +30979,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int i, v; for(i=1; i<nArg; i++){ v = booleanValue(azArg[i]); - oputf("%s: %d 0x%x\n", azArg[i], v, v); + sqlite3_fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v); } } if( cli_strncmp(azArg[0]+9, "integer", n-9)==0 ){ @@ -27078,7 +30988,7 @@ static int do_meta_command(char *zLine, ShellState *p){ char zBuf[200]; v = integerValue(azArg[i]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v); - oputz(zBuf); + sqlite3_fputs(zBuf, p->out); } } }else @@ -27105,8 +31015,9 @@ static int do_meta_command(char *zLine, ShellState *p){ bVerbose++; }else { - eputf("Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); - eputz("Should be one of: --init -v\n"); + sqlite3_fprintf(stderr, + "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); + sqlite3_fputs("Should be one of: --init -v\n", stderr); rc = 1; goto meta_command_exit; } @@ -27151,10 +31062,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zAns==0 ) continue; k = 0; if( bVerbose>0 ){ - sputf(stdout, "%d: %s %s\n", tno, zOp, zSql); + sqlite3_fprintf(stdout, "%d: %s %s\n", tno, zOp, zSql); } if( cli_strcmp(zOp,"memo")==0 ){ - oputf("%s\n", zSql); + sqlite3_fprintf(p->out, "%s\n", zSql); }else if( cli_strcmp(zOp,"run")==0 ){ char *zErrMsg = 0; @@ -27163,22 +31074,23 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); nTest++; if( bVerbose ){ - oputf("Result: %s\n", str.z); + sqlite3_fprintf(p->out, "Result: %s\n", str.z); } if( rc || zErrMsg ){ nErr++; rc = 1; - oputf("%d: error-code-%d: %s\n", tno, rc, zErrMsg); + sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg); sqlite3_free(zErrMsg); }else if( cli_strcmp(zAns,str.z)!=0 ){ nErr++; rc = 1; - oputf("%d: Expected: [%s]\n", tno, zAns); - oputf("%d: Got: [%s]\n", tno, str.z); + sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns); + sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.z); } } else{ - eputf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno); + sqlite3_fprintf(stderr, + "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); rc = 1; break; } @@ -27186,7 +31098,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_finalize(pStmt); } /* End loop over k */ freeText(&str); - oputf("%d errors out of %d tests\n", nErr, nTest); + sqlite3_fprintf(p->out, "%d errors out of %d tests\n", nErr, nTest); }else if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){ @@ -27234,7 +31146,8 @@ static int do_meta_command(char *zLine, ShellState *p){ bDebug = 1; }else { - eputf("Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); + sqlite3_fprintf(stderr, + "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); showHelp(p->out, azArg[0]); rc = 1; goto meta_command_exit; @@ -27312,7 +31225,7 @@ static int do_meta_command(char *zLine, ShellState *p){ freeText(&sQuery); freeText(&sSql); if( bDebug ){ - oputf("%s\n", zSql); + sqlite3_fprintf(p->out, "%s\n", zSql); }else{ shell_exec(p, zSql, 0); } @@ -27342,7 +31255,7 @@ static int do_meta_command(char *zLine, ShellState *p){ "' OR ') as query, tname from tabcols group by tname)" , zRevText); shell_check_oom(zRevText); - if( bDebug ) oputf("%s\n", zRevText); + if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zRevText); lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0); if( lrc!=SQLITE_OK ){ /* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the @@ -27355,7 +31268,7 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0); sqlite3_stmt *pCheckStmt; lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0); - if( bDebug ) oputf("%s\n", zGenQuery); + if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zGenQuery); if( lrc!=SQLITE_OK ){ rc = 1; }else{ @@ -27363,7 +31276,8 @@ static int do_meta_command(char *zLine, ShellState *p){ double countIrreversible = sqlite3_column_double(pCheckStmt, 0); if( countIrreversible>0 ){ int sz = (int)(countIrreversible + 0.5); - eputf("Digest includes %d invalidly encoded text field%s.\n", + sqlite3_fprintf(stderr, + "Digest includes %d invalidly encoded text field%s.\n", sz, (sz>1)? "s": ""); } } @@ -27397,11 +31311,11 @@ static int do_meta_command(char *zLine, ShellState *p){ zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"", zCmd, azArg[i]); } - consoleRestore(); + /*consoleRestore();*/ x = zCmd!=0 ? system(zCmd) : 1; - consoleRenewSetup(); + /*consoleRenewSetup();*/ sqlite3_free(zCmd); - if( x ) eputf("System command returns %d\n", x); + if( x ) sqlite3_fprintf(stderr,"System command returns %d\n", x); }else #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */ @@ -27414,46 +31328,48 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - oputf("%12.12s: %s\n","echo", + sqlite3_fprintf(p->out, "%12.12s: %s\n","echo", azBool[ShellHasFlag(p, SHFLG_Echo)]); - oputf("%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); - oputf("%12.12s: %s\n","explain", + sqlite3_fprintf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); + sqlite3_fprintf(p->out, "%12.12s: %s\n","explain", p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); - oputf("%12.12s: %s\n","headers", azBool[p->showHeader!=0]); + sqlite3_fprintf(p->out, "%12.12s: %s\n","headers", + azBool[p->showHeader!=0]); if( p->mode==MODE_Column || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) ){ - oputf("%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", + sqlite3_fprintf(p->out, + "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", modeDescr[p->mode], p->cmOpts.iWrap, p->cmOpts.bWordWrap ? "on" : "off", p->cmOpts.bQuote ? "" : "no"); }else{ - oputf("%12.12s: %s\n","mode", modeDescr[p->mode]); + sqlite3_fprintf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); } - oputf("%12.12s: ", "nullvalue"); - output_c_string(p->nullValue); - oputz("\n"); - oputf("%12.12s: %s\n","output", + sqlite3_fprintf(p->out, "%12.12s: ", "nullvalue"); + output_c_string(p->out, p->nullValue); + sqlite3_fputs("\n", p->out); + sqlite3_fprintf(p->out, "%12.12s: %s\n","output", strlen30(p->outfile) ? p->outfile : "stdout"); - oputf("%12.12s: ", "colseparator"); - output_c_string(p->colSeparator); - oputz("\n"); - oputf("%12.12s: ", "rowseparator"); - output_c_string(p->rowSeparator); - oputz("\n"); + sqlite3_fprintf(p->out, "%12.12s: ", "colseparator"); + output_c_string(p->out, p->colSeparator); + sqlite3_fputs("\n", p->out); + sqlite3_fprintf(p->out, "%12.12s: ", "rowseparator"); + output_c_string(p->out, p->rowSeparator); + sqlite3_fputs("\n", p->out); switch( p->statsOn ){ case 0: zOut = "off"; break; default: zOut = "on"; break; case 2: zOut = "stmt"; break; case 3: zOut = "vmstep"; break; } - oputf("%12.12s: %s\n","stats", zOut); - oputf("%12.12s: ", "width"); + sqlite3_fprintf(p->out, "%12.12s: %s\n","stats", zOut); + sqlite3_fprintf(p->out, "%12.12s: ", "width"); for (i=0;i<p->nWidth;i++) { - oputf("%d ", p->colWidth[i]); + sqlite3_fprintf(p->out, "%d ", p->colWidth[i]); } - oputz("\n"); - oputf("%12.12s: %s\n", "filename", + sqlite3_fputs("\n", p->out); + sqlite3_fprintf(p->out, "%12.12s: %s\n", "filename", p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : ""); }else @@ -27571,9 +31487,10 @@ static int do_meta_command(char *zLine, ShellState *p){ for(i=0; i<nPrintRow; i++){ for(j=i; j<nRow; j+=nPrintRow){ char *zSp = j<nPrintRow ? "" : " "; - oputf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); + sqlite3_fprintf(p->out, + "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); } - oputz("\n"); + sqlite3_fputs("\n", p->out); } } @@ -27585,7 +31502,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* Begin redirecting output to the file "testcase-out.txt" */ if( c=='t' && cli_strcmp(azArg[0],"testcase")==0 ){ output_reset(p); - p->out = output_file_open("testcase-out.txt", 0); + p->out = output_file_open("testcase-out.txt"); if( p->out==0 ){ eputz("Error: cannot open 'testcase-out.txt'\n"); } @@ -27611,24 +31528,24 @@ static int do_meta_command(char *zLine, ShellState *p){ /*{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/ {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, - /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/ + {"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." }, {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" }, {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" }, + {"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" }, {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" }, {"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" }, - {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" }, + {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK ..."}, #ifdef YYCOVERAGE {"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" }, #endif - {"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " }, + {"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,1, "OFFSET " }, {"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" }, {"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" }, {"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" }, {"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" }, {"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" }, {"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" }, - {"uselongdouble", SQLITE_TESTCTRL_USELONGDOUBLE,0,"?BOOLEAN|\"default\"?"}, }; int testctrl = -1; int iCtrl = -1; @@ -27648,10 +31565,10 @@ static int do_meta_command(char *zLine, ShellState *p){ /* --help lists all test-controls */ if( cli_strcmp(zCmd,"help")==0 ){ - oputz("Available test-controls:\n"); + sqlite3_fputs("Available test-controls:\n", p->out); for(i=0; i<ArraySize(aCtrl); i++){ if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue; - oputf(" .testctrl %s %s\n", + sqlite3_fprintf(p->out, " .testctrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); } rc = 1; @@ -27668,7 +31585,7 @@ static int do_meta_command(char *zLine, ShellState *p){ testctrl = aCtrl[i].ctrlCode; iCtrl = i; }else{ - eputf("Error: ambiguous test-control: \"%s\"\n" + sqlite3_fprintf(stderr,"Error: ambiguous test-control: \"%s\"\n" "Use \".testctrl --help\" for help\n", zCmd); rc = 1; goto meta_command_exit; @@ -27676,13 +31593,130 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( testctrl<0 ){ - eputf("Error: unknown test-control: %s\n" + sqlite3_fprintf(stderr,"Error: unknown test-control: %s\n" "Use \".testctrl --help\" for help\n", zCmd); }else{ switch(testctrl){ + /* Special processing for .testctrl opt MASK ... + ** Each MASK argument can be one of: + ** + ** +LABEL Enable the named optimization + ** + ** -LABEL Disable the named optimization + ** + ** INTEGER Mask of optimizations to disable + */ + case SQLITE_TESTCTRL_OPTIMIZATIONS: { + static const struct { + unsigned int mask; /* Mask for this optimization */ + unsigned int bDsply; /* Display this on output */ + const char *zLabel; /* Name of optimization */ + } aLabel[] = { + { 0x00000001, 1, "QueryFlattener" }, + { 0x00000001, 0, "Flatten" }, + { 0x00000002, 1, "WindowFunc" }, + { 0x00000004, 1, "GroupByOrder" }, + { 0x00000008, 1, "FactorOutConst" }, + { 0x00000010, 1, "DistinctOpt" }, + { 0x00000020, 1, "CoverIdxScan" }, + { 0x00000040, 1, "OrderByIdxJoin" }, + { 0x00000080, 1, "Transitive" }, + { 0x00000100, 1, "OmitNoopJoin" }, + { 0x00000200, 1, "CountOfView" }, + { 0x00000400, 1, "CurosrHints" }, + { 0x00000800, 1, "Stat4" }, + { 0x00001000, 1, "PushDown" }, + { 0x00002000, 1, "SimplifyJoin" }, + { 0x00004000, 1, "SkipScan" }, + { 0x00008000, 1, "PropagateConst" }, + { 0x00010000, 1, "MinMaxOpt" }, + { 0x00020000, 1, "SeekScan" }, + { 0x00040000, 1, "OmitOrderBy" }, + { 0x00080000, 1, "BloomFilter" }, + { 0x00100000, 1, "BloomPulldown" }, + { 0x00200000, 1, "BalancedMerge" }, + { 0x00400000, 1, "ReleaseReg" }, + { 0x00800000, 1, "FlttnUnionAll" }, + { 0x01000000, 1, "IndexedEXpr" }, + { 0x02000000, 1, "Coroutines" }, + { 0x04000000, 1, "NullUnusedCols" }, + { 0x08000000, 1, "OnePass" }, + { 0x10000000, 1, "OrderBySubq" }, + { 0xffffffff, 0, "All" }, + }; + unsigned int curOpt; + unsigned int newOpt; + unsigned int m; + int ii; + int nOff; + sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt); + newOpt = curOpt; + for(ii=2; ii<nArg; ii++){ + const char *z = azArg[ii]; + int useLabel = 0; + const char *zLabel = 0; + if( (z[0]=='+'|| z[0]=='-') && !IsDigit(z[1]) ){ + useLabel = z[0]; + zLabel = &z[1]; + }else if( !IsDigit(z[0]) && z[0]!=0 && !IsDigit(z[1]) ){ + useLabel = '+'; + zLabel = z; + }else{ + newOpt = (unsigned int)strtol(z,0,0); + } + if( useLabel ){ + int jj; + for(jj=0; jj<ArraySize(aLabel); jj++){ + if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break; + } + if( jj>=ArraySize(aLabel) ){ + sqlite3_fprintf(stderr, + "Error: no such optimization: \"%s\"\n", zLabel); + sqlite3_fputs("Should be one of:", stderr); + for(jj=0; jj<ArraySize(aLabel); jj++){ + sqlite3_fprintf(stderr," %s", aLabel[jj].zLabel); + } + sqlite3_fputs("\n", stderr); + rc = 1; + goto meta_command_exit; + } + if( useLabel=='+' ){ + newOpt &= ~aLabel[jj].mask; + }else{ + newOpt |= aLabel[jj].mask; + } + } + } + if( curOpt!=newOpt ){ + sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt); + } + for(ii=nOff=0, m=1; ii<32; ii++, m <<= 1){ + if( m & newOpt ) nOff++; + } + if( nOff<12 ){ + sqlite3_fputs("+All", p->out); + for(ii=0; ii<ArraySize(aLabel); ii++){ + if( !aLabel[ii].bDsply ) continue; + if( (newOpt & aLabel[ii].mask)!=0 ){ + sqlite3_fprintf(p->out, " -%s", aLabel[ii].zLabel); + } + } + }else{ + sqlite3_fputs("-All", p->out); + for(ii=0; ii<ArraySize(aLabel); ii++){ + if( !aLabel[ii].bDsply ) continue; + if( (newOpt & aLabel[ii].mask)==0 ){ + sqlite3_fprintf(p->out, " +%s", aLabel[ii].zLabel); + } + } + } + sqlite3_fputs("\n", p->out); + rc2 = isOk = 3; + break; + } + /* sqlite3_test_control(int, db, int) */ - case SQLITE_TESTCTRL_OPTIMIZATIONS: case SQLITE_TESTCTRL_FK_NO_ACTION: if( nArg==3 ){ unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); @@ -27717,7 +31751,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3 *db; if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){ sqlite3_randomness(sizeof(ii),&ii); - sputf(stdout, "-- random seed: %d\n", ii); + sqlite3_fprintf(stdout, "-- random seed: %d\n", ii); } if( nArg==3 ){ db = 0; @@ -27751,21 +31785,6 @@ static int do_meta_command(char *zLine, ShellState *p){ } break; - /* sqlite3_test_control(int, int) */ - case SQLITE_TESTCTRL_USELONGDOUBLE: { - int opt = -1; - if( nArg==3 ){ - if( cli_strcmp(azArg[2],"default")==0 ){ - opt = 2; - }else{ - opt = booleanValue(azArg[2]); - } - } - rc2 = sqlite3_test_control(testctrl, opt); - isOk = 1; - break; - } - /* sqlite3_test_control(sqlite3*) */ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: rc2 = sqlite3_test_control(testctrl, p->db); @@ -27785,7 +31804,7 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_SEEK_COUNT: { u64 x = 0; rc2 = sqlite3_test_control(testctrl, p->db, &x); - oputf("%llu\n", x); + sqlite3_fprintf(p->out, "%llu\n", x); isOk = 3; break; } @@ -27816,11 +31835,11 @@ static int do_meta_command(char *zLine, ShellState *p){ int val = 0; rc2 = sqlite3_test_control(testctrl, -id, &val); if( rc2!=SQLITE_OK ) break; - if( id>1 ) oputz(" "); - oputf("%d: %d", id, val); + if( id>1 ) sqlite3_fputs(" ", p->out); + sqlite3_fprintf(p->out, "%d: %d", id, val); id++; } - if( id>1 ) oputz("\n"); + if( id>1 ) sqlite3_fputs("\n", p->out); isOk = 3; } break; @@ -27833,15 +31852,106 @@ static int do_meta_command(char *zLine, ShellState *p){ isOk = 3; } break; + case SQLITE_TESTCTRL_JSON_SELFCHECK: + if( nArg==2 ){ + rc2 = -1; + isOk = 1; + }else{ + rc2 = booleanValue(azArg[2]); + isOk = 3; + } + sqlite3_test_control(testctrl, &rc2); + break; + case SQLITE_TESTCTRL_FAULT_INSTALL: { + int kk; + int bShowHelp = nArg<=2; + isOk = 3; + for(kk=2; kk<nArg; kk++){ + const char *z = azArg[kk]; + if( z[0]=='-' && z[1]=='-' ) z++; + if( cli_strcmp(z,"off")==0 ){ + sqlite3_test_control(testctrl, 0); + }else if( cli_strcmp(z,"on")==0 ){ + faultsim_state.iCnt = faultsim_state.nSkip; + if( faultsim_state.iErr==0 ) faultsim_state.iErr = 1; + faultsim_state.nHit = 0; + sqlite3_test_control(testctrl, faultsim_callback); + }else if( cli_strcmp(z,"reset")==0 ){ + faultsim_state.iCnt = faultsim_state.nSkip; + faultsim_state.nHit = 0; + sqlite3_test_control(testctrl, faultsim_callback); + }else if( cli_strcmp(z,"status")==0 ){ + sqlite3_fprintf(p->out, "faultsim.iId: %d\n", + faultsim_state.iId); + sqlite3_fprintf(p->out, "faultsim.iErr: %d\n", + faultsim_state.iErr); + sqlite3_fprintf(p->out, "faultsim.iCnt: %d\n", + faultsim_state.iCnt); + sqlite3_fprintf(p->out, "faultsim.nHit: %d\n", + faultsim_state.nHit); + sqlite3_fprintf(p->out, "faultsim.iInterval: %d\n", + faultsim_state.iInterval); + sqlite3_fprintf(p->out, "faultsim.eVerbose: %d\n", + faultsim_state.eVerbose); + sqlite3_fprintf(p->out, "faultsim.nRepeat: %d\n", + faultsim_state.nRepeat); + sqlite3_fprintf(p->out, "faultsim.nSkip: %d\n", + faultsim_state.nSkip); + }else if( cli_strcmp(z,"-v")==0 ){ + if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++; + }else if( cli_strcmp(z,"-q")==0 ){ + if( faultsim_state.eVerbose>0 ) faultsim_state.eVerbose--; + }else if( cli_strcmp(z,"-id")==0 && kk+1<nArg ){ + faultsim_state.iId = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-errcode")==0 && kk+1<nArg ){ + faultsim_state.iErr = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-interval")==0 && kk+1<nArg ){ + faultsim_state.iInterval = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-repeat")==0 && kk+1<nArg ){ + faultsim_state.nRepeat = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-skip")==0 && kk+1<nArg ){ + faultsim_state.nSkip = atoi(azArg[++kk]); + }else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){ + bShowHelp = 1; + }else{ + sqlite3_fprintf(stderr, + "Unrecognized fault_install argument: \"%s\"\n", + azArg[kk]); + rc = 1; + bShowHelp = 1; + break; + } + } + if( bShowHelp ){ + sqlite3_fputs( + "Usage: .testctrl fault_install ARGS\n" + "Possible arguments:\n" + " off Disable faultsim\n" + " on Activate faultsim\n" + " reset Reset the trigger counter\n" + " status Show current status\n" + " -v Increase verbosity\n" + " -q Decrease verbosity\n" + " --errcode N When triggered, return N as error code\n" + " --id ID Trigger only for the ID specified\n" + " --interval N Trigger only after every N-th call\n" + " --repeat N Turn off after N hits. 0 means never\n" + " --skip N Skip the first N encounters\n" + ,p->out + ); + } + break; + } } } if( isOk==0 && iCtrl>=0 ){ - oputf("Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); + sqlite3_fprintf(p->out, + "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); rc = 1; }else if( isOk==1 ){ - oputf("%d\n", rc2); + sqlite3_fprintf(p->out, "%d\n", rc2); }else if( isOk==2 ){ - oputf("0x%08x\n", rc2); + sqlite3_fprintf(p->out, "0x%08x\n", rc2); } }else #endif /* !defined(SQLITE_UNTESTABLE) */ @@ -27896,13 +32006,13 @@ static int do_meta_command(char *zLine, ShellState *p){ mType |= SQLITE_TRACE_CLOSE; } else { - eputf("Unknown option \"%s\" on \".trace\"\n", z); + sqlite3_fprintf(stderr,"Unknown option \"%s\" on \".trace\"\n", z); rc = 1; goto meta_command_exit; } }else{ output_file_close(p->traceOut); - p->traceOut = output_file_open(z, 0); + p->traceOut = output_file_open(z); } } if( p->traceOut==0 ){ @@ -27939,86 +32049,25 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif -#if SQLITE_USER_AUTHENTICATION - if( c=='u' && cli_strncmp(azArg[0], "user", n)==0 ){ - if( nArg<2 ){ - eputz("Usage: .user SUBCOMMAND ...\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); - if( cli_strcmp(azArg[1],"login")==0 ){ - if( nArg!=4 ){ - eputz("Usage: .user login USER PASSWORD\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], - strlen30(azArg[3])); - if( rc ){ - eputf("Authentication failed for user %s\n", azArg[2]); - rc = 1; - } - }else if( cli_strcmp(azArg[1],"add")==0 ){ - if( nArg!=5 ){ - eputz("Usage: .user add USER PASSWORD ISADMIN\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - eputf("User-Add failed: %d\n", rc); - rc = 1; - } - }else if( cli_strcmp(azArg[1],"edit")==0 ){ - if( nArg!=5 ){ - eputz("Usage: .user edit USER PASSWORD ISADMIN\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - eputf("User-Edit failed: %d\n", rc); - rc = 1; - } - }else if( cli_strcmp(azArg[1],"delete")==0 ){ - if( nArg!=3 ){ - eputz("Usage: .user delete USER\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_delete(p->db, azArg[2]); - if( rc ){ - eputf("User-Delete failed: %d\n", rc); - rc = 1; - } - }else{ - eputz("Usage: .user login|add|edit|delete ...\n"); - rc = 1; - goto meta_command_exit; - } - }else -#endif /* SQLITE_USER_AUTHENTICATION */ - if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){ char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit"; - oputf("SQLite %s %s\n" /*extra-version-info*/, + sqlite3_fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); + extern char* sqlite3mc_version(); + sqlite3_fprintf(p->out, "%s\n", sqlite3mc_version()); #if SQLITE_HAVE_ZLIB - oputf("zlib version %s\n", zlibVersion()); + sqlite3_fprintf(p->out, "zlib version %s\n", zlibVersion()); #endif #define CTIMEOPT_VAL_(opt) #opt #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) #if defined(__clang__) && defined(__clang_major__) - oputf("clang-" CTIMEOPT_VAL(__clang_major__) "." + sqlite3_fprintf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." CTIMEOPT_VAL(__clang_minor__) "." CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz); #elif defined(_MSC_VER) - oputf("msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz); + sqlite3_fprintf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz); #elif defined(__GNUC__) && defined(__VERSION__) - oputf("gcc-" __VERSION__ " (%s)\n", zPtrSz); + sqlite3_fprintf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz); #endif }else @@ -28028,10 +32077,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->db ){ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); if( pVfs ){ - oputf("vfs.zName = \"%s\"\n", pVfs->zName); - oputf("vfs.iVersion = %d\n", pVfs->iVersion); - oputf("vfs.szOsFile = %d\n", pVfs->szOsFile); - oputf("vfs.mxPathname = %d\n", pVfs->mxPathname); + sqlite3_fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); + sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); + sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); + sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); } } }else @@ -28043,13 +32092,13 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent); } for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ - oputf("vfs.zName = \"%s\"%s\n", pVfs->zName, + sqlite3_fprintf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName, pVfs==pCurrent ? " <--- CURRENT" : ""); - oputf("vfs.iVersion = %d\n", pVfs->iVersion); - oputf("vfs.szOsFile = %d\n", pVfs->szOsFile); - oputf("vfs.mxPathname = %d\n", pVfs->mxPathname); + sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); + sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); + sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); if( pVfs->pNext ){ - oputz("-----------------------------------\n"); + sqlite3_fputs("-----------------------------------\n", p->out); } } }else @@ -28060,7 +32109,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->db ){ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); if( zVfsName ){ - oputf("%s\n", zVfsName); + sqlite3_fprintf(p->out, "%s\n", zVfsName); sqlite3_free(zVfsName); } } @@ -28084,7 +32133,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else { - eputf("Error: unknown command or invalid arguments: " + sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: " " \"%s\". Enter \".help\" for help\n", azArg[0]); rc = 1; } @@ -28125,7 +32174,6 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, char cWait = (char)qss; /* intentional narrowing loss */ if( cWait==0 ){ PlainScan: - assert( cWait==0 ); while( (cin = *zLine++)!=0 ){ if( IsSpace(cin) ) continue; @@ -28151,7 +32199,7 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, break; case '[': cin = ']'; - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ case '`': case '\'': case '"': cWait = cin; qss = QSS_HasDark | cWait; @@ -28177,7 +32225,6 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, if( *zLine != '/' ) continue; ++zLine; - cWait = 0; CONTINUE_PROMPT_AWAITC(pst, 0); qss = QSS_SETV(qss, 0); goto PlainScan; @@ -28187,9 +32234,8 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss, ++zLine; continue; } - deliberate_fall_through; + deliberate_fall_through; /* FALLTHRU */ case ']': - cWait = 0; CONTINUE_PROMPT_AWAITC(pst, 0); qss = QSS_SETV(qss, 0); goto PlainScan; @@ -28239,6 +32285,91 @@ static int line_is_complete(char *zSql, int nSql){ return rc; } +/* +** This function is called after processing each line of SQL in the +** runOneSqlLine() function. Its purpose is to detect scenarios where +** defensive mode should be automatically turned off. Specifically, when +** +** 1. The first line of input is "PRAGMA foreign_keys=OFF;", +** 2. The second line of input is "BEGIN TRANSACTION;", +** 3. The database is empty, and +** 4. The shell is not running in --safe mode. +** +** The implementation uses the ShellState.eRestoreState to maintain state: +** +** 0: Have not seen any SQL. +** 1: Have seen "PRAGMA foreign_keys=OFF;". +** 2-6: Currently running .dump transaction. If the "2" bit is set, +** disable DEFENSIVE when done. If "4" is set, disable DQS_DDL. +** 7: Nothing left to do. This function becomes a no-op. +*/ +static int doAutoDetectRestore(ShellState *p, const char *zSql){ + int rc = SQLITE_OK; + + if( p->eRestoreState<7 ){ + switch( p->eRestoreState ){ + case 0: { + const char *zExpect = "PRAGMA foreign_keys=OFF;"; + assert( strlen(zExpect)==24 ); + if( p->bSafeMode==0 + && strlen(zSql)>=24 + && memcmp(zSql, zExpect, 25)==0 + ){ + p->eRestoreState = 1; + }else{ + p->eRestoreState = 7; + } + break; + }; + + case 1: { + int bIsDump = 0; + const char *zExpect = "BEGIN TRANSACTION;"; + assert( strlen(zExpect)==18 ); + if( memcmp(zSql, zExpect, 19)==0 ){ + /* Now check if the database is empty. */ + const char *zQuery = "SELECT 1 FROM sqlite_schema LIMIT 1"; + sqlite3_stmt *pStmt = 0; + + bIsDump = 1; + shellPrepare(p->db, &rc, zQuery, &pStmt); + if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ + bIsDump = 0; + } + shellFinalize(&rc, pStmt); + } + if( bIsDump && rc==SQLITE_OK ){ + int bDefense = 0; + int bDqsDdl = 0; + sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &bDefense); + sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, -1, &bDqsDdl); + sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0); + sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, 1, 0); + p->eRestoreState = (bDefense ? 2 : 0) + (bDqsDdl ? 4 : 0); + }else{ + p->eRestoreState = 7; + } + break; + } + + default: { + if( sqlite3_get_autocommit(p->db) ){ + if( (p->eRestoreState & 2) ){ + sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 1, 0); + } + if( (p->eRestoreState & 4) ){ + sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, 0, 0); + } + p->eRestoreState = 7; + } + break; + } + } + } + + return rc; +} + /* ** Run a single line of SQL. Return the number of errors. */ @@ -28251,7 +32382,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; BEGIN_TIMER; rc = shell_exec(p, zSql, &zErrMsg); - END_TIMER; + END_TIMER(p->out); if( rc || zErrMsg ){ char zPrefix[100]; const char *zErrorTail; @@ -28275,7 +32406,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType); } - eputf("%s %s\n", zPrefix, zErrorTail); + sqlite3_fprintf(stderr,"%s %s\n", zPrefix, zErrorTail); sqlite3_free(zErrMsg); zErrMsg = 0; return 1; @@ -28284,13 +32415,18 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ sqlite3_snprintf(sizeof(zLineBuf), zLineBuf, "changes: %lld total_changes: %lld", sqlite3_changes64(p->db), sqlite3_total_changes64(p->db)); - oputf("%s\n", zLineBuf); + sqlite3_fprintf(p->out, "%s\n", zLineBuf); } + + if( doAutoDetectRestore(p, zSql) ) return 1; return 0; } static void echo_group_input(ShellState *p, const char *zDo){ - if( ShellHasFlag(p, SHFLG_Echo) ) oputf("%s\n", zDo); + if( ShellHasFlag(p, SHFLG_Echo) ){ + sqlite3_fprintf(p->out, "%s\n", zDo); + fflush(p->out); + } } #ifdef SQLITE_SHELL_FIDDLE @@ -28348,7 +32484,7 @@ static int process_input(ShellState *p){ if( p->inputNesting==MAX_INPUT_NESTING ){ /* This will be more informative in a later version. */ - eputf("Input nesting limit (%d) reached at line %d." + sqlite3_fprintf(stderr,"Input nesting limit (%d) reached at line %d." " Check recursion.\n", MAX_INPUT_NESTING, p->lineno); return 1; } @@ -28360,7 +32496,7 @@ static int process_input(ShellState *p){ zLine = one_input_line(p->in, zLine, nSql>0); if( zLine==0 ){ /* End of input */ - if( p->in==0 && stdin_is_interactive ) oputz("\n"); + if( p->in==0 && stdin_is_interactive ) sqlite3_fputs("\n", p->out); break; } if( seenInterrupt ){ @@ -28517,27 +32653,29 @@ static char *find_home_dir(int clearFlag){ /* ** On non-Windows platforms, look for $XDG_CONFIG_HOME. ** If ${XDG_CONFIG_HOME}/sqlite3/sqliterc is found, return -** the path to it, else return 0. The result is cached for -** subsequent calls. +** the path to it. If there is no $(XDG_CONFIG_HOME) then +** look for $(HOME)/.config/sqlite3/sqliterc and if found +** return that. If none of these are found, return 0. +** +** The string returned is obtained from sqlite3_malloc() and +** should be freed by the caller. */ -static const char *find_xdg_config(void){ +static char *find_xdg_config(void){ #if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \ || defined(__RTP__) || defined(_WRS_KERNEL) return 0; #else - static int alreadyTried = 0; - static char *zConfig = 0; + char *zConfig = 0; const char *zXdgHome; - if( alreadyTried!=0 ){ - return zConfig; - } - alreadyTried = 1; zXdgHome = getenv("XDG_CONFIG_HOME"); if( zXdgHome==0 ){ - return 0; + const char *zHome = getenv("HOME"); + if( zHome==0 ) return 0; + zConfig = sqlite3_mprintf("%s/.config/sqlite3/sqliterc", zHome); + }else{ + zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome); } - zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome); shell_check_oom(zConfig); if( access(zConfig,0)!=0 ){ sqlite3_free(zConfig); @@ -28565,7 +32703,7 @@ static void process_sqliterc( int savedLineno = p->lineno; if( sqliterc == NULL ){ - sqliterc = find_xdg_config(); + sqliterc = zBuf = find_xdg_config(); } if( sqliterc == NULL ){ home_dir = find_home_dir(0); @@ -28578,15 +32716,15 @@ static void process_sqliterc( shell_check_oom(zBuf); sqliterc = zBuf; } - p->in = fopen(sqliterc,"rb"); + p->in = sqlite3_fopen(sqliterc,"rb"); if( p->in ){ if( stdin_is_interactive ){ - eputf("-- Loading resources from %s\n", sqliterc); + sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc); } if( process_input(p) && bail_on_error ) exit(1); fclose(p->in); }else if( sqliterc_override!=0 ){ - eputf("cannot open: \"%s\"\n", sqliterc); + sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc); if( bail_on_error ) exit(1); } p->in = inSaved; @@ -28638,6 +32776,7 @@ static const char zOptions[] = " -newline SEP set output row separator. Default: '\\n'\n" " -nofollow refuse to open symbolic links to database files\n" " -nonce STRING set the safe-mode escape nonce\n" + " -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n" " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" " -pcachetrace trace all page cache operations\n" @@ -28654,23 +32793,21 @@ static const char zOptions[] = " -unsafe-testing allow unsafe commands and modes for testing\n" " -version show SQLite version\n" " -vfs NAME use NAME as the default VFS\n" -#ifdef SQLITE_ENABLE_VFSTRACE " -vfstrace enable tracing of all VFS calls\n" -#endif #ifdef SQLITE_HAVE_ZLIB " -zip open the file as a ZIP Archive\n" #endif ; static void usage(int showDetail){ - eputf("Usage: %s [OPTIONS] [FILENAME [SQL]]\n" + sqlite3_fprintf(stderr,"Usage: %s [OPTIONS] [FILENAME [SQL]]\n" "FILENAME is the name of an SQLite database. A new database is created\n" "if the file does not previously exist. Defaults to :memory:.\n", Argv0); if( showDetail ){ - eputf("OPTIONS include:\n%s", zOptions); + sqlite3_fprintf(stderr,"OPTIONS include:\n%s", zOptions); }else{ eputz("Use the -help option for additional information\n"); } - exit(1); + exit(0); } /* @@ -28691,6 +32828,9 @@ static void main_init(ShellState *data) { memset(data, 0, sizeof(*data)); data->normalMode = data->cMode = data->mode = MODE_List; data->autoExplain = 1; +#ifdef _WIN32 + data->crlfMode = 1; +#endif data->pAuxDb = &data->aAuxDb[0]; memcpy(data->colSeparator,SEP_Column, 2); memcpy(data->rowSeparator,SEP_Row, 2); @@ -28719,14 +32859,14 @@ static void printBold(const char *zText){ FOREGROUND_RED|FOREGROUND_INTENSITY ); #endif - oputz(zText); + sputz(stdout, zText); #if !SQLITE_OS_WINRT SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); #endif } #else static void printBold(const char *zText){ - oputf("\033[1m%s\033[0m", zText); + sqlite3_fprintf(stdout, "\033[1m%s\033[0m", zText); } #endif @@ -28736,7 +32876,8 @@ static void printBold(const char *zText){ */ static char *cmdline_option_value(int argc, char **argv, int i){ if( i==argc ){ - eputf("%s: Error: missing argument to %s\n", argv[0], argv[argc-1]); + sqlite3_fprintf(stderr, + "%s: Error: missing argument to %s\n", argv[0], argv[argc-1]); exit(1); } return argv[i]; @@ -28746,6 +32887,15 @@ static void sayAbnormalExit(void){ if( seenInterrupt ) eputz("Program interrupted.\n"); } +/* Routine to output from vfstrace +*/ +static int vfstraceOut(const char *z, void *pArg){ + ShellState *p = (ShellState*)pArg; + sqlite3_fputs(z, p->out); + fflush(p->out); + return 1; +} + #ifndef SQLITE_SHELL_IS_UTF8 # if (defined(_WIN32) || defined(WIN32)) \ && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__))) @@ -28773,7 +32923,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ # define data shellState #else ShellState data; - StreamsAreConsole consStreams = SAC_NoConsole; #endif const char *zInitFile = 0; int i; @@ -28782,6 +32931,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ int readStdin = 1; int nCmd = 0; int nOptsEnd = argc; + int bEnableVfstrace = 0; char **azCmd = 0; const char *zVfs = 0; /* Value of -vfs command-line option */ #if !SQLITE_SHELL_IS_UTF8 @@ -28795,10 +32945,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ stdout_is_console = 1; data.wasm.zDefaultDbName = "/fiddle.sqlite3"; #else - consStreams = consoleClassifySetup(stdin, stdout, stderr); - stdin_is_interactive = (consStreams & SAC_InConsole)!=0; - stdout_is_console = (consStreams & SAC_OutConsole)!=0; - atexit(consoleRestore); + stdin_is_interactive = isatty(0); + stdout_is_console = isatty(1); #endif atexit(sayAbnormalExit); #ifdef SQLITE_DEBUG @@ -28807,9 +32955,15 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #if !defined(_WIN32_WCE) if( getenv("SQLITE_DEBUG_BREAK") ){ if( isatty(0) && isatty(2) ){ - eputf("attach debugger to process %d and press any key to continue.\n", + char zLine[100]; + sqlite3_fprintf(stderr, + "attach debugger to process %d and press ENTER to continue...", GETPID()); - fgetc(stdin); + if( sqlite3_fgets(zLine, sizeof(zLine), stdin)!=0 + && cli_strcmp(zLine,"stop")==0 + ){ + exit(1); + } }else{ #if defined(_WIN32) || defined(WIN32) #if SQLITE_OS_WINRT @@ -28832,6 +32986,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } #endif +#if USE_SYSTEM_SQLITE+0!=1 + if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ + sqlite3_fprintf(stderr, + "SQLite header and source version mismatch\n%s\n%s\n", + sqlite3_sourceid(), SQLITE_SOURCE_ID); + exit(1); + } +#endif main_init(&data); /* On Windows, we must translate command-line arguments into UTF-8. @@ -28913,10 +33075,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( cli_strcmp(z,"-init")==0 ){ zInitFile = cmdline_option_value(argc, argv, ++i); }else if( cli_strcmp(z,"-interactive")==0 ){ - /* Need to check for interactive override here to so that it can - ** affect console setup (for Windows only) and testing thereof. - */ - stdin_is_interactive = 1; }else if( cli_strcmp(z,"-batch")==0 ){ /* Need to check for batch mode here to so we can avoid printing ** informational messages (like from process_sqliterc) before @@ -28925,6 +33083,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ stdin_is_interactive = 0; }else if( cli_strcmp(z,"-utf8")==0 ){ }else if( cli_strcmp(z,"-no-utf8")==0 ){ + }else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){ + int val = 0; + sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW, &val); + assert( val==0 ); }else if( cli_strcmp(z,"-heap")==0 ){ #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) const char *zSize; @@ -28969,17 +33131,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break; default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break; } -#ifdef SQLITE_ENABLE_VFSTRACE }else if( cli_strcmp(z,"-vfstrace")==0 ){ - extern int vfstrace_register( - const char *zTraceName, - const char *zOldVfsName, - int (*xOut)(const char*,void*), - void *pOutArg, - int makeDefault - ); - vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); -#endif + bEnableVfstrace = 1; #ifdef SQLITE_ENABLE_MULTIPLEX }else if( cli_strcmp(z,"-multiplex")==0 ){ extern int sqlite3_multiplex_initialize(const char*,int); @@ -29035,7 +33188,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } } #ifndef SQLITE_SHELL_FIDDLE - verify_uninitialized(); + if( !bEnableVfstrace ) verify_uninitialized(); #endif @@ -29059,7 +33212,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( pVfs ){ sqlite3_vfs_register(pVfs, 1); }else{ - eputf("no such VFS: \"%s\"\n", zVfs); + sqlite3_fprintf(stderr,"no such VFS: \"%s\"\n", zVfs); exit(1); } } @@ -29069,11 +33222,15 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ data.pAuxDb->zDbFilename = ":memory:"; warnInmemoryDb = argc==1; #else - eputf("%s: Error: no database filename specified\n", Argv0); + sqlite3_fprintf(stderr, + "%s: Error: no database filename specified\n", Argv0); return 1; #endif } data.out = stdout; + if( bEnableVfstrace ){ + vfstrace_register("trace",0,vfstraceOut, &data, 1); + } #ifndef SQLITE_SHELL_FIDDLE sqlite3_appendvfs_init(0,0,0); #endif @@ -29186,17 +33343,22 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( cli_strcmp(z,"-bail")==0 ){ /* No-op. The bail_on_error flag should already be set. */ }else if( cli_strcmp(z,"-version")==0 ){ - oputf("%s %s (%d-bit)\n", sqlite3_libversion(), sqlite3_sourceid(), - 8*(int)sizeof(char*)); + sqlite3_fprintf(stdout, "%s %s (%d-bit)\n", + sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*)); return 0; }else if( cli_strcmp(z,"-interactive")==0 ){ - /* already handled */ + /* Need to check for interactive override here to so that it can + ** affect console setup (for Windows only) and testing thereof. + */ + stdin_is_interactive = 1; }else if( cli_strcmp(z,"-batch")==0 ){ /* already handled */ }else if( cli_strcmp(z,"-utf8")==0 ){ /* already handled */ }else if( cli_strcmp(z,"-no-utf8")==0 ){ /* already handled */ + }else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){ + /* already handled */ }else if( cli_strcmp(z,"-heap")==0 ){ i++; }else if( cli_strcmp(z,"-pagecache")==0 ){ @@ -29219,10 +33381,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #endif }else if( cli_strcmp(z,"-vfs")==0 ){ i++; -#ifdef SQLITE_ENABLE_VFSTRACE }else if( cli_strcmp(z,"-vfstrace")==0 ){ i++; -#endif #ifdef SQLITE_ENABLE_MULTIPLEX }else if( cli_strcmp(z,"-multiplex")==0 ){ i++; @@ -29243,17 +33403,17 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ open_db(&data, 0); rc = shell_exec(&data, z, &zErrMsg); if( zErrMsg!=0 ){ - eputf("Error: %s\n", zErrMsg); + shellEmitError(zErrMsg); if( bail_on_error ) return rc!=0 ? rc : 1; }else if( rc!=0 ){ - eputf("Error: unable to process SQL \"%s\"\n", z); + sqlite3_fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z); if( bail_on_error ) return rc; } } #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) }else if( cli_strncmp(z, "-A", 2)==0 ){ if( nCmd>0 ){ - eputf("Error: cannot mix regular SQL or dot-commands" + sqlite3_fprintf(stderr,"Error: cannot mix regular SQL or dot-commands" " with \"%s\"\n", z); return 1; } @@ -29272,7 +33432,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( cli_strcmp(z,"-unsafe-testing")==0 ){ /* Acted upon in first pass. */ }else{ - eputf("%s: Error: unknown option: %s\n", Argv0, z); + sqlite3_fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); eputz("Use -help for a list of options.\n"); return 1; } @@ -29288,8 +33448,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ if( azCmd[i][0]=='.' ){ rc = do_meta_command(azCmd[i], &data); if( rc ){ - free(azCmd); - return rc==2 ? 0 : rc; + if( rc==2 ) rc = 0; + goto shell_main_exit; } }else{ open_db(&data, 0); @@ -29297,13 +33457,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ rc = shell_exec(&data, azCmd[i], &zErrMsg); if( zErrMsg || rc ){ if( zErrMsg!=0 ){ - eputf("Error: %s\n", zErrMsg); + shellEmitError(zErrMsg); }else{ - eputf("Error: unable to process SQL: %s\n", azCmd[i]); + sqlite3_fprintf(stderr, + "Error: unable to process SQL: %s\n", azCmd[i]); } sqlite3_free(zErrMsg); - free(azCmd); - return rc!=0 ? rc : 1; + if( rc==0 ) rc = 1; + goto shell_main_exit; } } } @@ -29314,20 +33475,16 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ char *zHome; char *zHistory; int nHistory; -#if CIO_WIN_WC_XLATE -# define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "") -#else -# define SHELL_CIO_CHAR_SET "" -#endif extern char* sqlite3mc_version(); - oputf("SQLite version %s %.19s%s" /*extra-version-info*/ - " (%s)\n" /*SQLite3-Multiple-Ciphers-version-info*/ - "Enter \".help\" for usage hints.\n", - sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET, sqlite3mc_version()); + sqlite3_fprintf(stdout, + "SQLite version %s %.19s" /*extra-version-info*/ + " (%s)\n" /*SQLite3-Multiple-Ciphers-version-info*/ + "Enter \".help\" for usage hints.\n", + sqlite3_libversion(), sqlite3_sourceid(), sqlite3mc_version()); if( warnInmemoryDb ){ - oputz("Connected to a "); + sputz(stdout, "Connected to a "); printBold("transient in-memory database"); - oputz(".\nUse \".open FILENAME\" to reopen on a" + sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a" " persistent database.\n"); } zHistory = getenv("SQLITE_HISTORY"); @@ -29340,10 +33497,12 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } } if( zHistory ){ shell_read_history(zHistory); } -#if HAVE_READLINE || HAVE_EDITLINE +#if (HAVE_READLINE || HAVE_EDITLINE) && !defined(SQLITE_OMIT_READLINE_COMPLETION) rl_attempted_completion_function = readline_completion; -#elif HAVE_LINENOISE +#elif HAVE_LINENOISE==1 linenoiseSetCompletionCallback(linenoise_completion); +#elif HAVE_LINENOISE==2 + linenoiseSetCompletionCallback(linenoise_completion, NULL); #endif data.in = 0; rc = process_input(&data); @@ -29360,6 +33519,12 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #ifndef SQLITE_SHELL_FIDDLE /* In WASM mode we have to leave the db state in place so that ** client code can "push" SQL into it after this call returns. */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( data.expert.pExpert ){ + expertFinish(&data, 1, 0); + } +#endif + shell_main_exit: free(azCmd); set_table_name(&data, 0); if( data.db ){ @@ -29386,13 +33551,18 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ /* Clear the global data structure so that valgrind will detect memory ** leaks */ memset(&data, 0, sizeof(data)); + if( bEnableVfstrace ){ + vfstrace_unregister("trace"); + } #ifdef SQLITE_DEBUG if( sqlite3_memory_used()>mem_main_enter ){ - eputf("Memory leaked: %u bytes\n", + sqlite3_fprintf(stderr,"Memory leaked: %u bytes\n", (unsigned int)(sqlite3_memory_used()-mem_main_enter)); } #endif -#endif /* !SQLITE_SHELL_FIDDLE */ +#else /* SQLITE_SHELL_FIDDLE... */ + shell_main_exit: +#endif return rc; } @@ -29426,7 +33596,7 @@ sqlite3_vfs * fiddle_db_vfs(const char *zDbName){ /* Only for emcc experimentation purposes. */ sqlite3 * fiddle_db_arg(sqlite3 *arg){ - printf("fiddle_db_arg(%p)\n", (const void*)arg); + sqlite3_fprintf(stdout, "fiddle_db_arg(%p)\n", (const void*)arg); return arg; } @@ -29452,12 +33622,22 @@ const char * fiddle_db_filename(const char * zDbName){ /* ** Completely wipes out the contents of the currently-opened database -** but leaves its storage intact for reuse. +** but leaves its storage intact for reuse. If any transactions are +** active, they are forcibly rolled back. */ void fiddle_reset_db(void){ if( globalDb ){ - int rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); - if( 0==rc ) rc = sqlite3_exec(globalDb, "VACUUM", 0, 0, 0); + int rc; + while( sqlite3_txn_state(globalDb,0)>0 ){ + /* + ** Resolve problem reported in + ** https://sqlite.org/forum/forumpost/0b41a25d65 + */ + sqlite3_fputs("Rolling back in-progress transaction.\n", stdout); + sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0); + } + rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); + if( 0==rc ) sqlite3_exec(globalDb, "VACUUM", 0, 0, 0); sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); } } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlar.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlar.c index 0265643fbf..84eff3057a 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlar.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlar.c @@ -81,7 +81,7 @@ static void sqlarUncompressFunc( sqlite3_value **argv ){ uLong nData; - uLongf sz; + sqlite3_int64 sz; assert( argc==2 ); sz = sqlite3_value_int(argv[1]); @@ -89,31 +89,33 @@ static void sqlarUncompressFunc( if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){ sqlite3_result_value(context, argv[0]); }else{ + uLongf szf = sz; const Bytef *pData= sqlite3_value_blob(argv[0]); Bytef *pOut = sqlite3_malloc(sz); if( pOut==0 ){ sqlite3_result_error_nomem(context); - }else if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){ + }else if( Z_OK!=uncompress(pOut, &szf, pData, nData) ){ sqlite3_result_error(context, "error in uncompress()", -1); }else{ - sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT); + sqlite3_result_blob(context, pOut, szf, SQLITE_TRANSIENT); } sqlite3_free(pOut); } } -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_sqlar_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "sqlar_compress", 1, + rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, sqlarCompressFunc, 0, 0); if( rc==SQLITE_OK ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.c index 4c13b6a25b..76084e5c52 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.c @@ -3,7 +3,7 @@ ** Purpose: Amalgamation of the SQLite3 Multiple Ciphers encryption extension for SQLite ** Author: Ulrich Telle ** Created: 2020-02-28 -** Copyright: (c) 2006-2022 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -17,7 +17,6 @@ #ifdef SQLITE_USER_AUTHENTICATION #undef SQLITE_USER_AUTHENTICATION #endif -#define SQLITE_USER_AUTHENTICATION 0 /* Disable AES hardware support */ /* Note: this may be changed in the future depending on available support */ @@ -51,8 +50,15 @@ #define SQLITE_EXTRA_INIT sqlite3mc_initialize #define SQLITE_EXTRA_SHUTDOWN sqlite3mc_shutdown -int sqlite3mc_initialize(const char* arg); -void sqlite3mc_shutdown(void); +/* +** Declare all internal functions as 'static' unless told otherwise +*/ +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE static +#endif + +SQLITE_PRIVATE int sqlite3mc_initialize(const char* arg); +SQLITE_PRIVATE void sqlite3mc_shutdown(void); /* ** To enable the extension functions define SQLITE_ENABLE_EXTFUNC on compiling this module @@ -65,18 +71,12 @@ void sqlite3mc_shutdown(void); */ /* -** Enable the user authentication feature +** Disable the user authentication feature by default */ -#if !SQLITE_USER_AUTHENTICATION -/* Option not defined or explicitly disabled */ -#ifndef SQLITE_USER_AUTHENTICATION -/* Option not defined, therefore enable by default */ -#define SQLITE_USER_AUTHENTICATION 1 -#else +#ifdef SQLITE_USER_AUTHENTICATION /* Option defined and disabled, therefore undefine option */ #undef SQLITE_USER_AUTHENTICATION #endif -#endif #if defined(_WIN32) || defined(WIN32) @@ -117,13 +117,13 @@ void sqlite3mc_shutdown(void); #include <windows.h> /* SQLite functions only needed on Win32 */ -extern SQLITE_API void sqlite3_win32_write_debug(const char*, int); -extern SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR); -extern SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char*); -extern SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char*, int); -extern SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char*); -extern SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char*, int); -extern SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char*); +SQLITE_API void sqlite3_win32_write_debug(const char*, int); +SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR); +SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char*); +SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char*, int); +SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char*); +SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char*, int); +SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char*); #endif /* @@ -132,7 +132,7 @@ extern SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char*); #include "sqlite3.c" /* -** Include SQLite3MultiCipher components +** Include SQLite3MultiCipher components */ #include "sqlite3mc_config.h" #include "sqlite3mc.h" @@ -164,10 +164,6 @@ sqlite3mcVersion(sqlite3_context* context, int argc, sqlite3_value** argv) SQLITE_PRIVATE void sqlite3mcSetMemorySecurity(int value); SQLITE_PRIVATE int sqlite3mcGetMemorySecurity(); -#ifndef SQLITE3MC_USE_RANDOM_FILL_MEMORY -#define SQLITE3MC_USE_RANDOM_FILL_MEMORY 0 -#endif - /* Memory locking is currently not supported */ #ifdef SQLITE3MC_ENABLE_MEMLOCK #undef SQLITE3MC_ENABLE_MEMLOCK @@ -183,22 +179,18 @@ SQLITE_PRIVATE int sqlite3mcGetMemorySecurity(); #include "sha1.c" #include "sha2.c" -#if HAVE_CIPHER_CHACHA20 || HAVE_CIPHER_SQLCIPHER +#if HAVE_CIPHER_CHACHA20 || HAVE_CIPHER_SQLCIPHER || HAVE_CIPHER_ASCON128 || HAVE_CIPHER_AEGIS #include "fastpbkdf2.c" /* Prototypes for several crypto functions to make pedantic compilers happy */ -void chacha20_xor(void* data, size_t n, const uint8_t key[32], const uint8_t nonce[12], uint32_t counter); -void poly1305(const uint8_t* msg, size_t n, const uint8_t key[32], uint8_t tag[16]); -int poly1305_tagcmp(const uint8_t tag1[16], const uint8_t tag2[16]); -void chacha20_rng(void* out, size_t n); +SQLITE_PRIVATE void chacha20_xor(void* data, size_t n, const uint8_t key[32], const uint8_t nonce[12], uint32_t counter); +SQLITE_PRIVATE void poly1305(const uint8_t* msg, size_t n, const uint8_t key[32], uint8_t tag[16]); +SQLITE_PRIVATE int poly1305_tagcmp(const uint8_t tag1[16], const uint8_t tag2[16]); +SQLITE_PRIVATE void chacha20_rng(void* out, size_t n); #include "chacha20poly1305.c" #endif -#ifdef SQLITE_USER_AUTHENTICATION -#include "userauth.c" -#endif - /* ** Declare function prototype for registering the codec extension functions */ @@ -211,6 +203,18 @@ mcRegisterCodecExtensions(sqlite3* db, char** pzErrMsg, const sqlite3_api_routin #if HAVE_CIPHER_AES_128_CBC || HAVE_CIPHER_AES_256_CBC || HAVE_CIPHER_SQLCIPHER #include "rijndael.c" #endif + +#if HAVE_CIPHER_AEGIS + +/* Incremental encryption/decryption not needed */ +#define AEGIS_OMIT_INCREMENTAL +/* API for generating MAC not needed */ +#define AEGIS_OMIT_MAC_API + +#include "aegis/libaegis.c" +#include "argon2/libargon2.c" +#endif + #include "codec_algos.c" #include "cipher_wxaes128.c" @@ -219,6 +223,7 @@ mcRegisterCodecExtensions(sqlite3* db, char** pzErrMsg, const sqlite3_api_routin #include "cipher_sqlcipher.c" #include "cipher_sds_rc4.c" #include "cipher_ascon.c" +#include "cipher_aegis.c" #include "cipher_common.c" #include "cipher_config.c" @@ -243,9 +248,7 @@ int RegisterExtensionFunctions(sqlite3* db); */ #ifdef SQLITE_ENABLE_CSV /* Prototype for initialization function of CSV extension */ -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_csv_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi); #include "csv.c" #endif @@ -255,9 +258,7 @@ int sqlite3_csv_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* p */ #ifdef SQLITE_ENABLE_VSV /* Prototype for initialization function of VSV extension */ -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_vsv_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi); #include "vsv.c" #endif @@ -267,9 +268,7 @@ int sqlite3_vsv_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* p */ #ifdef SQLITE_ENABLE_SHA3 /* Prototype for initialization function of SHA3 extension */ -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_shathree_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi); #include "shathree.c" #endif @@ -279,9 +278,7 @@ int sqlite3_shathree_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routin */ #ifdef SQLITE_ENABLE_CARRAY /* Prototype for initialization function of CARRAY extension */ -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_carray_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi); #include "carray.c" #endif @@ -291,9 +288,7 @@ int sqlite3_carray_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines */ #ifdef SQLITE_ENABLE_FILEIO /* Prototype for initialization function of FILEIO extension */ -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_fileio_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi); /* MinGW specifics */ @@ -317,9 +312,7 @@ int sqlite3_fileio_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines */ #ifdef SQLITE_ENABLE_SERIES /* Prototype for initialization function of SERIES extension */ -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_series_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi); #include "series.c" #endif @@ -329,9 +322,7 @@ int sqlite3_series_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines */ #ifdef SQLITE_ENABLE_UUID /* Prototype for initialization function of UUID extension */ -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_uuid_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi); #include "uuid.c" #endif @@ -341,9 +332,7 @@ int sqlite3_uuid_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* */ #ifdef SQLITE_ENABLE_REGEXP /* Prototype for initialization function of REGEXP extension */ -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_regexp_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi); #include "regexp.c" #endif @@ -358,9 +347,7 @@ int sqlite3_regexp_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines ** COMPRESS */ #ifdef SQLITE_ENABLE_COMPRESS -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_compress_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi); #include "compress.c" #endif @@ -369,9 +356,7 @@ int sqlite3_compress_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routin ** SQLAR */ #ifdef SQLITE_ENABLE_SQLAR -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_sqlar_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi); #include "sqlar.c" #endif @@ -380,9 +365,7 @@ int sqlite3_sqlar_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines ** ZIPFILE */ #ifdef SQLITE_ENABLE_ZIPFILE -#ifdef _WIN32 -__declspec(dllexport) -#endif +SQLITE_API int sqlite3_zipfile_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi); #include "zipfile.c" #endif @@ -398,7 +381,8 @@ mcRegisterCodecExtensions(sqlite3* db, char** pzErrMsg, const sqlite3_api_routin int rc = SQLITE_OK; CodecParameter* codecParameterTable = NULL; - if (sqlite3FindFunction(db, "sqlite3mc_config_table", 1, SQLITE_UTF8, 0) != NULL) + void* codecParamTable = sqlite3_get_clientdata(db, globalConfigTableName); + if (codecParamTable) { /* Return if codec extension functions are already defined */ return rc; @@ -409,8 +393,7 @@ mcRegisterCodecExtensions(sqlite3* db, char** pzErrMsg, const sqlite3_api_routin rc = (codecParameterTable != NULL) ? SQLITE_OK : SQLITE_NOMEM; if (rc == SQLITE_OK) { - rc = sqlite3_create_function_v2(db, "sqlite3mc_config_table", 0, SQLITE_UTF8 | SQLITE_DETERMINISTIC, - codecParameterTable, sqlite3mcConfigTable, 0, 0, (void(*)(void*)) sqlite3mcFreeCodecParameterTable); + sqlite3_set_clientdata(db, globalConfigTableName, codecParameterTable, sqlite3mcFreeCodecParameterTable); } rc = (codecParameterTable != NULL) ? SQLITE_OK : SQLITE_NOMEM; @@ -456,7 +439,7 @@ sqlite3_extfunc_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *p #endif static int -mcCheckValidName(char* name) +mcCheckValidName(const char* name) { size_t nl; if (!name) @@ -576,9 +559,10 @@ sqlite3mcRegisterCipher(const CipherDescriptor* desc, const CipherParams* params /* Copy parameters */ for (n = 0; n < np; ++n) { + char* paramName = (char*) sqlite3_malloc((int)strlen(params[n].m_name) + 1); + strcpy(paramName, params[n].m_name); cipherParams[n] = params[n]; - cipherParams[n].m_name = (char*) sqlite3_malloc((int) strlen(params[n].m_name) + 1); - strcpy(cipherParams[n].m_name, params[n].m_name); + cipherParams[n].m_name = paramName; } /* Add sentinel */ cipherParams[n] = params[n]; @@ -626,6 +610,15 @@ sqlite3mcInitCipherTables() { size_t n; + /* Initialize global configuration table name */ + sqlite3_randomness(CIPHER_NAME_MAXLEN, globalConfigTableName); + for (n = 0; n < CIPHER_NAME_MAXLEN-1; ++n) + { + if (globalConfigTableName[n] == 0) + globalConfigTableName[n] = '@'; + } + globalConfigTableName[CIPHER_NAME_MAXLEN-1] = 0; + /* Initialize cipher name table */ strcpy(globalCipherNameTable[0].m_name, "global"); for (n = 1; n < CODEC_COUNT_MAX + 2; ++n) @@ -661,14 +654,15 @@ sqlite3mcTermCipherTables() CipherParams* params = globalCodecParameterTable[n].m_params; for (k = 0; params[k].m_name[0] != 0; ++k) { - sqlite3_free(params[k].m_name); + sqlite3_free((char*) params[k].m_name); } sqlite3_free(globalCodecParameterTable[n].m_params); } } + globalCipherCount = 0; } -int +SQLITE_PRIVATE int sqlite3mc_initialize(const char* arg) { int rc = sqlite3mcInitCipherTables(); @@ -708,6 +702,13 @@ sqlite3mc_initialize(const char* arg) rc = sqlite3mcRegisterCipher(&mcAscon128Descriptor, mcAscon128Params, (CODEC_TYPE_ASCON128 == CODEC_TYPE)); } #endif +#if HAVE_CIPHER_AEGIS + if (rc == SQLITE_OK) + { + aegis_init(); + rc = sqlite3mcRegisterCipher(&mcAegisDescriptor, mcAegisParams, (CODEC_TYPE_AEGIS == CODEC_TYPE)); + } +#endif /* ** Initialize and register MultiCipher VFS as default VFS @@ -800,7 +801,7 @@ sqlite3mc_initialize(const char* arg) return rc; } -void +SQLITE_PRIVATE void sqlite3mc_shutdown(void) { sqlite3mc_vfs_shutdown(); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.def b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.def index df4d8138bb..ca4076668b 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.def +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.def @@ -250,10 +250,6 @@ sqlite3_uri_int64 sqlite3_uri_key sqlite3_uri_parameter sqlite3_user_data -sqlite3_user_add -sqlite3_user_authenticate -sqlite3_user_change -sqlite3_user_delete sqlite3_value_blob sqlite3_value_bytes sqlite3_value_bytes16 diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.h index efdd85e9c2..f0d39807c4 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.h @@ -3,7 +3,7 @@ ** Purpose: Header file for SQLite3 Multiple Ciphers support ** Author: Ulrich Telle ** Created: 2020-03-01 -** Copyright: (c) 2019-2023 Ulrich Telle +** Copyright: (c) 2019-2024 Ulrich Telle ** License: MIT */ @@ -21,7 +21,7 @@ #include "sqlite3.h" #ifdef SQLITE_USER_AUTHENTICATION -#include "sqlite3userauth.h" +#undef SQLITE_USER_AUTHENTICATION #endif /* @@ -34,7 +34,8 @@ #define CODEC_TYPE_SQLCIPHER 4 #define CODEC_TYPE_RC4 5 #define CODEC_TYPE_ASCON128 6 -#define CODEC_TYPE_MAX_BUILTIN 6 +#define CODEC_TYPE_AEGIS 7 +#define CODEC_TYPE_MAX_BUILTIN 7 /* ** Definition of API functions @@ -133,7 +134,7 @@ SQLITE_API unsigned char* wxsqlite3_codec_data(sqlite3* db, const char* zDbName, */ typedef struct _CipherParams { - char* m_name; + const char* m_name; int m_value; int m_default; int m_minValue; @@ -166,13 +167,13 @@ typedef int (*GetLegacy_t)(void* cipher); typedef int (*GetPageSize_t)(void* cipher); typedef int (*GetReserved_t)(void* cipher); typedef unsigned char* (*GetSalt_t)(void* cipher); -typedef void (*GenerateKey_t)(void* cipher, BtSharedMC* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt); +typedef void (*GenerateKey_t)(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt); typedef int (*EncryptPage_t)(void* cipher, int page, unsigned char* data, int len, int reserved); typedef int (*DecryptPage_t)(void* cipher, int page, unsigned char* data, int len, int reserved, int hmacCheck); typedef struct _CipherDescriptor { - char* m_name; + const char* m_name; AllocateCipher_t m_allocateCipher; FreeCipher_t m_freeCipher; CloneCipher_t m_cloneCipher; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.rc b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.rc index fea52cf710..953a3dd8f2 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.rc +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc.rc @@ -16,7 +16,7 @@ #define SQLITE3MC_MAKE_VERSION_DOT_STRING(x, y, z, w) \ SQLITE3MC_STRINGIZE(x) "." SQLITE3MC_STRINGIZE(y) "." SQLITE3MC_STRINGIZE(z) "." SQLITE3MC_STRINGIZE(w) - + #define SQLITE3MC_FILE_VERSION_NUM_DOT_STRING \ SQLITE3MC_MAKE_VERSION_DOT_STRING(SQLITE3MC_VERSION_MAJOR, SQLITE3MC_VERSION_MINOR, SQLITE3MC_VERSION_RELEASE, SQLITE3MC_VERSION_SUBRELEASE) #define SQLITE3MC_PROD_VERSION_NUM_DOT_STRING \ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_config.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_config.h index 82f8be0307..e4f2988e04 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_config.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_config.h @@ -3,7 +3,7 @@ ** Purpose: Header file for SQLite3 Multiple Ciphers compile-time configuration ** Author: Ulrich Telle ** Created: 2021-09-27 -** Copyright: (c) 2019-2023 Ulrich Telle +** Copyright: (c) 2019-2024 Ulrich Telle ** License: MIT */ @@ -41,6 +41,10 @@ #define HAVE_CIPHER_ASCON128 WXSQLITE3_HAVE_CIPHER_ASCON128 #endif +#ifdef WXSQLITE3_HAVE_CIPHER_AEGIS +#define HAVE_CIPHER_AEGIS WXSQLITE3_HAVE_CIPHER_AEGIS +#endif + /* ** Actual definitions of supported ciphers */ @@ -68,6 +72,18 @@ #define HAVE_CIPHER_ASCON128 1 #endif +#ifndef HAVE_CIPHER_AEGIS +#define HAVE_CIPHER_AEGIS 1 +#endif + +/* +** Define whether dynamic ciphers will be used +*/ + +#ifndef SQLITE3MC_HAVE_DYNAMIC_CIPHERS +#define SQLITE3MC_HAVE_DYNAMIC_CIPHERS 0 +#endif + /* ** Disable all built-in ciphers on request */ @@ -83,22 +99,27 @@ #undef HAVE_CIPHER_SQLCIPHER #undef HAVE_CIPHER_RC4 #undef HAVE_CIPHER_ASCON128 +#undef HAVE_CIPHER_AEGIS #define HAVE_CIPHER_AES_128_CBC 0 #define HAVE_CIPHER_AES_256_CBC 0 #define HAVE_CIPHER_CHACHA20 0 #define HAVE_CIPHER_SQLCIPHER 0 #define HAVE_CIPHER_RC4 0 #define HAVE_CIPHER_ASCON128 0 +#define HAVE_CIPHER_AEGIS 0 #endif /* ** Check that at least one cipher is be supported */ -#if HAVE_CIPHER_AES_128_CBC == 0 && \ +#if SQLITE3MC_HAVE_DYNAMIC_CIPHERS == 0 && \ + HAVE_CIPHER_AES_128_CBC == 0 && \ HAVE_CIPHER_AES_256_CBC == 0 && \ HAVE_CIPHER_CHACHA20 == 0 && \ HAVE_CIPHER_SQLCIPHER == 0 && \ - HAVE_CIPHER_RC4 == 0 + HAVE_CIPHER_RC4 == 0 && \ + HAVE_CIPHER_ASCON128 == 0 && \ + HAVE_CIPHER_AEGIS == 0 #pragma message ("sqlite3mc_config.h: WARNING - No built-in cipher scheme enabled!") #endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_shell.rc b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_shell.rc index 2726967f86..8f29888021 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_shell.rc +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_shell.rc @@ -18,7 +18,7 @@ ID_SQLITE3 ICON "sqlite370.ico" #define SQLITE3MC_MAKE_VERSION_DOT_STRING(x, y, z, w) \ SQLITE3MC_STRINGIZE(x) "." SQLITE3MC_STRINGIZE(y) "." SQLITE3MC_STRINGIZE(z) "." SQLITE3MC_STRINGIZE(w) - + #define SQLITE3MC_FILE_VERSION_NUM_DOT_STRING \ SQLITE3MC_MAKE_VERSION_DOT_STRING(SQLITE3MC_VERSION_MAJOR, SQLITE3MC_VERSION_MINOR, SQLITE3MC_VERSION_RELEASE, SQLITE3MC_VERSION_SUBRELEASE) #define SQLITE3MC_PROD_VERSION_NUM_DOT_STRING \ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_version.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_version.h index 63133186fa..9f6fc0b8e2 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_version.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_version.h @@ -3,7 +3,7 @@ ** Purpose: SQLite3 Multiple Ciphers version numbers ** Author: Ulrich Telle ** Created: 2020-08-05 -** Copyright: (c) 2020-2023 Ulrich Telle +** Copyright: (c) 2020-2025 Ulrich Telle ** License: MIT */ @@ -12,10 +12,10 @@ #ifndef SQLITE3MC_VERSION_H_ #define SQLITE3MC_VERSION_H_ -#define SQLITE3MC_VERSION_MAJOR 1 -#define SQLITE3MC_VERSION_MINOR 8 -#define SQLITE3MC_VERSION_RELEASE 1 +#define SQLITE3MC_VERSION_MAJOR 2 +#define SQLITE3MC_VERSION_MINOR 0 +#define SQLITE3MC_VERSION_RELEASE 2 #define SQLITE3MC_VERSION_SUBRELEASE 0 -#define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 1.8.1" +#define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 2.0.2" #endif /* SQLITE3MC_VERSION_H_ */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_vfs.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_vfs.c index 71b7c1b098..6890a5f469 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_vfs.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_vfs.c @@ -98,6 +98,8 @@ static int mcIoUnfetch(sqlite3_file* pFile, sqlite3_int64 iOfst, void* p); #define SQLITE3MC_VFS_NAME ("multipleciphers") +#define SQLITE3MC_FCNTL_PVFS 0x3f98c078 + /* ** Header sizes of WAL journal files */ @@ -213,7 +215,7 @@ static void mcMainListRemove(sqlite3mc_file* pFile) } /* -** Given that zFileName points to a buffer containing a database file name passed to +** Given that zFileName points to a buffer containing a database file name passed to ** either the xOpen() or xAccess() VFS method, search the list of main database files ** for a file handle opened by the same database connection on the corresponding ** database file. @@ -242,36 +244,29 @@ static sqlite3mc_vfs* mcFindVfs(sqlite3* db, const char* zDbName) { /* ** The top level VFS is not a Multiple Ciphers VFS. - ** Retrieve the VFS names stack. + ** Retrieve the Multiple Ciphers VFS via file control function, + ** if it is included in the VFS stack. */ - char* zVfsNameStack = 0; - if ((sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsNameStack) == SQLITE_OK) && (zVfsNameStack != NULL)) + sqlite3mc_vfs* pVfs = NULL; + if ((sqlite3_file_control(db, zDbName, SQLITE3MC_FCNTL_PVFS, &pVfs) == SQLITE_OK) && + (pVfs && pVfs->base.xOpen == mcVfsOpen)) { - /* Search for the name prefix of a Multiple Ciphers VFS. */ - char* zVfsName = strstr(zVfsNameStack, SQLITE3MC_VFS_NAME); - if (zVfsName != NULL) - { - /* The prefix was found, now determine the full VFS name. */ - char* zVfsNameEnd = zVfsName + strlen(SQLITE3MC_VFS_NAME); - if (*zVfsNameEnd == '-') - { - for (++zVfsNameEnd; *zVfsNameEnd != '/' && *zVfsNameEnd != 0; ++zVfsNameEnd); - if (*zVfsNameEnd == '/') *zVfsNameEnd = 0; - - /* Find a pointer to the VFS with the determined name. */ - sqlite3_vfs* pVfs = sqlite3_vfs_find(zVfsName); - if (pVfs && pVfs->xOpen == mcVfsOpen) - { - pVfsMC = (sqlite3mc_vfs*) pVfs; - } - } - } - sqlite3_free(zVfsNameStack); + pVfsMC = pVfs; } } return pVfsMC; } +/* +** Check whether the VFS of the database file corresponding +** to the database schema name supports encryption. +*/ +SQLITE_PRIVATE int sqlite3mcIsEncryptionSupported(sqlite3* db, const char* zDbName) +{ + sqlite3mc_vfs* pVfsMC = mcFindVfs(db, zDbName); + return (pVfsMC != NULL); +} + /* ** Find the codec of the database file ** corresponding to the database schema name. @@ -301,6 +296,30 @@ SQLITE_PRIVATE Codec* sqlite3mcGetMainCodec(sqlite3* db) return sqlite3mcGetCodec(db, "main"); } +SQLITE_PRIVATE int sqlite3mcIsBackupSupported(sqlite3* pSrc, const char* zSrc, sqlite3* pDest, const char* zDest) +{ + int ok = 1; + if (pSrc != pDest) + { + Codec* codecSrc = sqlite3mcGetCodec(pSrc, zSrc); + Codec* codecDest = sqlite3mcGetCodec(pDest, zDest); + if (codecSrc && codecDest) + { + /* Both databases have a codec, are encrypted, and have the same page size */ + ok = sqlite3mcIsEncrypted(codecSrc) && sqlite3mcIsEncrypted(codecDest) && + (sqlite3mcGetPageSizeReadCipher(codecSrc) == sqlite3mcGetPageSizeWriteCipher(codecDest)) && + (sqlite3mcGetReadReserved(codecSrc) == sqlite3mcGetWriteReserved(codecDest)); + } + else + { + /* At least one database has no codec */ + /* Backup supported if both databases are plain databases */ + ok = !codecSrc && !codecDest; + } + } + return ok; +} + /* ** Set the codec of the database file with the given database file name. ** @@ -317,12 +336,13 @@ SQLITE_PRIVATE void sqlite3mcSetCodec(sqlite3* db, const char* zDbName, const ch sqlite3mc_vfs* pVfsMC = mcFindVfs(db, zDbName); if (pVfsMC) { - pDbMain = mcFindDbMainFileName((sqlite3mc_vfs*)(db->pVfs), zFileName); + pDbMain = mcFindDbMainFileName(pVfsMC, zFileName); } if (pDbMain) { Codec* prevCodec = pDbMain->codec; Codec* msgCodec = (codec) ? codec : prevCodec; + pDbMain->codec = codec; if (msgCodec) { /* Reset error state of pager */ @@ -335,7 +355,6 @@ SQLITE_PRIVATE void sqlite3mcSetCodec(sqlite3* db, const char* zDbName, const ch */ sqlite3mcCodecFree(prevCodec); } - pDbMain->codec = codec; } else { @@ -363,8 +382,8 @@ int libsql_pager_codec_impl(libsql_pghdr* pPg, void **ret) sqlite3_file* pFile = sqlite3PagerFile(pPg->pPager); void* aData = 0; - if (pFile->pMethods == &mcIoMethodsGlobal1 || - pFile->pMethods == &mcIoMethodsGlobal2 || + if (pFile->pMethods == &mcIoMethodsGlobal1 || + pFile->pMethods == &mcIoMethodsGlobal2 || pFile->pMethods == &mcIoMethodsGlobal3) { sqlite3mc_file* mcFile = (sqlite3mc_file*) pFile; @@ -643,6 +662,7 @@ static int mcReadMainDb(sqlite3_file* pFile, void* buffer, int count, sqlite3_in */ pageNo = prevOffset / pageSize + 1; bufferDecrypted = sqlite3mcCodec(mcFile->codec, pageBuffer, pageNo, 3); + rc = sqlite3mcGetCodecLastError(mcFile->codec); /* ** Return the requested content @@ -671,6 +691,7 @@ static int mcReadMainDb(sqlite3_file* pFile, void* buffer, int count, sqlite3_in for (iPage = 0; iPage < nPages; ++iPage) { void* bufferDecrypted = sqlite3mcCodec(mcFile->codec, data, pageNo, 3); + rc = sqlite3mcGetCodecLastError(mcFile->codec); data += pageSize; offset += pageSize; ++pageNo; @@ -699,6 +720,7 @@ static int mcReadMainJournal(sqlite3_file* pFile, const void* buffer, int count, ** Decrypt the page buffer, but only if the page number is valid */ void* bufferDecrypted = sqlite3mcCodec(codec, (char*) buffer, mcFile->pageNo, 3); + rc = sqlite3mcGetCodecLastError(codec); mcFile->pageNo = 0; } else if (count == 4) @@ -732,6 +754,7 @@ static int mcReadSubJournal(sqlite3_file* pFile, const void* buffer, int count, ** Decrypt the page buffer, but only if the page number is valid */ void* bufferDecrypted = sqlite3mcCodec(codec, (char*) buffer, mcFile->pageNo, 3); + rc = sqlite3mcGetCodecLastError(codec); } else if (count == 4) { @@ -780,6 +803,7 @@ static int mcReadWal(sqlite3_file* pFile, const void* buffer, int count, sqlite3 if (pageNo != 0) { void* bufferDecrypted = sqlite3mcCodec(codec, (char*)buffer, pageNo, 3); + rc = sqlite3mcGetCodecLastError(codec); } } else if (codec->m_walLegacy != 0 && count == pageSize + walFrameHeaderSize) @@ -792,6 +816,7 @@ static int mcReadWal(sqlite3_file* pFile, const void* buffer, int count, sqlite3 if (pageNo != 0) { void* bufferDecrypted = sqlite3mcCodec(codec, (char*)buffer+walFrameHeaderSize, pageNo, 3); + rc = sqlite3mcGetCodecLastError(codec); } } } @@ -1203,6 +1228,12 @@ static int mcIoFileControl(sqlite3_file* pFile, int op, void* pArg) switch (op) { + case SQLITE3MC_FCNTL_PVFS: + { + *(sqlite3mc_vfs**) pArg = p->pVfsMC; + doReal = 0; + } + break; case SQLITE_FCNTL_PDB: { #if 0 @@ -1219,7 +1250,7 @@ static int mcIoFileControl(sqlite3_file* pFile, int op, void* pArg) */ sqlite3* db = *((sqlite3**) pArg); #endif - } + } break; case SQLITE_FCNTL_PRAGMA: { diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_vfs.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_vfs.h index 847dc6a767..1626545da9 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_vfs.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3mc_vfs.h @@ -16,6 +16,7 @@ extern "C" { #ifndef SQLITE_PRIVATE #define SQLITE_PRIVATE #endif + SQLITE_PRIVATE int sqlite3mcCheckVfs(const char* zVfs); SQLITE_API int sqlite3mc_vfs_create(const char* zVfsReal, int makeDefault); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3patched.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3patched.c index 11c8ee6c62..47a6d0f692 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3patched.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3patched.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.44.2. By combining all the individual C code files into this +** version 3.48.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,8 +18,11 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** ebead0e7230cd33bcec9f95d2183069565b9. +** d2fe6b05f38d9d7cd78c5d252e99ac59f1ae with changes in files: +** +** */ +#ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE @@ -256,10 +259,13 @@ /* ** Macro to disable warnings about missing "break" at the end of a "case". */ -#if GCC_VERSION>=7000000 -# define deliberate_fall_through __attribute__((fallthrough)); -#else -# define deliberate_fall_through +#if defined(__has_attribute) +# if __has_attribute(fallthrough) +# define deliberate_fall_through __attribute__((fallthrough)); +# endif +#endif +#if !defined(deliberate_fall_through) +# define deliberate_fall_through #endif /* @@ -459,9 +465,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.2" -#define SQLITE_VERSION_NUMBER 3044002 -#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f" +#define SQLITE_VERSION "3.48.0" +#define SQLITE_VERSION_NUMBER 3048000 +#define SQLITE_SOURCE_ID "2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e84010" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -733,6 +739,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. ** <li> The application must not modify the SQL statement text passed into ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +** <li> The application must not dereference the arrays or string pointers +** passed as the 3rd and 4th callback parameters after it returns. ** </ul> */ SQLITE_API int sqlite3_exec( @@ -963,6 +971,13 @@ SQLITE_API int sqlite3_exec( ** filesystem supports doing multiple write operations atomically when those ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. +** +** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read +** from the database file in amounts that are not a multiple of the +** page size and that do not begin at a page boundary. Without this +** property, SQLite is careful to only do full-page reads and write +** on aligned pages, with the one exception that it will do a sub-page +** read of the first page to access the database header. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -979,6 +994,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 +#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 /* ** CAPI3REF: File Locking Levels @@ -1075,16 +1091,16 @@ struct sqlite3_file { ** </ul> ** xLock() upgrades the database file lock. In other words, xLock() moves the ** database file lock in the direction NONE toward EXCLUSIVE. The argument to -** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never +** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never ** SQLITE_LOCK_NONE. If the database file lock is already at or above the ** requested lock, then the call to xLock() is a no-op. ** xUnlock() downgrades the database file lock to either SHARED or NONE. -* If the lock is already at or below the requested lock state, then the call +** If the lock is already at or below the requested lock state, then the call ** to xUnlock() is a no-op. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, -** PENDING, or EXCLUSIVE lock on the file. It returns true -** if such a lock exists and false otherwise. +** PENDING, or EXCLUSIVE lock on the file. It returns, via its output +** pointer parameter, true if such a lock exists and false otherwise. ** ** The xFileControl() method is a generic interface that allows custom ** VFS implementations to directly control an open file using the @@ -1125,6 +1141,7 @@ struct sqlite3_file { ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] ** <li> [SQLITE_IOCAP_IMMUTABLE] ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] +** <li> [SQLITE_IOCAP_SUBPAGE_READ] ** </ul> ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of @@ -1402,6 +1419,11 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +** <li>[[SQLITE_FCNTL_NULL_IO]] +** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor +** or file handle for the [sqlite3_file] object such that it will no longer +** read or write to the database file. +** ** <li>[[SQLITE_FCNTL_WAL_BLOCK]] ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might ** be advantageous to block on the next WAL lock if the lock is not immediately @@ -1555,6 +1577,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +#define SQLITE_FCNTL_NULL_IO 43 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -2454,6 +2477,22 @@ struct sqlite3_mem_methods { ** configuration setting is never used, then the default maximum is determined ** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that ** compile-time option is not set, then the default maximum is 1073741824. +** +** [[SQLITE_CONFIG_ROWID_IN_VIEW]] +** <dt>SQLITE_CONFIG_ROWID_IN_VIEW +** <dd>The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability +** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is +** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability +** defaults to on. This configuration option queries the current setting or +** changes the setting to off or on. The argument is a pointer to an integer. +** If that integer initially holds a value of 1, then the ability for VIEWs to +** have ROWIDs is activated. If the integer initially holds zero, then the +** ability is deactivated. Any other initial value for the integer leaves the +** setting unchanged. After changes, if any, the integer is written with +** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite +** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and +** recommended case) then the integer is always filled with zero, regardless +** if its initial value. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -2485,6 +2524,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ +#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */ /* ** CAPI3REF: Database Connection Configuration Options @@ -2916,10 +2956,14 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** The two functions are identical except for the type of the return value -** and that if the number of rows modified by the most recent INSERT, UPDATE +** and that if the number of rows modified by the most recent INSERT, UPDATE, ** or DELETE is greater than the maximum value supported by type "int", then ** the return value of sqlite3_changes() is undefined. ^Executing any other ** type of SQL statement does not modify the value returned by these functions. +** For the purposes of this interface, a CREATE TABLE AS SELECT statement +** does not count as an INSERT, UPDATE or DELETE statement and hence the rows +** added to the new table by the CREATE TABLE AS SELECT statement are not +** counted. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], @@ -3599,8 +3643,8 @@ SQLITE_API int sqlite3_set_authorizer( #define SQLITE_RECURSIVE 33 /* NULL NULL */ /* -** CAPI3REF: Tracing And Profiling Functions -** METHOD: sqlite3 +** CAPI3REF: Deprecated Tracing And Profiling Functions +** DEPRECATED ** ** These routines are deprecated. Use the [sqlite3_trace_v2()] interface ** instead of the routines described here. @@ -3864,8 +3908,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> ** <dd>The database connection comes up in "extended result code mode". -** In other words, the database behaves has if -** [sqlite3_extended_result_codes(db,1)] where called on the database +** In other words, the database behaves as if +** [sqlite3_extended_result_codes(db,1)] were called on the database ** connection as soon as the connection is created. In addition to setting ** the extended result code mode, this flag also causes [sqlite3_open_v2()] ** to return an extended result code.</dd> @@ -4267,15 +4311,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** </ul> ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language -** text that describes the error, as either UTF-8 or UTF-16 respectively. +** text that describes the error, as either UTF-8 or UTF-16 respectively, +** or NULL if no error message is available. ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** -** ^The sqlite3_errstr() interface returns the English-language text -** that describes the [result code], as UTF-8. +** ^The sqlite3_errstr(E) interface returns the English-language text +** that describes the [result code] E, as UTF-8, or NULL if E is not an +** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** @@ -4477,11 +4523,22 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler ** to return an error (error code SQLITE_ERROR) if the statement uses ** any virtual tables. +** +** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt> +** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler +** errors from being sent to the error log defined by +** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test +** compiles to see if some SQL syntax is well-formed, without generating +** messages on the global error log when it is not. If the test compile +** fails, the sqlite3_prepare_v3() call returns the same error indications +** with or without this flag; it just omits the call to [sqlite3_log()] that +** logs the error. ** </dl> */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 #define SQLITE_PREPARE_NO_VTAB 0x04 +#define SQLITE_PREPARE_DONT_LOG 0x10 /* ** CAPI3REF: Compiling An SQL Statement @@ -4514,13 +4571,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the -** first zero terminator. ^If nByte is positive, then it is the -** number of bytes read from zSql. ^If nByte is zero, then no prepared +** first zero terminator. ^If nByte is positive, then it is the maximum +** number of bytes read from zSql. When nByte is positive, zSql is read +** up to the first zero terminator or until the nByte bytes have been read, +** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string <i>including</i> ** the nul-terminator. +** Note that nByte measure the length of the input in bytes, not +** characters, even for the UTF-16 interfaces. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only @@ -5891,7 +5952,7 @@ SQLITE_API int sqlite3_create_window_function( ** This flag instructs SQLite to omit some corner-case optimizations that ** might disrupt the operation of the [sqlite3_value_subtype()] function, ** causing it to return zero rather than the correct subtype(). -** SQL functions that invokes [sqlite3_value_subtype()] should have this +** All SQL functions that invoke [sqlite3_value_subtype()] should have this ** property. If the SQLITE_SUBTYPE property is omitted, then the return ** value from [sqlite3_value_subtype()] might sometimes be zero even though ** a non-zero subtype was specified by the function argument expression. @@ -5907,6 +5968,15 @@ SQLITE_API int sqlite3_create_window_function( ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. +** +** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd> +** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate +** that internally orders the values provided to the first argument. The +** ordered-set aggregate SQL notation with a single ORDER BY term can be +** used to invoke this function. If the ordered-set aggregate notation is +** used on a function that lacks this flag, then an error is raised. Note +** that the ordered-set aggregate syntax is only available if SQLite is +** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. ** </dd> ** </dl> */ @@ -5915,6 +5985,7 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_RESULT_SUBTYPE 0x001000000 +#define SQLITE_SELFORDER1 0x002000000 /* ** CAPI3REF: Deprecated Functions @@ -6112,7 +6183,7 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** -** Every [application-defined SQL function] that invoke this interface +** Every [application-defined SQL function] that invokes this interface ** should include the [SQLITE_SUBTYPE] property in the text ** encoding argument when the function is [sqlite3_create_function|registered]. ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() @@ -7179,6 +7250,12 @@ SQLITE_API int sqlite3_autovacuum_pages( ** The exceptions defined in this paragraph might change in a future ** release of SQLite. ** +** Whether the update hook is invoked before or after the +** corresponding change is currently unspecified and may differ +** depending on the type of change. Do not rely on the order of the +** hook call with regards to the final result of the operation which +** triggers the hook. +** ** The update hook implementation must not do anything that will modify ** the database connection that invoked the update hook. Any actions ** to modify the database connection must be deferred until after the @@ -7713,9 +7790,11 @@ struct sqlite3_module { ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a -** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - -** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite -** assumes that the strategy may visit at most one row. +** mask of SQLITE_INDEX_SCAN_* flags. One such flag is +** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] +** output to show the idxNum has hex instead of as decimal. Another flag is +** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will +** return at most one row. ** ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then ** SQLite also assumes that if a call to the xUpdate() method is made as @@ -7779,7 +7858,9 @@ struct sqlite3_index_info { ** [sqlite3_index_info].idxFlags field to some combination of ** these bits. */ -#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ +#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */ +#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */ + /* in EXPLAIN QUERY PLAN */ /* ** CAPI3REF: Virtual Table Constraint Operator Codes @@ -8350,9 +8431,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() -** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable -** behavior.)^ +** will always return SQLITE_BUSY. In most cases the SQLite core only uses +** sqlite3_mutex_try() as an optimization, so this is acceptable +** behavior. The exceptions are unix builds that set the +** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working +** sqlite3_mutex_try() is required.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior @@ -8611,8 +8694,10 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ +#define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ +#define SQLITE_TESTCTRL_GETOPT 16 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 @@ -8632,7 +8717,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 -#define SQLITE_TESTCTRL_USELONGDOUBLE 34 +#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* @@ -8646,7 +8731,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** The sqlite3_keyword_count() interface returns the number of distinct ** keywords understood by SQLite. ** -** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and +** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and ** makes *Z point to that keyword expressed as UTF8 and writes the number ** of bytes in the keyword into *L. The string that *Z points to is not ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns @@ -9608,6 +9693,16 @@ typedef struct sqlite3_backup sqlite3_backup; ** APIs are not strictly speaking threadsafe. If they are invoked at the ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. +** +** <b>Alternatives To Using The Backup API</b> +** +** Other techniques for safely creating a consistent backup of an SQLite +** database include: +** +** <ul> +** <li> The [VACUUM INTO] command. +** <li> The [sqlite3_rsync] utility program. +** </ul> */ SQLITE_API sqlite3_backup *sqlite3_backup_init( sqlite3 *pDest, /* Destination database handle */ @@ -10225,24 +10320,45 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** <li value="2"><p> ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means ** that the query planner does not need the rows returned in any particular -** order, as long as rows with the same values in all "aOrderBy" columns -** are adjacent.)^ ^(Furthermore, only a single row for each particular -** combination of values in the columns identified by the "aOrderBy" field -** needs to be returned.)^ ^It is always ok for two or more rows with the same -** values in all "aOrderBy" columns to be returned, as long as all such rows -** are adjacent. ^The virtual table may, if it chooses, omit extra rows -** that have the same value for all columns identified by "aOrderBy". -** ^However omitting the extra rows is optional. +** order, as long as rows with the same values in all columns identified +** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows +** contain the same values for all columns identified by "colUsed", all but +** one such row may optionally be omitted from the result.)^ +** The virtual table is not required to omit rows that are duplicates +** over the "colUsed" columns, but if the virtual table can do that without +** too much extra effort, it could potentially help the query to run faster. ** This mode is used for a DISTINCT query. ** <li value="3"><p> -** ^(If the sqlite3_vtab_distinct() interface returns 3, that means -** that the query planner needs only distinct rows but it does need the -** rows to be sorted.)^ ^The virtual table implementation is free to omit -** rows that are identical in all aOrderBy columns, if it wants to, but -** it is not required to omit any rows. This mode is used for queries +** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the +** virtual table must return rows in the order defined by "aOrderBy" as +** if the sqlite3_vtab_distinct() interface had returned 0. However if +** two or more rows in the result have the same values for all columns +** identified by "colUsed", then all but one such row may optionally be +** omitted.)^ Like when the return value is 2, the virtual table +** is not required to omit rows that are duplicates over the "colUsed" +** columns, but if the virtual table can do that without +** too much extra effort, it could potentially help the query to run faster. +** This mode is used for queries ** that have both DISTINCT and ORDER BY clauses. ** </ol> ** +** <p>The following table summarizes the conditions under which the +** virtual table is allowed to set the "orderByConsumed" flag based on +** the value returned by sqlite3_vtab_distinct(). This table is a +** restatement of the previous four paragraphs: +** +** <table border=1 cellspacing=0 cellpadding=10 width="90%"> +** <tr> +** <td valign="top">sqlite3_vtab_distinct() return value +** <td valign="top">Rows are returned in aOrderBy order +** <td valign="top">Rows with the same value in all aOrderBy columns are adjacent +** <td valign="top">Duplicates over all colUsed columns may be omitted +** <tr><td>0<td>yes<td>yes<td>no +** <tr><td>1<td>no<td>yes<td>no +** <tr><td>2<td>no<td>yes<td>yes +** <tr><td>3<td>yes<td>yes<td>yes +** </table> +** ** ^For the purposes of comparing virtual table output values to see if the ** values are same value for sorting purposes, two NULL values are considered ** to be the same. In other words, the comparison operator is "IS" @@ -10786,6 +10902,14 @@ typedef struct sqlite3_snapshot { ** If there is not already a read-transaction open on schema S when ** this function is called, one is opened automatically. ** +** If a read-transaction is opened by this function, then it is guaranteed +** that the returned snapshot object may not be invalidated by a database +** writer or checkpointer until after the read-transaction is closed. This +** is not guaranteed if a read-transaction is already open when this +** function is called. In that case, any subsequent write or checkpoint +** operation on the database may invalidate the returned snapshot handle, +** even while the read-transaction remains open. +** ** The following must be true for this function to succeed. If any of ** the following statements are false when sqlite3_snapshot_get() is ** called, SQLITE_ERROR is returned. The final value of *P is undefined @@ -11094,8 +11218,6 @@ SQLITE_API int sqlite3_deserialize( #if defined(__wasi__) # undef SQLITE_WASI # define SQLITE_WASI 1 -# undef SQLITE_OMIT_WAL -# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ # ifndef SQLITE_OMIT_LOAD_EXTENSION # define SQLITE_OMIT_LOAD_EXTENSION # endif @@ -11107,18 +11229,7 @@ SQLITE_API int sqlite3_deserialize( #if 0 } /* End of the 'extern "C"' block */ #endif -#endif /* SQLITE3_H */ - -/* Function prototypes of SQLite3 Multiple Ciphers */ -SQLITE_PRIVATE int sqlite3mcCheckVfs(const char*); -SQLITE_PRIVATE int sqlite3mcFileControlPragma(sqlite3*, const char*, int, void*); -SQLITE_PRIVATE int sqlite3mcHandleAttachKey(sqlite3*, const char*, const char*, sqlite3_value*, char**); -SQLITE_PRIVATE int sqlite3mcHandleMainKey(sqlite3*, const char*); -typedef struct PgHdr PgHdrMC; -SQLITE_PRIVATE void* sqlite3mcPagerCodec(PgHdrMC* pPg); -typedef struct Pager PagerMC; -SQLITE_PRIVATE int sqlite3mcPagerHasCodec(PagerMC* pPager); -SQLITE_PRIVATE void sqlite3mcInitMemoryMethods(); +/* #endif for SQLITE3_H will be added by mksqlite3.tcl */ /******** Begin file sqlite3rtree.h *********/ /* @@ -12298,6 +12409,30 @@ SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const c */ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); +/* +** CAPI3REF: Add A Single Change To A Changegroup +** METHOD: sqlite3_changegroup +** +** This function adds the single change currently indicated by the iterator +** passed as the second argument to the changegroup object. The rules for +** adding the change are just as described for [sqlite3changegroup_add()]. +** +** If the change is successfully added to the changegroup, SQLITE_OK is +** returned. Otherwise, an SQLite error code is returned. +** +** The iterator must point to a valid entry when this function is called. +** If it does not, SQLITE_ERROR is returned and no change is added to the +** changegroup. Additionally, the iterator must not have been opened with +** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also +** returned. +*/ +SQLITE_API int sqlite3changegroup_add_change( + sqlite3_changegroup*, + sqlite3_changeset_iter* +); + + + /* ** CAPI3REF: Obtain A Composite Changeset From A Changegroup ** METHOD: sqlite3_changegroup @@ -13102,8 +13237,8 @@ struct Fts5PhraseIter { ** EXTENSION API FUNCTIONS ** ** xUserData(pFts): -** Return a copy of the context pointer the extension function was -** registered with. +** Return a copy of the pUserData pointer passed to the xCreateFunction() +** API when the extension function was registered. ** ** xColumnTotalSize(pFts, iCol, pnToken): ** If parameter iCol is less than zero, set output variable *pnToken @@ -13135,8 +13270,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -13146,8 +13284,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -13163,12 +13303,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -13194,6 +13335,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -13275,6 +13420,10 @@ struct Fts5PhraseIter { ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** +** In all cases, matches are visited in (column ASC, offset ASC) order. +** i.e. all those in column 0, sorted by offset, followed by those in +** column 1, etc. +** ** xPhraseNext() ** See xPhraseFirst above. ** @@ -13308,9 +13457,80 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. +** +** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the locale associated +** with column iCol of the current row. Usually, there is no associated +** locale, and output parameters (*pzLocale) and (*pnLocale) are set +** to NULL and 0, respectively. However, if the fts5_locale() function +** was used to associate a locale with the value when it was inserted +** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated +** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) +** is set to the size in bytes of the buffer, not including the +** nul-terminator. +** +** If successful, SQLITE_OK is returned. Or, if an error occurs, an +** SQLite error code is returned. The final value of the output parameters +** is undefined in this case. +** +** xTokenize_v2: +** Tokenize text using the tokenizer belonging to the FTS5 table. This +** API is the same as the xTokenize() API, except that it allows a tokenizer +** locale to be specified. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 4 */ void *(*xUserData)(Fts5Context*); @@ -13345,6 +13565,22 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); + + /* Below this point are iVersion>=4 only */ + int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xTokenize_v2)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); }; /* @@ -13365,7 +13601,7 @@ struct Fts5ExtensionApi { ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) -** pointer provided by the application when the fts5_tokenizer object +** pointer provided by the application when the fts5_tokenizer_v2 object ** was registered with FTS5 (the third argument to xCreateTokenizer()). ** The second and third arguments are an array of nul-terminated strings ** containing the tokenizer arguments, if any, specified following the @@ -13389,7 +13625,7 @@ struct Fts5ExtensionApi { ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** -** The second argument indicates the reason that FTS5 is requesting +** The third argument indicates the reason that FTS5 is requesting ** tokenization of the supplied text. This is always one of the following ** four values: ** @@ -13413,6 +13649,13 @@ struct Fts5ExtensionApi { ** on a columnsize=0 database. ** </ul> ** +** The sixth and seventh arguments passed to xTokenize() - pLocale and +** nLocale - are a pointer to a buffer containing the locale to use for +** tokenization (e.g. "en_US") and its size in bytes, respectively. The +** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in +** which case nLocale is always 0) to indicate that the tokenizer should +** use its default locale. +** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth @@ -13436,6 +13679,30 @@ struct Fts5ExtensionApi { ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** +** If the tokenizer is registered using an fts5_tokenizer_v2 object, +** then the xTokenize() method has two additional arguments - pLocale +** and nLocale. These specify the locale that the tokenizer should use +** for the current request. If pLocale and nLocale are both 0, then the +** tokenizer should use its default locale. Otherwise, pLocale points to +** an nLocale byte buffer containing the name of the locale to use as utf-8 +** text. pLocale is not nul-terminated. +** +** FTS5_TOKENIZER +** +** There is also an fts5_tokenizer object. This is an older, deprecated, +** version of fts5_tokenizer_v2. It is similar except that: +** +** <ul> +** <li> There is no "iVersion" field, and +** <li> The xTokenize() method does not take a locale argument. +** </ul> +** +** Legacy fts5_tokenizer tokenizers must be registered using the +** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). +** +** Tokenizer implementations registered using either API may be retrieved +** using both xFindTokenizer() and xFindTokenizer_v2(). +** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a @@ -13544,6 +13811,33 @@ struct Fts5ExtensionApi { ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; +struct fts5_tokenizer_v2 { + int iVersion; /* Currently always 2 */ + + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* +** New code should use the fts5_tokenizer_v2 type to define tokenizer +** implementations. The following type is included for legacy applications +** that still use it. +*/ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); @@ -13563,6 +13857,7 @@ struct fts5_tokenizer { ); }; + /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 @@ -13582,7 +13877,7 @@ struct fts5_tokenizer { */ typedef struct fts5_api fts5_api; struct fts5_api { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( @@ -13609,6 +13904,25 @@ struct fts5_api { fts5_extension_function xFunction, void (*xDestroy)(void*) ); + + /* APIs below this point are only available if iVersion>=3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer_v2 *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer + ); }; /* @@ -13622,6 +13936,20 @@ struct fts5_api { #endif /* _FTS5_H */ /******** End of fts5.h *********/ +#endif /* SQLITE3_H */ + +/* Function prototypes of SQLite3 Multiple Ciphers */ +SQLITE_PRIVATE int sqlite3mcCheckVfs(const char*); +SQLITE_PRIVATE int sqlite3mcFileControlPragma(sqlite3*, const char*, int, void*); +SQLITE_PRIVATE int sqlite3mcHandleAttachKey(sqlite3*, const char*, const char*, sqlite3_value*, char**); +SQLITE_PRIVATE int sqlite3mcHandleMainKey(sqlite3*, const char*); +typedef struct PgHdr PgHdrMC; +SQLITE_PRIVATE void* sqlite3mcPagerCodec(PgHdrMC* pPg); +typedef struct Pager PagerMC; +SQLITE_PRIVATE int sqlite3mcPagerHasCodec(PagerMC* pPager); +SQLITE_PRIVATE void sqlite3mcInitMemoryMethods(); +SQLITE_PRIVATE int sqlite3mcIsBackupSupported(sqlite3*, const char*, sqlite3*, const char*); +SQLITE_PRIVATE void sqlite3mcCodecGetKey(sqlite3* db, int nDb, void** zKey, int* nKey); /************** End of sqlite3.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -13667,6 +13995,7 @@ struct fts5_api { #ifndef SQLITE_MAX_LENGTH # define SQLITE_MAX_LENGTH 1000000000 #endif +#define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */ /* ** This is the maximum number of @@ -13732,9 +14061,13 @@ struct fts5_api { /* ** The maximum number of arguments to an SQL function. +** +** This value has a hard upper limit of 32767 due to storage +** constraints (it needs to fit inside a i16). We keep it +** lower than that to prevent abuse. */ #ifndef SQLITE_MAX_FUNCTION_ARG -# define SQLITE_MAX_FUNCTION_ARG 127 +# define SQLITE_MAX_FUNCTION_ARG 1000 #endif /* @@ -13831,7 +14164,7 @@ struct fts5_api { ** max_page_count macro. */ #ifndef SQLITE_MAX_PAGE_COUNT -# define SQLITE_MAX_PAGE_COUNT 1073741823 +# define SQLITE_MAX_PAGE_COUNT 0xfffffffe /* 4294967294 */ #endif /* @@ -13970,6 +14303,19 @@ struct fts5_api { # undef SQLITE_USE_SEH #endif +/* +** Enable SQLITE_DIRECT_OVERFLOW_READ, unless the build explicitly +** disables it using -DSQLITE_DIRECT_OVERFLOW_READ=0 +*/ +#if defined(SQLITE_DIRECT_OVERFLOW_READ) && SQLITE_DIRECT_OVERFLOW_READ+1==1 + /* Disable if -DSQLITE_DIRECT_OVERFLOW_READ=0 */ +# undef SQLITE_DIRECT_OVERFLOW_READ +#else + /* In all other cases, enable */ +# define SQLITE_DIRECT_OVERFLOW_READ 1 +#endif + + /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never @@ -14238,6 +14584,8 @@ struct fts5_api { # define SQLITE_OMIT_ALTERTABLE #endif +#define SQLITE_DIGIT_SEPARATOR '_' + /* ** Return true (non-zero) if the input is an integer that is too large ** to fit in 32-bits. This macro is used inside of various testcase() @@ -14403,135 +14751,135 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 -#define TK_MATCH 46 -#define TK_LIKE_KW 47 -#define TK_BETWEEN 48 -#define TK_IN 49 -#define TK_ISNULL 50 -#define TK_NOTNULL 51 -#define TK_NE 52 -#define TK_EQ 53 -#define TK_GT 54 -#define TK_LE 55 -#define TK_LT 56 -#define TK_GE 57 -#define TK_ESCAPE 58 -#define TK_ID 59 -#define TK_COLUMNKW 60 -#define TK_DO 61 -#define TK_FOR 62 -#define TK_IGNORE 63 -#define TK_INITIALLY 64 -#define TK_INSTEAD 65 -#define TK_NO 66 -#define TK_KEY 67 -#define TK_OF 68 -#define TK_OFFSET 69 -#define TK_PRAGMA 70 -#define TK_RAISE 71 -#define TK_RECURSIVE 72 -#define TK_REPLACE 73 -#define TK_RESTRICT 74 -#define TK_ROW 75 -#define TK_ROWS 76 -#define TK_TRIGGER 77 -#define TK_VACUUM 78 -#define TK_VIEW 79 -#define TK_VIRTUAL 80 -#define TK_WITH 81 -#define TK_NULLS 82 -#define TK_FIRST 83 -#define TK_LAST 84 -#define TK_CURRENT 85 -#define TK_FOLLOWING 86 -#define TK_PARTITION 87 -#define TK_PRECEDING 88 -#define TK_RANGE 89 -#define TK_UNBOUNDED 90 -#define TK_EXCLUDE 91 -#define TK_GROUPS 92 -#define TK_OTHERS 93 -#define TK_TIES 94 -#define TK_GENERATED 95 -#define TK_ALWAYS 96 -#define TK_MATERIALIZED 97 -#define TK_REINDEX 98 -#define TK_RENAME 99 -#define TK_CTIME_KW 100 -#define TK_ANY 101 -#define TK_BITAND 102 -#define TK_BITOR 103 -#define TK_LSHIFT 104 -#define TK_RSHIFT 105 -#define TK_PLUS 106 -#define TK_MINUS 107 -#define TK_STAR 108 -#define TK_SLASH 109 -#define TK_REM 110 -#define TK_CONCAT 111 -#define TK_PTR 112 -#define TK_COLLATE 113 -#define TK_BITNOT 114 -#define TK_ON 115 -#define TK_INDEXED 116 -#define TK_STRING 117 -#define TK_JOIN_KW 118 -#define TK_CONSTRAINT 119 -#define TK_DEFAULT 120 -#define TK_NULL 121 -#define TK_PRIMARY 122 -#define TK_UNIQUE 123 -#define TK_CHECK 124 -#define TK_REFERENCES 125 -#define TK_AUTOINCR 126 -#define TK_INSERT 127 -#define TK_DELETE 128 -#define TK_UPDATE 129 -#define TK_SET 130 -#define TK_DEFERRABLE 131 -#define TK_FOREIGN 132 -#define TK_DROP 133 -#define TK_UNION 134 -#define TK_ALL 135 -#define TK_EXCEPT 136 -#define TK_INTERSECT 137 -#define TK_SELECT 138 -#define TK_VALUES 139 -#define TK_DISTINCT 140 -#define TK_DOT 141 -#define TK_FROM 142 -#define TK_JOIN 143 -#define TK_USING 144 -#define TK_ORDER 145 -#define TK_GROUP 146 -#define TK_HAVING 147 -#define TK_LIMIT 148 -#define TK_WHERE 149 -#define TK_RETURNING 150 -#define TK_INTO 151 -#define TK_NOTHING 152 -#define TK_FLOAT 153 -#define TK_BLOB 154 -#define TK_INTEGER 155 -#define TK_VARIABLE 156 -#define TK_CASE 157 -#define TK_WHEN 158 -#define TK_THEN 159 -#define TK_ELSE 160 -#define TK_INDEX 161 -#define TK_ALTER 162 -#define TK_ADD 163 -#define TK_WINDOW 164 -#define TK_OVER 165 -#define TK_FILTER 166 -#define TK_COLUMN 167 -#define TK_AGG_FUNCTION 168 -#define TK_AGG_COLUMN 169 -#define TK_TRUEFALSE 170 -#define TK_ISNOT 171 +#define TK_ISNOT 46 +#define TK_MATCH 47 +#define TK_LIKE_KW 48 +#define TK_BETWEEN 49 +#define TK_IN 50 +#define TK_ISNULL 51 +#define TK_NOTNULL 52 +#define TK_NE 53 +#define TK_EQ 54 +#define TK_GT 55 +#define TK_LE 56 +#define TK_LT 57 +#define TK_GE 58 +#define TK_ESCAPE 59 +#define TK_ID 60 +#define TK_COLUMNKW 61 +#define TK_DO 62 +#define TK_FOR 63 +#define TK_IGNORE 64 +#define TK_INITIALLY 65 +#define TK_INSTEAD 66 +#define TK_NO 67 +#define TK_KEY 68 +#define TK_OF 69 +#define TK_OFFSET 70 +#define TK_PRAGMA 71 +#define TK_RAISE 72 +#define TK_RECURSIVE 73 +#define TK_REPLACE 74 +#define TK_RESTRICT 75 +#define TK_ROW 76 +#define TK_ROWS 77 +#define TK_TRIGGER 78 +#define TK_VACUUM 79 +#define TK_VIEW 80 +#define TK_VIRTUAL 81 +#define TK_WITH 82 +#define TK_NULLS 83 +#define TK_FIRST 84 +#define TK_LAST 85 +#define TK_CURRENT 86 +#define TK_FOLLOWING 87 +#define TK_PARTITION 88 +#define TK_PRECEDING 89 +#define TK_RANGE 90 +#define TK_UNBOUNDED 91 +#define TK_EXCLUDE 92 +#define TK_GROUPS 93 +#define TK_OTHERS 94 +#define TK_TIES 95 +#define TK_GENERATED 96 +#define TK_ALWAYS 97 +#define TK_MATERIALIZED 98 +#define TK_REINDEX 99 +#define TK_RENAME 100 +#define TK_CTIME_KW 101 +#define TK_ANY 102 +#define TK_BITAND 103 +#define TK_BITOR 104 +#define TK_LSHIFT 105 +#define TK_RSHIFT 106 +#define TK_PLUS 107 +#define TK_MINUS 108 +#define TK_STAR 109 +#define TK_SLASH 110 +#define TK_REM 111 +#define TK_CONCAT 112 +#define TK_PTR 113 +#define TK_COLLATE 114 +#define TK_BITNOT 115 +#define TK_ON 116 +#define TK_INDEXED 117 +#define TK_STRING 118 +#define TK_JOIN_KW 119 +#define TK_CONSTRAINT 120 +#define TK_DEFAULT 121 +#define TK_NULL 122 +#define TK_PRIMARY 123 +#define TK_UNIQUE 124 +#define TK_CHECK 125 +#define TK_REFERENCES 126 +#define TK_AUTOINCR 127 +#define TK_INSERT 128 +#define TK_DELETE 129 +#define TK_UPDATE 130 +#define TK_SET 131 +#define TK_DEFERRABLE 132 +#define TK_FOREIGN 133 +#define TK_DROP 134 +#define TK_UNION 135 +#define TK_ALL 136 +#define TK_EXCEPT 137 +#define TK_INTERSECT 138 +#define TK_SELECT 139 +#define TK_VALUES 140 +#define TK_DISTINCT 141 +#define TK_DOT 142 +#define TK_FROM 143 +#define TK_JOIN 144 +#define TK_USING 145 +#define TK_ORDER 146 +#define TK_GROUP 147 +#define TK_HAVING 148 +#define TK_LIMIT 149 +#define TK_WHERE 150 +#define TK_RETURNING 151 +#define TK_INTO 152 +#define TK_NOTHING 153 +#define TK_FLOAT 154 +#define TK_BLOB 155 +#define TK_INTEGER 156 +#define TK_VARIABLE 157 +#define TK_CASE 158 +#define TK_WHEN 159 +#define TK_THEN 160 +#define TK_ELSE 161 +#define TK_INDEX 162 +#define TK_ALTER 163 +#define TK_ADD 164 +#define TK_WINDOW 165 +#define TK_OVER 166 +#define TK_FILTER 167 +#define TK_COLUMN 168 +#define TK_AGG_FUNCTION 169 +#define TK_AGG_COLUMN 170 +#define TK_TRUEFALSE 171 #define TK_FUNCTION 172 -#define TK_UMINUS 173 -#define TK_UPLUS 174 +#define TK_UPLUS 173 +#define TK_UMINUS 174 #define TK_TRUTH 175 #define TK_REGISTER 176 #define TK_VECTOR 177 @@ -14540,8 +14888,9 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_ASTERISK 180 #define TK_SPAN 181 #define TK_ERROR 182 -#define TK_SPACE 183 -#define TK_ILLEGAL 184 +#define TK_QNUMBER 183 +#define TK_SPACE 184 +#define TK_ILLEGAL 185 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14550,6 +14899,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #include <string.h> #include <assert.h> #include <stddef.h> +#include <ctype.h> /* ** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY. @@ -14570,7 +14920,8 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite_int64 # define float sqlite_int64 -# define LONGDOUBLE_TYPE sqlite_int64 +# define fabs(X) ((X)<0?-(X):(X)) +# define sqlite3IsOverflow(X) 0 # ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) # endif @@ -14745,9 +15096,6 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); # define INT8_TYPE signed char # endif #endif -#ifndef LONGDOUBLE_TYPE -# define LONGDOUBLE_TYPE long double -#endif typedef sqlite_int64 i64; /* 8-byte signed integer */ typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ @@ -14803,7 +15151,7 @@ typedef INT16_TYPE LogEst; # define SQLITE_PTRSIZE __SIZEOF_POINTER__ # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ - (defined(__APPLE__) && defined(__POWERPC__)) || \ + (defined(__APPLE__) && defined(__ppc__)) || \ (defined(__TOS_AIX__) && !defined(__64BIT__)) # define SQLITE_PTRSIZE 4 # else @@ -15040,6 +15388,7 @@ SQLITE_PRIVATE u32 sqlite3TreeTrace; ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing ** 0x00020000 Transform DISTINCT into GROUP BY ** 0x00040000 SELECT tree dump after all code has been generated +** 0x00080000 NOT NULL strength reduction */ /* @@ -15070,7 +15419,7 @@ SQLITE_PRIVATE u32 sqlite3WhereTrace; ** 0x00000010 Display sqlite3_index_info xBestIndex calls ** 0x00000020 Range an equality scan metrics ** 0x00000040 IN operator decisions -** 0x00000080 WhereLoop cost adjustements +** 0x00000080 WhereLoop cost adjustments ** 0x00000100 ** 0x00000200 Covering index decisions ** 0x00000400 OR optimization @@ -15246,6 +15595,7 @@ typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; +typedef struct Subquery Subquery; typedef struct SrcItem SrcItem; typedef struct SrcList SrcList; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ @@ -15719,6 +16069,22 @@ typedef struct PgHdr DbPage; #define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ #define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ +#define isWalMode(x) ((x)==PAGER_JOURNALMODE_WAL) + +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods!=0) + /* ** Flags that make up the mask passed to sqlite3PagerGet(). */ @@ -15852,7 +16218,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); -SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, u64*); SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); @@ -16128,6 +16494,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursor( ); SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void); SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(Btree*,BtCursor*); +#endif SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); #ifdef SQLITE_ENABLE_CURSOR_HINTS @@ -16219,6 +16588,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( sqlite3 *db, /* Database connection that is running the check */ Btree *p, /* The btree to be checked */ Pgno *aRoot, /* An array of root pages numbers for individual trees */ + sqlite3_value *aCnt, /* OUT: entry counts for each btree in aRoot[] */ int nRoot, /* Number of entries in aRoot[] */ int mxErr, /* Stop reporting errors after this many */ int *pnErr, /* OUT: Write number of errors seen to this variable */ @@ -16345,6 +16715,19 @@ typedef struct Vdbe Vdbe; */ typedef struct sqlite3_value Mem; typedef struct SubProgram SubProgram; +typedef struct SubrtnSig SubrtnSig; + +/* +** A signature for a reusable subroutine that materializes the RHS of +** an IN operator. +*/ +struct SubrtnSig { + int selId; /* SELECT-id for the SELECT statement on the RHS */ + char *zAff; /* Affinity of the overall IN expression */ + int iTable; /* Ephemeral table generated by the subroutine */ + int iAddr; /* Subroutine entry address */ + int regReturn; /* Register used to hold return address */ +}; /* ** A single instruction of the virtual machine has an opcode @@ -16373,6 +16756,7 @@ struct VdbeOp { u32 *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ + SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif @@ -16439,6 +16823,8 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ +#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ +#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 @@ -16488,12 +16874,12 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Vacuum 5 #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ -#define OP_Init 8 /* jump, synopsis: Start at P2 */ +#define OP_Init 8 /* jump0, synopsis: Start at P2 */ #define OP_Goto 9 /* jump */ #define OP_Gosub 10 /* jump */ -#define OP_InitCoroutine 11 /* jump */ -#define OP_Yield 12 /* jump */ -#define OP_MustBeInt 13 /* jump */ +#define OP_InitCoroutine 11 /* jump0 */ +#define OP_Yield 12 /* jump0 */ +#define OP_MustBeInt 13 /* jump0 */ #define OP_Jump 14 /* jump */ #define OP_Once 15 /* jump */ #define OP_If 16 /* jump */ @@ -16501,22 +16887,22 @@ typedef struct VdbeOpList VdbeOpList; #define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */ #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ #define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ -#define OP_SeekLT 21 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekLE 22 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGT 24 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekLT 21 /* jump0, synopsis: key=r[P3@P4] */ +#define OP_SeekLE 22 /* jump0, synopsis: key=r[P3@P4] */ +#define OP_SeekGE 23 /* jump0, synopsis: key=r[P3@P4] */ +#define OP_SeekGT 24 /* jump0, synopsis: key=r[P3@P4] */ #define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ #define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ #define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ #define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ #define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */ +#define OP_SeekRowid 30 /* jump0, synopsis: intkey=r[P3] */ #define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ -#define OP_Last 32 /* jump */ -#define OP_IfSmaller 33 /* jump */ +#define OP_Last 32 /* jump0 */ +#define OP_IfSizeBetween 33 /* jump */ #define OP_SorterSort 34 /* jump */ #define OP_Sort 35 /* jump */ -#define OP_Rewind 36 /* jump */ +#define OP_Rewind 36 /* jump0 */ #define OP_SorterNext 37 /* jump */ #define OP_Prev 38 /* jump */ #define OP_Next 39 /* jump */ @@ -16528,18 +16914,18 @@ typedef struct VdbeOpList VdbeOpList; #define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ #define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ -#define OP_Program 48 /* jump */ +#define OP_Program 48 /* jump0 */ #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ -#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ -#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ -#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ -#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ -#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ -#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ -#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ -#define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ -#define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ -#define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IfPos 50 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ +#define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ +#define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ +#define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ +#define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ +#define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ +#define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ +#define OP_Ge 58 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ +#define OP_ElseEq 59 /* jump, same as TK_ESCAPE */ #define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ #define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ #define OP_IncrVacuum 62 /* jump */ @@ -16558,7 +16944,7 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Null 75 /* synopsis: r[P2..P3]=NULL */ #define OP_SoftNull 76 /* synopsis: r[P1]=NULL */ #define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */ -#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */ +#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1) */ #define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */ #define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ #define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */ @@ -16582,23 +16968,23 @@ typedef struct VdbeOpList VdbeOpList; #define OP_ReadCookie 99 #define OP_SetCookie 100 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ -#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ -#define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ -#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 102 /* synopsis: root=P2 iDb=P3 */ +#define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ +#define OP_ShiftRight 106 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ +#define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ -#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -#define OP_OpenDup 115 +#define OP_OpenDup 114 +#define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ -#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */ +#define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_SorterOpen 119 #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ @@ -16633,8 +17019,8 @@ typedef struct VdbeOpList VdbeOpList; #define OP_LoadAnalysis 150 #define OP_DropTable 151 #define OP_DropIndex 152 -#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_DropTrigger 154 +#define OP_DropTrigger 153 +#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ #define OP_IntegrityCk 155 #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ #define OP_Param 157 @@ -16661,13 +17047,15 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Pagecount 178 #define OP_MaxPgcnt 179 #define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */ -#define OP_FilterAdd 181 /* synopsis: filter(P1) += key(P3@P4) */ -#define OP_Trace 182 -#define OP_CursorHint 183 -#define OP_ReleaseReg 184 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 185 -#define OP_Explain 186 -#define OP_Abortable 187 +#define OP_GetSubtype 181 /* synopsis: r[P2] = r[P1].subtype */ +#define OP_SetSubtype 182 /* synopsis: r[P2].subtype = r[P1] */ +#define OP_FilterAdd 183 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 184 +#define OP_CursorHint 185 +#define OP_ReleaseReg 186 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 187 +#define OP_Explain 188 +#define OP_Abortable 189 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -16680,31 +17068,32 @@ typedef struct VdbeOpList VdbeOpList; #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ #define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */ +#define OPFLG_JUMP0 0x80 /* jump0: P2 might be zero */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ -/* 8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\ -/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x49, 0x49, 0x49,\ -/* 24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\ -/* 32 */ 0x41, 0x01, 0x41, 0x41, 0x41, 0x01, 0x41, 0x41,\ +/* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\ +/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\ +/* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ +/* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ -/* 48 */ 0x01, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ +/* 48 */ 0x81, 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ +/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x41,\ /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ -/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26, 0x26,\ +/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\ +/* 112 */ 0x26, 0x00, 0x40, 0x12, 0x40, 0x40, 0x10, 0x00,\ /* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ +/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04,\ /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ -/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00,\ -/* 184 */ 0x00, 0x00, 0x00, 0x00,} +/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ +/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -16721,7 +17110,7 @@ typedef struct VdbeOpList VdbeOpList; ** Additional non-public SQLITE_PREPARE_* flags */ #define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */ -#define SQLITE_PREPARE_MASK 0x0f /* Mask of public flags */ +#define SQLITE_PREPARE_MASK 0x1f /* Mask of public flags */ /* ** Prototypes for the VDBE interface. See comments on the implementation @@ -16847,6 +17236,8 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*); +SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val); + SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); #ifdef SQLITE_ENABLE_BYTECODE_VTAB SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); @@ -17434,43 +17825,11 @@ struct FuncDefHash { }; #define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) -#ifdef SQLITE_USER_AUTHENTICATION -/* -** Information held in the "sqlite3" database connection object and used -** to manage user authentication. -*/ -typedef struct sqlite3_userauth sqlite3_userauth; -struct sqlite3_userauth { - u8 authLevel; /* Current authentication level */ - int nAuthPW; /* Size of the zAuthPW in bytes */ - char *zAuthPW; /* Password used to authenticate */ - char *zAuthUser; /* User name used to authenticate */ -}; - -/* Allowed values for sqlite3_userauth.authLevel */ -#define UAUTH_Unknown 0 /* Authentication not yet checked */ -#define UAUTH_Fail 1 /* User authentication failed */ -#define UAUTH_User 2 /* Authenticated as a normal user */ -#define UAUTH_Admin 3 /* Authenticated as an administrator */ - -/* Functions used only by user authorization logic */ -SQLITE_PRIVATE int sqlite3UserAuthTable(const char*); -SQLITE_PRIVATE int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); -SQLITE_PRIVATE void sqlite3UserAuthInit(sqlite3*); -SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); - -#endif /* SQLITE_USER_AUTHENTICATION */ - /* ** typedef for the authorization callback function. */ -#ifdef SQLITE_USER_AUTHENTICATION - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*, const char*); -#else - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*); -#endif +typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*); #ifndef SQLITE_OMIT_DEPRECATED /* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing @@ -17631,9 +17990,6 @@ struct sqlite3 { void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif -#ifdef SQLITE_USER_AUTHENTICATION - sqlite3_userauth auth; /* User authentication information */ -#endif }; /* @@ -17737,7 +18093,7 @@ struct sqlite3 { #define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ #define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ -#define SQLITE_PushDown 0x00001000 /* The push-down optimization */ +#define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */ #define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ #define SQLITE_SkipScan 0x00004000 /* Skip-scans */ #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ @@ -17755,6 +18111,7 @@ struct sqlite3 { #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ +#define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -17791,7 +18148,7 @@ struct sqlite3 { ** field is used by per-connection app-def functions. */ struct FuncDef { - i8 nArg; /* Number of arguments. -1 means unlimited */ + i16 nArg; /* Number of arguments. -1 means unlimited */ u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ @@ -17965,11 +18322,11 @@ struct FuncDestructor { #define MFUNCTION(zName, nArg, xPtr, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } -#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \ +#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, bJsonB, iArg, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\ SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\ ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg|((bJsonB)*JSON_BLOB)),0,xFunc,0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_FUNC_BUILTIN|\ SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ @@ -18310,8 +18667,7 @@ struct Table { #define TF_HasStored 0x00000040 /* Has one or more STORED columns */ #define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */ #define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */ -#define TF_StatsUsed 0x00000100 /* Query planner decisions affected by - ** Index.aiRowLogEst[] values */ +#define TF_MaybeReanalyze 0x00000100 /* Maybe run ANALYZE on this table */ #define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */ #define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */ #define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */ @@ -18367,6 +18723,15 @@ struct Table { #define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0) #define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0) +/* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is +** available. By default, this macro is false +*/ +#ifndef SQLITE_ALLOW_ROWID_IN_VIEW +# define ViewCanHaveRowid 0 +#else +# define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0) +#endif + /* ** Each foreign key constraint is an instance of the following structure. ** @@ -18604,6 +18969,7 @@ struct Index { unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ + unsigned bLowQual:1; /* sqlite_stat1 says this is a low-quality index */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ @@ -18717,6 +19083,7 @@ struct AggInfo { int iOBTab; /* Ephemeral table to implement ORDER BY */ u8 bOBPayload; /* iOBTab has payload columns separate from key */ u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ + u8 bUseSubtype; /* Transfer subtype info through sorter */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ @@ -18732,9 +19099,15 @@ struct AggInfo { ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** The assert()s that are part of this macro verify that constraint. */ +#ifndef NDEBUG #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) #define AggInfoFuncReg(A,I) \ (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) +#else +#define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I)) +#define AggInfoFuncReg(A,I) \ + ((A)->iFirstReg+(A)->nColumn+(I)) +#endif /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. @@ -18915,7 +19288,7 @@ struct Expr { #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */ - /* 0x80000000 // Available */ +#define EP_SubtArg 0x80000000 /* Is argument to SQLITE_SUBTYPE function */ /* The EP_Propagate mask is a set of properties that automatically propagate ** upwards into parent nodes. @@ -19086,6 +19459,16 @@ struct IdList { #define EU4_IDX 1 /* Uses IdList.a.u4.idx */ #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ +/* +** Details of the implementation of a subquery. +*/ +struct Subquery { + Select *pSelect; /* A SELECT statement used in place of a table name */ + int addrFillSub; /* Address of subroutine to initialize a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ +}; + /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. @@ -19098,27 +19481,40 @@ struct IdList { ** In the colUsed field, the high-order bit (bit 63) is set if the table ** contains more than 63 columns and the 64-th or later column is used. ** -** Union member validity: +** Aggressive use of "union" helps keep the size of the object small. This +** has been shown to boost performance, in addition to saving memory. +** Access to union elements is gated by the following rules which should +** always be checked, either by an if-statement or by an assert(). +** +** Field Only access if this is true +** --------------- ----------------------------------- +** u1.zIndexedBy fg.isIndexedBy +** u1.pFuncArg fg.isTabFunc +** u1.nRow !fg.isTabFunc && !fg.isIndexedBy +** +** u2.pIBIndex fg.isIndexedBy +** u2.pCteUse fg.isCte +** +** u3.pOn !fg.isUsing +** u3.pUsing fg.isUsing +** +** u4.zDatabase !fg.fixedSchema && !fg.isSubquery +** u4.pSchema fg.fixedSchema +** u4.pSubq fg.isSubquery ** -** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc -** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy -** u2.pIBIndex fg.isIndexedBy && !fg.isCte -** u2.pCteUse fg.isCte && !fg.isIndexedBy +** See also the sqlite3SrcListDelete() routine for assert() statements that +** check invariants on the fields of this object, especially the flags +** inside the fg struct. */ struct SrcItem { - Schema *pSchema; /* Schema to which this item is fixed */ - char *zDatabase; /* Name of database holding this table */ char *zName; /* Name of the table */ char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ - Table *pTab; /* An SQL table corresponding to zName */ - Select *pSelect; /* A SELECT statement used in place of a table name */ - int addrFillSub; /* Address of subroutine to manifest a subquery */ - int regReturn; /* Register holding return address of addrFillSub */ - int regResult; /* Registers holding results of a co-routine */ + Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */ struct { u8 jointype; /* Type of join between this table and the previous */ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ + unsigned isSubquery :1; /* True if this term is a subquery */ unsigned isTabFunc :1; /* True if table-valued-function syntax */ unsigned isCorrelated :1; /* True if sub-query is correlated */ unsigned isMaterialized:1; /* This is a materialized view */ @@ -19131,21 +19527,30 @@ struct SrcItem { unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ + unsigned rowidUsed :1; /* The ROWID of this table is referenced */ + unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */ + unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ - union { - Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ - IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ - } u3; Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ union { char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ ExprList *pFuncArg; /* Arguments to table-valued-function */ + u32 nRow; /* Number of rows in a VALUES clause */ } u1; union { Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ } u2; + union { + Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ + IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ + } u3; + union { + Schema *pSchema; /* Schema to which this item is fixed */ + char *zDatabase; /* Name of database holding this table */ + Subquery *pSubq; /* Description of a subquery */ + } u4; }; /* @@ -19205,7 +19610,7 @@ struct SrcList { #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ #define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ - /* 0x2000 not currently used */ +#define WHERE_KEEP_ALL_JOINS 0x2000 /* Do not do the omit-noop-join opt */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ @@ -19250,6 +19655,7 @@ struct NameContext { int nRef; /* Number of names resolved by this context */ int nNcErr; /* Number of errors encountered while resolving names */ int ncFlags; /* Zero or more NC_* flags defined below */ + u32 nNestedSelect; /* Number of nested selects using this NC */ Select *pWinSelect; /* SELECT statement for any window functions */ }; @@ -19276,13 +19682,14 @@ struct NameContext { #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ #define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ -#define NC_Complex 0x002000 /* True if a function or subquery seen */ +/* 0x002000 // available for reuse */ #define NC_AllowWin 0x004000 /* Window functions are allowed here */ #define NC_HasWin 0x008000 /* One or more window functions seen */ #define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ #define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */ #define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */ #define NC_NoSelect 0x080000 /* Do not descend into sub-selects */ +#define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */ #define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */ /* @@ -19306,6 +19713,7 @@ struct Upsert { Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */ + u8 isDup; /* True if 2nd or later with same pUpsertIdx */ /* Above this point is the parse tree for the ON CONFLICT clauses. ** The next group of fields stores intermediate data. */ void *pToFree; /* Free memory when deleting the Upsert object */ @@ -19395,14 +19803,17 @@ struct Select { #define SF_View 0x0200000 /* SELECT statement is a view */ #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ #define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ -#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ +#define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ +#define SF_Correlated 0x20000000 /* True if references the outer context */ -/* True if S exists and has SF_NestedFrom */ -#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) +/* True if SrcItem X is a subquery that has SF_NestedFrom */ +#define IsNestedFrom(X) \ + ((X)->fg.isSubquery && \ + ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0) /* ** The results of a SELECT can be distributed in several ways, as defined @@ -19432,7 +19843,11 @@ struct Select { ** SRT_Set The result must be a single column. Store each ** row of result as the key in table pDest->iSDParm. ** Apply the affinity pDest->affSdst before storing -** results. Used to implement "IN (SELECT ...)". +** results. if pDest->iSDParm2 is positive, then it is +** a register holding a Bloom filter for the IN operator +** that should be populated in addition to the +** pDest->iSDParm table. This SRT is used to +** implement "IN (SELECT ...)". ** ** SRT_EphemTab Create an temporary table pDest->iSDParm and store ** the result there. The cursor is left open after @@ -19639,6 +20054,8 @@ struct Parse { u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ + u8 bHasWith; /* True if statement contains WITH */ + u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif @@ -19934,7 +20351,7 @@ struct Returning { }; /* -** An objected used to accumulate the text of a string where we +** An object used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. */ struct sqlite3_str { @@ -19948,7 +20365,7 @@ struct sqlite3_str { }; #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ -#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ +#define SQLITE_PRINTF_MALLOCED 0x04 /* True if zText is allocated space */ #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) @@ -19966,6 +20383,9 @@ struct sqlite3_str { ** ** 3. Make a (read-only) copy of a read-only RCStr string using ** sqlite3RCStrRef(). +** +** "String" is in the name, but an RCStr object can also be used to hold +** binary data. */ struct RCStr { u64 nRCRef; /* Number of references */ @@ -20023,7 +20443,9 @@ struct Sqlite3Config { u8 bUseCis; /* Use covering indices for full-scans */ u8 bSmallMalloc; /* Avoid large memory allocations if true */ u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ - u8 bUseLongDouble; /* Make use of long double */ +#ifdef SQLITE_DEBUG + u8 bJsonSelfcheck; /* Double-check JSON parsing */ +#endif int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ @@ -20070,6 +20492,11 @@ struct Sqlite3Config { #endif #ifndef SQLITE_UNTESTABLE int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ +#endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW + ** feature is disabled. 0 if rowids can + ** occur in views. */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ @@ -20307,6 +20734,9 @@ struct Window { ** due to the SQLITE_SUBTYPE flag */ }; +SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow); +SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal); + #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*); SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window*); @@ -20387,15 +20817,6 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); # define SQLITE_ENABLE_FTS3 1 #endif -/* -** The ctype.h header is needed for non-ASCII systems. It is also -** needed by FTS3 when FTS3 is included in the amalgamation. -*/ -#if !defined(SQLITE_ASCII) || \ - (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION)) -# include <ctype.h> -#endif - /* ** The following macros mimic the standard library functions toupper(), ** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The @@ -20526,10 +20947,13 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*); # define EXP754 (((u64)0x7ff)<<52) # define MAN754 ((((u64)1)<<52)-1) # define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0) +# define IsOvfl(X) (((X)&EXP754)==EXP754) SQLITE_PRIVATE int sqlite3IsNaN(double); +SQLITE_PRIVATE int sqlite3IsOverflow(double); #else -# define IsNaN(X) 0 -# define sqlite3IsNaN(X) 0 +# define IsNaN(X) 0 +# define sqlite3IsNaN(X) 0 +# define sqlite3IsOVerflow(X) 0 #endif /* @@ -20621,6 +21045,7 @@ SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); SQLITE_PRIVATE void sqlite3Dequote(char*); SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); SQLITE_PRIVATE void sqlite3DequoteToken(Token*); +SQLITE_PRIVATE void sqlite3DequoteNumber(Parse*, Expr*); SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*); @@ -20650,7 +21075,8 @@ SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*); SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); -SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*); +SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse*, Expr*); SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); @@ -20659,6 +21085,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int); SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); @@ -20749,6 +21176,7 @@ SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3*, void*); SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); #ifndef SQLITE_OMIT_AUTOINCREMENT SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); @@ -20767,6 +21195,9 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*); +SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*); +SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); @@ -20785,6 +21216,7 @@ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); @@ -20815,6 +21247,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg); SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); #ifndef SQLITE_OMIT_GENERATED_COLUMNS SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); @@ -20870,16 +21303,14 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*); SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*); SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*); -SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); -SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); +SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); -SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); -SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int); +SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif -SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); @@ -21007,10 +21438,11 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); SQLITE_PRIVATE int sqlite3Atoi(const char*); #ifndef SQLITE_OMIT_UTF16 -SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar); #endif SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); +SQLITE_PRIVATE int sqlite3Utf8ReadLimited(const u8*, int, u32*); SQLITE_PRIVATE LogEst sqlite3LogEst(u64); SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); @@ -21059,7 +21491,9 @@ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*); SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); +#if !defined(SQLITE_OMIT_BLOB_LITERAL) SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); +#endif SQLITE_PRIVATE u8 sqlite3HexToInt(int h); SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); @@ -21357,6 +21791,7 @@ SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); #else # define sqlite3CteNew(P,T,E,S) ((void*)0) @@ -21369,7 +21804,7 @@ SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); -SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); +SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*); SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*); @@ -21759,6 +22194,9 @@ static const char * const sqlite3azCompileOpt[] = { "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), # endif #endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + "ALLOW_ROWID_IN_VIEW", +#endif #ifdef SQLITE_ALLOW_URI_AUTHORITY "ALLOW_URI_AUTHORITY", #endif @@ -21986,6 +22424,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC "ENABLE_OFFSET_SQL_FUNC", #endif +#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES + "ENABLE_ORDERED_SET_AGGREGATES", +#endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif @@ -22455,9 +22896,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_UNTESTABLE "UNTESTABLE", #endif -#ifdef SQLITE_USER_AUTHENTICATION - "USER_AUTHENTICATION", -#endif #ifdef SQLITE_USE_ALLOCA "USE_ALLOCA", #endif @@ -22733,7 +23171,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0, /* bSmallMalloc */ 1, /* bExtraSchemaChecks */ - sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ +#ifdef SQLITE_DEBUG + 0, /* bJsonSelfcheck */ +#endif 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ @@ -22775,6 +23215,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { #endif #ifndef SQLITE_UNTESTABLE 0, /* xTestCallback */ +#endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */ #endif 0, /* bLocaltimeFault */ 0, /* xAltLocaltime */ @@ -23300,7 +23743,7 @@ struct sqlite3_context { int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ - u8 argc; /* Number of arguments */ + u16 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; @@ -23447,9 +23890,11 @@ struct PreUpdate { int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ + Mem oldipk; /* Memory cell holding "old" IPK value */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ + sqlite3_value **apDflt; /* Array of default values, if required */ }; /* @@ -23986,7 +24431,7 @@ SQLITE_API int sqlite3_db_status( case SQLITE_DBSTATUS_CACHE_MISS: case SQLITE_DBSTATUS_CACHE_WRITE:{ int i; - int nRet = 0; + u64 nRet = 0; assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); @@ -23999,7 +24444,7 @@ SQLITE_API int sqlite3_db_status( *pHighwater = 0; /* IMP: R-42420-56072 */ /* IMP: R-54100-20147 */ /* IMP: R-29431-39229 */ - *pCurrent = nRet; + *pCurrent = (int)nRet & 0x7fffffff; break; } @@ -24096,13 +24541,14 @@ struct DateTime { int tz; /* Timezone offset in minutes */ double s; /* Seconds */ char validJD; /* True (1) if iJD is valid */ - char rawS; /* Raw numeric value stored in s */ char validYMD; /* True (1) if Y,M,D are valid */ char validHMS; /* True (1) if h,m,s are valid */ - char validTZ; /* True (1) if tz is valid */ - char tzSet; /* Timezone was set explicitly */ - char isError; /* An overflow has occurred */ - char useSubsec; /* Display subsecond precision */ + char nFloor; /* Days to implement "floor" */ + unsigned rawS : 1; /* Raw numeric value stored in s */ + unsigned isError : 1; /* An overflow has occurred */ + unsigned useSubsec : 1; /* Display subsecond precision */ + unsigned isUtc : 1; /* Time is known to be UTC */ + unsigned isLocal : 1; /* Time is known to be localtime */ }; @@ -24200,6 +24646,8 @@ static int parseTimezone(const char *zDate, DateTime *p){ sgn = +1; }else if( c=='Z' || c=='z' ){ zDate++; + p->isLocal = 0; + p->isUtc = 1; goto zulu_time; }else{ return c!=0; @@ -24212,7 +24660,6 @@ static int parseTimezone(const char *zDate, DateTime *p){ p->tz = sgn*(nMn + nHr*60); zulu_time: while( sqlite3Isspace(*zDate) ){ zDate++; } - p->tzSet = 1; return *zDate!=0; } @@ -24256,7 +24703,6 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ p->m = m; p->s = s + ms; if( parseTimezone(zDate, p) ) return 1; - p->validTZ = (p->tz!=0)?1:0; return 0; } @@ -24295,23 +24741,48 @@ static void computeJD(DateTime *p){ Y--; M += 12; } - A = Y/100; - B = 2 - A + (A/4); + A = (Y+4800)/100; + B = 38 - A + (A/4); X1 = 36525*(Y+4716)/100; X2 = 306001*(M+1)/10000; p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); p->validJD = 1; if( p->validHMS ){ p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); - if( p->validTZ ){ + if( p->tz ){ p->iJD -= p->tz*60000; p->validYMD = 0; p->validHMS = 0; - p->validTZ = 0; + p->tz = 0; + p->isUtc = 1; + p->isLocal = 0; } } } +/* +** Given the YYYY-MM-DD information current in p, determine if there +** is day-of-month overflow and set nFloor to the number of days that +** would need to be subtracted from the date in order to bring the +** date back to the end of the month. +*/ +static void computeFloor(DateTime *p){ + assert( p->validYMD || p->isError ); + assert( p->D>=0 && p->D<=31 ); + assert( p->M>=0 && p->M<=12 ); + if( p->D<=28 ){ + p->nFloor = 0; + }else if( (1<<p->M) & 0x15aa ){ + p->nFloor = 0; + }else if( p->M!=2 ){ + p->nFloor = (p->D==31); + }else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){ + p->nFloor = p->D - 28; + }else{ + p->nFloor = p->D - 29; + } +} + /* ** Parse dates of the form ** @@ -24350,12 +24821,16 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ p->Y = neg ? -Y : Y; p->M = M; p->D = D; - if( p->validTZ ){ + computeFloor(p); + if( p->tz ){ computeJD(p); } return 0; } + +static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */ + /* ** Set the time to the current time reported by the VFS. ** @@ -24365,6 +24840,9 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ p->iJD = sqlite3StmtCurrentTime(context); if( p->iJD>0 ){ p->validJD = 1; + p->isUtc = 1; + p->isLocal = 0; + clearYMD_HMS_TZ(p); return 0; }else{ return 1; @@ -24448,7 +24926,7 @@ static int validJulianDay(sqlite3_int64 iJD){ ** Compute the Year, Month, and Day from the julian day number. */ static void computeYMD(DateTime *p){ - int Z, A, B, C, D, E, X1; + int Z, alpha, A, B, C, D, E, X1; if( p->validYMD ) return; if( !p->validJD ){ p->Y = 2000; @@ -24459,8 +24937,8 @@ static void computeYMD(DateTime *p){ return; }else{ Z = (int)((p->iJD + 43200000)/86400000); - A = (int)((Z - 1867216.25)/36524.25); - A = Z + 1 + A - (A/4); + alpha = (int)((Z + 32044.75)/36524.25) - 52; + A = Z + 1 + alpha - ((alpha+100)/4) + 25; B = A + 1524; C = (int)((B - 122.1)/365.25); D = (36525*(C&32767))/100; @@ -24503,7 +24981,7 @@ static void computeYMD_HMS(DateTime *p){ static void clearYMD_HMS_TZ(DateTime *p){ p->validYMD = 0; p->validHMS = 0; - p->validTZ = 0; + p->tz = 0; } #ifndef SQLITE_OMIT_LOCALTIME @@ -24635,7 +25113,7 @@ static int toLocaltime( p->validHMS = 1; p->validJD = 0; p->rawS = 0; - p->validTZ = 0; + p->tz = 0; p->isError = 0; return SQLITE_OK; } @@ -24655,12 +25133,12 @@ static const struct { float rLimit; /* Maximum NNN value for this transform */ float rXform; /* Constant used for this transform */ } aXformType[] = { - { 6, "second", 4.6427e+14, 1.0 }, - { 6, "minute", 7.7379e+12, 60.0 }, - { 4, "hour", 1.2897e+11, 3600.0 }, - { 3, "day", 5373485.0, 86400.0 }, - { 5, "month", 176546.0, 2592000.0 }, - { 4, "year", 14713.0, 31536000.0 }, + /* 0 */ { 6, "second", 4.6427e+14, 1.0 }, + /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, + /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, + /* 3 */ { 3, "day", 5373485.0, 86400.0 }, + /* 4 */ { 5, "month", 176546.0, 2592000.0 }, + /* 5 */ { 4, "year", 14713.0, 31536000.0 }, }; /* @@ -24692,14 +25170,20 @@ static void autoAdjustDate(DateTime *p){ ** NNN.NNNN seconds ** NNN months ** NNN years +** +/-YYYY-MM-DD HH:MM:SS.SSS +** ceiling +** floor ** start of month ** start of year ** start of week ** start of day ** weekday N ** unixepoch +** auto ** localtime ** utc +** subsec +** subsecond ** ** Return 0 on success and 1 if there is any kind of error. If the error ** is in a system call (i.e. localtime()), then an error message is written @@ -24730,6 +25214,37 @@ static int parseModifier( } break; } + case 'c': { + /* + ** ceiling + ** + ** Resolve day-of-month overflow by rolling forward into the next + ** month. As this is the default action, this modifier is really + ** a no-op that is only included for symmetry. See "floor". + */ + if( sqlite3_stricmp(z, "ceiling")==0 ){ + computeJD(p); + clearYMD_HMS_TZ(p); + rc = 0; + p->nFloor = 0; + } + break; + } + case 'f': { + /* + ** floor + ** + ** Resolve day-of-month overflow by rolling back to the end of the + ** previous month. + */ + if( sqlite3_stricmp(z, "floor")==0 ){ + computeJD(p); + p->iJD -= p->nFloor*86400000; + clearYMD_HMS_TZ(p); + rc = 0; + } + break; + } case 'j': { /* ** julianday @@ -24756,7 +25271,9 @@ static int parseModifier( ** show local time. */ if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){ - rc = toLocaltime(p, pCtx); + rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx); + p->isUtc = 0; + p->isLocal = 1; } break; } @@ -24781,7 +25298,7 @@ static int parseModifier( } #ifndef SQLITE_OMIT_LOCALTIME else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ - if( p->tzSet==0 ){ + if( p->isUtc==0 ){ i64 iOrigJD; /* Original localtime */ i64 iGuess; /* Guess at the corresponding utc time */ int cnt = 0; /* Safety to prevent infinite loop */ @@ -24804,7 +25321,8 @@ static int parseModifier( memset(p, 0, sizeof(*p)); p->iJD = iGuess; p->validJD = 1; - p->tzSet = 1; + p->isUtc = 1; + p->isLocal = 0; } rc = SQLITE_OK; } @@ -24824,7 +25342,7 @@ static int parseModifier( && r>=0.0 && r<7.0 && (n=(int)r)==r ){ sqlite3_int64 Z; computeYMD_HMS(p); - p->validTZ = 0; + p->tz = 0; p->validJD = 0; computeJD(p); Z = ((p->iJD + 129600000)/86400000) % 7; @@ -24864,7 +25382,7 @@ static int parseModifier( p->h = p->m = 0; p->s = 0.0; p->rawS = 0; - p->validTZ = 0; + p->tz = 0; p->validJD = 0; if( sqlite3_stricmp(z,"month")==0 ){ p->D = 1; @@ -24935,6 +25453,7 @@ static int parseModifier( x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; p->Y += x; p->M -= x*12; + computeFloor(p); computeJD(p); p->validHMS = 0; p->validYMD = 0; @@ -24981,11 +25500,12 @@ static int parseModifier( z += n; while( sqlite3Isspace(*z) ) z++; n = sqlite3Strlen30(z); - if( n>10 || n<3 ) break; + if( n<3 || n>10 ) break; if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; computeJD(p); assert( rc==1 ); rRounder = r<0 ? -0.5 : +0.5; + p->nFloor = 0; for(i=0; i<ArraySize(aXformType); i++){ if( aXformType[i].nName==n && sqlite3_strnicmp(aXformType[i].zName, z, n)==0 @@ -24993,21 +25513,24 @@ static int parseModifier( ){ switch( i ){ case 4: { /* Special processing to add months */ - assert( strcmp(aXformType[i].zName,"month")==0 ); + assert( strcmp(aXformType[4].zName,"month")==0 ); computeYMD_HMS(p); p->M += (int)r; x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; p->Y += x; p->M -= x*12; + computeFloor(p); p->validJD = 0; r -= (int)r; break; } case 5: { /* Special processing to add years */ int y = (int)r; - assert( strcmp(aXformType[i].zName,"year")==0 ); + assert( strcmp(aXformType[5].zName,"year")==0 ); computeYMD_HMS(p); + assert( p->M>=0 && p->M<=12 ); p->Y += y; + computeFloor(p); p->validJD = 0; r -= (int)r; break; @@ -25068,6 +25591,12 @@ static int isDate( } computeJD(p); if( p->isError || !validJulianDay(p->iJD) ) return 1; + if( argc==1 && p->validYMD && p->D>28 ){ + /* Make sure a YYYY-MM-DD is normalized. + ** Example: 2023-02-31 -> 2023-03-03 */ + assert( p->validJD ); + p->validYMD = 0; + } return 0; } @@ -25255,22 +25784,83 @@ static void dateFunc( } } +/* +** Compute the number of days after the most recent January 1. +** +** In other words, compute the zero-based day number for the +** current year: +** +** Jan01 = 0, Jan02 = 1, ..., Jan31 = 30, Feb01 = 31, ... +** Dec31 = 364 or 365. +*/ +static int daysAfterJan01(DateTime *pDate){ + DateTime jan01 = *pDate; + assert( jan01.validYMD ); + assert( jan01.validHMS ); + assert( pDate->validJD ); + jan01.validJD = 0; + jan01.M = 1; + jan01.D = 1; + computeJD(&jan01); + return (int)((pDate->iJD-jan01.iJD+43200000)/86400000); +} + +/* +** Return the number of days after the most recent Monday. +** +** In other words, return the day of the week according +** to this code: +** +** 0=Monday, 1=Tuesday, 2=Wednesday, ..., 6=Sunday. +*/ +static int daysAfterMonday(DateTime *pDate){ + assert( pDate->validJD ); + return (int)((pDate->iJD+43200000)/86400000) % 7; +} + +/* +** Return the number of days after the most recent Sunday. +** +** In other words, return the day of the week according +** to this code: +** +** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday +*/ +static int daysAfterSunday(DateTime *pDate){ + assert( pDate->validJD ); + return (int)((pDate->iJD+129600000)/86400000) % 7; +} + /* ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...) ** ** Return a string described by FORMAT. Conversions as follows: ** -** %d day of month +** %d day of month 01-31 +** %e day of month 1-31 ** %f ** fractional seconds SS.SSS +** %F ISO date. YYYY-MM-DD +** %G ISO year corresponding to %V 0000-9999. +** %g 2-digit ISO year corresponding to %V 00-99 ** %H hour 00-24 -** %j day of year 000-366 +** %k hour 0-24 (leading zero converted to space) +** %I hour 01-12 +** %j day of year 001-366 ** %J ** julian day number +** %l hour 1-12 (leading zero converted to space) ** %m month 01-12 ** %M minute 00-59 +** %p "am" or "pm" +** %P "AM" or "PM" +** %R time as HH:MM ** %s seconds since 1970-01-01 ** %S seconds 00-59 -** %w day of week 0-6 Sunday==0 -** %W week of year 00-53 +** %T time as HH:MM:SS +** %u day of week 1-7 Monday==1, Sunday==7 +** %w day of week 0-6 Sunday==0, Monday==1 +** %U week of year 00-53 (First Sunday is start of week 01) +** %V week of year 01-53 (First week containing Thursday is week 01) +** %W week of year 00-53 (First Monday is start of week 01) ** %Y year 0000-9999 ** %% % */ @@ -25307,7 +25897,7 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D); break; } - case 'f': { + case 'f': { /* Fractional seconds. (Non-standard) */ double s = x.s; if( s>59.999 ) s = 59.999; sqlite3_str_appendf(&sRes, "%06.3f", s); @@ -25317,6 +25907,21 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D); break; } + case 'G': /* Fall thru */ + case 'g': { + DateTime y = x; + assert( y.validJD ); + /* Move y so that it is the Thursday in the same week as x */ + y.iJD += (3 - daysAfterMonday(&x))*86400000; + y.validYMD = 0; + computeYMD(&y); + if( cf=='g' ){ + sqlite3_str_appendf(&sRes, "%02d", y.Y%100); + }else{ + sqlite3_str_appendf(&sRes, "%04d", y.Y); + } + break; + } case 'H': case 'k': { sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h); @@ -25330,25 +25935,11 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); break; } - case 'W': /* Fall thru */ - case 'j': { - int nDay; /* Number of days since 1st day of year */ - DateTime y = x; - y.validJD = 0; - y.M = 1; - y.D = 1; - computeJD(&y); - nDay = (int)((x.iJD-y.iJD+43200000)/86400000); - if( cf=='W' ){ - int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ - wd = (int)(((x.iJD+43200000)/86400000)%7); - sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7); - }else{ - sqlite3_str_appendf(&sRes,"%03d",nDay+1); - } + case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */ + sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1); break; } - case 'J': { + case 'J': { /* Julian day number. (Non-standard) */ sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0); break; } @@ -25391,13 +25982,33 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); break; } - case 'u': /* Fall thru */ - case 'w': { - char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; + case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */ + case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */ + char c = (char)daysAfterSunday(&x) + '0'; if( c=='0' && cf=='u' ) c = '7'; sqlite3_str_appendchar(&sRes, 1, c); break; } + case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */ + sqlite3_str_appendf(&sRes,"%02d", + (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7); + break; + } + case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */ + DateTime y = x; + /* Adjust y so that is the Thursday in the same week as x */ + assert( y.validJD ); + y.iJD += (3 - daysAfterMonday(&x))*86400000; + y.validYMD = 0; + computeYMD(&y); + sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1); + break; + } + case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */ + sqlite3_str_appendf(&sRes,"%02d", + (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7); + break; + } case 'Y': { sqlite3_str_appendf(&sRes,"%04d",x.Y); break; @@ -25544,9 +26155,7 @@ static void timediffFunc( d1.iJD = d2.iJD - d1.iJD; d1.iJD += (u64)1486995408 * (u64)100000; } - d1.validYMD = 0; - d1.validHMS = 0; - d1.validTZ = 0; + clearYMD_HMS_TZ(&d1); computeYMD_HMS(&d1); sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", @@ -25615,6 +26224,36 @@ static void currentTimeFunc( } #endif +#if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG) +/* +** datedebug(...) +** +** This routine returns JSON that describes the internal DateTime object. +** Used for debugging and testing only. Subject to change. +*/ +static void datedebugFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + char *zJson; + zJson = sqlite3_mprintf( + "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d," + "s:%.3f,validJD:%d,validYMS:%d,validHMS:%d," + "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d," + "isUtc:%d,isLocal:%d}", + x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz, + x.s, x.validJD, x.validYMD, x.validHMS, + x.nFloor, x.rawS, x.isError, x.useSubsec, + x.isUtc, x.isLocal); + sqlite3_result_text(context, zJson, -1, sqlite3_free); + } +} +#endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */ + + /* ** This function registered all of the above C functions as SQL ** functions. This should be the only routine in this file with @@ -25630,6 +26269,9 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), PURE_DATE(timediff, 2, 0, 0, timediffFunc ), +#ifdef SQLITE_DEBUG + PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ), +#endif DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), DFUNCTION(current_date, 0, 0, 0, cdateFunc ), @@ -28698,16 +29340,29 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. +** +** Because these routines raise false-positive alerts in TSAN, disable +** them (make them always return 1) when compiling with TSAN. */ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) + p = 0; +# endif +# endif assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); } SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) + p = 0; +# endif +# endif assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); } -#endif +#endif /* NDEBUG */ #endif /* !defined(SQLITE_MUTEX_OMIT) */ @@ -30051,6 +30706,24 @@ static void sqlite3MallocAlarm(int nByte){ sqlite3_mutex_enter(mem0.mutex); } +#ifdef SQLITE_DEBUG +/* +** This routine is called whenever an out-of-memory condition is seen, +** It's only purpose to to serve as a breakpoint for gdb or similar +** code debuggers when working on out-of-memory conditions, for example +** caused by PRAGMA hard_heap_limit=N. +*/ +static SQLITE_NOINLINE void test_oom_breakpoint(u64 n){ + static u64 nOomFault = 0; + nOomFault += n; + /* The assert() is never reached in a human lifetime. It is here mostly + ** to prevent code optimizers from optimizing out this function. */ + assert( (nOomFault>>32) < 0xffffffff ); +} +#else +# define test_oom_breakpoint(X) /* No-op for production builds */ +#endif + /* ** Do a memory allocation with statistics and alarms. Assume the ** lock is already held. @@ -30077,6 +30750,7 @@ static void mallocWithAlarm(int n, void **pp){ if( mem0.hardLimit ){ nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed >= mem0.hardLimit - nFull ){ + test_oom_breakpoint(1); *pp = 0; return; } @@ -30365,6 +31039,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ sqlite3MallocAlarm(nDiff); if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){ sqlite3_mutex_leave(mem0.mutex); + test_oom_breakpoint(1); return 0; } } @@ -31231,6 +31906,7 @@ SQLITE_API void sqlite3_str_vappendf( if( xtype==etFLOAT ){ iRound = -precision; }else if( xtype==etGENERIC ){ + if( precision==0 ) precision = 1; iRound = precision; }else{ iRound = precision+1; @@ -31266,13 +31942,14 @@ SQLITE_API void sqlite3_str_vappendf( } exp = s.iDP-1; - if( xtype==etGENERIC && precision>0 ) precision--; /* ** If the field type is etGENERIC, then convert to either etEXP ** or etFLOAT, as appropriate. */ if( xtype==etGENERIC ){ + assert( precision>0 ); + precision--; flag_rtz = !flag_alternateform; if( exp<-4 || exp>precision ){ xtype = etEXP; @@ -31579,18 +32256,25 @@ SQLITE_API void sqlite3_str_vappendf( if( pItem->zAlias && !flag_altform2 ){ sqlite3_str_appendall(pAccum, pItem->zAlias); }else if( pItem->zName ){ - if( pItem->zDatabase ){ - sqlite3_str_appendall(pAccum, pItem->zDatabase); + if( pItem->fg.fixedSchema==0 + && pItem->fg.isSubquery==0 + && pItem->u4.zDatabase!=0 + ){ + sqlite3_str_appendall(pAccum, pItem->u4.zDatabase); sqlite3_str_append(pAccum, ".", 1); } sqlite3_str_appendall(pAccum, pItem->zName); }else if( pItem->zAlias ){ sqlite3_str_appendall(pAccum, pItem->zAlias); - }else{ - Select *pSel = pItem->pSelect; + }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */ + Select *pSel = pItem->u4.pSubq->pSelect; assert( pSel!=0 ); if( pSel->selFlags & SF_NestedFrom ){ sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); + }else if( pSel->selFlags & SF_MultiValue ){ + assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy ); + sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE", + pItem->u1.nRow); }else{ sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId); } @@ -31662,6 +32346,7 @@ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExp pExpr = pExpr->pLeft; } if( pExpr==0 ) return; + if( ExprHasProperty(pExpr, EP_FromDDL) ) return; db->errByteOffset = pExpr->w.iOfst; } @@ -32102,7 +32787,7 @@ SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ /***************************************************************************** -** Reference counted string storage +** Reference counted string/blob storage *****************************************************************************/ /* @@ -32366,9 +33051,11 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); x.printfFlags |= SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); - if( pItem->pTab ){ - sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx", - pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed); + if( pItem->pSTab ){ + sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", + pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab, + pItem->colUsed, + pItem->fg.rowidUsed ? "+rowid" : ""); } if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); @@ -32386,10 +33073,13 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3_str_appendf(&x, " DDL"); } if( pItem->fg.isCte ){ - sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); + static const char *aMat[] = {",MAT", "", ",NO-MAT"}; + sqlite3_str_appendf(&x, " CteUse=%d%s", + pItem->u2.pCteUse->nUse, + aMat[pItem->u2.pCteUse->eM10d]); } if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ - sqlite3_str_appendf(&x, " ON"); + sqlite3_str_appendf(&x, " isOn"); } if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); @@ -32397,23 +33087,27 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); + if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema"); + if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema"); + if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery"); sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); n = 0; - if( pItem->pSelect ) n++; + if( pItem->fg.isSubquery ) n++; if( pItem->fg.isTabFunc ) n++; if( pItem->fg.isUsing ) n++; if( pItem->fg.isUsing ){ sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); } - if( pItem->pSelect ){ - if( pItem->pTab ){ - Table *pTab = pItem->pTab; + if( pItem->fg.isSubquery ){ + assert( n==1 ); + if( pItem->pSTab ){ + Table *pTab = pItem->pSTab; sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); - sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); + sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); @@ -32455,7 +33149,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m n = 1000; }else{ n = 0; - if( p->pSrc && p->pSrc->nSrc ) n++; + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++; if( p->pWhere ) n++; if( p->pGroupBy ) n++; if( p->pHaving ) n++; @@ -32481,7 +33175,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m sqlite3TreeViewPop(&pView); } #endif - if( p->pSrc && p->pSrc->nSrc ){ + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){ sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, p->pSrc); @@ -32517,7 +33211,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); if( p->pLimit->pRight ){ - sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); + sqlite3TreeViewItem(pView, "OFFSET", 0); sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); sqlite3TreeViewPop(&pView); } @@ -32954,7 +33648,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m assert( pExpr->x.pList->nExpr==2 ); pY = pExpr->x.pList->a[0].pExpr; pZ = pExpr->x.pList->a[1].pExpr; - sqlite3TreeViewLine(pView, "BETWEEN"); + sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs); sqlite3TreeViewExpr(pView, pX, 1); sqlite3TreeViewExpr(pView, pY, 1); sqlite3TreeViewExpr(pView, pZ, 0); @@ -32989,7 +33683,8 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m case OE_Ignore: zType = "ignore"; break; } assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); + sqlite3TreeViewLine(pView, "RAISE %s", zType); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } #endif @@ -33069,9 +33764,10 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList( sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; i<pList->nExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; + u8 sortFlags = pList->a[i].fg.sortFlags; char *zName = pList->a[i].zEName; int moreToFollow = i<pList->nExpr - 1; - if( j || zName ){ + if( j || zName || sortFlags ){ sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); @@ -33092,13 +33788,18 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList( } } if( j ){ - fprintf(stdout, "iOrderByCol=%d", j); + fprintf(stdout, "iOrderByCol=%d ", j); + } + if( sortFlags & KEYINFO_ORDER_DESC ){ + fprintf(stdout, "DESC "); + }else if( sortFlags & KEYINFO_ORDER_BIGNULL ){ + fprintf(stdout, "NULLS-LAST"); } fprintf(stdout, "\n"); fflush(stdout); } sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); - if( j || zName ){ + if( j || zName || sortFlags ){ sqlite3TreeViewPop(&pView); } } @@ -33459,6 +34160,10 @@ SQLITE_PRIVATE void sqlite3TreeViewTrigger( ** accessible to the debugging, and to avoid warnings about unused ** functions. But these routines only exist in debugging builds, so they ** do not contaminate the interface. +** +** See Also: +** +** sqlite3ShowWhereTerm() in where.c */ SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} @@ -34061,7 +34766,7 @@ static const unsigned char sqlite3Utf8Trans1[] = { c = *(zIn++); \ if( c>=0xc0 ){ \ c = sqlite3Utf8Trans1[c-0xc0]; \ - while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + while( zIn<zTerm && (*zIn & 0xc0)==0x80 ){ \ c = (c<<6) + (0x3f & *(zIn++)); \ } \ if( c<0x80 \ @@ -34089,7 +34794,38 @@ SQLITE_PRIVATE u32 sqlite3Utf8Read( return c; } - +/* +** Read a single UTF8 character out of buffer z[], but reading no +** more than n characters from the buffer. z[] is not zero-terminated. +** +** Return the number of bytes used to construct the character. +** +** Invalid UTF8 might generate a strange result. No effort is made +** to detect invalid UTF8. +** +** At most 4 bytes will be read out of z[]. The return value will always +** be between 1 and 4. +*/ +SQLITE_PRIVATE int sqlite3Utf8ReadLimited( + const u8 *z, + int n, + u32 *piOut +){ + u32 c; + int i = 1; + assert( n>0 ); + c = z[0]; + if( c>=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + if( n>4 ) n = 4; + while( i<n && (z[i] & 0xc0)==0x80 ){ + c = (c<<6) + (0x3f & z[i]); + i++; + } + } + *piOut = c; + return i; +} /* @@ -34408,20 +35144,22 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 e } /* -** zIn is a UTF-16 encoded unicode string at least nChar characters long. +** zIn is a UTF-16 encoded unicode string at least nByte bytes long. ** Return the number of bytes in the first nChar unicode characters -** in pZ. nChar must be non-negative. +** in pZ. nChar must be non-negative. Surrogate pairs count as a single +** character. */ -SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){ +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){ int c; unsigned char const *z = zIn; + unsigned char const *zEnd = &z[nByte-1]; int n = 0; if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; - while( n<nChar ){ + while( n<nChar && ALWAYS(z<=zEnd) ){ c = z[0]; z += 2; - if( c>=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2; + if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; n++; } return (int)(z-(unsigned char const *)zIn) @@ -34531,6 +35269,19 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){ } #endif /* SQLITE_OMIT_FLOATING_POINT */ +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Return true if the floating point value is NaN or +Inf or -Inf. +*/ +SQLITE_PRIVATE int sqlite3IsOverflow(double x){ + int rc; /* The value return */ + u64 y; + memcpy(&y,&x,sizeof(y)); + rc = IsOvfl(y); + return rc; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + /* ** Compute a string length that is limited to what can be stored in ** lower 30 bits of a 32-bit signed integer. @@ -34604,7 +35355,7 @@ SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ */ SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ if( rc==SQLITE_IOERR_NOMEM ) return; -#ifdef SQLITE_USE_SEH +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) if( rc==SQLITE_IOERR_IN_PAGE ){ int ii; int iErr; @@ -34774,6 +35525,44 @@ SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){ sqlite3Dequote(p->u.zToken); } +/* +** Expression p is a QNUMBER (quoted number). Dequote the value in p->u.zToken +** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those +** that contain '_' characters that must be removed before further processing. +*/ +SQLITE_PRIVATE void sqlite3DequoteNumber(Parse *pParse, Expr *p){ + assert( p!=0 || pParse->db->mallocFailed ); + if( p ){ + const char *pIn = p->u.zToken; + char *pOut = p->u.zToken; + int bHex = (pIn[0]=='0' && (pIn[1]=='x' || pIn[1]=='X')); + int iValue; + assert( p->op==TK_QNUMBER ); + p->op = TK_INTEGER; + do { + if( *pIn!=SQLITE_DIGIT_SEPARATOR ){ + *pOut++ = *pIn; + if( *pIn=='e' || *pIn=='E' || *pIn=='.' ) p->op = TK_FLOAT; + }else{ + if( (bHex==0 && (!sqlite3Isdigit(pIn[-1]) || !sqlite3Isdigit(pIn[1]))) + || (bHex==1 && (!sqlite3Isxdigit(pIn[-1]) || !sqlite3Isxdigit(pIn[1]))) + ){ + sqlite3ErrorMsg(pParse, "unrecognized token: \"%s\"", p->u.zToken); + } + } + }while( *pIn++ ); + if( bHex ) p->op = TK_INTEGER; + + /* tag-20240227-a: If after dequoting, the number is an integer that + ** fits in 32 bits, then it must be converted into EP_IntValue. Other + ** parts of the code expect this. See also tag-20240227-b. */ + if( p->op==TK_INTEGER && sqlite3GetInt32(p->u.zToken, &iValue) ){ + p->u.iValue = iValue; + p->flags |= EP_IntValue; + } + } +} + /* ** If the input token p is quoted, try to adjust the token to remove ** the quotes. This is not always possible: @@ -34951,6 +35740,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en int eValid = 1; /* True exponent is either not used or is well-formed */ int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ + u64 s2; /* round-tripped significand */ + double rr[2]; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ @@ -35053,7 +35844,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en e = (e*esign) + d; /* Try to adjust the exponent to make it smaller */ - while( e>0 && s<(LARGEST_UINT64/10) ){ + while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){ s *= 10; e--; } @@ -35062,65 +35853,52 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en e++; } - if( e==0 ){ - *pResult = s; - }else if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; - if( e>0 ){ - while( e>=100 ){ e-=100; r *= 1.0e+100L; } - while( e>=10 ){ e-=10; r *= 1.0e+10L; } - while( e>=1 ){ e-=1; r *= 1.0e+01L; } - }else{ - while( e<=-100 ){ e+=100; r *= 1.0e-100L; } - while( e<=-10 ){ e+=10; r *= 1.0e-10L; } - while( e<=-1 ){ e+=1; r *= 1.0e-01L; } - } - assert( r>=0.0 ); - if( r>+1.7976931348623157081452742373e+308L ){ -#ifdef INFINITY - *pResult = +INFINITY; -#else - *pResult = 1.0e308*10.0; + rr[0] = (double)s; + assert( sizeof(s2)==sizeof(rr[0]) ); +#ifdef SQLITE_DEBUG + rr[1] = 18446744073709549568.0; + memcpy(&s2, &rr[1], sizeof(s2)); + assert( s2==0x43efffffffffffffLL ); #endif - }else{ - *pResult = (double)r; - } - }else{ - double rr[2]; - u64 s2; - rr[0] = (double)s; + /* Largest double that can be safely converted to u64 + ** vvvvvvvvvvvvvvvvvvvvvv */ + if( rr[0]<=18446744073709549568.0 ){ s2 = (u64)rr[0]; rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); - if( e>0 ){ - while( e>=100 ){ - e -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( e>=10 ){ - e -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( e>=1 ){ - e -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } - }else{ - while( e<=-100 ){ - e += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( e<=-10 ){ - e += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( e<=-1 ){ - e += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } + }else{ + rr[1] = 0.0; + } + assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */ + + if( e>0 ){ + while( e>=100 ){ + e -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( e>=10 ){ + e -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( e>=1 ){ + e -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); + } + }else{ + while( e<=-100 ){ + e += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( e<=-10 ){ + e += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( e<=-1 ){ + e += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); } - *pResult = rr[0]+rr[1]; - if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; } + *pResult = rr[0]+rr[1]; + if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; if( sign<0 ) *pResult = -*pResult; assert( !sqlite3IsNaN(*pResult) ); @@ -35424,10 +36202,13 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ ** Decode a floating-point value into an approximate decimal ** representation. ** -** Round the decimal representation to n significant digits if -** n is positive. Or round to -n signficant digits after the -** decimal point if n is negative. No rounding is performed if -** n is zero. +** If iRound<=0 then round to -iRound significant digits to the +** the left of the decimal point, or to a maximum of mxRound total +** significant digits. +** +** If iRound>0 round to min(iRound,mxRound) significant digits total. +** +** mxRound must be positive. ** ** The significant digits of the decimal representation are ** stored in p->z[] which is a often (but not always) a pointer @@ -35438,8 +36219,11 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou int i; u64 v; int e, exp = 0; + double rr[2]; + p->isSpecial = 0; p->z = p->zBuf; + assert( mxRound>0 ); /* Convert negative numbers to positive. Deal with Infinity, 0.0, and ** NaN. */ @@ -35466,62 +36250,45 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou /* Multiply r by powers of ten until it lands somewhere in between ** 1.0e+19 and 1.0e+17. + ** + ** Use Dekker-style double-double computation to increase the + ** precision. + ** + ** The error terms on constants like 1.0e+100 computed using the + ** decimal extension, for example as follows: + ** + ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); */ - if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE rr = r; - if( rr>=1.0e+19 ){ - while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } - while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; } - while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; } - }else{ - while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; } - while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; } - while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; } + rr[0] = r; + rr[1] = 0.0; + if( rr[0]>9.223372036854774784e+18 ){ + while( rr[0]>9.223372036854774784e+118 ){ + exp += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( rr[0]>9.223372036854774784e+28 ){ + exp += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( rr[0]>9.223372036854774784e+18 ){ + exp += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); } - v = (u64)rr; }else{ - /* If high-precision floating point is not available using "long double", - ** then use Dekker-style double-double computation to increase the - ** precision. - ** - ** The error terms on constants like 1.0e+100 computed using the - ** decimal extension, for example as follows: - ** - ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); - */ - double rr[2]; - rr[0] = r; - rr[1] = 0.0; - if( rr[0]>9.223372036854774784e+18 ){ - while( rr[0]>9.223372036854774784e+118 ){ - exp += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( rr[0]>9.223372036854774784e+28 ){ - exp += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( rr[0]>9.223372036854774784e+18 ){ - exp += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } - }else{ - while( rr[0]<9.223372036854774784e-83 ){ - exp -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( rr[0]<9.223372036854774784e+07 ){ - exp -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( rr[0]<9.22337203685477478e+17 ){ - exp -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } + while( rr[0]<9.223372036854774784e-83 ){ + exp -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( rr[0]<9.223372036854774784e+07 ){ + exp -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( rr[0]<9.22337203685477478e+17 ){ + exp -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); } - v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; } - + v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; /* Extract significant digits. */ i = sizeof(p->zBuf)-1; @@ -35532,7 +36299,7 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou assert( p->n>0 ); assert( p->n<sizeof(p->zBuf) ); p->iDP = p->n + exp; - if( iRound<0 ){ + if( iRound<=0 ){ iRound = p->iDP - iRound; if( iRound==0 && p->zBuf[i+1]>='5' ){ iRound = 1; @@ -36292,104 +37059,6 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam return 0; } -/* -** High-resolution hardware timer used for debugging and testing only. -*/ -#if defined(VDBE_PROFILE) \ - || defined(SQLITE_PERFORMANCE_TRACE) \ - || defined(SQLITE_ENABLE_STMT_SCANSTATUS) -/************** Include hwtime.h in the middle of util.c *********************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 and x86_64 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on Pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if !defined(__STRICT_ANSI__) && \ - (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - /* - ** asm() is needed for hardware timing support. Without asm(), - ** disable the sqlite3Hwtime() routine. - ** - ** sqlite3Hwtime() is only used for some obscure debugging - ** and analysis configurations, not in any deliverable, so this - ** should not be a great loss. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in util.c ***********************/ -#endif - /************** End of util.c ************************************************/ /************** Begin file hash.c ********************************************/ /* @@ -36710,7 +37379,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), /* 32 */ "Last" OpHelp(""), - /* 33 */ "IfSmaller" OpHelp(""), + /* 33 */ "IfSizeBetween" OpHelp(""), /* 34 */ "SorterSort" OpHelp(""), /* 35 */ "Sort" OpHelp(""), /* 36 */ "Rewind" OpHelp(""), @@ -36727,16 +37396,16 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 48 */ "Program" OpHelp(""), /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), - /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), - /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), - /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), - /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), - /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), - /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), - /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"), - /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), - /* 58 */ "ElseEq" OpHelp(""), - /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 50 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), + /* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"), + /* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"), + /* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"), + /* 57 */ "Lt" OpHelp("IF r[P3]<r[P1]"), + /* 58 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), + /* 59 */ "ElseEq" OpHelp(""), /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), /* 62 */ "IncrVacuum" OpHelp(""), @@ -36755,7 +37424,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"), /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"), /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), - /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1)"), /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"), @@ -36779,23 +37448,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 99 */ "ReadCookie" OpHelp(""), /* 100 */ "SetCookie" OpHelp(""), /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), - /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), - /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 102 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), + /* 106 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), + /* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), - /* 115 */ "OpenDup" OpHelp(""), + /* 114 */ "OpenDup" OpHelp(""), + /* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 117 */ "String8" OpHelp("r[P2]='P4'"), - /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 118 */ "String8" OpHelp("r[P2]='P4'"), /* 119 */ "SorterOpen" OpHelp(""), /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), @@ -36830,8 +37499,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 150 */ "LoadAnalysis" OpHelp(""), /* 151 */ "DropTable" OpHelp(""), /* 152 */ "DropIndex" OpHelp(""), - /* 153 */ "Real" OpHelp("r[P2]=P4"), - /* 154 */ "DropTrigger" OpHelp(""), + /* 153 */ "DropTrigger" OpHelp(""), + /* 154 */ "Real" OpHelp("r[P2]=P4"), /* 155 */ "IntegrityCk" OpHelp(""), /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), /* 157 */ "Param" OpHelp(""), @@ -36858,13 +37527,15 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 178 */ "Pagecount" OpHelp(""), /* 179 */ "MaxPgcnt" OpHelp(""), /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), - /* 181 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), - /* 182 */ "Trace" OpHelp(""), - /* 183 */ "CursorHint" OpHelp(""), - /* 184 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 185 */ "Noop" OpHelp(""), - /* 186 */ "Explain" OpHelp(""), - /* 187 */ "Abortable" OpHelp(""), + /* 181 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"), + /* 182 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"), + /* 183 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), + /* 184 */ "Trace" OpHelp(""), + /* 185 */ "CursorHint" OpHelp(""), + /* 186 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 187 */ "Noop" OpHelp(""), + /* 188 */ "Explain" OpHelp(""), + /* 189 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -38073,7 +38744,7 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void){ # endif #else /* !SQLITE_WASI */ # ifndef HAVE_FCHMOD -# define HAVE_FCHMOD +# define HAVE_FCHMOD 1 # endif #endif /* SQLITE_WASI */ @@ -38182,7 +38853,7 @@ static pid_t randomnessPid = 0; #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ -#ifndef SQLITE_DISABLE_DIRSYNC +#if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX) # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ #else # define UNIXFILE_DIRSYNC 0x00 @@ -39155,8 +39826,12 @@ static int unixLogErrorAtLine( ** available, the error message will often be an empty string. Not a ** huge problem. Incorrectly concluding that the GNU version is available ** could lead to a segfault though. + ** + ** Forum post 3f13857fa4062301 reports that the Android SDK may use + ** int-type return, depending on its version. */ -#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) +#if (defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)) \ + && !defined(ANDROID) && !defined(__ANDROID__) zErr = # endif strerror_r(iErrno, aErr, sizeof(aErr)-1); @@ -40135,26 +40810,22 @@ static int nolockClose(sqlite3_file *id) { /* ** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -** -** In dotfile locking, either a lock exists or it does not. So in this -** variation of CheckReservedLock(), *pResOut is set to true if any lock -** is held on the file and false if the file is unlocked. +** file by this or any other process. If the caller holds a SHARED +** or greater lock when it is called, then it is assumed that no other +** client may hold RESERVED. Or, if the caller holds no lock, then it +** is assumed another client holds RESERVED if the lock-file exists. */ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { - int rc = SQLITE_OK; - int reserved = 0; unixFile *pFile = (unixFile*)id; - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - assert( pFile ); - reserved = osAccess((const char*)pFile->lockingContext, 0)==0; - OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); - *pResOut = reserved; - return rc; + if( pFile->eFileLock>=SHARED_LOCK ){ + *pResOut = 0; + }else{ + *pResOut = osAccess((const char*)pFile->lockingContext, 0)==0; + } + OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut)); + return SQLITE_OK; } /* @@ -40324,54 +40995,33 @@ static int robust_flock(int fd, int op){ ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ - int rc = SQLITE_OK; - int reserved = 0; +#ifdef SQLITE_DEBUG unixFile *pFile = (unixFile*)id; +#else + UNUSED_PARAMETER(id); +#endif SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); + assert( pFile->eFileLock<=SHARED_LOCK ); - /* Check if a thread in this process holds such a lock */ - if( pFile->eFileLock>SHARED_LOCK ){ - reserved = 1; - } - - /* Otherwise see if some other process holds it. */ - if( !reserved ){ - /* attempt to get the lock */ - int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); - if( !lrc ){ - /* got the lock, unlock it */ - lrc = robust_flock(pFile->h, LOCK_UN); - if ( lrc ) { - int tErrno = errno; - /* unlock failed with an error */ - lrc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } else { - int tErrno = errno; - reserved = 1; - /* someone else might have it reserved */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(lrc) ){ - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } - } - OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); + /* The flock VFS only ever takes exclusive locks (see function flockLock). + ** Therefore, if this connection is holding any lock at all, no other + ** connection may be holding a RESERVED lock. So set *pResOut to 0 + ** in this case. + ** + ** Or, this connection may be holding no lock. In that case, set *pResOut to + ** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the + ** db in order to roll the hot journal back. If there is another connection + ** holding a lock, that attempt will fail and an SQLITE_BUSY returned to + ** the user. With other VFS, we try to avoid this, in order to allow a reader + ** to proceed while a writer is preparing its transaction. But that won't + ** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is + ** not a problem in this case. */ + *pResOut = 0; -#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & 0xff) == SQLITE_IOERR ){ - rc = SQLITE_OK; - reserved=1; - } -#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - *pResOut = reserved; - return rc; + return SQLITE_OK; } /* @@ -41843,7 +42493,7 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ /* Forward declaration */ static int unixGetTempname(int nBuf, char *zBuf); -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) static int unixFcntlExternalReader(unixFile*, int*); #endif @@ -41868,6 +42518,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } #endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + case SQLITE_FCNTL_NULL_IO: { + osClose(pFile->h); + pFile->h = -1; + return SQLITE_OK; + } case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; @@ -41914,7 +42569,13 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT case SQLITE_FCNTL_LOCK_TIMEOUT: { int iOld = pFile->iBusyTimeout; +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 pFile->iBusyTimeout = *(int*)pArg; +#elif SQLITE_ENABLE_SETLK_TIMEOUT==2 + pFile->iBusyTimeout = !!(*(int*)pArg); +#else +# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" +#endif *(int*)pArg = iOld; return SQLITE_OK; } @@ -41964,7 +42625,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ case SQLITE_FCNTL_EXTERNAL_READER: { -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) return unixFcntlExternalReader((unixFile*)id, (int*)pArg); #else *(int*)pArg = 0; @@ -42003,6 +42664,7 @@ static void setDeviceCharacteristics(unixFile *pFd){ if( pFd->ctrlFlags & UNIXFILE_PSOW ){ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; } + pFd->deviceCharacteristics |= SQLITE_IOCAP_SUBPAGE_READ; pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; } @@ -42053,7 +42715,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; @@ -42061,7 +42723,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; @@ -42137,7 +42799,7 @@ static int unixGetpagesize(void){ #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) /* ** Object used to represent an shared memory buffer. @@ -42167,6 +42829,25 @@ static int unixGetpagesize(void){ ** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and ** unixMutexHeld() is true when reading or writing any other field ** in this structure. +** +** aLock[SQLITE_SHM_NLOCK]: +** This array records the various locks held by clients on each of the +** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no +** locks are held by the process on this slot. If it is set to -1, then +** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[] +** value is set to a positive value, then it is the number of shared +** locks currently held on the slot. +** +** aMutex[SQLITE_SHM_NLOCK]: +** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex +** pShmMutex is used to protect the aLock[] array and the right to +** call fcntl() on unixShmNode.hShm to obtain or release locks. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array +** of mutexes - one for each locking slot. To read or write locking +** slot aLock[iSlot], the caller must hold the corresponding mutex +** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a +** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held. */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ @@ -42180,10 +42861,11 @@ struct unixShmNode { char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK]; +#endif int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ #ifdef SQLITE_DEBUG - u8 exclMask; /* Mask of exclusive locks held */ - u8 sharedMask; /* Mask of shared locks held */ u8 nextShmId; /* Next available unixShm.id value */ #endif }; @@ -42266,16 +42948,35 @@ static int unixShmSystemLock( struct flock f; /* The posix advisory locking structure */ int rc = SQLITE_OK; /* Result code form fcntl() */ - /* Access to the unixShmNode object is serialized by the caller */ pShmNode = pFile->pInode->pShmNode; - assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); - assert( pShmNode->nRef>0 || unixMutexHeld() ); + + /* Assert that the parameters are within expected range and that the + ** correct mutex or mutexes are held. */ + assert( pShmNode->nRef>=0 ); + assert( (ofst==UNIX_SHM_DMS && n==1) + || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK)) + ); + if( ofst==UNIX_SHM_DMS ){ + assert( pShmNode->nRef>0 || unixMutexHeld() ); + assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); + }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int ii; + for(ii=ofst-UNIX_SHM_BASE; ii<ofst-UNIX_SHM_BASE+n; ii++){ + assert( sqlite3_mutex_held(pShmNode->aMutex[ii]) ); + } +#else + assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); + assert( pShmNode->nRef>0 ); +#endif + } /* Shared locks never span more than one byte */ assert( n==1 || lockType!=F_RDLCK ); /* Locks are within range */ assert( n>=1 && n<=SQLITE_SHM_NLOCK ); + assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) ); if( pShmNode->hShm>=0 ){ int res; @@ -42286,7 +42987,7 @@ static int unixShmSystemLock( f.l_len = n; res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); if( res==-1 ){ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1 rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY); #else rc = SQLITE_BUSY; @@ -42294,39 +42995,28 @@ static int unixShmSystemLock( } } - /* Update the global lock state and do debug tracing */ + /* Do debug tracing */ #ifdef SQLITE_DEBUG - { u16 mask; OSTRACE(("SHM-LOCK ")); - mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst); if( rc==SQLITE_OK ){ if( lockType==F_UNLCK ){ - OSTRACE(("unlock %d ok", ofst)); - pShmNode->exclMask &= ~mask; - pShmNode->sharedMask &= ~mask; + OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1)); }else if( lockType==F_RDLCK ){ - OSTRACE(("read-lock %d ok", ofst)); - pShmNode->exclMask &= ~mask; - pShmNode->sharedMask |= mask; + OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1)); }else{ assert( lockType==F_WRLCK ); - OSTRACE(("write-lock %d ok", ofst)); - pShmNode->exclMask |= mask; - pShmNode->sharedMask &= ~mask; + OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1)); } }else{ if( lockType==F_UNLCK ){ - OSTRACE(("unlock %d failed", ofst)); + OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1)); }else if( lockType==F_RDLCK ){ - OSTRACE(("read-lock failed")); + OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1)); }else{ assert( lockType==F_WRLCK ); - OSTRACE(("write-lock %d failed", ofst)); + OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1)); } } - OSTRACE((" - afterwards %03x,%03x\n", - pShmNode->sharedMask, pShmNode->exclMask)); - } #endif return rc; @@ -42363,6 +43053,11 @@ static void unixShmPurge(unixFile *pFd){ int i; assert( p->pInode==pFd->pInode ); sqlite3_mutex_free(p->pShmMutex); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + for(i=0; i<SQLITE_SHM_NLOCK; i++){ + sqlite3_mutex_free(p->aMutex[i]); + } +#endif for(i=0; i<p->nRegion; i+=nShmPerMap){ if( p->hShm>=0 ){ osMunmap(p->apRegion[i], p->szRegion); @@ -42422,7 +43117,20 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ pShmNode->isUnlocked = 1; rc = SQLITE_READONLY_CANTINIT; }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* Do not use a blocking lock here. If the lock cannot be obtained + ** immediately, it means some other connection is truncating the + ** *-shm file. And after it has done so, it will not release its + ** lock, but only downgrade it to a shared lock. So no point in + ** blocking here. The call below to obtain the shared DMS lock may + ** use a blocking lock. */ + int iSaveTimeout = pDbFd->iBusyTimeout; + pDbFd->iBusyTimeout = 0; +#endif rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + pDbFd->iBusyTimeout = iSaveTimeout; +#endif /* The first connection to attach must truncate the -shm file. We ** truncate to 3 bytes (an arbitrary small number, less than the ** -shm header size) rather than 0 as a system debugging aid, to @@ -42543,6 +43251,18 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ rc = SQLITE_NOMEM_BKPT; goto shm_open_err; } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + { + int ii; + for(ii=0; ii<SQLITE_SHM_NLOCK; ii++){ + pShmNode->aMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->aMutex[ii]==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } + } + } +#endif } if( pInode->bProcessLock==0 ){ @@ -42764,9 +43484,11 @@ static int unixShmMap( */ #ifdef SQLITE_DEBUG static int assertLockingArrayOk(unixShmNode *pShmNode){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + return 1; +#else unixShm *pX; int aLock[SQLITE_SHM_NLOCK]; - assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); memset(aLock, 0, sizeof(aLock)); for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ @@ -42784,13 +43506,14 @@ static int assertLockingArrayOk(unixShmNode *pShmNode){ assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); +#endif } #endif /* ** Change the lock state for a shared-memory segment. ** -** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** Note that the relationship between SHARED and EXCLUSIVE locks is a little ** different here than in posix. In xShmLock(), one can go from unlocked ** to shared and back or from unlocked to exclusive and back. But one may ** not go from shared to exclusive or from exclusive to shared. @@ -42805,7 +43528,7 @@ static int unixShmLock( unixShm *p; /* The shared memory being locked */ unixShmNode *pShmNode; /* The underlying file iNode */ int rc = SQLITE_OK; /* Result code */ - u16 mask; /* Mask of locks to take or release */ + u16 mask = (1<<(ofst+n)) - (1<<ofst); /* Mask of locks to take or release */ int *aLock; p = pDbFd->pShm; @@ -42840,88 +43563,151 @@ static int unixShmLock( ** It is not permitted to block on the RECOVER lock. */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2) /* not RECOVER */ - && (ofst!=1 || (p->exclMask|p->sharedMask)==0) - && (ofst!=0 || (p->exclMask|p->sharedMask)<3) - && (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst)) - )); + { + u16 lockMask = (p->exclMask|p->sharedMask); + assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( + (ofst!=2) /* not RECOVER */ + && (ofst!=1 || lockMask==0 || lockMask==2) + && (ofst!=0 || lockMask<3) + && (ofst<3 || lockMask<(1<<ofst)) + )); + } #endif - mask = (1<<(ofst+n)) - (1<<ofst); - assert( n>1 || mask==(1<<ofst) ); - sqlite3_mutex_enter(pShmNode->pShmMutex); - assert( assertLockingArrayOk(pShmNode) ); - if( flags & SQLITE_SHM_UNLOCK ){ - if( (p->exclMask|p->sharedMask) & mask ){ - int ii; - int bUnlock = 1; + /* Check if there is any work to do. There are three cases: + ** + ** a) An unlock operation where there are locks to unlock, + ** b) An shared lock where the requested lock is not already held + ** c) An exclusive lock where the requested lock is not already held + ** + ** The SQLite core never requests an exclusive lock that it already holds. + ** This is assert()ed below. + */ + assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK) + || 0==(p->exclMask & mask) + ); + if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) + || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) + || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) + ){ - for(ii=ofst; ii<ofst+n; ii++){ - if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){ - bUnlock = 0; - } + /* Take the required mutexes. In SETLK_TIMEOUT mode (blocking locks), if + ** this is an attempt on an exclusive lock use sqlite3_mutex_try(). If any + ** other thread is holding this mutex, then it is either holding or about + ** to hold a lock exclusive to the one being requested, and we may + ** therefore return SQLITE_BUSY to the caller. + ** + ** Doing this prevents some deadlock scenarios. For example, thread 1 may + ** be a checkpointer blocked waiting on the WRITER lock. And thread 2 + ** may be a normal SQL client upgrading to a write transaction. In this + ** case thread 2 does a non-blocking request for the WRITER lock. But - + ** if it were to use sqlite3_mutex_enter() then it would effectively + ** become a (doomed) blocking request, as thread 2 would block until thread + ** 1 obtained WRITER and released the mutex. Since thread 2 already holds + ** a lock on a read-locking slot at this point, this breaks the + ** anti-deadlock rules (see above). */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int iMutex; + for(iMutex=ofst; iMutex<ofst+n; iMutex++){ + if( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ){ + rc = sqlite3_mutex_try(pShmNode->aMutex[iMutex]); + if( rc!=SQLITE_OK ) goto leave_shmnode_mutexes; + }else{ + sqlite3_mutex_enter(pShmNode->aMutex[iMutex]); } + } +#else + sqlite3_mutex_enter(pShmNode->pShmMutex); +#endif - if( bUnlock ){ - rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); - if( rc==SQLITE_OK ){ - memset(&aLock[ofst], 0, sizeof(int)*n); + if( ALWAYS(rc==SQLITE_OK) ){ + if( flags & SQLITE_SHM_UNLOCK ){ + /* Case (a) - unlock. */ + int bUnlock = 1; + assert( (p->exclMask & p->sharedMask)==0 ); + assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); + assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); + + /* If this is a SHARED lock being unlocked, it is possible that other + ** clients within this process are holding the same SHARED lock. In + ** this case, set bUnlock to 0 so that the posix lock is not removed + ** from the file-descriptor below. */ + if( flags & SQLITE_SHM_SHARED ){ + assert( n==1 ); + assert( aLock[ofst]>=1 ); + if( aLock[ofst]>1 ){ + bUnlock = 0; + aLock[ofst]--; + p->sharedMask &= ~mask; + } } - }else if( ALWAYS(p->sharedMask & (1<<ofst)) ){ - assert( n==1 && aLock[ofst]>1 ); - aLock[ofst]--; - } - /* Undo the local locks */ - if( rc==SQLITE_OK ){ - p->exclMask &= ~mask; - p->sharedMask &= ~mask; - } - } - }else if( flags & SQLITE_SHM_SHARED ){ - assert( n==1 ); - assert( (p->exclMask & (1<<ofst))==0 ); - if( (p->sharedMask & mask)==0 ){ - if( aLock[ofst]<0 ){ - rc = SQLITE_BUSY; - }else if( aLock[ofst]==0 ){ - rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); - } + if( bUnlock ){ + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + memset(&aLock[ofst], 0, sizeof(int)*n); + p->sharedMask &= ~mask; + p->exclMask &= ~mask; + } + } + }else if( flags & SQLITE_SHM_SHARED ){ + /* Case (b) - a shared lock. */ - /* Get the local shared locks */ - if( rc==SQLITE_OK ){ - p->sharedMask |= mask; - aLock[ofst]++; - } - } - }else{ - /* Make sure no sibling connections hold locks that will block this - ** lock. If any do, return SQLITE_BUSY right away. */ - int ii; - for(ii=ofst; ii<ofst+n; ii++){ - assert( (p->sharedMask & mask)==0 ); - if( ALWAYS((p->exclMask & (1<<ii))==0) && aLock[ii] ){ - rc = SQLITE_BUSY; - break; - } - } + if( aLock[ofst]<0 ){ + /* An exclusive lock is held by some other connection. BUSY. */ + rc = SQLITE_BUSY; + }else if( aLock[ofst]==0 ){ + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); + } - /* Get the exclusive locks at the system level. Then if successful - ** also update the in-memory values. */ - if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); - if( rc==SQLITE_OK ){ + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + aLock[ofst]++; + } + }else{ + /* Case (c) - an exclusive lock. */ + int ii; + + assert( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ); assert( (p->sharedMask & mask)==0 ); - p->exclMask |= mask; + assert( (p->exclMask & mask)==0 ); + + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. */ for(ii=ofst; ii<ofst+n; ii++){ - aLock[ii] = -1; + if( aLock[ii] ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also update the in-memory values. */ + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + p->exclMask |= mask; + for(ii=ofst; ii<ofst+n; ii++){ + aLock[ii] = -1; + } + } } } + assert( assertLockingArrayOk(pShmNode) ); } + + /* Drop the mutexes acquired above. */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + leave_shmnode_mutexes: + for(iMutex--; iMutex>=ofst; iMutex--){ + sqlite3_mutex_leave(pShmNode->aMutex[iMutex]); + } +#else + sqlite3_mutex_leave(pShmNode->pShmMutex); +#endif } - assert( assertLockingArrayOk(pShmNode) ); - sqlite3_mutex_leave(pShmNode->pShmMutex); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", p->id, osGetpid(0), p->sharedMask, p->exclMask)); return rc; @@ -43171,11 +43957,16 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ #if SQLITE_MAX_MMAP_SIZE>0 if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; if( pFd->pMapRegion==0 ){ int rc = unixMapfile(pFd, -1); if( rc!=SQLITE_OK ) return rc; } - if( pFd->mmapSize >= iOff+nAmt ){ + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ *pp = &((u8 *)pFd->pMapRegion)[iOff]; pFd->nFetchOut++; } @@ -44119,12 +44910,19 @@ static int unixOpen( rc = SQLITE_READONLY_DIRECTORY; }else if( errno!=EISDIR && isReadWrite ){ /* Failed to open the file for read/write access. Try read-only. */ + UnixUnusedFd *pReadonly = 0; flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); openFlags &= ~(O_RDWR|O_CREAT); flags |= SQLITE_OPEN_READONLY; openFlags |= O_RDONLY; isReadonly = 1; - fd = robust_open(zName, openFlags, openMode); + pReadonly = findReusableFd(zName, flags); + if( pReadonly ){ + fd = pReadonly->fd; + sqlite3_free(pReadonly); + }else{ + fd = robust_open(zName, openFlags, openMode); + } } } if( fd<0 ){ @@ -49606,6 +50404,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } #endif + case SQLITE_FCNTL_NULL_IO: { + (void)osCloseHandle(pFile->h); + pFile->h = NULL; + return SQLITE_OK; + } case SQLITE_FCNTL_TEMPFILENAME: { char *zTFile = 0; int rc = winGetTempname(pFile->pVfs, &zTFile); @@ -49667,7 +50470,7 @@ static int winSectorSize(sqlite3_file *id){ */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_SUBPAGE_READ | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } @@ -50528,6 +51331,11 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ #if SQLITE_MAX_MMAP_SIZE>0 if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; if( pFd->pMapRegion==0 ){ int rc = winMapfile(pFd, -1); if( rc!=SQLITE_OK ){ @@ -50536,7 +51344,7 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ return rc; } } - if( pFd->mmapSize >= iOff+nAmt ){ + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ assert( pFd->pMapRegion!=0 ); *pp = &((u8 *)pFd->pMapRegion)[iOff]; pFd->nFetchOut++; @@ -51050,7 +51858,7 @@ static int winOpen( int rc = SQLITE_OK; /* Function Return Code */ #if !defined(NDEBUG) || SQLITE_OS_WINCE - int eType = flags&0xFFFFFF00; /* Type of file to open */ + int eType = flags&0x0FFF00; /* Type of file to open */ #endif int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); @@ -53015,6 +53823,14 @@ SQLITE_API unsigned char *sqlite3_serialize( pOut = 0; }else{ sz = sqlite3_column_int64(pStmt, 0)*szPage; + if( sz==0 ){ + sqlite3_reset(pStmt); + sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + sz = sqlite3_column_int64(pStmt, 0)*szPage; + } + } if( piSize ) *piSize = sz; if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ pOut = 0; @@ -54073,6 +54889,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; memset(pPgHdr->pExtra, 0, 8); + assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) ); pPgHdr->pCache = pCache; pPgHdr->pgno = pgno; pPgHdr->flags = PGHDR_CLEAN; @@ -54819,7 +55636,8 @@ static int pcache1InitBulk(PCache1 *pCache){ do{ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; pX->page.pBuf = zBulk; - pX->page.pExtra = &pX[1]; + pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); + assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); pX->isBulkLocal = 1; pX->isAnchor = 0; pX->pNext = pCache->pFree; @@ -54956,7 +55774,8 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ if( pPg==0 ) return 0; p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; p->page.pBuf = pPg; - p->page.pExtra = &p[1]; + p->page.pExtra = (u8*)p + ROUND8(sizeof(*p)); + assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) ); p->isBulkLocal = 0; p->isAnchor = 0; p->pLruPrev = 0; /* Initializing this saves a valgrind error */ @@ -57139,7 +57958,7 @@ struct Pager { char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ - int aStat[4]; /* Total cache hits, misses, writes, spills */ + u32 aStat[4]; /* Total cache hits, misses, writes, spills */ #ifdef SQLITE_TEST int nRead; /* Database pages read */ #endif @@ -57240,41 +58059,34 @@ static const unsigned char aJournalMagic[] = { # define USEFETCH(x) 0 #endif -/* -** The argument to this macro is a file descriptor (type sqlite3_file*). -** Return 0 if it is not open, or non-zero (but not 1) if it is. -** -** This is so that expressions can be written as: -** -** if( isOpen(pPager->jfd) ){ ... -** -** instead of -** -** if( pPager->jfd->pMethods ){ ... -*/ -#define isOpen(pFd) ((pFd)->pMethods!=0) - #ifdef SQLITE_DIRECT_OVERFLOW_READ /* ** Return true if page pgno can be read directly from the database file ** by the b-tree layer. This is the case if: ** -** * the database file is open, -** * there are no dirty pages in the cache, and -** * the desired page is not currently in the wal file. +** (1) the database file is open +** (2) the VFS for the database is able to do unaligned sub-page reads +** (3) there are no dirty pages in the cache, and +** (4) the desired page is not currently in the wal file. */ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ - if( pPager->fd->pMethods==0 ) return 0; - if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; + assert( pPager!=0 ); + assert( pPager->fd!=0 ); + if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ if( sqlite3mcPagerHasCodec(pPager) != 0 ) return 0; #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ u32 iRead = 0; - int rc; - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); - return (rc==SQLITE_OK && iRead==0); + (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + return iRead==0; /* Condition (4) */ } #endif + assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); + if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) + & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ + return 0; /* Case (2) */ + } return 1; } #endif @@ -58533,7 +59345,7 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ } pPager->journalOff = 0; }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST - || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) + || (pPager->exclusiveMode && pPager->journalMode<PAGER_JOURNALMODE_WAL) ){ rc = zeroJournalHdr(pPager, hasSuper||pPager->tempFile); pPager->journalOff = 0; @@ -60517,6 +61329,7 @@ static int pagerAcquireMapPage( return SQLITE_NOMEM_BKPT; } p->pExtra = (void *)&p[1]; + assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) ); p->flags = PGHDR_MMAP; p->nRef = 1; p->pPager = pPager; @@ -63284,11 +64097,11 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; a[4] = pPager->eState; a[5] = pPager->errCode; - a[6] = pPager->aStat[PAGER_STAT_HIT]; - a[7] = pPager->aStat[PAGER_STAT_MISS]; + a[6] = (int)pPager->aStat[PAGER_STAT_HIT] & 0x7fffffff; + a[7] = (int)pPager->aStat[PAGER_STAT_MISS] & 0x7fffffff; a[8] = 0; /* Used to be pPager->nOvfl */ a[9] = pPager->nRead; - a[10] = pPager->aStat[PAGER_STAT_WRITE]; + a[10] = (int)pPager->aStat[PAGER_STAT_WRITE] & 0x7fffffff; return a; } #endif @@ -63304,7 +64117,7 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ ** reset parameter is non-zero, the cache hit or miss count is zeroed before ** returning. */ -SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, u64 *pnVal){ assert( eStat==SQLITE_DBSTATUS_CACHE_HIT || eStat==SQLITE_DBSTATUS_CACHE_MISS @@ -63540,7 +64353,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){ ** This will be either the rollback journal or the WAL file. */ SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ -#if SQLITE_OMIT_WAL +#ifdef SQLITE_OMIT_WAL return pPager->jfd; #else return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; @@ -64244,7 +65057,7 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ } #endif -#ifdef SQLITE_USE_SEH +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ return sqlite3WalSystemErrno(pPager->pWal); } @@ -64300,7 +65113,7 @@ SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ ** 28: Checksum-2 (second part of checksum for first 24 bytes of header). ** ** Immediately following the wal-header are zero or more frames. Each -** frame consists of a 24-byte frame-header followed by a <page-size> bytes +** frame consists of a 24-byte frame-header followed by <page-size> bytes ** of page data. The frame-header is six big-endian 32-bit unsigned ** integer values, as follows: ** @@ -64797,6 +65610,7 @@ struct Wal { #endif #ifdef SQLITE_ENABLE_SNAPSHOT WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + int bGetSnapshot; /* Transaction opened for sqlite3_get_snapshot() */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *db; @@ -66260,6 +67074,19 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT + + +/* +** Attempt to enable blocking locks that block for nMs ms. Return 1 if +** blocking locks are successfully enabled, or 0 otherwise. +*/ +static int walEnableBlockingMs(Wal *pWal, int nMs){ + int rc = sqlite3OsFileControl( + pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs + ); + return (rc==SQLITE_OK); +} + /* ** Attempt to enable blocking locks. Blocking locks are enabled only if (a) ** they are supported by the VFS, and (b) the database handle is configured @@ -66271,11 +67098,7 @@ static int walEnableBlocking(Wal *pWal){ if( pWal->db ){ int tmout = pWal->db->busyTimeout; if( tmout ){ - int rc; - rc = sqlite3OsFileControl( - pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout - ); - res = (rc==SQLITE_OK); + res = walEnableBlockingMs(pWal, tmout); } } return res; @@ -66324,20 +67147,10 @@ SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){ pWal->db = db; } -/* -** Take an exclusive WRITE lock. Blocking if so configured. -*/ -static int walLockWriter(Wal *pWal){ - int rc; - walEnableBlocking(pWal); - rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); - walDisableBlocking(pWal); - return rc; -} #else # define walEnableBlocking(x) 0 # define walDisableBlocking(x) -# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1) +# define walEnableBlockingMs(pWal, ms) 0 # define sqlite3WalDb(pWal, db) #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ @@ -66690,7 +67503,7 @@ static int walHandleException(Wal *pWal){ /* ** Assert that the Wal.lockMask mask, which indicates the locks held -** by the connenction, is consistent with the Wal.readLock, Wal.writeLock +** by the connection, is consistent with the Wal.readLock, Wal.writeLock ** and Wal.ckptLock variables. To be used as: ** ** assert( walAssertLockmask(pWal) ); @@ -66938,7 +67751,9 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ } }else{ int bWriteLock = pWal->writeLock; - if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){ + if( bWriteLock + || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) + ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); @@ -66946,7 +67761,8 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ /* If the wal-index header is still malformed even while holding ** a WRITE lock, it can only mean that the header is corrupted and ** needs to be reconstructed. So run recovery to do exactly that. - */ + ** Disable blocking locks first. */ + walDisableBlocking(pWal); rc = walIndexRecover(pWal); *pChanged = 1; } @@ -67156,6 +67972,37 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ return rc; } +/* +** The final argument passed to walTryBeginRead() is of type (int*). The +** caller should invoke walTryBeginRead as follows: +** +** int cnt = 0; +** do { +** rc = walTryBeginRead(..., &cnt); +** }while( rc==WAL_RETRY ); +** +** The final value of "cnt" is of no use to the caller. It is used by +** the implementation of walTryBeginRead() as follows: +** +** + Each time walTryBeginRead() is called, it is incremented. Once +** it reaches WAL_RETRY_PROTOCOL_LIMIT - indicating that walTryBeginRead() +** has many times been invoked and failed with WAL_RETRY - walTryBeginRead() +** returns SQLITE_PROTOCOL. +** +** + If SQLITE_ENABLE_SETLK_TIMEOUT is defined and walTryBeginRead() failed +** because a blocking lock timed out (SQLITE_BUSY_TIMEOUT from the OS +** layer), the WAL_RETRY_BLOCKED_MASK bit is set in "cnt". In this case +** the next invocation of walTryBeginRead() may omit an expected call to +** sqlite3OsSleep(). There has already been a delay when the previous call +** waited on a lock. +*/ +#define WAL_RETRY_PROTOCOL_LIMIT 100 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +# define WAL_RETRY_BLOCKED_MASK 0x10000000 +#else +# define WAL_RETRY_BLOCKED_MASK 0 +#endif + /* ** Attempt to start a read transaction. This might fail due to a race or ** other transient condition. When that happens, it returns WAL_RETRY to @@ -67206,13 +68053,12 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ ** so it takes care to hold an exclusive lock on the corresponding ** WAL_READ_LOCK() while changing values. */ -static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ +static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ - u32 mxReadMark; /* Largest aReadMark[] value */ - int mxI; /* Index of largest aReadMark[] value */ - int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ - u32 mxFrame; /* Wal frame to lock to */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int nBlockTmout = 0; +#endif assert( pWal->readLock<0 ); /* Not currently locked */ @@ -67236,14 +68082,34 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. ** The total delay time before giving up is less than 10 seconds. */ - if( cnt>5 ){ + (*pCnt)++; + if( *pCnt>5 ){ int nDelay = 1; /* Pause time in microseconds */ - if( cnt>100 ){ + int cnt = (*pCnt & ~WAL_RETRY_BLOCKED_MASK); + if( cnt>WAL_RETRY_PROTOCOL_LIMIT ){ VVA_ONLY( pWal->lockError = 1; ) return SQLITE_PROTOCOL; } - if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; + if( *pCnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor + ** to block for locks for approximately nDelay us. This affects three + ** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if + ** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the + ** first attempted read fails, and (c) the shared lock taken on the + ** read-mark. + ** + ** If the previous call failed due to an SQLITE_BUSY_TIMEOUT error, + ** then sleep for the minimum of 1us. The previous call already provided + ** an extra delay while it was blocking on the lock. + */ + nBlockTmout = (nDelay+998) / 1000; + if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){ + if( *pCnt & WAL_RETRY_BLOCKED_MASK ) nDelay = 1; + } +#endif sqlite3OsSleep(pWal->pVfs, nDelay); + *pCnt &= ~WAL_RETRY_BLOCKED_MASK; } if( !useWal ){ @@ -67251,6 +68117,13 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ if( pWal->bShmUnreliable==0 ){ rc = walIndexReadHdr(pWal, pChanged); } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + walDisableBlocking(pWal); + if( rc==SQLITE_BUSY_TIMEOUT ){ + rc = SQLITE_BUSY; + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#endif if( rc==SQLITE_BUSY ){ /* If there is not a recovery running in another thread or process ** then convert BUSY errors to WAL_RETRY. If recovery is known to @@ -67288,131 +68161,147 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ assert( pWal->apWiData[0]!=0 ); pInfo = walCkptInfo(pWal); SEH_INJECT_FAULT; - if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame + { + u32 mxReadMark; /* Largest aReadMark[] value */ + int mxI; /* Index of largest aReadMark[] value */ + int i; /* Loop counter */ + u32 mxFrame; /* Wal frame to lock to */ + if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT - && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) + && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) #endif - ){ - /* The WAL has been completely backfilled (or it is empty). - ** and can be safely ignored. - */ - rc = walLockShared(pWal, WAL_READ_LOCK(0)); - walShmBarrier(pWal); - if( rc==SQLITE_OK ){ - if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ - /* It is not safe to allow the reader to continue here if frames - ** may have been appended to the log before READ_LOCK(0) was obtained. - ** When holding READ_LOCK(0), the reader ignores the entire log file, - ** which implies that the database file contains a trustworthy - ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from - ** happening, this is usually correct. - ** - ** However, if frames have been appended to the log (or if the log - ** is wrapped and written for that matter) before the READ_LOCK(0) - ** is obtained, that is not necessarily true. A checkpointer may - ** have started to backfill the appended frames but crashed before - ** it finished. Leaving a corrupt image in the database file. - */ - walUnlockShared(pWal, WAL_READ_LOCK(0)); - return WAL_RETRY; + ){ + /* The WAL has been completely backfilled (or it is empty). + ** and can be safely ignored. + */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + walShmBarrier(pWal); + if( rc==SQLITE_OK ){ + if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr,sizeof(WalIndexHdr)) ){ + /* It is not safe to allow the reader to continue here if frames + ** may have been appended to the log before READ_LOCK(0) was obtained. + ** When holding READ_LOCK(0), the reader ignores the entire log file, + ** which implies that the database file contains a trustworthy + ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from + ** happening, this is usually correct. + ** + ** However, if frames have been appended to the log (or if the log + ** is wrapped and written for that matter) before the READ_LOCK(0) + ** is obtained, that is not necessarily true. A checkpointer may + ** have started to backfill the appended frames but crashed before + ** it finished. Leaving a corrupt image in the database file. + */ + walUnlockShared(pWal, WAL_READ_LOCK(0)); + return WAL_RETRY; + } + pWal->readLock = 0; + return SQLITE_OK; + }else if( rc!=SQLITE_BUSY ){ + return rc; } - pWal->readLock = 0; - return SQLITE_OK; - }else if( rc!=SQLITE_BUSY ){ - return rc; } - } - /* If we get this far, it means that the reader will want to use - ** the WAL to get at content from recent commits. The job now is - ** to select one of the aReadMark[] entries that is closest to - ** but not exceeding pWal->hdr.mxFrame and lock that entry. - */ - mxReadMark = 0; - mxI = 0; - mxFrame = pWal->hdr.mxFrame; + /* If we get this far, it means that the reader will want to use + ** the WAL to get at content from recent commits. The job now is + ** to select one of the aReadMark[] entries that is closest to + ** but not exceeding pWal->hdr.mxFrame and lock that entry. + */ + mxReadMark = 0; + mxI = 0; + mxFrame = pWal->hdr.mxFrame; #ifdef SQLITE_ENABLE_SNAPSHOT - if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){ - mxFrame = pWal->pSnapshot->mxFrame; - } -#endif - for(i=1; i<WAL_NREADER; i++){ - u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; - if( mxReadMark<=thisMark && thisMark<=mxFrame ){ - assert( thisMark!=READMARK_NOT_USED ); - mxReadMark = thisMark; - mxI = i; + if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){ + mxFrame = pWal->pSnapshot->mxFrame; } - } - if( (pWal->readOnly & WAL_SHM_RDONLY)==0 - && (mxReadMark<mxFrame || mxI==0) - ){ +#endif for(i=1; i<WAL_NREADER; i++){ - rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); - if( rc==SQLITE_OK ){ - AtomicStore(pInfo->aReadMark+i,mxFrame); - mxReadMark = mxFrame; + u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; + if( mxReadMark<=thisMark && thisMark<=mxFrame ){ + assert( thisMark!=READMARK_NOT_USED ); + mxReadMark = thisMark; mxI = i; - walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); - break; - }else if( rc!=SQLITE_BUSY ){ - return rc; } } - } - if( mxI==0 ){ - assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); - return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; - } + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMark<mxFrame || mxI==0) + ){ + for(i=1; i<WAL_NREADER; i++){ + rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ + AtomicStore(pInfo->aReadMark+i,mxFrame); + mxReadMark = mxFrame; + mxI = i; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + break; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + } + if( mxI==0 ){ + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; + } - rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); - if( rc ){ - return rc==SQLITE_BUSY ? WAL_RETRY : rc; - } - /* Now that the read-lock has been obtained, check that neither the - ** value in the aReadMark[] array or the contents of the wal-index - ** header have changed. - ** - ** It is necessary to check that the wal-index header did not change - ** between the time it was read and when the shared-lock was obtained - ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility - ** that the log file may have been wrapped by a writer, or that frames - ** that occur later in the log than pWal->hdr.mxFrame may have been - ** copied into the database by a checkpointer. If either of these things - ** happened, then reading the database with the current value of - ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry - ** instead. - ** - ** Before checking that the live wal-index header has not changed - ** since it was read, set Wal.minFrame to the first frame in the wal - ** file that has not yet been checkpointed. This client will not need - ** to read any frames earlier than minFrame from the wal file - they - ** can be safely read directly from the database file. - ** - ** Because a ShmBarrier() call is made between taking the copy of - ** nBackfill and checking that the wal-header in shared-memory still - ** matches the one cached in pWal->hdr, it is guaranteed that the - ** checkpointer that set nBackfill was not working with a wal-index - ** header newer than that cached in pWal->hdr. If it were, that could - ** cause a problem. The checkpointer could omit to checkpoint - ** a version of page X that lies before pWal->minFrame (call that version - ** A) on the basis that there is a newer version (version B) of the same - ** page later in the wal file. But if version B happens to like past - ** frame pWal->hdr.mxFrame - then the client would incorrectly assume - ** that it can read version A from the database file. However, since - ** we can guarantee that the checkpointer that set nBackfill could not - ** see any pages past pWal->hdr.mxFrame, this problem does not come up. - */ - pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; - walShmBarrier(pWal); - if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark - || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) - ){ - walUnlockShared(pWal, WAL_READ_LOCK(mxI)); - return WAL_RETRY; - }else{ - assert( mxReadMark<=pWal->hdr.mxFrame ); - pWal->readLock = (i16)mxI; + (void)walEnableBlockingMs(pWal, nBlockTmout); + rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + walDisableBlocking(pWal); + if( rc ){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#else + assert( rc!=SQLITE_BUSY_TIMEOUT ); +#endif + assert((rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT); + return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; + } + /* Now that the read-lock has been obtained, check that neither the + ** value in the aReadMark[] array or the contents of the wal-index + ** header have changed. + ** + ** It is necessary to check that the wal-index header did not change + ** between the time it was read and when the shared-lock was obtained + ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility + ** that the log file may have been wrapped by a writer, or that frames + ** that occur later in the log than pWal->hdr.mxFrame may have been + ** copied into the database by a checkpointer. If either of these things + ** happened, then reading the database with the current value of + ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry + ** instead. + ** + ** Before checking that the live wal-index header has not changed + ** since it was read, set Wal.minFrame to the first frame in the wal + ** file that has not yet been checkpointed. This client will not need + ** to read any frames earlier than minFrame from the wal file - they + ** can be safely read directly from the database file. + ** + ** Because a ShmBarrier() call is made between taking the copy of + ** nBackfill and checking that the wal-header in shared-memory still + ** matches the one cached in pWal->hdr, it is guaranteed that the + ** checkpointer that set nBackfill was not working with a wal-index + ** header newer than that cached in pWal->hdr. If it were, that could + ** cause a problem. The checkpointer could omit to checkpoint + ** a version of page X that lies before pWal->minFrame (call that version + ** A) on the basis that there is a newer version (version B) of the same + ** page later in the wal file. But if version B happens to like past + ** frame pWal->hdr.mxFrame - then the client would incorrectly assume + ** that it can read version A from the database file. However, since + ** we can guarantee that the checkpointer that set nBackfill could not + ** see any pages past pWal->hdr.mxFrame, this problem does not come up. + */ + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; + walShmBarrier(pWal); + if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark + || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) + ){ + walUnlockShared(pWal, WAL_READ_LOCK(mxI)); + return WAL_RETRY; + }else{ + assert( mxReadMark<=pWal->hdr.mxFrame ); + pWal->readLock = (i16)mxI; + } } return rc; } @@ -67555,7 +68444,7 @@ static int walBeginReadTransaction(Wal *pWal, int *pChanged){ #endif do{ - rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); + rc = walTryBeginRead(pWal, pChanged, 0, &cnt); }while( rc==WAL_RETRY ); testcase( (rc&0xff)==SQLITE_BUSY ); testcase( (rc&0xff)==SQLITE_IOERR ); @@ -67736,6 +68625,7 @@ static int walFindFrame( iRead = iFrame; } if( (nCollide--)==0 ){ + *piRead = 0; return SQLITE_CORRUPT_BKPT; } iKey = walNextHash(iKey); @@ -68039,7 +68929,7 @@ static int walRestartLog(Wal *pWal){ cnt = 0; do{ int notUsed; - rc = walTryBeginRead(pWal, &notUsed, 1, ++cnt); + rc = walTryBeginRead(pWal, &notUsed, 1, &cnt); }while( rc==WAL_RETRY ); assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ testcase( (rc&0xff)==SQLITE_IOERR ); @@ -68460,10 +69350,9 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( if( pWal->readOnly ) return SQLITE_READONLY; WALTRACE(("WAL%p: checkpoint begins\n", pWal)); - /* Enable blocking locks, if possible. If blocking locks are successfully - ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */ + /* Enable blocking locks, if possible. */ sqlite3WalDb(pWal, db); - (void)walEnableBlocking(pWal); + if( xBusy2 ) (void)walEnableBlocking(pWal); /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive ** "checkpoint" lock on the database file. @@ -68504,9 +69393,14 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( /* Read the wal-index header. */ SEH_TRY { if( rc==SQLITE_OK ){ + /* For a passive checkpoint, do not re-enable blocking locks after + ** reading the wal-index header. A passive checkpoint should not block + ** or invoke the busy handler. The only lock such a checkpoint may + ** attempt to obtain is a lock on a read-slot, and it should give up + ** immediately and do a partial checkpoint if it cannot obtain it. */ walDisableBlocking(pWal); rc = walIndexReadHdr(pWal, &isChanged); - (void)walEnableBlocking(pWal); + if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal); if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ sqlite3OsUnfetch(pWal->pDbFd, 0, 0); } @@ -68675,7 +69569,20 @@ SQLITE_PRIVATE void sqlite3WalSnapshotOpen( Wal *pWal, sqlite3_snapshot *pSnapshot ){ - pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + if( pSnapshot && ((WalIndexHdr*)pSnapshot)->iVersion==0 ){ + /* iVersion==0 means that this is a call to sqlite3_snapshot_get(). In + ** this case set the bGetSnapshot flag so that if the call to + ** sqlite3_snapshot_get() is about to read transaction on this wal + ** file, it does not take read-lock 0 if the wal file has been completely + ** checkpointed. Taking read-lock 0 would work, but then it would be + ** possible for a subsequent writer to destroy the snapshot even while + ** this connection is holding its read-transaction open. This is contrary + ** to user expectations, so we avoid it by not taking read-lock 0. */ + pWal->bGetSnapshot = 1; + }else{ + pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + pWal->bGetSnapshot = 0; + } } /* @@ -68843,7 +69750,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ ** 22 1 Min embedded payload fraction (must be 32) ** 23 1 Min leaf payload fraction (must be 32) ** 24 4 File change counter -** 28 4 Reserved for future use +** 28 4 The size of the database in pages ** 32 4 First freelist page ** 36 4 Number of freelist pages in the file ** 40 60 15 4-byte meta values passed to higher layers @@ -69486,6 +70393,7 @@ struct IntegrityCk { StrAccum errMsg; /* Accumulate the error message text here */ u32 *heap; /* Min-heap used for analyzing cell coverage */ sqlite3 *db; /* Database connection running the check */ + i64 nRow; /* Number of rows visited in current tree */ }; /* @@ -69960,8 +70868,47 @@ int corruptPageError(int lineno, MemPage *p){ # define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno) #endif +/* Default value for SHARED_LOCK_TRACE macro if shared-cache is disabled +** or if the lock tracking is disabled. This is always the value for +** release builds. +*/ +#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) /*no-op*/ + #ifndef SQLITE_OMIT_SHARED_CACHE +#if 0 +/* ^---- Change to 1 and recompile to enable shared-lock tracing +** for debugging purposes. +** +** Print all shared-cache locks on a BtShared. Debugging use only. +*/ +static void sharedLockTrace( + BtShared *pBt, + const char *zMsg, + int iRoot, + int eLockType +){ + BtLock *pLock; + if( iRoot>0 ){ + printf("%s-%p %u%s:", zMsg, pBt, iRoot, eLockType==READ_LOCK?"R":"W"); + }else{ + printf("%s-%p:", zMsg, pBt); + } + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + printf(" %p/%u%s", pLock->pBtree, pLock->iTable, + pLock->eLock==READ_LOCK ? "R" : "W"); + while( pLock->pNext && pLock->pBtree==pLock->pNext->pBtree ){ + pLock = pLock->pNext; + printf(",%u%s", pLock->iTable, pLock->eLock==READ_LOCK ? "R" : "W"); + } + } + printf("\n"); + fflush(stdout); +} +#undef SHARED_LOCK_TRACE +#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) sharedLockTrace(X,MSG,TAB,TYPE) +#endif /* Shared-lock tracing */ + #ifdef SQLITE_DEBUG /* **** This function is only used as part of an assert() statement. *** @@ -70038,6 +70985,8 @@ static int hasSharedCacheTableLock( iTab = iRoot; } + SHARED_LOCK_TRACE(pBtree->pBt,"hasLock",iRoot,eLockType); + /* Search for the required lock. Either a write-lock on root-page iTab, a ** write-lock on the schema table, or (if the client is reading) a ** read-lock on iTab will suffice. Return 1 if any of these are found. */ @@ -70171,6 +71120,8 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ BtLock *pLock = 0; BtLock *pIter; + SHARED_LOCK_TRACE(pBt,"setLock", iTable, eLock); + assert( sqlite3BtreeHoldsMutex(p) ); assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); assert( p->db!=0 ); @@ -70238,6 +71189,8 @@ static void clearAllSharedCacheTableLocks(Btree *p){ assert( p->sharable || 0==*ppIter ); assert( p->inTrans>0 ); + SHARED_LOCK_TRACE(pBt, "clearAllLocks", 0, 0); + while( *ppIter ){ BtLock *pLock = *ppIter; assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); @@ -70276,6 +71229,9 @@ static void clearAllSharedCacheTableLocks(Btree *p){ */ static void downgradeAllSharedCacheTableLocks(Btree *p){ BtShared *pBt = p->pBt; + + SHARED_LOCK_TRACE(pBt, "downgradeLocks", 0, 0); + if( pBt->pWriter==p ){ BtLock *pLock; pBt->pWriter = 0; @@ -74507,6 +75463,25 @@ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ return ROUND8(sizeof(BtCursor)); } +#ifdef SQLITE_DEBUG +/* +** Return true if and only if the Btree object will be automatically +** closed with the BtCursor closes. This is used within assert() statements +** only. +*/ +SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor( + Btree *pBtree, /* the btree object */ + BtCursor *pCur /* Corresponding cursor */ +){ + BtShared *pBt = pBtree->pBt; + if( (pBt->openFlags & BTREE_SINGLE)==0 ) return 0; + if( pBt->pCursor!=pCur ) return 0; + if( pCur->pNext!=0 ) return 0; + if( pCur->pBtree!=pBtree ) return 0; + return 1; +} +#endif + /* ** Initialize memory that will be converted into a BtCursor object. ** @@ -74889,9 +75864,12 @@ static int accessPayload( if( pCur->aOverflow==0 || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) ){ - Pgno *aNew = (Pgno*)sqlite3Realloc( - pCur->aOverflow, nOvfl*2*sizeof(Pgno) - ); + Pgno *aNew; + if( sqlite3FaultSim(413) ){ + aNew = 0; + }else{ + aNew = (Pgno*)sqlite3Realloc(pCur->aOverflow, nOvfl*2*sizeof(Pgno)); + } if( aNew==0 ){ return SQLITE_NOMEM_BKPT; }else{ @@ -74901,6 +75879,12 @@ static int accessPayload( memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); pCur->curFlags |= BTCF_ValidOvfl; }else{ + /* Sanity check the validity of the overflow page cache */ + assert( pCur->aOverflow[0]==nextPage + || pCur->aOverflow[0]==0 + || CORRUPT_DB ); + assert( pCur->aOverflow[0]!=0 || pCur->aOverflow[offset/ovflSize]==0 ); + /* If the overflow page-list cache has been allocated and the ** entry for the first required overflow page is valid, skip ** directly to it. @@ -74970,7 +75954,6 @@ static int accessPayload( assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); - if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT; nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else @@ -75383,6 +76366,23 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ return rc; } +#ifdef SQLITE_DEBUG +/* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that +** this flags are true for a consistent database. +** +** This routine is is called from within assert() statements only. +** It is an internal verification routine and does not appear in production +** builds. +*/ +static int cursorIsAtLastEntry(BtCursor *pCur){ + int ii; + for(ii=0; ii<pCur->iPage; ii++){ + if( pCur->aiIdx[ii]!=pCur->apPage[ii]->nCell ) return 0; + } + return pCur->ix==pCur->pPage->nCell-1 && pCur->pPage->leaf!=0; +} +#endif + /* Move the cursor to the last entry in the table. Return SQLITE_OK ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. @@ -75411,18 +76411,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ /* If the cursor already points to the last entry, this is a no-op. */ if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ -#ifdef SQLITE_DEBUG - /* This block serves to assert() that the cursor really does point - ** to the last entry in the b-tree. */ - int ii; - for(ii=0; ii<pCur->iPage; ii++){ - assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); - } - assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB ); - testcase( pCur->ix!=pCur->pPage->nCell-1 ); - /* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */ - assert( pCur->pPage->leaf ); -#endif + assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB ); *pRes = 0; return SQLITE_OK; } @@ -75475,6 +76464,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto( } if( pCur->info.nKey<intKey ){ if( (pCur->curFlags & BTCF_AtLast)!=0 ){ + assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB ); *pRes = -1; return SQLITE_OK; } @@ -75735,7 +76725,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 && pIdxKey->errCode==SQLITE_OK ){ - pCur->curFlags &= ~BTCF_ValidOvfl; + pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); if( !pCur->pPage->isInit ){ return SQLITE_CORRUPT_BKPT; } @@ -75941,10 +76931,10 @@ SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - /* Currently this interface is only called by the OP_IfSmaller - ** opcode, and it that case the cursor will always be valid and - ** will always point to a leaf node. */ - if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1; + /* Currently this interface is only called by the OP_IfSizeBetween + ** opcode and the OP_Count opcode with P3=1. In either case, + ** the cursor will always be valid unless the btree is empty. */ + if( pCur->eState!=CURSOR_VALID ) return 0; if( NEVER(pCur->pPage->leaf==0) ) return -1; n = pCur->pPage->nCell; @@ -76090,7 +77080,10 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ } pPage = pCur->pPage; - assert( pPage->isInit ); + if( sqlite3FaultSim(412) ) pPage->isInit = 0; + if( !pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } if( !pPage->leaf ){ int idx = pCur->ix; rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); @@ -76763,7 +77756,10 @@ static int fillInCell( n = nHeader + nPayload; testcase( n==3 ); testcase( n==4 ); - if( n<4 ) n = 4; + if( n<4 ){ + n = 4; + pPayload[nPayload] = 0; + } *pnSize = n; assert( nSrc<=nPayload ); testcase( nSrc<nPayload ); @@ -77307,7 +78303,8 @@ static int rebuildPage( if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); - for(k=0; ALWAYS(k<NB*2) && pCArray->ixNx[k]<=i; k++){} + assert( pCArray->ixNx[NB*2-1]>i ); + for(k=0; pCArray->ixNx[k]<=i; k++){} pSrcEnd = pCArray->apEnd[k]; pData = pEnd; @@ -77390,7 +78387,8 @@ static int pageInsertArray( u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; - for(k=0; ALWAYS(k<NB*2) && pCArray->ixNx[k]<=i ; k++){} + assert( pCArray->ixNx[NB*2-1]>i ); + for(k=0; pCArray->ixNx[k]<=i ; k++){} pEnd = pCArray->apEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; @@ -77675,6 +78673,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ b.szCell = &szCell; b.apEnd[0] = pPage->aDataEnd; b.ixNx[0] = 2; + b.ixNx[NB*2-1] = 0x7fffffff; rc = rebuildPage(&b, 0, 1, pNew); if( NEVER(rc) ){ releasePage(pNew); @@ -77910,7 +78909,9 @@ static int balance_nonroot( CellArray b; /* Parsed information on cells being balanced */ memset(abDone, 0, sizeof(abDone)); - memset(&b, 0, sizeof(b)); + assert( sizeof(b) - sizeof(b.ixNx) == offsetof(CellArray,ixNx) ); + memset(&b, 0, sizeof(b)-sizeof(b.ixNx[0])); + b.ixNx[NB*2-1] = 0x7fffffff; pBt = pParent->pBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); @@ -78069,7 +79070,7 @@ static int balance_nonroot( ** table-interior, index-leaf, or index-interior). */ if( pOld->aData[0]!=apOld[0]->aData[0] ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pOld); goto balance_cleanup; } @@ -78093,7 +79094,7 @@ static int balance_nonroot( memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); if( pOld->nOverflow>0 ){ if( NEVER(limit<pOld->aiOvfl[0]) ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pOld); goto balance_cleanup; } limit = pOld->aiOvfl[0]; @@ -78501,7 +79502,8 @@ static int balance_nonroot( iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; ALWAYS(k<NB*2) && b.ixNx[k]<=j; k++){} + assert( b.ixNx[NB*2-1]>j ); + for(k=0; b.ixNx[k]<=j; k++){} pSrcEnd = b.apEnd[k]; if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){ rc = SQLITE_CORRUPT_BKPT; @@ -78736,7 +79738,7 @@ static int anotherValidCursor(BtCursor *pCur){ && pOther->eState==CURSOR_VALID && pOther->pPage==pCur->pPage ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pCur->pPage); } } return SQLITE_OK; @@ -78796,7 +79798,7 @@ static int balance(BtCursor *pCur){ /* The page being written is not a root page, and there is currently ** more than one reference to it. This only happens if the page is one ** of its own ancestor pages. Corruption. */ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pPage); }else{ MemPage * const pParent = pCur->apPage[iPage-1]; int const iIdx = pCur->aiIdx[iPage-1]; @@ -78960,7 +79962,7 @@ static SQLITE_NOINLINE int btreeOverwriteOverflowCell( rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); if( rc ) return rc; if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pPage); }else{ if( iOffset+ovflPageSize<(u32)nTotal ){ ovflPgno = get4byte(pPage->aData); @@ -78988,7 +79990,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd || pCur->info.pPayload < pPage->aData + pPage->cellOffset ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } if( pCur->info.nLocal==nTotal ){ /* The entire cell is local */ @@ -79069,7 +80071,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( ** Which can only happen if the SQLITE_NoSchemaError flag was set when ** the schema was loaded. This cannot be asserted though, as a user might ** set the flag, load the schema, and then unset the flag. */ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot); } } @@ -79192,7 +80194,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( if( pPage->nFree<0 ){ if( NEVER(pCur->eState>CURSOR_INVALID) ){ /* ^^^^^--- due to the moveToRoot() call above */ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pPage); }else{ rc = btreeComputeFreeSpace(pPage); } @@ -79209,7 +80211,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( if( flags & BTREE_PREFORMAT ){ rc = SQLITE_OK; szNew = p->pBt->nPreformatSize; - if( szNew<4 ) szNew = 4; + if( szNew<4 ){ + szNew = 4; + newCell[3] = 0; + } if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ CellInfo info; pPage->xParseCell(pPage, newCell, &info); @@ -79231,7 +80236,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( CellInfo info; assert( idx>=0 ); if( idx>=pPage->nCell ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ){ @@ -79258,10 +80263,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ if( oldCell < pPage->aData+pPage->hdrOffset+10 ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } if( oldCell+szNew > pPage->aDataEnd ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } memcpy(oldCell, newCell, szNew); return SQLITE_OK; @@ -79271,7 +80276,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( }else if( loc<0 && pPage->nCell>0 ){ assert( pPage->leaf ); idx = ++pCur->ix; - pCur->curFlags &= ~BTCF_ValidNKey; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); }else{ assert( pPage->leaf ); } @@ -79301,7 +80306,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( */ if( pPage->nOverflow ){ assert( rc==SQLITE_OK ); - pCur->curFlags &= ~(BTCF_ValidNKey); + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); rc = balance(pCur); /* Must make sure nOverflow is reset to zero even if the balance() @@ -79363,7 +80368,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; if( aIn+nIn>pSrc->pPage->aDataEnd ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pSrc->pPage); } nRem = pSrc->info.nPayload; if( nIn==nRem && nIn<pDest->pPage->maxLocal ){ @@ -79388,7 +80393,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 if( nRem>nIn ){ if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pSrc->pPage); } ovflIn = get4byte(&pSrc->info.pPayload[nIn]); } @@ -79484,7 +80489,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); if( rc || pCur->eState!=CURSOR_VALID ) return rc; }else{ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot); } } assert( pCur->eState==CURSOR_VALID ); @@ -79493,14 +80498,14 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ iCellIdx = pCur->ix; pPage = pCur->pPage; if( pPage->nCell<=iCellIdx ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } pCell = findCell(pPage, iCellIdx); if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } if( pCell<&pPage->aCellIdx[pPage->nCell] ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PAGE(pPage); } /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must @@ -79591,7 +80596,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ n = pCur->pPage->pgno; } pCell = findCell(pLeaf, pLeaf->nCell-1); - if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; + if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_PAGE(pLeaf); nCell = pLeaf->xCellSize(pLeaf, pCell); assert( MX_CELL_SIZE(pBt) >= nCell ); pTmp = pBt->pTmpSpace; @@ -79707,7 +80712,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ */ sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); if( pgnoRoot>btreePagecount(pBt) ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(pgnoRoot); } pgnoRoot++; @@ -79755,7 +80760,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ } rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PGNO(pgnoRoot); } if( rc!=SQLITE_OK ){ releasePage(pRoot); @@ -79845,14 +80850,14 @@ static int clearDatabasePage( assert( sqlite3_mutex_held(pBt->mutex) ); if( pgno>btreePagecount(pBt) ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(pgno); } rc = getAndInitPage(pBt, pgno, &pPage, 0); if( rc ) return rc; if( (pBt->openFlags & BTREE_SINGLE)==0 && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) ){ - rc = SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_PAGE(pPage); goto cleardatabasepage_out; } hdr = pPage->hdrOffset; @@ -79956,7 +80961,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ assert( p->inTrans==TRANS_WRITE ); assert( iTable>=2 ); if( iTable>btreePagecount(pBt) ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_PGNO(iTable); } rc = sqlite3BtreeClearTable(p, iTable, 0); @@ -80550,6 +81555,9 @@ static int checkTreePage( ** number of cells on the page. */ nCell = get2byte(&data[hdr+3]); assert( pPage->nCell==nCell ); + if( pPage->leaf || pPage->intKey==0 ){ + pCheck->nRow += nCell; + } /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page ** immediately follows the b-tree page header. */ @@ -80661,6 +81669,7 @@ static int checkTreePage( btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); } } + assert( heap!=0 ); /* Add the freeblocks to the min-heap ** ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header @@ -80760,6 +81769,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( sqlite3 *db, /* Database connection that is running the check */ Btree *p, /* The btree to be checked */ Pgno *aRoot, /* An array of root pages numbers for individual trees */ + Mem *aCnt, /* Memory cells to write counts for each tree to */ int nRoot, /* Number of entries in aRoot[] */ int mxErr, /* Stop reporting errors after this many */ int *pnErr, /* OUT: Write number of errors seen to this variable */ @@ -80773,7 +81783,9 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( int bPartial = 0; /* True if not checking all btrees */ int bCkFreelist = 1; /* True to scan the freelist */ VVA_ONLY( int nRef ); + assert( nRoot>0 ); + assert( aCnt!=0 ); /* aRoot[0]==0 means this is a partial check */ if( aRoot[0]==0 ){ @@ -80846,15 +81858,18 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( testcase( pBt->db->flags & SQLITE_CellSizeCk ); pBt->db->flags &= ~(u64)SQLITE_CellSizeCk; for(i=0; (int)i<nRoot && sCheck.mxErr; i++){ - i64 notUsed; - if( aRoot[i]==0 ) continue; + sCheck.nRow = 0; + if( aRoot[i] ){ + i64 notUsed; #ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){ - checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); - } + if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){ + checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); + } #endif - sCheck.v0 = aRoot[i]; - checkTreePage(&sCheck, aRoot[i], &notUsed, LARGEST_INT64); + sCheck.v0 = aRoot[i]; + checkTreePage(&sCheck, aRoot[i], &notUsed, LARGEST_INT64); + } + sqlite3MemSetArrayInt64(aCnt, i, sCheck.nRow); } pBt->db->flags = savedDbFlags; @@ -81348,6 +82363,12 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init( } #endif + /* Check whether databases are compatible with backup */ + if (!sqlite3mcIsBackupSupported(pSrcDb, zSrcDb, pDestDb, zDestDb)){ + sqlite3ErrorWithMsg(pDestDb, SQLITE_ERROR, "backup is not supported with incompatible source and target databases"); + return NULL; + } + /* Lock the source database handle. The destination database ** handle is not locked in this routine, but it is locked in ** sqlite3_backup_step(). The user is required to ensure that no @@ -82909,6 +83930,13 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ } } +/* +** Set the iIdx'th entry of array aMem[] to contain integer value val. +*/ +SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val){ + sqlite3VdbeMemSetInt64(&aMem[iIdx], val); +} + /* A no-op destructor */ SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } @@ -83493,7 +84521,8 @@ static int valueFromFunction( goto value_from_function_out; } for(i=0; i<nVal; i++){ - rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]); + rc = sqlite3Stat4ValueFromExpr(pCtx->pParse, pList->a[i].pExpr, aff, + &apVal[i]); if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; } } @@ -83597,14 +84626,20 @@ static int valueFromExpr( } /* Handle negative integers in a single step. This is needed in the - ** case when the value is -9223372036854775808. - */ - if( op==TK_UMINUS - && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ - pExpr = pExpr->pLeft; - op = pExpr->op; - negInt = -1; - zNeg = "-"; + ** case when the value is -9223372036854775808. Except - do not do this + ** for hexadecimal literals. */ + if( op==TK_UMINUS ){ + Expr *pLeft = pExpr->pLeft; + if( (pLeft->op==TK_INTEGER || pLeft->op==TK_FLOAT) ){ + if( ExprHasProperty(pLeft, EP_IntValue) + || pLeft->u.zToken[0]!='0' || (pLeft->u.zToken[1] & ~0x20)!='X' + ){ + pExpr = pLeft; + op = pExpr->op; + negInt = -1; + zNeg = "-"; + } + } } if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ @@ -83613,12 +84648,26 @@ static int valueFromExpr( if( ExprHasProperty(pExpr, EP_IntValue) ){ sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); }else{ - zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); - if( zVal==0 ) goto no_mem; - sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + i64 iVal; + if( op==TK_INTEGER && 0==sqlite3DecOrHexToI64(pExpr->u.zToken, &iVal) ){ + sqlite3VdbeMemSetInt64(pVal, iVal*negInt); + }else{ + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); + if( zVal==0 ) goto no_mem; + sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + } } - if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){ - sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); + if( affinity==SQLITE_AFF_BLOB ){ + if( op==TK_FLOAT ){ + assert( pVal && pVal->z && pVal->flags==(MEM_Str|MEM_Term) ); + sqlite3AtoF(pVal->z, &pVal->u.r, pVal->n, SQLITE_UTF8); + pVal->flags = MEM_Real; + }else if( op==TK_INTEGER ){ + /* This case is required by -9223372036854775808 and other strings + ** that look like integers but cannot be handled by the + ** sqlite3DecOrHexToI64() call above. */ + sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); + } }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } @@ -83888,17 +84937,17 @@ SQLITE_PRIVATE int sqlite3Stat4Column( sqlite3_value **ppVal /* OUT: Extracted value */ ){ u32 t = 0; /* a column type code */ - int nHdr; /* Size of the header in the record */ - int iHdr; /* Next unread header byte */ - int iField; /* Next unread data byte */ - int szField = 0; /* Size of the current data field */ + u32 nHdr; /* Size of the header in the record */ + u32 iHdr; /* Next unread header byte */ + i64 iField; /* Next unread data byte */ + u32 szField = 0; /* Size of the current data field */ int i; /* Column index */ u8 *a = (u8*)pRec; /* Typecast byte array */ Mem *pMem = *ppVal; /* Write result into this Mem object */ assert( iCol>0 ); iHdr = getVarint32(a, nHdr); - if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; + if( nHdr>(u32)nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; iField = nHdr; for(i=0; i<=iCol; i++){ iHdr += getVarint32(&a[iHdr], t); @@ -84933,6 +85982,15 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ assert( aLabel!=0 ); /* True because of tag-20230419-1 */ pOp->p2 = aLabel[ADDR(pOp->p2)]; } + + /* OPFLG_JUMP opcodes never have P2==0, though OPFLG_JUMP0 opcodes + ** might */ + assert( pOp->p2>0 + || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP0)!=0 ); + + /* Jumps never go off the end of the bytecode array */ + assert( pOp->p2<p->nOp + || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)==0 ); break; } } @@ -85394,6 +86452,16 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); break; } + case P4_TABLEREF: { + if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); + break; + } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = (SubrtnSig*)p4; + sqlite3DbFree(db, pSig->zAff); + sqlite3DbFree(db, pSig); + break; + } } } @@ -85521,7 +86589,7 @@ static void SQLITE_NOINLINE vdbeChangeP4Full( int n ){ if( pOp->p4type ){ - freeP4(p->db, pOp->p4type, pOp->p4.p); + assert( pOp->p4type > P4_FREE_IF_LE ); pOp->p4type = 0; pOp->p4.p = 0; } @@ -85973,6 +87041,11 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ zP4 = pOp->p4.pTab->zName; break; } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = pOp->p4.pSubrtnSig; + sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); + break; + } default: { zP4 = pOp->p4.z; } @@ -86114,6 +87187,7 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ ** will be initialized before use. */ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ + assert( db!=0 ); if( N>0 ){ do{ p->flags = flags; @@ -86139,6 +87213,7 @@ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; + assert( db!=0 ); if( db->pnBytesFreed ){ do{ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); @@ -86619,6 +87694,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( assert( pParse!=0 ); assert( p->eVdbeState==VDBE_INIT_STATE ); assert( pParse==p->pParse ); + assert( pParse->db==p->db ); p->pVList = pParse->pVList; pParse->pVList = 0; db = p->db; @@ -87336,7 +88412,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ /* Check for immediate foreign key violations. */ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ - sqlite3VdbeCheckFk(p, 0); + (void)sqlite3VdbeCheckFk(p, 0); } /* If the auto-commit flag is set and this is the only active writer @@ -88050,6 +89126,23 @@ static void serialGet( pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; } } +static int serialGet7( + const unsigned char *buf, /* Buffer to deserialize from */ + Mem *pMem /* Memory cell to write value into */ +){ + u64 x = FOUR_BYTE_UINT(buf); + u32 y = FOUR_BYTE_UINT(buf+4); + x = (x<<32) + y; + assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); + swapMixedEndianFloat(x); + memcpy(&pMem->u.r, &x, sizeof(x)); + if( IsNaN(x) ){ + pMem->flags = MEM_Null; + return 1; + } + pMem->flags = MEM_Real; + return 0; +} SQLITE_PRIVATE void sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ @@ -88465,7 +89558,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem ** We must use separate SQLITE_NOINLINE functions here, since otherwise ** optimizer code movement causes gcov to become very confused. */ -#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) static int SQLITE_NOINLINE doubleLt(double a, double b){ return a<b; } static int SQLITE_NOINLINE doubleEq(double a, double b){ return a==b; } #endif @@ -88480,26 +89573,17 @@ SQLITE_PRIVATE int sqlite3IntFloatCompare(i64 i, double r){ /* SQLite considers NaN to be a NULL. And all integer values are greater ** than NULL */ return 1; - } - if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; - testcase( x<r ); - testcase( x>r ); - testcase( x==r ); - return (x<r) ? -1 : (x>r); }else{ i64 y; - double s; if( r<-9223372036854775808.0 ) return +1; if( r>=9223372036854775808.0 ) return -1; y = (i64)r; if( i<y ) return -1; if( i>y ) return +1; - s = (double)i; - testcase( doubleLt(s,r) ); - testcase( doubleLt(r,s) ); - testcase( doubleEq(r,s) ); - return (s<r) ? -1 : (s>r); + testcase( doubleLt(((double)i),r) ); + testcase( doubleLt(r,((double)i)) ); + testcase( doubleEq(r,((double)i)) ); + return (((double)i)<r) ? -1 : (((double)i)>r); } } @@ -88729,7 +89813,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( }else if( serial_type==0 ){ rc = -1; }else if( serial_type==7 ){ - sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); + serialGet7(&aKey1[d1], &mem1); rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); }else{ i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); @@ -88754,14 +89838,18 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( }else if( serial_type==0 ){ rc = -1; }else{ - sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); if( serial_type==7 ){ - if( mem1.u.r<pRhs->u.r ){ + if( serialGet7(&aKey1[d1], &mem1) ){ + rc = -1; /* mem1 is a NaN */ + }else if( mem1.u.r<pRhs->u.r ){ rc = -1; }else if( mem1.u.r>pRhs->u.r ){ rc = +1; + }else{ + assert( rc==0 ); } }else{ + sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); } } @@ -88831,7 +89919,14 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( /* RHS is null */ else{ serial_type = aKey1[idx1]; - rc = (serial_type!=0 && serial_type!=10); + if( serial_type==0 + || serial_type==10 + || (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0) + ){ + assert( rc==0 ); + }else{ + rc = 1; + } } if( rc!=0 ){ @@ -89291,7 +90386,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff assert( iVar>0 ); if( v ){ Mem *pMem = &v->aVar[iVar-1]; - assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); + assert( (v->db->flags & SQLITE_EnableQPSG)==0 + || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); if( 0==(pMem->flags & MEM_Null) ){ sqlite3_value *pRet = sqlite3ValueNew(v->db); if( pRet ){ @@ -89311,7 +90407,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff */ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ assert( iVar>0 ); - assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); + assert( (v->db->flags & SQLITE_EnableQPSG)==0 + || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); if( iVar>=32 ){ v->expmask |= 0x80000000; }else{ @@ -89478,6 +90575,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( sqlite3DbFree(db, preupdate.aRecord); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); + sqlite3VdbeMemRelease(&preupdate.oldipk); if( preupdate.aNew ){ int i; for(i=0; i<pCsr->nField; i++){ @@ -89485,6 +90583,13 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( } sqlite3DbNNFreeNN(db, preupdate.aNew); } + if( preupdate.apDflt ){ + int i; + for(i=0; i<pTab->nCol; i++){ + sqlite3ValueFree(preupdate.apDflt[i]); + } + sqlite3DbFree(db, preupdate.apDflt); + } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -89644,7 +90749,15 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ int rc = SQLITE_OK; Vdbe *p = (Vdbe*)pStmt; #if SQLITE_THREADSAFE - sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; + sqlite3_mutex *mutex; +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif +#if SQLITE_THREADSAFE + mutex = p->db->mutex; #endif sqlite3_mutex_enter(mutex); for(i=0; i<p->nVar; i++){ @@ -90434,9 +91547,8 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ #ifdef SQLITE_ENABLE_API_ARMOR if( p==0 ) return 0; -#else - assert( p && p->pFunc ); #endif + assert( p && p->pFunc ); return p->pFunc->pUserData; } @@ -90820,7 +91932,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ ** sqlite3_column_int64() ** sqlite3_column_text() ** sqlite3_column_text16() -** sqlite3_column_real() +** sqlite3_column_double() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() ** sqlite3_column_blob() @@ -91106,6 +92218,17 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ ** ** The error code stored in database p->db is overwritten with the return ** value in any case. +** +** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK, +** that means all of the the following will be true: +** +** p!=0 +** p->pVar!=0 +** i>0 +** i<=p->nVar +** +** An assert() is normally added after vdbeUnbind() to help static analyzers +** realize this. */ static int vdbeUnbind(Vdbe *p, unsigned int i){ Mem *pVar; @@ -91163,6 +92286,7 @@ static int bindText( rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ if( zData!=0 ){ pVar = &p->aVar[i-1]; rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); @@ -91212,6 +92336,7 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); sqlite3_mutex_leave(p->db->mutex); } @@ -91225,6 +92350,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); sqlite3_mutex_leave(p->db->mutex); } @@ -91235,6 +92361,7 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3_mutex_leave(p->db->mutex); } return rc; @@ -91250,6 +92377,7 @@ SQLITE_API int sqlite3_bind_pointer( Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ @@ -91331,6 +92459,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ #ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #else @@ -91665,37 +92794,64 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa goto preupdate_old_out; } - /* If the old.* record has not yet been loaded into memory, do so now. */ - if( p->pUnpacked==0 ){ - u32 nRec; - u8 *aRec; + if( iIdx==p->pTab->iPKey ){ + *ppValue = pMem = &p->oldipk; + sqlite3VdbeMemSetInt64(pMem, p->iKey1); + }else{ + + /* If the old.* record has not yet been loaded into memory, do so now. */ + if( p->pUnpacked==0 ){ + u32 nRec; + u8 *aRec; - assert( p->pCsr->eCurType==CURTYPE_BTREE ); - nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); - aRec = sqlite3DbMallocRaw(db, nRec); - if( !aRec ) goto preupdate_old_out; - rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); - if( rc==SQLITE_OK ){ - p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); - if( !p->pUnpacked ) rc = SQLITE_NOMEM; - } - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, aRec); - goto preupdate_old_out; + assert( p->pCsr->eCurType==CURTYPE_BTREE ); + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); + aRec = sqlite3DbMallocRaw(db, nRec); + if( !aRec ) goto preupdate_old_out; + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); + if( rc==SQLITE_OK ){ + p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); + if( !p->pUnpacked ) rc = SQLITE_NOMEM; + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, aRec); + goto preupdate_old_out; + } + p->aRecord = aRec; } - p->aRecord = aRec; - } - pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; - if( iIdx==p->pTab->iPKey ){ - sqlite3VdbeMemSetInt64(pMem, p->iKey1); - }else if( iIdx>=p->pUnpacked->nField ){ - *ppValue = (sqlite3_value *)columnNullValue(); - }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ - if( pMem->flags & (MEM_Int|MEM_IntReal) ){ - testcase( pMem->flags & MEM_Int ); - testcase( pMem->flags & MEM_IntReal ); - sqlite3VdbeMemRealify(pMem); + pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; + if( iIdx>=p->pUnpacked->nField ){ + /* This occurs when the table has been extended using ALTER TABLE + ** ADD COLUMN. The value to return is the default value of the column. */ + Column *pCol = &p->pTab->aCol[iIdx]; + if( pCol->iDflt>0 ){ + if( p->apDflt==0 ){ + int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); + if( p->apDflt==0 ) goto preupdate_old_out; + } + if( p->apDflt[iIdx]==0 ){ + sqlite3_value *pVal = 0; + Expr *pDflt; + assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); + pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; + rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); + if( rc==SQLITE_OK && pVal==0 ){ + rc = SQLITE_CORRUPT_BKPT; + } + p->apDflt[iIdx] = pVal; + } + *ppValue = p->apDflt[iIdx]; + }else{ + *ppValue = (sqlite3_value *)columnNullValue(); + } + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pMem); + } } } @@ -91889,7 +93045,6 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( } if( flags & SQLITE_SCANSTAT_COMPLEX ){ idx = iScan; - pScan = &p->aScan[idx]; }else{ /* If the COMPLEX flag is clear, then this function must ignore any ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ @@ -91902,6 +93057,8 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( } } if( idx>=p->nScan ) return 1; + assert( pScan==0 || pScan==&p->aScan[idx] ); + pScan = &p->aScan[idx]; switch( iScanStatusOp ){ case SQLITE_SCANSTAT_NLOOP: { @@ -92242,6 +93399,104 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ +/* +** High-resolution hardware timer used for debugging and testing only. +*/ +#if defined(VDBE_PROFILE) \ + || defined(SQLITE_PERFORMANCE_TRACE) \ + || defined(SQLITE_ENABLE_STMT_SCANSTATUS) +/************** Include hwtime.h in the middle of vdbe.c *********************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains inline asm code for retrieving "high-performance" +** counters for x86 and x86_64 class CPUs. +*/ +#ifndef SQLITE_HWTIME_H +#define SQLITE_HWTIME_H + +/* +** The following routine only works on Pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if !defined(__STRICT_ANSI__) && \ + (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + /* + ** asm() is needed for hardware timing support. Without asm(), + ** disable the sqlite3Hwtime() routine. + ** + ** sqlite3Hwtime() is only used for some obscure debugging + ** and analysis configurations, not in any deliverable, so this + ** should not be a great loss. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(SQLITE_HWTIME_H) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in vdbe.c ***********************/ +#endif + /* ** Invoke this macro on memory cells just prior to changing the ** value of the cell. This macro verifies that shallow copies are @@ -93350,7 +94605,7 @@ case OP_Return: { /* in1 */ ** ** See also: EndCoroutine */ -case OP_InitCoroutine: { /* jump */ +case OP_InitCoroutine: { /* jump0 */ assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); assert( pOp->p2>=0 && pOp->p2<p->nOp ); assert( pOp->p3>=0 && pOp->p3<p->nOp ); @@ -93373,7 +94628,9 @@ case OP_InitCoroutine: { /* jump */ ** ** The instruction at the address in register P1 is a Yield. ** Jump to the P2 parameter of that Yield. -** After the jump, register P1 becomes undefined. +** After the jump, the value register P1 is left with a value +** such that subsequent OP_Yields go back to the this same +** OP_EndCoroutine instruction. ** ** See also: InitCoroutine */ @@ -93385,8 +94642,8 @@ case OP_EndCoroutine: { /* in1 */ pCaller = &aOp[pIn1->u.i]; assert( pCaller->opcode==OP_Yield ); assert( pCaller->p2>=0 && pCaller->p2<p->nOp ); + pIn1->u.i = (int)(pOp - p->aOp) - 1; pOp = &aOp[pCaller->p2 - 1]; - pIn1->flags = MEM_Undefined; break; } @@ -93403,7 +94660,7 @@ case OP_EndCoroutine: { /* in1 */ ** ** See also: InitCoroutine */ -case OP_Yield: { /* in1, jump */ +case OP_Yield: { /* in1, jump0 */ int pcDest; pIn1 = &aMem[pOp->p1]; assert( VdbeMemDynamic(pIn1)==0 ); @@ -93433,7 +94690,7 @@ case OP_HaltIfNull: { /* in3 */ /* no break */ deliberate_fall_through } -/* Opcode: Halt P1 P2 * P4 P5 +/* Opcode: Halt P1 P2 P3 P4 P5 ** ** Exit immediately. All open cursors, etc are closed ** automatically. @@ -93446,18 +94703,22 @@ case OP_HaltIfNull: { /* in3 */ ** then back out all changes that have occurred during this execution of the ** VDBE, but do not rollback the transaction. ** -** If P4 is not null then it is an error message string. +** If P3 is not zero and P4 is NULL, then P3 is a register that holds the +** text of an error message. ** -** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. +** If P3 is zero and P4 is not null then the error message string is held +** in P4. +** +** P5 is a value between 1 and 4, inclusive, then the P4 error message +** string is modified as follows: ** -** 0: (no change) ** 1: NOT NULL constraint failed: P4 ** 2: UNIQUE constraint failed: P4 ** 3: CHECK constraint failed: P4 ** 4: FOREIGN KEY constraint failed: P4 ** -** If P5 is not zero and P4 is NULL, then everything after the ":" is -** omitted. +** If P3 is zero and P5 is not zero and P4 is NULL, then everything after +** the ":" is omitted. ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program @@ -93470,6 +94731,9 @@ case OP_Halt: { #ifdef SQLITE_DEBUG if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif + assert( pOp->p4type==P4_NOTUSED + || pOp->p4type==P4_STATIC + || pOp->p4type==P4_DYNAMIC ); /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates ** something is wrong with the code generator. Raise an assertion in order @@ -93500,7 +94764,12 @@ case OP_Halt: { p->errorAction = (u8)pOp->p2; assert( pOp->p5<=4 ); if( p->rc ){ - if( pOp->p5 ){ + if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){ + const char *zErr; + assert( pOp->p3<=(p->nMem + 1 - p->nCursor) ); + zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8); + sqlite3VdbeError(p, "%s", zErr); + }else if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", "FOREIGN KEY" }; testcase( pOp->p5==1 ); @@ -93733,19 +95002,15 @@ case OP_Blob: { /* out2 */ break; } -/* Opcode: Variable P1 P2 * P4 * -** Synopsis: r[P2]=parameter(P1,P4) +/* Opcode: Variable P1 P2 * * * +** Synopsis: r[P2]=parameter(P1) ** ** Transfer the values of bound parameter P1 into register P2 -** -** If the parameter is named, then its name appears in P4. -** The P4 value is used by sqlite3_bind_parameter_name(). */ case OP_Variable: { /* out2 */ Mem *pVar; /* Value being transferred */ assert( pOp->p1>0 && pOp->p1<=p->nVar ); - assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) ); pVar = &p->aVar[pOp->p1 - 1]; if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; @@ -94255,7 +95520,7 @@ case OP_AddImm: { /* in1 */ pIn1 = &aMem[pOp->p1]; memAboutToChange(p, pIn1); sqlite3VdbeMemIntegerify(pIn1); - pIn1->u.i += pOp->p2; + *(u64*)&pIn1->u.i += (u64)pOp->p2; break; } @@ -94266,7 +95531,7 @@ case OP_AddImm: { /* in1 */ ** without data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. */ -case OP_MustBeInt: { /* jump, in1 */ +case OP_MustBeInt: { /* jump0, in1 */ pIn1 = &aMem[pOp->p1]; if( (pIn1->flags & MEM_Int)==0 ){ applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); @@ -94307,7 +95572,7 @@ case OP_RealAffinity: { /* in1 */ } #endif -#ifndef SQLITE_OMIT_CAST +#if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE) /* Opcode: Cast P1 P2 * * * ** Synopsis: affinity(r[P1]) ** @@ -94522,7 +95787,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ } } }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ - if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ + if( (flags1 & MEM_Str)!=0 ){ + pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + }else if( (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_Real ); testcase( pIn1->flags & MEM_IntReal ); @@ -94531,7 +95798,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; } - if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ + if( (flags3 & MEM_Str)!=0 ){ + pIn3->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + }else if( (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn3->flags & MEM_Int ); testcase( pIn3->flags & MEM_Real ); testcase( pIn3->flags & MEM_IntReal ); @@ -95875,11 +97144,16 @@ case OP_MakeRecord: { switch( len ){ default: zPayload[7] = (u8)(v&0xff); v >>= 8; zPayload[6] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; zPayload[4] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through case 1: zPayload[0] = (u8)(v&0xff); } zPayload += len; @@ -96538,23 +97812,23 @@ case OP_OpenWrite: if( pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = pDb->pSchema->file_format; } + if( pOp->p5 & OPFLAG_P2ISREG ){ + assert( p2>0 ); + assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); + pIn2 = &aMem[p2]; + assert( memIsValid(pIn2) ); + assert( (pIn2->flags & MEM_Int)!=0 ); + sqlite3VdbeMemIntegerify(pIn2); + p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateBtree opcode and + ** that opcode will always set the p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + assert( p2>=2 ); + } }else{ wrFlag = 0; - } - if( pOp->p5 & OPFLAG_P2ISREG ){ - assert( p2>0 ); - assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); - assert( pOp->opcode==OP_OpenWrite ); - pIn2 = &aMem[p2]; - assert( memIsValid(pIn2) ); - assert( (pIn2->flags & MEM_Int)!=0 ); - sqlite3VdbeMemIntegerify(pIn2); - p2 = (int)pIn2->u.i; - /* The p2 value always comes from a prior OP_CreateBtree opcode and - ** that opcode will always set the p2 value to 2 or more or else fail. - ** If there were a failure, the prepared statement would have halted - ** before reaching this instruction. */ - assert( p2>=2 ); + assert( (pOp->p5 & OPFLAG_P2ISREG)==0 ); } if( pOp->p4type==P4_KEYINFO ){ pKeyInfo = pOp->p4.pKeyInfo; @@ -96731,8 +98005,13 @@ case OP_OpenEphemeral: { /* ncycle */ } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + assert( p->apCsr[pOp->p1]==pCx ); if( rc ){ + assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); sqlite3BtreeClose(pCx->ub.pBtx); + p->apCsr[pOp->p1] = 0; /* Not required; helps with static analysis */ + }else{ + assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); } } } @@ -96798,7 +98077,8 @@ case OP_SequenceTest: { ** is the only cursor opcode that works with a pseudo-table. ** ** P3 is the number of fields in the records that will be stored by -** the pseudo-table. +** the pseudo-table. If P2 is 0 or negative then the pseudo-cursor +** will return NULL for every column. */ case OP_OpenPseudo: { VdbeCursor *pCx; @@ -96941,10 +98221,10 @@ case OP_ColumnsUsed: { ** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt */ -case OP_SeekLT: /* jump, in3, group, ncycle */ -case OP_SeekLE: /* jump, in3, group, ncycle */ -case OP_SeekGE: /* jump, in3, group, ncycle */ -case OP_SeekGT: { /* jump, in3, group, ncycle */ +case OP_SeekLT: /* jump0, in3, group, ncycle */ +case OP_SeekLE: /* jump0, in3, group, ncycle */ +case OP_SeekGE: /* jump0, in3, group, ncycle */ +case OP_SeekGT: { /* jump0, in3, group, ncycle */ int res; /* Comparison result */ int oc; /* Opcode */ VdbeCursor *pC; /* The cursor to seek */ @@ -97509,6 +98789,7 @@ case OP_Found: { /* jump, in3, ncycle */ r.pKeyInfo = pC->pKeyInfo; r.default_rc = 0; #ifdef SQLITE_DEBUG + (void)sqlite3FaultSim(50); /* For use by --counter in TH3 */ for(ii=0; ii<r.nField; ii++){ assert( memIsValid(&r.aMem[ii]) ); assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 ); @@ -97611,7 +98892,7 @@ case OP_Found: { /* jump, in3, ncycle */ ** ** See also: Found, NotFound, NoConflict, SeekRowid */ -case OP_SeekRowid: { /* jump, in3, ncycle */ +case OP_SeekRowid: { /* jump0, in3, ncycle */ VdbeCursor *pC; BtCursor *pCrsr; int res; @@ -98370,7 +99651,7 @@ case OP_NullRow: { ** configured to use Prev, not Next. */ case OP_SeekEnd: /* ncycle */ -case OP_Last: { /* jump, ncycle */ +case OP_Last: { /* jump0, ncycle */ VdbeCursor *pC; BtCursor *pCrsr; int res; @@ -98404,28 +99685,38 @@ case OP_Last: { /* jump, ncycle */ break; } -/* Opcode: IfSmaller P1 P2 P3 * * +/* Opcode: IfSizeBetween P1 P2 P3 P4 * ** -** Estimate the number of rows in the table P1. Jump to P2 if that -** estimate is less than approximately 2**(0.1*P3). +** Let N be the approximate number of rows in the table or index +** with cursor P1 and let X be 10*log2(N) if N is positive or -1 +** if N is zero. +** +** Jump to P2 if X is in between P3 and P4, inclusive. */ -case OP_IfSmaller: { /* jump */ +case OP_IfSizeBetween: { /* jump */ VdbeCursor *pC; BtCursor *pCrsr; int res; i64 sz; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + assert( pOp->p4type==P4_INT32 ); + assert( pOp->p3>=-1 && pOp->p3<=640*2 ); + assert( pOp->p4.i>=-1 && pOp->p4.i<=640*2 ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->uc.pCursor; assert( pCrsr ); rc = sqlite3BtreeFirst(pCrsr, &res); if( rc ) goto abort_due_to_error; - if( res==0 ){ + if( res!=0 ){ + sz = -1; /* -Infinity encoding */ + }else{ sz = sqlite3BtreeRowCountEst(pCrsr); - if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1; + assert( sz>0 ); + sz = sqlite3LogEst((u64)sz); } + res = sz>=pOp->p3 && sz<=pOp->p4.i; VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; break; @@ -98478,7 +99769,7 @@ case OP_Sort: { /* jump ncycle */ ** from the beginning toward the end. In other words, the cursor is ** configured to use Next, not Prev. */ -case OP_Rewind: { /* jump, ncycle */ +case OP_Rewind: { /* jump0, ncycle */ VdbeCursor *pC; BtCursor *pCrsr; int res; @@ -99125,11 +100416,18 @@ case OP_CreateBtree: { /* out2 */ break; } -/* Opcode: SqlExec * * * P4 * +/* Opcode: SqlExec P1 P2 * P4 * ** ** Run the SQL statement or statements specified in the P4 string. -** Disable Auth and Trace callbacks while those statements are running if -** P1 is true. +** +** The P1 parameter is a bitmask of options: +** +** 0x0001 Disable Auth and Trace callbacks while the statements +** in P4 are running. +** +** 0x0002 Set db->nAnalysisLimit to P2 while the statements in +** P4 are running. +** */ case OP_SqlExec: { char *zErr; @@ -99137,6 +100435,7 @@ case OP_SqlExec: { sqlite3_xauth xAuth; #endif u8 mTrace; + int savedAnalysisLimit; sqlite3VdbeIncrWriteCounter(p, 0); db->nSqlExec++; @@ -99145,18 +100444,23 @@ case OP_SqlExec: { xAuth = db->xAuth; #endif mTrace = db->mTrace; - if( pOp->p1 ){ + savedAnalysisLimit = db->nAnalysisLimit; + if( pOp->p1 & 0x0001 ){ #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = 0; #endif db->mTrace = 0; } + if( pOp->p1 & 0x0002 ){ + db->nAnalysisLimit = pOp->p2; + } rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); db->nSqlExec--; #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; #endif db->mTrace = mTrace; + db->nAnalysisLimit = savedAnalysisLimit; if( zErr || rc ){ sqlite3VdbeError(p, "%s", zErr); sqlite3_free(zErr); @@ -99308,11 +100612,11 @@ case OP_DropTrigger: { /* Opcode: IntegrityCk P1 P2 P3 P4 P5 ** ** Do an analysis of the currently open database. Store in -** register P1 the text of an error message describing any problems. -** If no problems are found, store a NULL in register P1. +** register (P1+1) the text of an error message describing any problems. +** If no problems are found, store a NULL in register (P1+1). ** -** The register P3 contains one less than the maximum number of allowed errors. -** At most reg(P3) errors will be reported. +** The register (P1) contains one less than the maximum number of allowed +** errors. At most reg(P1) errors will be reported. ** In other words, the analysis stops as soon as reg(P1) errors are ** seen. Reg(P1) is updated with the number of errors remaining. ** @@ -99332,19 +100636,21 @@ case OP_IntegrityCk: { Mem *pnErr; /* Register keeping track of errors remaining */ assert( p->bIsReader ); + assert( pOp->p4type==P4_INTARRAY ); nRoot = pOp->p2; aRoot = pOp->p4.ai; assert( nRoot>0 ); + assert( aRoot!=0 ); assert( aRoot[0]==(Pgno)nRoot ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - pnErr = &aMem[pOp->p3]; + assert( pOp->p1>0 && (pOp->p1+1)<=(p->nMem+1 - p->nCursor) ); + pnErr = &aMem[pOp->p1]; assert( (pnErr->flags & MEM_Int)!=0 ); assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); - pIn1 = &aMem[pOp->p1]; + pIn1 = &aMem[pOp->p1+1]; assert( pOp->p5<db->nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); - rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, - (int)pnErr->u.i+1, &nErr, &z); + rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], + &aMem[pOp->p3], nRoot, (int)pnErr->u.i+1, &nErr, &z); sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); @@ -99471,7 +100777,9 @@ case OP_RowSetTest: { /* jump, in1, in3 */ ** P1 contains the address of the memory cell that contains the first memory ** cell in an array of values used as arguments to the sub-program. P2 ** contains the address to jump to if the sub-program throws an IGNORE -** exception using the RAISE() function. Register P3 contains the address +** exception using the RAISE() function. P2 might be zero, if there is +** no possibility that an IGNORE exception will be raised. +** Register P3 contains the address ** of a memory cell in this (the parent) VM that is used to allocate the ** memory required by the sub-vdbe at runtime. ** @@ -99479,7 +100787,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ ** ** If P5 is non-zero, then recursive program invocation is enabled. */ -case OP_Program: { /* jump */ +case OP_Program: { /* jump0 */ int nMem; /* Number of memory registers for sub-program */ int nByte; /* Bytes of runtime space required for sub-program */ Mem *pRt; /* Register to allocate runtime space */ @@ -99844,18 +101152,29 @@ case OP_AggInverse: case OP_AggStep: { int n; sqlite3_context *pCtx; + u64 nAlloc; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + - (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); + + /* Allocate space for (a) the context object and (n-1) extra pointers + ** to append to the sqlite3_context.argv[1] array, and (b) a memory + ** cell in which to store the accumulation. Be careful that the memory + ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. + ** + ** Note: We could avoid this by using a regular memory cell from aMem[] for + ** the accumulator, instead of allocating one here. */ + nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); + pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); if( pCtx==0 ) goto no_mem; - pCtx->pMem = 0; - pCtx->pOut = (Mem*)&(pCtx->argv[n]); + pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); + assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); + pCtx->pMem = 0; pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; @@ -100401,9 +101720,10 @@ case OP_VCheck: { /* out2 */ pOut = &aMem[pOp->p2]; sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ - assert( pOp->p4type==P4_TABLE ); + assert( pOp->p4type==P4_TABLEREF ); pTab = pOp->p4.pTab; assert( pTab!=0 ); + assert( pTab->nTabRef>0 ); assert( IsVirtual(pTab) ); if( pTab->u.vtab.p==0 ) break; pVtab = pTab->u.vtab.p->pVtab; @@ -100412,13 +101732,11 @@ case OP_VCheck: { /* out2 */ assert( pModule!=0 ); assert( pModule->iVersion>=4 ); assert( pModule->xIntegrity!=0 ); - pTab->nTabRef++; sqlite3VtabLock(pTab->u.vtab.p); assert( pOp->p1>=0 && pOp->p1<db->nDb ); rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, pOp->p3, &zErr); sqlite3VtabUnlock(pTab->u.vtab.p); - sqlite3DeleteTable(db, pTab); if( rc ){ sqlite3_free(zErr); goto abort_due_to_error; @@ -100543,6 +101861,7 @@ case OP_VColumn: { /* ncycle */ const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; + FuncDef nullFunc; VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur!=0 ); @@ -100560,6 +101879,9 @@ case OP_VColumn: { /* ncycle */ memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; sContext.enc = encoding; + nullFunc.pUserData = 0; + nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE; + sContext.pFunc = &nullFunc; assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); if( pOp->p5 & OPFLAG_NOCHNG ){ sqlite3VdbeMemSetNull(pDest); @@ -100892,6 +102214,42 @@ case OP_ClrSubtype: { /* in1 */ break; } +/* Opcode: GetSubtype P1 P2 * * * +** Synopsis: r[P2] = r[P1].subtype +** +** Extract the subtype value from register P1 and write that subtype +** into register P2. If P1 has no subtype, then P1 gets a NULL. +*/ +case OP_GetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Subtype ){ + sqlite3VdbeMemSetInt64(pOut, pIn1->eSubtype); + }else{ + sqlite3VdbeMemSetNull(pOut); + } + break; +} + +/* Opcode: SetSubtype P1 P2 * * * +** Synopsis: r[P2].subtype = r[P1] +** +** Set the subtype value of register P2 to the integer from register P1. +** If P1 is NULL, clear the subtype from p2. +*/ +case OP_SetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Null ){ + pOut->flags &= ~MEM_Subtype; + }else{ + assert( pIn1->flags & MEM_Int ); + pOut->flags |= MEM_Subtype; + pOut->eSubtype = (u8)(pIn1->u.i & 0xff); + } + break; +} + /* Opcode: FilterAdd P1 * P3 P4 * ** Synopsis: filter(P1) += key(P3@P4) ** @@ -100989,7 +102347,7 @@ case OP_Filter: { /* jump */ ** error is encountered. */ case OP_Trace: -case OP_Init: { /* jump */ +case OP_Init: { /* jump0 */ int i; #ifndef SQLITE_OMIT_TRACE char *zTrace; @@ -101150,14 +102508,29 @@ case OP_ReleaseReg: { /* Opcode: Noop * * * * * ** -** Do nothing. This instruction is often useful as a jump -** destination. +** Do nothing. Continue downward to the next opcode. */ -/* -** The magic Explain opcode are only inserted when explain==2 (which -** is to say when the EXPLAIN QUERY PLAN syntax is used.) -** This opcode records information from the optimizer. It is the -** the same as a no-op. This opcodesnever appears in a real VM program. +/* Opcode: Explain P1 P2 P3 P4 * +** +** This is the same as OP_Noop during normal query execution. The +** purpose of this opcode is to hold information about the query +** plan for the purpose of EXPLAIN QUERY PLAN output. +** +** The P4 value is human-readable text that describes the query plan +** element. Something like "SCAN t1" or "SEARCH t2 USING INDEX t2x1". +** +** The P1 value is the ID of the current element and P2 is the parent +** element for the case of nested query plan elements. If P2 is zero +** then this element is a top-level element. +** +** For loop elements, P3 is the estimated code of each invocation of this +** element. +** +** As with all opcodes, the meanings of the parameters for OP_Explain +** are subject to change from one release to the next. Applications +** should not attempt to interpret or use any of the information +** contained in the OP_Explain opcode. The information provided by this +** opcode is intended for testing and debugging use only. */ default: { /* This is really OP_Noop, OP_Explain */ assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); @@ -101484,6 +102857,11 @@ SQLITE_API int sqlite3_blob_open( pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); } + if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s", + zTable); + } #ifndef SQLITE_OMIT_VIEW if( pTab && IsView(pTab) ){ pTab = 0; @@ -102391,13 +103769,14 @@ static int vdbePmaReadBlob( while( nRem>0 ){ int rc; /* vdbePmaReadBlob() return code */ int nCopy; /* Number of bytes to copy */ - u8 *aNext; /* Pointer to buffer to copy data from */ + u8 *aNext = 0; /* Pointer to buffer to copy data from */ nCopy = nRem; if( nRem>p->nBuffer ) nCopy = p->nBuffer; rc = vdbePmaReadBlob(p, nCopy, &aNext); if( rc!=SQLITE_OK ) return rc; assert( aNext!=p->aAlloc ); + assert( aNext!=0 ); memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); nRem -= nCopy; } @@ -104890,10 +106269,10 @@ static int bytecodevtabColumn( #ifdef SQLITE_ENABLE_STMT_SCANSTATUS case 9: /* nexec */ - sqlite3_result_int(ctx, pOp->nExec); + sqlite3_result_int64(ctx, pOp->nExec); break; case 10: /* ncycle */ - sqlite3_result_int(ctx, pOp->nCycle); + sqlite3_result_int64(ctx, pOp->nCycle); break; #else case 9: /* nexec */ @@ -105667,7 +107046,9 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ pSrc = p->pSrc; if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ + if( pItem->fg.isSubquery + && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect) + ){ return WRC_Abort; } if( pItem->fg.isTabFunc @@ -105837,6 +107218,8 @@ static void resolveAlias( assert( iCol>=0 && iCol<pEList->nExpr ); pOrig = pEList->a[iCol].pExpr; assert( pOrig!=0 ); + assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); + if( pExpr->pAggInfo ) return; db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( db->mallocFailed ){ @@ -105940,6 +107323,7 @@ SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){ assert( ExprUseYTab(pExpr) ); pExTab = pExpr->y.pTab; assert( pExTab!=0 ); + assert( n < pExTab->nCol ); if( (pExTab->tabFlags & TF_HasGenerated)!=0 && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 ){ @@ -105970,7 +107354,7 @@ static void extendFJMatch( if( pNew ){ pNew->iTable = pMatch->iCursor; pNew->iColumn = iColumn; - pNew->y.pTab = pMatch->pTab; + pNew->y.pTab = pMatch->pSTab; assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); ExprSetProperty(pNew, EP_CanBeNull); *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); @@ -105983,7 +107367,7 @@ static void extendFJMatch( static SQLITE_NOINLINE int isValidSchemaTableName( const char *zTab, /* Name as it appears in the SQL */ Table *pTab, /* The schema table we are trying to match */ - Schema *pSchema /* non-NULL if a database qualifier is present */ + const char *zDb /* non-NULL if a database qualifier is present */ ){ const char *zLegacy; assert( pTab!=0 ); @@ -105994,7 +107378,7 @@ static SQLITE_NOINLINE int isValidSchemaTableName( if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ return 1; } - if( pSchema==0 ) return 0; + if( zDb==0 ) return 0; if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; }else{ @@ -106034,7 +107418,7 @@ static int lookupName( Parse *pParse, /* The parsing context */ const char *zDb, /* Name of the database containing table, or NULL */ const char *zTab, /* Name of table containing column, or NULL */ - const char *zCol, /* Name of the column. */ + const Expr *pRight, /* Name of the column. */ NameContext *pNC, /* The name context used to resolve the name */ Expr *pExpr /* Make this EXPR node point to the selected column */ ){ @@ -106051,6 +107435,7 @@ static int lookupName( Table *pTab = 0; /* Table holding the row */ Column *pCol; /* A column of pTab */ ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ + const char *zCol = pRight->u.zToken; assert( pNC ); /* the name context cannot be NULL. */ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ @@ -106100,10 +107485,10 @@ static int lookupName( if( pSrcList ){ for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ u8 hCol; - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem)); if( pItem->fg.isNestedFrom ){ /* In this case, pItem is a subquery that has been formed from a ** parenthesized subset of the FROM clause terms. Example: @@ -106112,8 +107497,12 @@ static int lookupName( ** This pItem -------------^ */ int hit = 0; - assert( pItem->pSelect!=0 ); - pEList = pItem->pSelect->pEList; + Select *pSel; + assert( pItem->fg.isSubquery ); + assert( pItem->u4.pSubq!=0 ); + pSel = pItem->u4.pSubq->pSelect; + assert( pSel!=0 ); + pEList = pSel->pEList; assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; j<pEList->nExpr; j++){ @@ -106176,7 +107565,7 @@ static int lookupName( } }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ if( pTab->tnum!=1 ) continue; - if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue; + if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue; } assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT && pItem->zAlias ){ @@ -106223,14 +107612,43 @@ static int lookupName( } } if( 0==cnt && VisibleRowid(pTab) ){ + /* pTab is a potential ROWID match. Keep track of it and match + ** the ROWID later if that seems appropriate. (Search for "cntTab" + ** to find related code.) Only allow a ROWID match if there is + ** a single ROWID match candidate. + */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + /* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match + ** if there is a single VIEW candidate or if there is a single + ** non-VIEW candidate plus multiple VIEW candidates. In other + ** words non-VIEW candidate terms take precedence over VIEWs. + */ + if( cntTab==0 + || (cntTab==1 + && pMatch!=0 + && ALWAYS(pMatch->pSTab!=0) + && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0 + && (pTab->tabFlags & TF_Ephemeral)==0) + ){ + cntTab = 1; + pMatch = pItem; + }else{ + cntTab++; + } +#else + /* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is + ** simpler since we require exactly one candidate, which will + ** always be a non-VIEW + */ cntTab++; pMatch = pItem; +#endif } } if( pMatch ){ pExpr->iTable = pMatch->iCursor; assert( ExprUseYTab(pExpr) ); - pExpr->y.pTab = pMatch->pTab; + pExpr->y.pTab = pMatch->pSTab; if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } @@ -106253,7 +107671,8 @@ static int lookupName( if( pParse->bReturning ){ if( (pNC->ncFlags & NC_UBaseReg)!=0 && ALWAYS(zTab==0 - || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) + || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0 + || isValidSchemaTableName(zTab, pParse->pTriggerTab, 0)) ){ pExpr->iTable = op!=TK_DELETE; pTab = pParse->pTriggerTab; @@ -106271,7 +107690,7 @@ static int lookupName( if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ - pTab = pUpsert->pUpsertSrc->a[0].pTab; + pTab = pUpsert->pUpsertSrc->a[0].pSTab; pExpr->iTable = EXCLUDED_TABLE_NUMBER; } } @@ -106350,13 +107769,18 @@ static int lookupName( ** Perhaps the name is a reference to the ROWID */ if( cnt==0 - && cntTab==1 + && cntTab>=1 && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) + && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom) ){ - cnt = 1; + cnt = cntTab; +#if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 + if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){ + eNewExprOp = TK_NULL; + } +#endif if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } @@ -106510,12 +107934,17 @@ static int lookupName( sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); }else if( zTab ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); + }else if( cnt==0 && ExprHasProperty(pRight,EP_DblQuoted) ){ + sqlite3ErrorMsg(pParse, "%s: \"%s\" - should this be a" + " string literal in single-quotes?", + zErr, zCol); }else{ sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); } sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); pParse->checkSchema = 1; pTopNC->nNcErr++; + eNewExprOp = TK_NULL; } assert( pFJMatch==0 ); @@ -106542,8 +107971,12 @@ static int lookupName( ** If a generated column is referenced, set bits for every column ** of the table. */ - if( pExpr->iColumn>=0 && pMatch!=0 ){ - pMatch->colUsed |= sqlite3ExprColUsed(pExpr); + if( pMatch ){ + if( pExpr->iColumn>=0 ){ + pMatch->colUsed |= sqlite3ExprColUsed(pExpr); + }else{ + pMatch->fg.rowidUsed = 1; + } } pExpr->op = eNewExprOp; @@ -106581,7 +108014,7 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab; assert( ExprUseYTab(p) ); - pTab = p->y.pTab = pItem->pTab; + pTab = p->y.pTab = pItem->pSTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; @@ -106700,7 +108133,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pItem = pSrcList->a; pExpr->op = TK_COLUMN; assert( ExprUseYTab(pExpr) ); - pExpr->y.pTab = pItem->pTab; + pExpr->y.pTab = pItem->pSTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn--; pExpr->affExpr = SQLITE_AFF_INTEGER; @@ -106720,6 +108153,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** resolved. This prevents "column" from being counted as having been ** referenced, which might prevent a SELECT from being erroneously ** marked as correlated. + ** + ** 2024-03-28: Beware of aggregates. A bare column of aggregated table + ** can still evaluate to NULL even though it is marked as NOT NULL. + ** Example: + ** + ** CREATE TABLE t1(a INT NOT NULL); + ** SELECT a, a IS NULL, a IS NOT NULL, count(*) FROM t1; + ** + ** The "a IS NULL" and "a IS NOT NULL" expressions cannot be optimized + ** here because at the time this case is hit, we do not yet know whether + ** or not t1 is being aggregated. We have to assume the worst and omit + ** the optimization. The only time it is safe to apply this optimization + ** is within the WHERE clause. */ case TK_NOTNULL: case TK_ISNULL: { @@ -106730,19 +108176,36 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ anRef[i] = p->nRef; } sqlite3WalkExpr(pWalker, pExpr->pLeft); - if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ - testcase( ExprHasProperty(pExpr, EP_OuterON) ); - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - pExpr->u.iValue = (pExpr->op==TK_NOTNULL); - pExpr->flags |= EP_IntValue; - pExpr->op = TK_INTEGER; + if( IN_RENAME_OBJECT ) return WRC_Prune; + if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ + /* The expression can be NULL. So the optimization does not apply */ + return WRC_Prune; + } - for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){ - p->nRef = anRef[i]; + for(i=0, p=pNC; p; p=p->pNext, i++){ + if( (p->ncFlags & NC_Where)==0 ){ + return WRC_Prune; /* Not in a WHERE clause. Unsafe to optimize. */ } - sqlite3ExprDelete(pParse->db, pExpr->pLeft); - pExpr->pLeft = 0; } + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x80000 ){ + sqlite3DebugPrintf( + "NOT NULL strength reduction converts the following to %d:\n", + pExpr->op==TK_NOTNULL + ); + sqlite3ShowExpr(pExpr); + } +#endif /* TREETRACE_ENABLED */ + pExpr->u.iValue = (pExpr->op==TK_NOTNULL); + pExpr->flags |= EP_IntValue; + pExpr->op = TK_INTEGER; + for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){ + p->nRef = anRef[i]; + } + sqlite3ExprDelete(pParse->db, pExpr->pLeft); + pExpr->pLeft = 0; return WRC_Prune; } @@ -106756,7 +108219,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ */ case TK_ID: case TK_DOT: { - const char *zColumn; const char *zTable; const char *zDb; Expr *pRight; @@ -106765,7 +108227,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ zDb = 0; zTable = 0; assert( !ExprHasProperty(pExpr, EP_IntValue) ); - zColumn = pExpr->u.zToken; + pRight = pExpr; }else{ Expr *pLeft = pExpr->pLeft; testcase( pNC->ncFlags & NC_IdxExpr ); @@ -106784,21 +108246,20 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) ); zTable = pLeft->u.zToken; - zColumn = pRight->u.zToken; assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); } } - return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); + return lookupName(pParse, zDb, zTable, pRight, pNC, pExpr); } /* Resolve function names */ case TK_FUNCTION: { - ExprList *pList = pExpr->x.pList; /* The argument list */ - int n = pList ? pList->nExpr : 0; /* Number of arguments */ + ExprList *pList; /* The argument list */ + int n; /* Number of arguments */ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ @@ -106811,6 +108272,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); + pList = pExpr->x.pList; + n = pList ? pList->nExpr : 0; zId = pExpr->u.zToken; pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ @@ -106859,6 +108322,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } } #endif + + /* If the function may call sqlite3_value_subtype(), then set the + ** EP_SubtArg flag on all of its argument expressions. This prevents + ** where.c from replacing the expression with a value read from an + ** index on the same expression, which will not have the correct + ** subtype. Also set the flag if the function expression itself is + ** an EP_SubtArg expression. In this case subtypes are required as + ** the function may return a value with a subtype back to its + ** caller using sqlite3_result_value(). */ + if( (pDef->funcFlags & SQLITE_SUBTYPE) + || ExprHasProperty(pExpr, EP_SubtArg) + ){ + int ii; + for(ii=0; ii<n; ii++){ + ExprSetProperty(pList->a[ii].pExpr, EP_SubtArg); + } + } + if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ /* For the purposes of the EP_ConstFunc flag, date and time ** functions and other functions that change slowly are considered @@ -106967,11 +108448,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif } } -#ifndef SQLITE_OMIT_WINDOWFUNC - else if( ExprHasProperty(pExpr, EP_WinFunc) ){ + else if( ExprHasProperty(pExpr, EP_WinFunc) || pExpr->pLeft ){ is_agg = 1; } -#endif sqlite3WalkExprList(pWalker, pList); if( is_agg ){ if( pExpr->pLeft ){ @@ -106980,9 +108459,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); } #ifndef SQLITE_OMIT_WINDOWFUNC - if( pWin ){ + if( pWin && pParse->nErr==0 ){ Select *pSel = pNC->pWinSelect; - assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) ); + assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); if( pParse->db->mallocFailed ) break; @@ -107007,11 +108486,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ while( pNC2 && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 ){ - pExpr->op2++; + pExpr->op2 += (1 + pNC2->nNestedSelect); pNC2 = pNC2->pNext; } assert( pDef!=0 || IN_RENAME_OBJECT ); if( pNC2 && pDef ){ + pExpr->op2 += pNC2->nNestedSelect; assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); @@ -107040,6 +108520,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_PartIdx ); testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); + assert( pExpr->x.pSelect ); if( pNC->ncFlags & NC_SelfRef ){ notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); }else{ @@ -107048,6 +108529,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); + pExpr->x.pSelect->selFlags |= SF_Correlated; } pNC->ncFlags |= NC_Subquery; } @@ -107186,7 +108668,7 @@ static int resolveOrderByTermToExprList( int rc; /* Return code from subprocedures */ u8 savedSuppErr; /* Saved value of db->suppressErr */ - assert( sqlite3ExprIsInteger(pE, &i)==0 ); + assert( sqlite3ExprIsInteger(pE, &i, 0)==0 ); pEList = pSelect->pEList; /* Resolve all names in the ORDER BY term expression @@ -107285,7 +108767,7 @@ static int resolveCompoundOrderBy( if( pItem->fg.done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( NEVER(pE==0) ) continue; - if( sqlite3ExprIsInteger(pE, &iCol) ){ + if( sqlite3ExprIsInteger(pE, &iCol, 0) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); return 1; @@ -107470,7 +108952,7 @@ static int resolveOrderGroupBy( continue; } } - if( sqlite3ExprIsInteger(pE2, &iCol) ){ + if( sqlite3ExprIsInteger(pE2, &iCol, 0) ){ /* The ORDER BY term is an integer constant. Again, set the column ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ @@ -107561,7 +109043,11 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** moves the pOrderBy down to the sub-query. It will be moved back ** after the names have been resolved. */ if( p->selFlags & SF_Converted ){ - Select *pSub = p->pSrc->a[0].pSelect; + Select *pSub; + assert( p->pSrc->a[0].fg.isSubquery ); + assert( p->pSrc->a[0].u4.pSubq!=0 ); + pSub = p->pSrc->a[0].u4.pSubq->pSelect; + assert( pSub!=0 ); assert( p->pSrc->nSrc==1 && p->pOrderBy ); assert( pSub->pPrior && pSub->pOrderBy==0 ); pSub->pOrderBy = p->pOrderBy; @@ -107570,14 +109056,19 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Recursively resolve names in all subqueries in the FROM clause */ + if( pOuterNC ) pOuterNC->nNestedSelect++; for(i=0; i<p->pSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; - if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ + assert( pItem->zName!=0 + || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/ + if( pItem->fg.isSubquery + && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0 + ){ int nRef = pOuterNC ? pOuterNC->nRef : 0; const char *zSavedContext = pParse->zAuthContext; if( pItem->zName ) pParse->zAuthContext = pItem->zName; - sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); + sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; if( pParse->nErr ) return WRC_Abort; assert( db->mallocFailed==0 ); @@ -107594,6 +109085,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } } + if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){ + pOuterNC->nNestedSelect--; + } /* Set up the local name-context to pass to sqlite3ResolveExprNames() to ** resolve the result-set expression list. @@ -107637,7 +109131,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; } + sNC.ncFlags |= NC_Where; if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; + sNC.ncFlags &= ~NC_Where; /* Resolve names in table-valued-function arguments */ for(i=0; i<p->pSrc->nSrc; i++){ @@ -107674,7 +109170,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** These integers will be replaced by copies of the corresponding result ** set expressions by the call to resolveOrderGroupBy() below. */ if( p->selFlags & SF_Converted ){ - Select *pSub = p->pSrc->a[0].pSelect; + Select *pSub; + assert( p->pSrc->a[0].fg.isSubquery ); + pSub = p->pSrc->a[0].u4.pSubq->pSelect; + assert( pSub!=0 ); p->pOrderBy = pSub->pOrderBy; pSub->pOrderBy = 0; } @@ -107828,6 +109327,9 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames( ** Resolve all names for all expression in an expression list. This is ** just like sqlite3ResolveExprNames() except that it works for an expression ** list rather than a single expression. +** +** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a +** failure. */ SQLITE_PRIVATE int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ @@ -107836,7 +109338,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( int i; int savedHasAgg = 0; Walker w; - if( pList==0 ) return WRC_Continue; + if( pList==0 ) return SQLITE_OK; w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; @@ -107850,7 +109352,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight += pExpr->nHeight; if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ - return WRC_Abort; + return SQLITE_ERROR; } #endif sqlite3WalkExprNN(&w, pExpr); @@ -107867,10 +109369,10 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); } - if( w.pParse->nErr>0 ) return WRC_Abort; + if( w.pParse->nErr>0 ) return SQLITE_ERROR; } pNC->ncFlags |= savedHasAgg; - return WRC_Continue; + return SQLITE_OK; } /* @@ -107938,7 +109440,7 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference( if( pTab ){ sSrc.nSrc = 1; sSrc.a[0].zName = pTab->zName; - sSrc.a[0].pTab = pTab; + sSrc.a[0].pSTab = pTab; sSrc.a[0].iCursor = -1; if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP @@ -108043,7 +109545,9 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ op = pExpr->op; continue; } - if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; + if( op!=TK_REGISTER ) break; + op = pExpr->op2; + if( NEVER( op==TK_REGISTER ) ) break; } return pExpr->affExpr; } @@ -108176,9 +109680,10 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ assert( pExpr->x.pList->nExpr>0 ); assert( pExpr->op==TK_FUNCTION ); pExpr = pExpr->x.pList->a[0].pExpr; - }else{ - assert( pExpr->op==TK_COLLATE ); + }else if( pExpr->op==TK_COLLATE ){ pExpr = pExpr->pLeft; + }else{ + break; } } return pExpr; @@ -108434,7 +109939,7 @@ static int codeCompare( p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); - sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); + sqlite3VdbeChangeP5(pParse->pVdbe, (u16)p5); return addr; } @@ -108872,11 +110377,12 @@ SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ ** appear to be quoted. If the quotes were of the form "..." (double-quotes) ** then the EP_DblQuoted flag is set on the expression node. ** -** Special case: If op==TK_INTEGER and pToken points to a string that -** can be translated into a 32-bit integer, then the token is not -** stored in u.zToken. Instead, the integer values is written -** into u.iValue and the EP_IntValue flag is set. No extra storage +** Special case (tag-20240227-a): If op==TK_INTEGER and pToken points to +** a string that can be translated into a 32-bit integer, then the token is +** not stored in u.zToken. Instead, the integer values is written +** into u.iValue and the EP_IntValue flag is set. No extra storage ** is allocated to hold the integer text and the dequote flag is ignored. +** See also tag-20240227-b. */ SQLITE_PRIVATE Expr *sqlite3ExprAlloc( sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ @@ -108892,7 +110398,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc( if( pToken ){ if( op!=TK_INTEGER || pToken->z==0 || sqlite3GetInt32(pToken->z, &iValue)==0 ){ - nExtra = pToken->n+1; + nExtra = pToken->n+1; /* tag-20240227-a */ assert( iValue>=0 ); } } @@ -109181,9 +110687,7 @@ SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy( assert( ExprUseXList(pExpr) ); if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ /* Ignore ORDER BY on zero-argument aggregates */ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pOrderBy); return; } if( IsWindowFunc(pExpr) ){ @@ -109326,6 +110830,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); assert( db!=0 ); +exprDeleteRestart: assert( !ExprUseUValue(p) || p->u.iValue>=0 ); assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); @@ -109341,7 +110846,6 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 ); - if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); if( p->pRight ){ assert( !ExprHasProperty(p, EP_WinFunc) ); sqlite3ExprDeleteNN(db, p->pRight); @@ -109356,6 +110860,19 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ } #endif } + if( p->pLeft && p->op!=TK_SELECT_COLUMN ){ + Expr *pLeft = p->pLeft; + if( !ExprHasProperty(p, EP_Static) + && !ExprHasProperty(pLeft, EP_Static) + ){ + /* Avoid unnecessary recursion on unary operators */ + sqlite3DbNNFreeNN(db, p); + p = pLeft; + goto exprDeleteRestart; + }else{ + sqlite3ExprDeleteNN(db, pLeft); + } + } } if( !ExprHasProperty(p, EP_Static) ){ sqlite3DbNNFreeNN(db, p); @@ -109364,6 +110881,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) sqlite3ExprDeleteNN(db, (Expr*)p); +} /* ** Clear both elements of an OnOrUsing object @@ -109385,13 +110905,11 @@ SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ ** ** The pExpr might be deleted immediately on an OOM error. ** -** The deferred delete is (currently) implemented by adding the -** pExpr to the pParse->pConstExpr list with a register number of 0. +** Return 0 if the delete was successfully deferred. Return non-zero +** if the delete happened immediately because of an OOM. */ -SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprDelete, - pExpr); +SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ + return 0==sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr); } /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the @@ -109819,30 +111337,46 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla SrcItem *pNewItem = &pNew->a[i]; const SrcItem *pOldItem = &p->a[i]; Table *pTab; - pNewItem->pSchema = pOldItem->pSchema; - pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); + pNewItem->fg = pOldItem->fg; + if( pOldItem->fg.isSubquery ){ + Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery)); + if( pNewSubq==0 ){ + assert( db->mallocFailed ); + pNewItem->fg.isSubquery = 0; + }else{ + memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq)); + pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags); + if( pNewSubq->pSelect==0 ){ + sqlite3DbFree(db, pNewSubq); + pNewSubq = 0; + pNewItem->fg.isSubquery = 0; + } + } + pNewItem->u4.pSubq = pNewSubq; + }else if( pOldItem->fg.fixedSchema ){ + pNewItem->u4.pSchema = pOldItem->u4.pSchema; + }else{ + pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase); + } pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); - pNewItem->fg = pOldItem->fg; pNewItem->iCursor = pOldItem->iCursor; - pNewItem->addrFillSub = pOldItem->addrFillSub; - pNewItem->regReturn = pOldItem->regReturn; if( pNewItem->fg.isIndexedBy ){ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); + }else if( pNewItem->fg.isTabFunc ){ + pNewItem->u1.pFuncArg = + sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); + }else{ + pNewItem->u1.nRow = pOldItem->u1.nRow; } pNewItem->u2 = pOldItem->u2; if( pNewItem->fg.isCte ){ pNewItem->u2.pCteUse->nUse++; } - if( pNewItem->fg.isTabFunc ){ - pNewItem->u1.pFuncArg = - sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); - } - pTab = pNewItem->pTab = pOldItem->pTab; + pTab = pNewItem->pSTab = pOldItem->pSTab; if( pTab ){ pTab->nTabRef++; } - pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); if( pOldItem->fg.isUsing ){ assert( pNewItem->fg.isUsing ); pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); @@ -109916,7 +111450,6 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla pp = &pNew->pPrior; pNext = pNew; } - return pRet; } #else @@ -110197,6 +111730,9 @@ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ if( pList ) exprListDeleteNN(db, pList); } +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3 *db, void *pList){ + if( ALWAYS(pList) ) exprListDeleteNN(db, (ExprList*)pList); +} /* ** Return the bitwise-OR of all Expr.flags fields in the given @@ -110300,6 +111836,54 @@ SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ return pExpr; } +/* +** pExpr is a TK_FUNCTION node. Try to determine whether or not the +** function is a constant function. A function is constant if all of +** the following are true: +** +** (1) It is a scalar function (not an aggregate or window function) +** (2) It has either the SQLITE_FUNC_CONSTANT or SQLITE_FUNC_SLOCHNG +** property. +** (3) All of its arguments are constants +** +** This routine sets pWalker->eCode to 0 if pExpr is not a constant. +** It makes no changes to pWalker->eCode if pExpr is constant. In +** every case, it returns WRC_Abort. +** +** Called as a service subroutine from exprNodeIsConstant(). +*/ +static SQLITE_NOINLINE int exprNodeIsConstantFunction( + Walker *pWalker, + Expr *pExpr +){ + int n; /* Number of arguments */ + ExprList *pList; /* List of arguments */ + FuncDef *pDef; /* The function */ + sqlite3 *db; /* The database */ + + assert( pExpr->op==TK_FUNCTION ); + if( ExprHasProperty(pExpr, EP_TokenOnly) + || (pList = pExpr->x.pList)==0 + ){; + n = 0; + }else{ + n = pList->nExpr; + sqlite3WalkExprList(pWalker, pList); + if( pWalker->eCode==0 ) return WRC_Abort; + } + db = pWalker->pParse->db; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( pDef==0 + || pDef->xFinalize!=0 + || (pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 + || ExprHasProperty(pExpr, EP_WinFunc) + ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Prune; +} + /* ** These routines are Walker callbacks used to check expressions to @@ -110328,6 +111912,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ ** malformed schema error. */ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ + assert( pWalker->eCode>0 ); /* If pWalker->eCode is 2 then any term of the expression that comes from ** the ON or USING clauses of an outer join disqualifies the expression @@ -110347,6 +111932,8 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ ){ if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); return WRC_Continue; + }else if( pWalker->pParse ){ + return exprNodeIsConstantFunction(pWalker, pExpr); }else{ pWalker->eCode = 0; return WRC_Abort; @@ -110375,9 +111962,11 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ case TK_IF_NULL_ROW: case TK_REGISTER: case TK_DOT: + case TK_RAISE: testcase( pExpr->op==TK_REGISTER ); testcase( pExpr->op==TK_IF_NULL_ROW ); testcase( pExpr->op==TK_DOT ); + testcase( pExpr->op==TK_RAISE ); pWalker->eCode = 0; return WRC_Abort; case TK_VARIABLE: @@ -110399,15 +111988,15 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ return WRC_Continue; } } -static int exprIsConst(Expr *p, int initFlag, int iCur){ +static int exprIsConst(Parse *pParse, Expr *p, int initFlag){ Walker w; w.eCode = initFlag; + w.pParse = pParse; w.xExprCallback = exprNodeIsConstant; w.xSelectCallback = sqlite3SelectWalkFail; #ifdef SQLITE_DEBUG w.xSelectCallback2 = sqlite3SelectWalkAssert2; #endif - w.u.iCur = iCur; sqlite3WalkExpr(&w, p); return w.eCode; } @@ -110419,9 +112008,15 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){ ** For the purposes of this function, a double-quoted string (ex: "abc") ** is considered a variable but a single-quoted string (ex: 'abc') is ** a constant. +** +** The pParse parameter may be NULL. But if it is NULL, there is no way +** to determine if function calls are constant or not, and hence all +** function calls will be considered to be non-constant. If pParse is +** not NULL, then a function call might be constant, depending on the +** function and on its parameters. */ -SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ - return exprIsConst(p, 1, 0); +SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse *pParse, Expr *p){ + return exprIsConst(pParse, p, 1); } /* @@ -110437,8 +112032,24 @@ SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ ** can be added to the pParse->pConstExpr list and evaluated once when ** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce(). */ -SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ - return exprIsConst(p, 2, 0); +static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){ + return exprIsConst(pParse, p, 2); +} + +/* +** This routine examines sub-SELECT statements as an expression is being +** walked as part of sqlite3ExprIsTableConstant(). Sub-SELECTs are considered +** constant as long as they are uncorrelated - meaning that they do not +** contain any terms from outer contexts. +*/ +static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){ + assert( pSelect!=0 ); + assert( pWalker->eCode==3 || pWalker->eCode==0 ); + if( (pSelect->selFlags & SF_Correlated)!=0 ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Prune; } /* @@ -110446,9 +112057,26 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ ** for any single row of the table with cursor iCur. In other words, the ** expression must not refer to any non-deterministic function nor any ** table other than iCur. +** +** Consider uncorrelated subqueries to be constants if the bAllowSubq +** parameter is true. */ -SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ - return exprIsConst(p, 3, iCur); +static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){ + Walker w; + w.eCode = 3; + w.pParse = 0; + w.xExprCallback = exprNodeIsConstant; + if( bAllowSubq ){ + w.xSelectCallback = exprSelectWalkTableConstant; + }else{ + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + } + w.u.iCur = iCur; + sqlite3WalkExpr(&w, p); + return w.eCode; } /* @@ -110466,7 +112094,10 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ ** ** (1) pExpr cannot refer to any table other than pSrc->iCursor. ** -** (2) pExpr cannot use subqueries or non-deterministic functions. +** (2a) pExpr cannot use subqueries unless the bAllowSubq parameter is +** true and the subquery is non-correlated +** +** (2b) pExpr cannot use non-deterministic functions. ** ** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. ** (Is there some way to relax this constraint?) @@ -110475,7 +112106,7 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ ** (4a) pExpr must come from an ON clause.. ** (4b) and specifically the ON clause associated with the LEFT JOIN. ** -** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** (5) If pSrc is the right operand of a LEFT JOIN or the left ** operand of a RIGHT JOIN, then pExpr must be from the WHERE ** clause, not an ON clause. ** @@ -110495,7 +112126,8 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( Expr *pExpr, /* The constraint */ const SrcList *pSrcList, /* Complete FROM clause */ - int iSrc /* Which element of pSrcList to use */ + int iSrc, /* Which element of pSrcList to use */ + int bAllowSubq /* Allow non-correlated subqueries */ ){ const SrcItem *pSrc = &pSrcList->a[iSrc]; if( pSrc->fg.jointype & JT_LTORJ ){ @@ -110520,7 +112152,8 @@ SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( } } } - return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ + /* Rules (1), (2a), and (2b) handled by the following: */ + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor, bAllowSubq); } @@ -110605,7 +112238,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprLi */ SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ assert( isInit==0 || isInit==1 ); - return exprIsConst(p, 4+isInit, 0); + return exprIsConst(0, p, 4+isInit); } #ifdef SQLITE_ENABLE_CURSOR_HINTS @@ -110631,8 +112264,12 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. +** +** If the pParse pointer is provided, then allow the expression p to be +** a parameter (TK_VARIABLE) that is bound to an integer. +** But if pParse is NULL, then p must be a pure integer literal. */ -SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse){ int rc = 0; if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ @@ -110647,18 +112284,38 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ } switch( p->op ){ case TK_UPLUS: { - rc = sqlite3ExprIsInteger(p->pLeft, pValue); + rc = sqlite3ExprIsInteger(p->pLeft, pValue, 0); break; } case TK_UMINUS: { int v = 0; - if( sqlite3ExprIsInteger(p->pLeft, &v) ){ + if( sqlite3ExprIsInteger(p->pLeft, &v, 0) ){ assert( ((unsigned int)v)!=0x80000000 ); *pValue = -v; rc = 1; } break; } + case TK_VARIABLE: { + sqlite3_value *pVal; + if( pParse==0 ) break; + if( NEVER(pParse->pVdbe==0) ) break; + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) break; + sqlite3VdbeSetVarmask(pParse->pVdbe, p->iColumn); + pVal = sqlite3VdbeGetBoundValue(pParse->pReprepare, p->iColumn, + SQLITE_AFF_BLOB); + if( pVal ){ + if( sqlite3_value_type(pVal)==SQLITE_INTEGER ){ + sqlite3_int64 vv = sqlite3_value_int64(pVal); + if( vv == (vv & 0x7fffffff) ){ /* non-negative numbers only */ + *pValue = (int)vv; + rc = 1; + } + } + sqlite3ValueFree(pVal); + } + break; + } default: break; } return rc; @@ -110695,10 +112352,14 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ return 0; case TK_COLUMN: assert( ExprUseYTab(p) ); - return ExprHasProperty(p, EP_CanBeNull) || - p->y.pTab==0 || /* Reference to column of index on expression */ - (p->iColumn>=0 + return ExprHasProperty(p, EP_CanBeNull) + || NEVER(p->y.pTab==0) /* Reference to column of index on expr */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + || (p->iColumn==XN_ROWID && IsView(p->y.pTab)) +#endif + || (p->iColumn>=0 && p->y.pTab->aCol!=0 /* Possible due to prior error */ + && ALWAYS(p->iColumn<p->y.pTab->nCol) && p->y.pTab->aCol[p->iColumn].notNull==0); default: return 1; @@ -110808,8 +112469,8 @@ static Select *isCandidateForInOpt(const Expr *pX){ pSrc = p->pSrc; assert( pSrc!=0 ); if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ - if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ - pTab = pSrc->a[0].pTab; + if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */ + pTab = pSrc->a[0].pSTab; assert( pTab!=0 ); assert( !IsView(pTab) ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ @@ -110849,13 +112510,13 @@ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ ** The argument is an IN operator with a list (not a subquery) on the ** right-hand side. Return TRUE if that list is constant. */ -static int sqlite3InRhsIsConstant(Expr *pIn){ +static int sqlite3InRhsIsConstant(Parse *pParse, Expr *pIn){ Expr *pLHS; int res; assert( !ExprHasProperty(pIn, EP_xIsSelect) ); pLHS = pIn->pLeft; pIn->pLeft = 0; - res = sqlite3ExprIsConstant(pIn); + res = sqlite3ExprIsConstant(pParse, pIn); pIn->pLeft = pLHS; return res; } @@ -110992,7 +112653,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ - pTab = p->pSrc->a[0].pTab; + pTab = p->pSrc->a[0].pSTab; /* Code an OP_Transaction and OP_TableLock for <table>. */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -111084,6 +112745,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( if( aiMap ) aiMap[i] = j; } + assert( nExpr>0 && nExpr<BMS ); assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); if( colUsed==(MASKBIT(nExpr)-1) ){ /* If we reach this point, that means the index pIdx is usable */ @@ -111124,7 +112786,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( if( eType==0 && (inFlags & IN_INDEX_NOOP_OK) && ExprUseXList(pX) - && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) + && (!sqlite3InRhsIsConstant(pParse,pX) || pX->x.pList->nExpr<=2) ){ pParse->nTab--; /* Back out the allocation of the unused cursor */ iTab = -1; /* Cursor is not allocated */ @@ -111232,6 +112894,49 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ } } +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Scan all previously generated bytecode looking for an OP_BeginSubrtn +** that is compatible with pExpr. If found, add the y.sub values +** to pExpr and return true. If not found, return false. +*/ +static int findCompatibleInRhsSubrtn( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* IN operator with RHS that we want to reuse */ + SubrtnSig *pNewSig /* Signature for the IN operator */ +){ + VdbeOp *pOp, *pEnd; + SubrtnSig *pSig; + Vdbe *v; + + if( pNewSig==0 ) return 0; + if( (pParse->mSubrtnSig & (1<<(pNewSig->selId&7)))==0 ) return 0; + assert( pExpr->op==TK_IN ); + assert( !ExprUseYSub(pExpr) ); + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( (pExpr->x.pSelect->selFlags & SF_All)==0 ); + v = pParse->pVdbe; + assert( v!=0 ); + pOp = sqlite3VdbeGetOp(v, 1); + pEnd = sqlite3VdbeGetLastOp(v); + for(; pOp<pEnd; pOp++){ + if( pOp->p4type!=P4_SUBRTNSIG ) continue; + assert( pOp->opcode==OP_BeginSubrtn ); + pSig = pOp->p4.pSubrtnSig; + assert( pSig!=0 ); + if( pNewSig->selId!=pSig->selId ) continue; + if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; + pExpr->y.sub.iAddr = pSig->iAddr; + pExpr->y.sub.regReturn = pSig->regReturn; + pExpr->iTable = pSig->iTable; + ExprSetProperty(pExpr, EP_Subrtn); + return 1; + } + return 0; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code that will construct an ephemeral table containing all terms @@ -111281,11 +112986,28 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( ** and reuse it many names. */ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ - /* Reuse of the RHS is allowed */ - /* If this routine has already been coded, but the previous code - ** might not have been invoked yet, so invoke it now as a subroutine. + /* Reuse of the RHS is allowed + ** + ** Compute a signature for the RHS of the IN operator to facility + ** finding and reusing prior instances of the same IN operator. + */ + SubrtnSig *pSig = 0; + assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 ); + if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){ + pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0])); + if( pSig ){ + pSig->selId = pExpr->x.pSelect->selId; + pSig->zAff = exprINAffinity(pParse, pExpr); + } + } + + /* Check to see if there is a prior materialization of the RHS of + ** this IN operator. If there is, then make use of that prior + ** materialization rather than recomputing it. */ - if( ExprHasProperty(pExpr, EP_Subrtn) ){ + if( ExprHasProperty(pExpr, EP_Subrtn) + || findCompatibleInRhsSubrtn(pParse, pExpr, pSig) + ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); if( ExprUseXSelect(pExpr) ){ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", @@ -111297,6 +113019,10 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( assert( iTab!=pExpr->iTable ); sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); sqlite3VdbeJumpHere(v, addrOnce); + if( pSig ){ + sqlite3DbFree(pParse->db, pSig->zAff); + sqlite3DbFree(pParse->db, pSig); + } return; } @@ -111307,7 +113033,13 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; - + if( pSig ){ + pSig->iAddr = pExpr->y.sub.iAddr; + pSig->regReturn = pExpr->y.sub.regReturn; + pSig->iTable = iTab; + pParse->mSubrtnSig = 1 << (pSig->selId&7); + sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); + } addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } @@ -111348,15 +113080,30 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( SelectDest dest; int i; int rc; + int addrBloom = 0; sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; + if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ + int regBloom = ++pParse->nMem; + addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); + VdbeComment((v, "Bloom filter")); + dest.iSDParm2 = regBloom; + } testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); + if( addrBloom ){ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + if( dest.iSDParm2==0 ){ + sqlite3VdbeChangeToNoop(v, addrBloom); + }else{ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + } + } if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; @@ -111407,7 +113154,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ - if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ + if( addrOnce && !sqlite3ExprIsConstant(pParse, pE2) ){ sqlite3VdbeChangeToNoop(v, addrOnce-1); sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); @@ -111654,9 +113401,7 @@ static void sqlite3ExprCodeIN( if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); nVector = sqlite3ExprVectorSize(pExpr->pLeft); - aiMap = (int*)sqlite3DbMallocZero( - pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 - ); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, nVector*sizeof(int)); if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; /* Attempt to compute the RHS. After this step, if anything other than @@ -111799,6 +113544,15 @@ static void sqlite3ExprCodeIN( sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); + assert( pOp->opcode==OP_Once || pParse->nErr ); + if( pOp->opcode==OP_Once && pOp->p3>0 ){ + assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); + sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + } + } sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); goto sqlite3ExprCodeIN_finished; @@ -112081,13 +113835,17 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n ** register iReg. The caller must ensure that iReg already contains ** the correct value for the expression. */ -static void exprToRegister(Expr *pExpr, int iReg){ +SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg){ Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); if( NEVER(p==0) ) return; - p->op2 = p->op; - p->op = TK_REGISTER; - p->iTable = iReg; - ExprClearProperty(p, EP_Skip); + if( p->op==TK_REGISTER ){ + assert( p->iTable==iReg ); + }else{ + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iReg; + ExprClearProperty(p, EP_Skip); + } } /* @@ -112257,6 +114015,59 @@ static int exprCodeInlineFunction( return target; } +/* +** Expression Node callback for sqlite3ExprCanReturnSubtype(). +** +** Only a function call is able to return a subtype. So if the node +** is not a function call, return WRC_Prune immediately. +** +** A function call is able to return a subtype if it has the +** SQLITE_RESULT_SUBTYPE property. +** +** Assume that every function is able to pass-through a subtype from +** one of its argument (using sqlite3_result_value()). Most functions +** are not this way, but we don't have a mechanism to distinguish those +** that are from those that are not, so assume they all work this way. +** That means that if one of its arguments is another function and that +** other function is able to return a subtype, then this function is +** able to return a subtype. +*/ +static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ + int n; + FuncDef *pDef; + sqlite3 *db; + if( pExpr->op!=TK_FUNCTION ){ + return WRC_Prune; + } + assert( ExprUseXList(pExpr) ); + db = pWalker->pParse->db; + n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ + pWalker->eCode = 1; + return WRC_Prune; + } + return WRC_Continue; +} + +/* +** Return TRUE if expression pExpr is able to return a subtype. +** +** A TRUE return does not guarantee that a subtype will be returned. +** It only indicates that a subtype return is possible. False positives +** are acceptable as they only disable an optimization. False negatives, +** on the other hand, can lead to incorrect answers. +*/ +static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ + Walker w; + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = exprNodeCanReturnSubtype; + sqlite3WalkExpr(&w, pExpr); + return w.eCode; +} + + /* ** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. ** If it is, then resolve the expression by reading from the index and @@ -112289,6 +114100,17 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( continue; } + + /* Functions that might set a subtype should not be replaced by the + ** value taken from an expression index if they are themselves an + ** argument to another scalar function or aggregate. + ** https://sqlite.org/forum/forumpost/68d284c86b082c3e */ + if( ExprHasProperty(pExpr, EP_SubtArg) + && sqlite3ExprCanReturnSubtype(pParse, pExpr) + ){ + continue; + } + v = pParse->pVdbe; assert( v!=0 ); if( p->bMaybeNullRow ){ @@ -112571,12 +114393,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) assert( pExpr->u.zToken!=0 ); assert( pExpr->u.zToken[0]!=0 ); sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); - if( pExpr->u.zToken[1]!=0 ){ - const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); - assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) ); - pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */ - sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); - } return target; } case TK_REGISTER: { @@ -112750,7 +114566,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } #endif - if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ + if( ConstFactorOk(pParse) + && sqlite3ExprIsConstantNotJoin(pParse,pExpr) + ){ /* SQL functions can be expensive. So try to avoid running them ** multiple times if we know they always give the same result */ return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); @@ -112781,7 +114599,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } for(i=0; i<nFarg; i++){ - if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ + if( i<32 && sqlite3ExprIsConstant(pParse, pFarg->a[i].pExpr) ){ testcase( i==31 ); constMask |= MASKBIT32(i); } @@ -112923,8 +114741,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) if( !ExprHasProperty(pExpr, EP_Collate) ){ /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called ** "SOFT-COLLATE" that is added to constraints that are pushed down - ** from outer queries into sub-queries by the push-down optimization. - ** Clear subtypes as subtypes may not cross a subquery boundary. + ** from outer queries into sub-queries by the WHERE-clause push-down + ** optimization. Clear subtypes as subtypes may not cross a subquery + ** boundary. */ assert( pExpr->pLeft ); sqlite3ExprCode(pParse, pExpr->pLeft, target); @@ -113093,7 +114912,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) break; } testcase( pX->op==TK_COLUMN ); - exprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1)); + sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1)); testcase( regFree1==0 ); memset(&opCompare, 0, sizeof(opCompare)); opCompare.op = TK_EQ; @@ -113147,15 +114966,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->affExpr==OE_Ignore ){ - sqlite3VdbeAddOp4( - v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore); VdbeCoverage(v); }else{ - sqlite3HaltConstraint(pParse, + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1); + sqlite3VdbeAddOp3(v, OP_Halt, pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, - pExpr->affExpr, pExpr->u.zToken, 0, 0); + pExpr->affExpr, r1); } - break; } #endif @@ -113248,7 +115066,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ if( ConstFactorOk(pParse) && ALWAYS(pExpr!=0) && pExpr->op!=TK_REGISTER - && sqlite3ExprIsConstantNotJoin(pExpr) + && sqlite3ExprIsConstantNotJoin(pParse, pExpr) ){ *pReg = 0; r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); @@ -113280,8 +115098,10 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); if( inReg!=target ){ u8 op; - if( ALWAYS(pExpr) - && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER) + Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr); + testcase( pX!=pExpr ); + if( ALWAYS(pX) + && (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER) ){ op = OP_Copy; }else{ @@ -113310,7 +115130,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ ** might choose to code the expression at initialization time. */ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ - if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ + if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){ sqlite3ExprCodeRunJustOnce(pParse, pExpr, target); }else{ sqlite3ExprCodeCopy(pParse, pExpr, target); @@ -113369,7 +115189,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList( sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); } }else if( (flags & SQLITE_ECEL_FACTOR)!=0 - && sqlite3ExprIsConstantNotJoin(pExpr) + && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){ sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i); }else{ @@ -113442,7 +115262,7 @@ static void exprCodeBetween( compRight.op = TK_LE; compRight.pLeft = pDel; compRight.pRight = pExpr->x.pList->a[1].pExpr; - exprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1)); + sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, &regFree1)); if( xJump ){ xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ @@ -113821,16 +115641,23 @@ SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,i ** same as that currently bound to variable pVar, non-zero is returned. ** Otherwise, if the values are not the same or if pExpr is not a simple ** SQL value, zero is returned. +** +** If the SQLITE_EnableQPSG flag is set on the database connection, then +** this routine always returns false. */ -static int exprCompareVariable( +static SQLITE_NOINLINE int exprCompareVariable( const Parse *pParse, const Expr *pVar, const Expr *pExpr ){ - int res = 0; + int res = 2; int iVar; sqlite3_value *pL, *pR = 0; + if( pExpr->op==TK_VARIABLE && pVar->iColumn==pExpr->iColumn ){ + return 0; + } + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2; sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); if( pR ){ iVar = pVar->iColumn; @@ -113840,12 +115667,11 @@ static int exprCompareVariable( if( sqlite3_value_type(pL)==SQLITE_TEXT ){ sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */ } - res = 0==sqlite3MemCompare(pL, pR, 0); + res = sqlite3MemCompare(pL, pR, 0) ? 2 : 0; } sqlite3ValueFree(pR); sqlite3ValueFree(pL); } - return res; } @@ -113871,12 +115697,10 @@ static int exprCompareVariable( ** just might result in some slightly slower code. But returning ** an incorrect 0 or 1 could lead to a malfunction. ** -** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in -** pParse->pReprepare can be matched against literals in pB. The -** pParse->pVdbe->expmask bitmask is updated for each variable referenced. -** If pParse is NULL (the normal case) then any TK_VARIABLE term in -** Argument pParse should normally be NULL. If it is not NULL and pA or -** pB causes a return value of 2. +** If pParse is not NULL and SQLITE_EnableQPSG is off then TK_VARIABLE +** terms in pA with bindings in pParse->pReprepare can be matched against +** literals in pB. The pParse->pVdbe->expmask bitmask is updated for +** each variable referenced. */ SQLITE_PRIVATE int sqlite3ExprCompare( const Parse *pParse, @@ -113888,8 +115712,8 @@ SQLITE_PRIVATE int sqlite3ExprCompare( if( pA==0 || pB==0 ){ return pB==pA ? 0 : 2; } - if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){ - return 0; + if( pParse && pA->op==TK_VARIABLE ){ + return exprCompareVariable(pParse, pA, pB); } combinedFlags = pA->flags | pB->flags; if( combinedFlags & EP_IntValue ){ @@ -114084,18 +115908,70 @@ static int exprImpliesNotNull( return 0; } +/* +** Return true if the boolean value of the expression is always either +** FALSE or NULL. +*/ +static int sqlite3ExprIsNotTrue(Expr *pExpr){ + int v; + if( pExpr->op==TK_NULL ) return 1; + if( pExpr->op==TK_TRUEFALSE && sqlite3ExprTruthValue(pExpr)==0 ) return 1; + v = 1; + if( sqlite3ExprIsInteger(pExpr, &v, 0) && v==0 ) return 1; + return 0; +} + +/* +** Return true if the expression is one of the following: +** +** CASE WHEN x THEN y END +** CASE WHEN x THEN y ELSE NULL END +** CASE WHEN x THEN y ELSE false END +** iif(x,y) +** iif(x,y,NULL) +** iif(x,y,false) +*/ +static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){ + ExprList *pList; + if( pExpr->op==TK_FUNCTION ){ + const char *z = pExpr->u.zToken; + FuncDef *pDef; + if( (z[0]!='i' && z[0]!='I') ) return 0; + if( pExpr->x.pList==0 ) return 0; + pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 ) return 0; +#else + if( NEVER(pDef==0) ) return 0; +#endif + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0; + if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0; + }else if( pExpr->op==TK_CASE ){ + if( pExpr->pLeft!=0 ) return 0; + }else{ + return 0; + } + pList = pExpr->x.pList; + assert( pList!=0 ); + if( pList->nExpr==2 ) return 1; + if( pList->nExpr==3 && sqlite3ExprIsNotTrue(pList->a[2].pExpr) ) return 1; + return 0; +} + /* ** Return true if we can prove the pE2 will always be true if pE1 is ** true. Return false if we cannot complete the proof or if pE2 might ** be false. Examples: ** -** pE1: x==5 pE2: x==5 Result: true -** pE1: x>0 pE2: x==5 Result: false -** pE1: x=21 pE2: x=21 OR y=43 Result: true -** pE1: x!=123 pE2: x IS NOT NULL Result: true -** pE1: x!=?1 pE2: x IS NOT NULL Result: true -** pE1: x IS NULL pE2: x IS NOT NULL Result: false -** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: iif(x,y) pE2: x Result: true +** PE1: iif(x,y,0) pE2: x Result: true ** ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has ** Expr.iTable<0 then assume a table number given by iTab. @@ -114129,6 +116005,9 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr( ){ return 1; } + if( sqlite3ExprIsIIF(pParse->db, pE1) ){ + return sqlite3ExprImpliesExpr(pParse,pE1->x.pList->a[0].pExpr,pE2,iTab); + } return 0; } @@ -114520,9 +116399,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ && pAggInfo->aCol[iAgg].pCExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); - if( pExpr ){ + if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){ pAggInfo->aCol[iAgg].pCExpr = pExpr; - sqlite3ExprDeferredDelete(pParse, pExpr); } } }else{ @@ -114531,9 +116409,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ && pAggInfo->aFunc[iAgg].pFExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); - if( pExpr ){ + if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){ pAggInfo->aFunc[iAgg].pFExpr = pExpr; - sqlite3ExprDeferredDelete(pParse, pExpr); } } } @@ -114727,13 +116604,14 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ case TK_AGG_FUNCTION: { if( (pNC->ncFlags & NC_InAggFunc)==0 && pWalker->walkerDepth==pExpr->op2 + && pExpr->pAggInfo==0 ){ /* Check to see if pExpr is a duplicate of another aggregate ** function that is already in the pAggInfo structure */ struct AggInfo_func *pItem = pAggInfo->aFunc; for(i=0; i<pAggInfo->nFunc; i++, pItem++){ - if( pItem->pFExpr==pExpr ) break; + if( NEVER(pItem->pFExpr==pExpr) ) break; if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ break; } @@ -114776,6 +116654,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ }else{ pItem->bOBPayload = 1; } + pItem->bUseSubtype = + (pItem->pFunc->funcFlags & SQLITE_SUBTYPE)!=0; }else{ pItem->iOBTab = -1; } @@ -116289,7 +118169,7 @@ static int renameResolveTrigger(Parse *pParse){ /* ALWAYS() because if the table of the trigger does not exist, the ** error would have been hit before this point */ if( ALWAYS(pParse->pTriggerTab) ){ - rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); + rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0; } /* Resolve symbols in WHEN clause */ @@ -116335,8 +118215,9 @@ static int renameResolveTrigger(Parse *pParse){ int i; for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){ SrcItem *p = &pStep->pFrom->a[i]; - if( p->pSelect ){ - sqlite3SelectPrep(pParse, p->pSelect, 0); + if( p->fg.isSubquery ){ + assert( p->u4.pSubq!=0 ); + sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0); } } } @@ -116404,8 +118285,12 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ } if( pStep->pFrom ){ int i; - for(i=0; i<pStep->pFrom->nSrc; i++){ - sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect); + SrcList *pFrom = pStep->pFrom; + for(i=0; i<pFrom->nSrc; i++){ + if( pFrom->a[i].fg.isSubquery ){ + assert( pFrom->a[i].u4.pSubq!=0 ); + sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect); + } } } } @@ -116652,7 +118537,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ } for(i=0; i<pSrc->nSrc; i++){ SrcItem *pItem = &pSrc->a[i]; - if( pItem->pTab==p->pTab ){ + if( pItem->pSTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } } @@ -117231,7 +119116,12 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T if( i==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regOut); }else{ + char aff = pTab->aCol[i].affinity; + if( aff==SQLITE_AFF_REAL ){ + pTab->aCol[i].affinity = SQLITE_AFF_NUMERIC; + } sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + pTab->aCol[i].affinity = aff; } nField++; } @@ -117542,9 +119432,9 @@ static void openStatTable( typedef struct StatAccum StatAccum; typedef struct StatSample StatSample; struct StatSample { - tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anDLt; /* sqlite_stat4.nDLt */ #ifdef SQLITE_ENABLE_STAT4 + tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anLt; /* sqlite_stat4.nLt */ union { i64 iRowid; /* Rowid in main table of the key */ @@ -117702,9 +119592,9 @@ static void statInit( /* Allocate the space required for the StatAccum object */ n = sizeof(*p) - + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */ - + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ + + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ #ifdef SQLITE_ENABLE_STAT4 + n += sizeof(tRowcnt)*nColUp; /* StatAccum.anEq */ if( mxSample ){ n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ @@ -117725,9 +119615,9 @@ static void statInit( p->nKeyCol = nKeyCol; p->nSkipAhead = 0; p->current.anDLt = (tRowcnt*)&p[1]; - p->current.anEq = &p->current.anDLt[nColUp]; #ifdef SQLITE_ENABLE_STAT4 + p->current.anEq = &p->current.anDLt[nColUp]; p->mxSample = p->nLimit==0 ? mxSample : 0; if( mxSample ){ u8 *pSpace; /* Allocated space not yet assigned */ @@ -117994,7 +119884,9 @@ static void statPush( if( p->nRow==0 ){ /* This is the first call to this function. Do initialization. */ +#ifdef SQLITE_ENABLE_STAT4 for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; +#endif }else{ /* Second and subsequent calls get processed here */ #ifdef SQLITE_ENABLE_STAT4 @@ -118003,15 +119895,17 @@ static void statPush( /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply ** to the current row of the index. */ +#ifdef SQLITE_ENABLE_STAT4 for(i=0; i<iChng; i++){ p->current.anEq[i]++; } +#endif for(i=iChng; i<p->nCol; i++){ p->current.anDLt[i]++; #ifdef SQLITE_ENABLE_STAT4 if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i]; -#endif p->current.anEq[i] = 1; +#endif } } @@ -118145,7 +120039,9 @@ static void statGet( u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; sqlite3_str_appendf(&sStat, " %llu", iVal); - assert( p->current.anEq[i] ); +#ifdef SQLITE_ENABLE_STAT4 + assert( p->current.anEq[i] || p->nRow==0 ); +#endif } sqlite3ResultStrAccum(context, &sStat); } @@ -118329,7 +120225,7 @@ static void analyzeOneTable( for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; /* Number of columns in pIdx. "N" */ - int addrRewind; /* Address of "OP_Rewind iIdxCur" */ + int addrGotoEnd; /* Address of "OP_Rewind iIdxCur" */ int addrNextRow; /* Address of "next_row:" */ const char *zIdxName; /* Name of the index */ int nColTest; /* Number of columns to test for changes */ @@ -118353,9 +120249,14 @@ static void analyzeOneTable( /* ** Pseudo-code for loop that calls stat_push(): ** - ** Rewind csr - ** if eof(csr) goto end_of_scan; ** regChng = 0 + ** Rewind csr + ** if eof(csr){ + ** stat_init() with count = 0; + ** goto end_of_scan; + ** } + ** count() + ** stat_init() ** goto chng_addr_0; ** ** next_row: @@ -118394,41 +120295,36 @@ static void analyzeOneTable( sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); - /* Invoke the stat_init() function. The arguments are: + /* Implementation of the following: ** + ** regChng = 0 + ** Rewind csr + ** if eof(csr){ + ** stat_init() with count = 0; + ** goto end_of_scan; + ** } + ** count() + ** stat_init() + ** goto chng_addr_0; + */ + assert( regTemp2==regStat+4 ); + sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); + + /* Arguments to stat_init(): ** (1) the number of columns in the index including the rowid ** (or for a WITHOUT ROWID table, the number of PK columns), ** (2) the number of columns in the key without the rowid/pk - ** (3) estimated number of rows in the index, - */ + ** (3) estimated number of rows in the index. */ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1); assert( regRowid==regStat+2 ); sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid); -#ifdef SQLITE_ENABLE_STAT4 - if( OptimizationEnabled(db, SQLITE_Stat4) ){ - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp); - addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); - VdbeCoverage(v); - }else -#endif - { - addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1); - } - assert( regTemp2==regStat+4 ); - sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); + sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, + OptimizationDisabled(db, SQLITE_Stat4)); sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4, &statInitFuncdef, 0); + addrGotoEnd = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); + VdbeCoverage(v); - /* Implementation of the following: - ** - ** Rewind csr - ** if eof(csr) goto end_of_scan; - ** regChng = 0 - ** goto next_push_0; - ** - */ sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); addrNextRow = sqlite3VdbeCurrentAddr(v); @@ -118535,6 +120431,12 @@ static void analyzeOneTable( } /* Add the entry to the stat1 table. */ + if( pIdx->pPartIdxWhere ){ + /* Partial indexes might get a zero-entry in sqlite_stat1. But + ** an empty table is omitted from sqlite_stat1. */ + sqlite3VdbeJumpHere(v, addrGotoEnd); + addrGotoEnd = 0; + } callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1); assert( "BBB"[0]==SQLITE_AFF_TEXT ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); @@ -118558,6 +120460,13 @@ static void analyzeOneTable( int addrIsNull; u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; + /* No STAT4 data is generated if the number of rows is zero */ + if( addrGotoEnd==0 ){ + sqlite3VdbeAddOp2(v, OP_Cast, regStat1, SQLITE_AFF_INTEGER); + addrGotoEnd = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); + VdbeCoverage(v); + } + if( doOnce ){ int mxCol = nCol; Index *pX; @@ -118610,7 +120519,7 @@ static void analyzeOneTable( #endif /* SQLITE_ENABLE_STAT4 */ /* End of analysis */ - sqlite3VdbeJumpHere(v, addrRewind); + if( addrGotoEnd ) sqlite3VdbeJumpHere(v, addrGotoEnd); } @@ -118834,6 +120743,16 @@ static void decodeIntArray( while( z[0]!=0 && z[0]!=' ' ) z++; while( z[0]==' ' ) z++; } + + /* Set the bLowQual flag if the peak number of rows obtained + ** from a full equality match is so large that a full table scan + ** seems likely to be faster than using the index. + */ + if( aLog[0] > 66 /* Index has more than 100 rows */ + && aLog[0] <= aLog[nOut-1] /* And only a single value seen */ + ){ + pIndex->bLowQual = 1; + } } } @@ -119046,12 +120965,13 @@ static int loadStatTbl( while( sqlite3_step(pStmt)==SQLITE_ROW ){ int nIdxCol = 1; /* Number of columns in stat4 records */ - char *zIndex; /* Index name */ - Index *pIdx; /* Pointer to the index object */ - int nSample; /* Number of samples */ - int nByte; /* Bytes of space required */ - int i; /* Bytes of space required */ - tRowcnt *pSpace; + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nSample; /* Number of samples */ + i64 nByte; /* Bytes of space required */ + i64 i; /* Bytes of space required */ + tRowcnt *pSpace; /* Available allocated memory space */ + u8 *pPtr; /* Available memory as a u8 for easier manipulation */ zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; @@ -119071,7 +120991,7 @@ static int loadStatTbl( } pIdx->nSampleCol = nIdxCol; pIdx->mxSample = nSample; - nByte = sizeof(IndexSample) * nSample; + nByte = ROUND8(sizeof(IndexSample) * nSample); nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ @@ -119080,7 +121000,10 @@ static int loadStatTbl( sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } - pSpace = (tRowcnt*)&pIdx->aSample[nSample]; + pPtr = (u8*)pIdx->aSample; + pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); + pSpace = (tRowcnt*)pPtr; + assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); pIdx->aAvgEq = pSpace; pSpace += nIdxCol; pIdx->pTable->tabFlags |= TF_HasStat4; for(i=0; i<nSample; i++){ @@ -119501,15 +121424,6 @@ static void attachFunc( sqlite3BtreeLeaveAll(db); assert( zErrDyn==0 || rc!=SQLITE_OK ); } -#ifdef SQLITE_USER_AUTHENTICATION - if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){ - u8 newAuth = 0; - rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); - if( newAuth<db->auth.authLevel ){ - rc = SQLITE_AUTH_USER; - } - } -#endif if( rc ){ if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ int iDb = db->nDb - 1; @@ -119753,20 +121667,21 @@ static int fixSelectCb(Walker *p, Select *pSelect){ if( NEVER(pList==0) ) return WRC_Continue; for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ - if( pFix->bTemp==0 ){ - if( pItem->zDatabase ){ - if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ + if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){ + if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ + if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); + pFix->zType, pFix->pName, pItem->u4.zDatabase); return WRC_Abort; } - sqlite3DbFree(db, pItem->zDatabase); - pItem->zDatabase = 0; + sqlite3DbFree(db, pItem->u4.zDatabase); pItem->fg.notCte = 1; + pItem->fg.hadSchema = 1; } - pItem->pSchema = pFix->pSchema; + pItem->u4.pSchema = pFix->pSchema; pItem->fg.fromDDL = 1; + pItem->fg.fixedSchema = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( pList->a[i].fg.isUsing==0 @@ -120006,11 +121921,7 @@ SQLITE_PRIVATE int sqlite3AuthReadCol( int rc; /* Auth callback return code */ if( db->init.busy ) return SQLITE_OK; - rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext); if( rc==SQLITE_DENY ){ char *z = sqlite3_mprintf("%s.%s", zTab, zCol); if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); @@ -120059,7 +121970,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( assert( pTabList ); for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ - pTab = pTabList->a[iSrc].pTab; + pTab = pTabList->a[iSrc].pSTab; break; } } @@ -120117,11 +122028,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( testcase( zArg3==0 ); testcase( pParse->zAuthContext==0 ); - rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); + rc = db->xAuth(db->pAuthArg,code,zArg1,zArg2,zArg3,pParse->zAuthContext); if( rc==SQLITE_DENY ){ sqlite3ErrorMsg(pParse, "not authorized"); pParse->rc = SQLITE_AUTH; @@ -120354,17 +122261,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } sqlite3VdbeAddOp0(v, OP_Halt); -#if SQLITE_USER_AUTHENTICATION - if( pParse->nTableLock>0 && db->init.busy==0 ){ - sqlite3UserAuthInit(db); - if( db->auth.authLevel<UAUTH_User ){ - sqlite3ErrorMsg(pParse, "user not authenticated"); - pParse->rc = SQLITE_AUTH_USER; - return; - } - } -#endif - /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a @@ -120493,16 +122389,6 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ pParse->nested--; } -#if SQLITE_USER_AUTHENTICATION -/* -** Return TRUE if zTable is the name of the system table that stores the -** list of users and their access credentials. -*/ -SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){ - return sqlite3_stricmp(zTable, "sqlite_user")==0; -} -#endif - /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -120521,13 +122407,6 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha /* All mutexes are required for schema access. Make sure we hold them. */ assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); -#if SQLITE_USER_AUTHENTICATION - /* Only the admin user is allowed to know that the sqlite_user table - ** exists */ - if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){ - return 0; - } -#endif if( zDatabase ){ for(i=0; i<db->nDb; i++){ if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break; @@ -120662,12 +122541,12 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem( SrcItem *p ){ const char *zDb; - assert( p->pSchema==0 || p->zDatabase==0 ); - if( p->pSchema ){ - int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); + if( p->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema); zDb = pParse->db->aDb[iDb].zDbSName; }else{ - zDb = p->zDatabase; + assert( !p->fg.isSubquery ); + zDb = p->u4.zDatabase; } return sqlite3LocateTable(pParse, flags, p->zName, zDb); } @@ -120885,7 +122764,7 @@ SQLITE_PRIVATE void sqlite3ColumnSetExpr( */ SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ if( pCol->iDflt==0 ) return 0; - if( NEVER(!IsOrdinaryTable(pTab)) ) return 0; + if( !IsOrdinaryTable(pTab) ) return 0; if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0; return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; @@ -121038,6 +122917,9 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; deleteTable(db, pTable); } +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3 *db, void *pTable){ + sqlite3DeleteTable(db, (Table*)pTable); +} /* @@ -121575,7 +123457,8 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ /* ** Clean up the data structures associated with the RETURNING clause. */ -static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ +static void sqlite3DeleteReturning(sqlite3 *db, void *pArg){ + Returning *pRet = (Returning*)pArg; Hash *pHash; pHash = &(db->aDb[1].pSchema->trigHash); sqlite3HashInsert(pHash, pRet->zName, 0); @@ -121617,8 +123500,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pParse->u1.pReturning = pRet; pRet->pParse = pParse; pRet->pReturnEL = pList; - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); + sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet); testcase( pParse->earlyCleanup ); if( db->mallocFailed ) return; sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, @@ -121817,7 +123699,8 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){ assert( zIn!=0 ); while( zIn[0] ){ - h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; + u8 x = *(u8*)zIn; + h = (h<<8) + sqlite3UpperToLower[x]; zIn++; if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ aff = SQLITE_AFF_TEXT; @@ -122989,20 +124872,20 @@ SQLITE_PRIVATE void sqlite3EndTable( int regRowid; /* Rowid of the next row to insert */ int addrInsLoop; /* Top of the loop for inserting rows */ Table *pSelTab; /* A table that describes the SELECT results */ + int iCsr; /* Write cursor on the new table */ if( IN_SPECIAL_PARSE ){ pParse->rc = SQLITE_ERROR; pParse->nErr++; return; } + iCsr = pParse->nTab++; regYield = ++pParse->nMem; regRec = ++pParse->nMem; regRowid = ++pParse->nMem; - assert(pParse->nTab==1); sqlite3MayAbort(pParse); - sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); + sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->regRoot, iDb); sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); - pParse->nTab = 2; addrTop = sqlite3VdbeCurrentAddr(v) + 1; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); if( pParse->nErr ) return; @@ -123023,11 +124906,11 @@ SQLITE_PRIVATE void sqlite3EndTable( VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); sqlite3TableAffinity(v, p, 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid); + sqlite3VdbeAddOp2(v, OP_NewRowid, iCsr, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iCsr, regRec, regRowid); sqlite3VdbeGoto(v, addrInsLoop); sqlite3VdbeJumpHere(v, addrInsLoop); - sqlite3VdbeAddOp1(v, OP_Close, 1); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); } /* Compute the complete text of the CREATE statement */ @@ -123084,13 +124967,10 @@ SQLITE_PRIVATE void sqlite3EndTable( /* Test for cycles in generated columns and illegal expressions ** in CHECK constraints and in DEFAULT clauses. */ if( p->tabFlags & TF_HasGenerated ){ - sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3VdbeAddOp4(v, OP_SqlExec, 0x0001, 0, 0, sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); } - sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, - sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)", - db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); } /* Add the table to the in-memory representation of the database. @@ -123167,9 +125047,12 @@ SQLITE_PRIVATE void sqlite3CreateView( ** on a view, even though views do not have rowids. The following flag ** setting fixes this problem. But the fix can be disabled by compiling ** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that - ** depend upon the old buggy behavior. */ -#ifndef SQLITE_ALLOW_ROWID_IN_VIEW - p->tabFlags |= TF_NoVisibleRowid; + ** depend upon the old buggy behavior. The ability can also be toggled + ** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */ +#else + p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */ #endif sqlite3TwoPartName(pParse, pName1, pName2, &pName); @@ -123225,8 +125108,9 @@ SQLITE_PRIVATE void sqlite3CreateView( #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** The Table structure pTable is really a VIEW. Fill in the names of -** the columns of the view in the pTable structure. Return the number -** of errors. If an error is seen leave an error message in pParse->zErrMsg. +** the columns of the view in the pTable structure. Return non-zero if +** there are errors. If an error is seen an error message is left +** in pParse->zErrMsg. */ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ @@ -123349,7 +125233,7 @@ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ sqlite3DeleteColumnNames(db, pTable); } #endif /* SQLITE_OMIT_VIEW */ - return nErr; + return nErr + pParse->nErr; } SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable!=0 ); @@ -123647,6 +125531,8 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 ); + assert( pName->a[0].fg.isSubquery==0 ); if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; assert( isView==0 || isView==LOCATE_VIEW ); @@ -123655,7 +125541,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, if( pTab==0 ){ if( noErr ){ - sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); sqlite3ForceNotReadOnly(pParse); } goto exit_drop_table; @@ -124179,9 +126065,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex( if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && db->init.busy==0 && pTblName!=0 -#if SQLITE_USER_AUTHENTICATION - && sqlite3UserAuthTable(pTab->zName)==0 -#endif ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; @@ -124746,15 +126629,17 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists } assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 ); + assert( pName->a[0].fg.isSubquery==0 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } - pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); + pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase); if( pIndex==0 ){ if( !ifExists ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); }else{ - sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); sqlite3ForceNotReadOnly(pParse); } pParse->checkSchema = 1; @@ -125051,12 +126936,14 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( if( pDatabase && pDatabase->z==0 ){ pDatabase = 0; } + assert( pItem->fg.fixedSchema==0 ); + assert( pItem->fg.isSubquery==0 ); if( pDatabase ){ pItem->zName = sqlite3NameFromToken(db, pDatabase); - pItem->zDatabase = sqlite3NameFromToken(db, pTable); + pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable); }else{ pItem->zName = sqlite3NameFromToken(db, pTable); - pItem->zDatabase = 0; + pItem->u4.zDatabase = 0; } return pList; } @@ -125072,13 +126959,40 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pItem->iCursor>=0 ) continue; pItem->iCursor = pParse->nTab++; - if( pItem->pSelect ){ - sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); + if( pItem->fg.isSubquery ){ + assert( pItem->u4.pSubq!=0 ); + assert( pItem->u4.pSubq->pSelect!=0 ); + assert( pItem->u4.pSubq->pSelect->pSrc!=0 ); + sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc); } } } } +/* +** Delete a Subquery object and its substructure. +*/ +SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){ + assert( pSubq!=0 && pSubq->pSelect!=0 ); + sqlite3SelectDelete(db, pSubq->pSelect); + sqlite3DbFree(db, pSubq); +} + +/* +** Remove a Subquery from a SrcItem. Return the associated Select object. +** The returned Select becomes the responsibility of the caller. +*/ +SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){ + Select *pSel; + assert( pItem!=0 ); + assert( pItem->fg.isSubquery ); + pSel = pItem->u4.pSubq->pSelect; + sqlite3DbFree(db, pItem->u4.pSubq); + pItem->u4.pSubq = 0; + pItem->fg.isSubquery = 0; + return pSel; +} + /* ** Delete an entire SrcList including all its substructure. */ @@ -125088,13 +127002,24 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ assert( db!=0 ); if( pList==0 ) return; for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ - if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase); + + /* Check invariants on SrcItem */ + assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc ); + assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy ); + assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery ); + assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 && + pItem->u4.pSubq->pSelect!=0) ); + if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); + if( pItem->fg.isSubquery ){ + sqlite3SubqueryDelete(db, pItem->u4.pSubq); + }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ + sqlite3DbNNFreeNN(db, pItem->u4.zDatabase); + } if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); - sqlite3DeleteTable(db, pItem->pTab); - if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); + sqlite3DeleteTable(db, pItem->pSTab); if( pItem->fg.isUsing ){ sqlite3IdListDelete(db, pItem->u3.pUsing); }else if( pItem->u3.pOn ){ @@ -125104,6 +127029,54 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ sqlite3DbNNFreeNN(db, pList); } +/* +** Attach a Subquery object to pItem->uv.pSubq. Set the +** pSelect value but leave all the other values initialized +** to zero. +** +** A copy of the Select object is made if dupSelect is true, and the +** SrcItem takes responsibility for deleting the copy. If dupSelect is +** false, ownership of the Select passes to the SrcItem. Either way, +** the SrcItem will take responsibility for deleting the Select. +** +** When dupSelect is zero, that means the Select might get deleted right +** away if there is an OOM error. Beware. +** +** Return non-zero on success. Return zero on an OOM error. +*/ +SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery( + Parse *pParse, /* Parsing context */ + SrcItem *pItem, /* Item to which the subquery is to be attached */ + Select *pSelect, /* The subquery SELECT. Must be non-NULL */ + int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/ +){ + Subquery *p; + assert( pSelect!=0 ); + assert( pItem->fg.isSubquery==0 ); + if( pItem->fg.fixedSchema ){ + pItem->u4.pSchema = 0; + pItem->fg.fixedSchema = 0; + }else if( pItem->u4.zDatabase!=0 ){ + sqlite3DbFree(pParse->db, pItem->u4.zDatabase); + pItem->u4.zDatabase = 0; + } + if( dupSelect ){ + pSelect = sqlite3SelectDup(pParse->db, pSelect, 0); + if( pSelect==0 ) return 0; + } + p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery)); + if( p==0 ){ + sqlite3SelectDelete(pParse->db, pSelect); + return 0; + } + pItem->fg.isSubquery = 1; + p->pSelect = pSelect; + assert( offsetof(Subquery, pSelect)==0 ); + memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect)); + return 1; +} + + /* ** This routine is called by the parser to add a new term to the ** end of a growing FROM clause. The "p" parameter is the part of @@ -125153,10 +127126,12 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); } + assert( pSubquery==0 || pDatabase==0 ); if( pSubquery ){ - pItem->pSelect = pSubquery; - if( pSubquery->selFlags & SF_NestedFrom ){ - pItem->fg.isNestedFrom = 1; + if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){ + if( pSubquery->selFlags & SF_NestedFrom ){ + pItem->fg.isNestedFrom = 1; + } } } assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); @@ -125682,7 +127657,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ if( iDb<0 ) return; z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; - zDb = db->aDb[iDb].zDbSName; + zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; pTab = sqlite3FindTable(db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); @@ -125692,6 +127667,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ pIndex = sqlite3FindIndex(db, z, zDb); sqlite3DbFree(db, z); if( pIndex ){ + iDb = sqlite3SchemaToIndex(db, pIndex->pTable->pSchema); sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3RefillIndex(pParse, pIndex, -1); return; @@ -125857,6 +127833,9 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ sqlite3DbFree(db, pWith); } } +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){ + sqlite3WithDelete(db, (With*)pWith); +} #endif /* !defined(SQLITE_OMIT_CTE) */ /************** End of build.c ***********************************************/ @@ -126430,8 +128409,8 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ ** ** The following fields are initialized appropriate in pSrc: ** -** pSrc->a[0].pTab Pointer to the Table object -** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one +** pSrc->a[0].spTab Pointer to the Table object +** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one ** */ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ @@ -126439,8 +128418,8 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); - if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab); - pItem->pTab = pTab; + if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab); + pItem->pSTab = pTab; pItem->fg.notCte = 1; if( pTab ){ pTab->nTabRef++; @@ -126481,6 +128460,7 @@ SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char * ** is for a top-level SQL statement. */ static int vtabIsReadOnly(Parse *pParse, Table *pTab){ + assert( IsVirtual(pTab) ); if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ return 1; } @@ -126562,7 +128542,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView( if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); - pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 ); + pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); assert( pFrom->a[0].fg.isUsing==0 ); assert( pFrom->a[0].u3.pOn==0 ); } @@ -126624,7 +128605,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( ** ); */ - pTab = pSrc->a[0].pTab; + pTab = pSrc->a[0].pSTab; if( HasRowid(pTab) ){ pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); pEList = sqlite3ExprListAppend( @@ -126657,9 +128638,9 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ - pSrc->a[0].pTab = 0; + pSrc->a[0].pSTab = 0; pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); - pSrc->a[0].pTab = pTab; + pSrc->a[0].pSTab = pTab; if( pSrc->a[0].fg.isIndexedBy ){ assert( pSrc->a[0].fg.isCte==0 ); pSrc->a[0].u2.pIBIndex = 0; @@ -127791,7 +129772,6 @@ static void substrFunc( int len; int p0type; i64 p1, p2; - int negP2 = 0; assert( argc==3 || argc==2 ); if( sqlite3_value_type(argv[1])==SQLITE_NULL @@ -127800,7 +129780,7 @@ static void substrFunc( return; } p0type = sqlite3_value_type(argv[0]); - p1 = sqlite3_value_int(argv[1]); + p1 = sqlite3_value_int64(argv[1]); if( p0type==SQLITE_BLOB ){ len = sqlite3_value_bytes(argv[0]); z = sqlite3_value_blob(argv[0]); @@ -127825,19 +129805,18 @@ static void substrFunc( if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */ #endif if( argc==3 ){ - p2 = sqlite3_value_int(argv[2]); - if( p2<0 ){ - p2 = -p2; - negP2 = 1; - } + p2 = sqlite3_value_int64(argv[2]); }else{ p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; } if( p1<0 ){ p1 += len; if( p1<0 ){ - p2 += p1; - if( p2<0 ) p2 = 0; + if( p2<0 ){ + p2 = 0; + }else{ + p2 += p1; + } p1 = 0; } }else if( p1>0 ){ @@ -127845,12 +129824,13 @@ static void substrFunc( }else if( p2>0 ){ p2--; } - if( negP2 ){ - p1 -= p2; - if( p1<0 ){ - p2 += p1; - p1 = 0; + if( p2<0 ){ + if( p2<-p1 ){ + p2 = p1; + }else{ + p2 = -p2; } + p1 -= p2; } assert( p1>=0 && p2>=0 ); if( p0type!=SQLITE_BLOB ){ @@ -127864,9 +129844,11 @@ static void substrFunc( sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, SQLITE_UTF8); }else{ - if( p1+p2>len ){ + if( p1>=len ){ + p1 = p2 = 0; + }else if( p2>len-p1 ){ p2 = len-p1; - if( p2<0 ) p2 = 0; + assert( p2>0 ); } sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); } @@ -127877,13 +129859,13 @@ static void substrFunc( */ #ifndef SQLITE_OMIT_FLOATING_POINT static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - int n = 0; + i64 n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; - n = sqlite3_value_int(argv[1]); + n = sqlite3_value_int64(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } @@ -127898,7 +129880,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ - zBuf = sqlite3_mprintf("%!.*f",n,r); + zBuf = sqlite3_mprintf("%!.*f",(int)n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; @@ -128538,13 +130520,13 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ double r1, r2; const char *zVal; r1 = sqlite3_value_double(pValue); - sqlite3_str_appendf(pStr, "%!.15g", r1); + sqlite3_str_appendf(pStr, "%!0.15g", r1); zVal = sqlite3_str_value(pStr); if( zVal ){ sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8); if( r1!=r2 ){ sqlite3_str_reset(pStr); - sqlite3_str_appendf(pStr, "%!.20e", r1); + sqlite3_str_appendf(pStr, "%!0.20e", r1); } } break; @@ -128846,7 +130828,7 @@ static void replaceFunc( } if( zPattern[0]==0 ){ assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); - sqlite3_result_value(context, argv[0]); + sqlite3_result_text(context, (const char*)zStr, nStr, SQLITE_TRANSIENT); return; } nPattern = sqlite3_value_bytes(argv[1]); @@ -129329,7 +131311,7 @@ static void sumFinalize(sqlite3_context *context){ if( p->approx ){ if( p->ovrfl ){ sqlite3_result_error(context,"integer overflow",-1); - }else if( !sqlite3IsNaN(p->rErr) ){ + }else if( !sqlite3IsOverflow(p->rErr) ){ sqlite3_result_double(context, p->rSum+p->rErr); }else{ sqlite3_result_double(context, p->rSum); @@ -129346,7 +131328,7 @@ static void avgFinalize(sqlite3_context *context){ double r; if( p->approx ){ r = p->rSum; - if( !sqlite3IsNaN(p->rErr) ) r += p->rErr; + if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; }else{ r = (double)(p->iSum); } @@ -129360,7 +131342,7 @@ static void totalFinalize(sqlite3_context *context){ if( p ){ if( p->approx ){ r = p->rSum; - if( !sqlite3IsNaN(p->rErr) ) r += p->rErr; + if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; }else{ r = (double)(p->iSum); } @@ -129486,7 +131468,11 @@ static void minMaxFinalize(sqlite3_context *context){ ** group_concat(EXPR, ?SEPARATOR?) ** string_agg(EXPR, SEPARATOR) ** -** The SEPARATOR goes before the EXPR string. This is tragic. The +** Content is accumulated in GroupConcatCtx.str with the SEPARATOR +** coming before the EXPR value, except for the first entry which +** omits the SEPARATOR. +** +** It is tragic that the SEPARATOR goes before the EXPR string. The ** groupConcatInverse() implementation would have been easier if the ** SEPARATOR were appended after EXPR. And the order is undocumented, ** so we could change it, in theory. But the old behavior has been @@ -129590,7 +131576,7 @@ static void groupConcatInverse( /* pGCC is always non-NULL since groupConcatStep() will have always ** run first to initialize it */ if( ALWAYS(pGCC) ){ - int nVS; + int nVS; /* Number of characters to remove */ /* Must call sqlite3_value_text() to convert the argument into text prior ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ (void)sqlite3_value_text(argv[0]); @@ -129643,6 +131629,8 @@ static void groupConcatValue(sqlite3_context *context){ sqlite3_result_error_toobig(context); }else if( pAccum->accError==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); + }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){ + sqlite3_result_text(context, "", 1, SQLITE_STATIC); }else{ const char *zText = sqlite3_str_value(pAccum); sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); @@ -129966,7 +131954,13 @@ static void signFunc( ** Implementation of fpdecode(x,y,z) function. ** ** x is a real number that is to be decoded. y is the precision. -** z is the maximum real precision. +** z is the maximum real precision. Return a string that shows the +** results of the sqlite3FpDecode() function. +** +** Used for testing and debugging only, specifically testing and debugging +** of the sqlite3FpDecode() function. This SQL function does not appear +** in production builds. This function is not an API and is subject to +** modification or removal in future versions of SQLite. */ static void fpdecodeFunc( sqlite3_context *context, @@ -129982,6 +131976,7 @@ static void fpdecodeFunc( x = sqlite3_value_double(argv[0]); y = sqlite3_value_int(argv[1]); z = sqlite3_value_int(argv[2]); + if( z<=0 ) z = 1; sqlite3FpDecode(&s, x, y, z); if( s.isSpecial==2 ){ sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); @@ -129992,6 +131987,82 @@ static void fpdecodeFunc( } #endif /* SQLITE_DEBUG */ +#ifdef SQLITE_DEBUG +/* +** Implementation of parseuri(uri,flags) function. +** +** Required Arguments: +** "uri" The URI to parse. +** "flags" Bitmask of flags, as if to sqlite3_open_v2(). +** +** Additional arguments beyond the first two make calls to +** sqlite3_uri_key() for integers and sqlite3_uri_parameter for +** anything else. +** +** The result is a string showing the results of calling sqlite3ParseUri(). +** +** Used for testing and debugging only, specifically testing and debugging +** of the sqlite3ParseUri() function. This SQL function does not appear +** in production builds. This function is not an API and is subject to +** modification or removal in future versions of SQLite. +*/ +static void parseuriFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + sqlite3_str *pResult; + const char *zVfs; + const char *zUri; + unsigned int flgs; + int rc; + sqlite3_vfs *pVfs = 0; + char *zFile = 0; + char *zErr = 0; + + if( argc<2 ) return; + pVfs = sqlite3_vfs_find(0); + assert( pVfs ); + zVfs = pVfs->zName; + zUri = (const char*)sqlite3_value_text(argv[0]); + if( zUri==0 ) return; + flgs = (unsigned int)sqlite3_value_int(argv[1]); + rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr); + pResult = sqlite3_str_new(0); + if( pResult ){ + int i; + sqlite3_str_appendf(pResult, "rc=%d", rc); + sqlite3_str_appendf(pResult, ", flags=0x%x", flgs); + sqlite3_str_appendf(pResult, ", vfs=%Q", pVfs ? pVfs->zName: 0); + sqlite3_str_appendf(pResult, ", err=%Q", zErr); + sqlite3_str_appendf(pResult, ", file=%Q", zFile); + if( zFile ){ + const char *z = zFile; + z += sqlite3Strlen30(z)+1; + while( z[0] ){ + sqlite3_str_appendf(pResult, ", %Q", z); + z += sqlite3Strlen30(z)+1; + } + for(i=2; i<argc; i++){ + const char *zArg; + if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ + int k = sqlite3_value_int(argv[i]); + sqlite3_str_appendf(pResult, ", '%d:%q'",k,sqlite3_uri_key(zFile, k)); + }else if( (zArg = (const char*)sqlite3_value_text(argv[i]))!=0 ){ + sqlite3_str_appendf(pResult, ", '%q:%q'", + zArg, sqlite3_uri_parameter(zFile,zArg)); + }else{ + sqlite3_str_appendf(pResult, ", NULL"); + } + } + } + sqlite3_result_text(ctx, sqlite3_str_finish(pResult), -1, sqlite3_free); + } + sqlite3_free_filename(zFile); + sqlite3_free(zErr); +} +#endif /* SQLITE_DEBUG */ + /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as @@ -130026,9 +132097,6 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ SFUNCTION(load_extension, 1, 0, 0, loadExt ), SFUNCTION(load_extension, 2, 0, 0, loadExt ), #endif -#if SQLITE_USER_AUTHENTICATION - FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), -#endif #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), @@ -130054,7 +132122,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), - FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), + FUNCTION2(subtype, 1, 0, 0, subtypeFunc, + SQLITE_FUNC_TYPEOF|SQLITE_SUBTYPE), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN), FUNCTION(instr, 2, 0, 0, instrFunc ), @@ -130065,6 +132134,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(abs, 1, 0, 0, absFunc ), #ifdef SQLITE_DEBUG FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), + FUNCTION(parseuri, -1, 0, 0, parseuriFunc ), #endif #ifndef SQLITE_OMIT_FLOATING_POINT FUNCTION(round, 1, 0, 0, roundFunc ), @@ -130159,11 +132229,14 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ MFUNCTION(sqrt, 1, sqrt, math1Func ), MFUNCTION(radians, 1, degToRad, math1Func ), MFUNCTION(degrees, 1, radToDeg, math1Func ), - FUNCTION(pi, 0, 0, 0, piFunc ), + MFUNCTION(pi, 0, 0, piFunc ), #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ FUNCTION(sign, 1, 0, 0, signFunc ), INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), + INLINE_FUNC(iif, 2, INLINEFUNC_iif, 0 ), INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), + INLINE_FUNC(if, 2, INLINEFUNC_iif, 0 ), + INLINE_FUNC(if, 3, INLINEFUNC_iif, 0 ), }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); @@ -131238,9 +133311,9 @@ SQLITE_PRIVATE void sqlite3FkCheck( pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ SrcItem *pItem = pSrc->a; - pItem->pTab = pFKey->pFrom; + pItem->pSTab = pFKey->pFrom; pItem->zName = pFKey->pFrom->zName; - pItem->pTab->nTabRef++; + pItem->pSTab->nTabRef++; pItem->iCursor = pParse->nTab++; if( regNew!=0 ){ @@ -131523,7 +133596,8 @@ static Trigger *fkActionTrigger( SrcList *pSrc; Expr *pRaise; - pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); + pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"), + pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0); if( pRaise ){ pRaise->affExpr = OE_Abort; } @@ -131531,7 +133605,8 @@ static Trigger *fkActionTrigger( if( pSrc ){ assert( pSrc->nSrc==1 ); pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); - pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 ); + pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), @@ -132257,6 +134332,210 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ # define autoIncStep(A,B,C) #endif /* SQLITE_OMIT_AUTOINCREMENT */ +/* +** If argument pVal is a Select object returned by an sqlite3MultiValues() +** that was able to use the co-routine optimization, finish coding the +** co-routine. +*/ +SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ + if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ + SrcItem *pItem = &pVal->pSrc->a[0]; + assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr ); + if( pItem->fg.isSubquery ){ + sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn); + sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1); + } + } +} + +/* +** Return true if all expressions in the expression-list passed as the +** only argument are constant. +*/ +static int exprListIsConstant(Parse *pParse, ExprList *pRow){ + int ii; + for(ii=0; ii<pRow->nExpr; ii++){ + if( 0==sqlite3ExprIsConstant(pParse, pRow->a[ii].pExpr) ) return 0; + } + return 1; +} + +/* +** Return true if all expressions in the expression-list passed as the +** only argument are both constant and have no affinity. +*/ +static int exprListIsNoAffinity(Parse *pParse, ExprList *pRow){ + int ii; + if( exprListIsConstant(pParse,pRow)==0 ) return 0; + for(ii=0; ii<pRow->nExpr; ii++){ + Expr *pExpr = pRow->a[ii].pExpr; + assert( pExpr->op!=TK_RAISE ); + assert( pExpr->affExpr==0 ); + if( 0!=sqlite3ExprAffinity(pExpr) ) return 0; + } + return 1; + +} + +/* +** This function is called by the parser for the second and subsequent +** rows of a multi-row VALUES clause. Argument pLeft is the part of +** the VALUES clause already parsed, argument pRow is the vector of values +** for the new row. The Select object returned represents the complete +** VALUES clause, including the new row. +** +** There are two ways in which this may be achieved - by incremental +** coding of a co-routine (the "co-routine" method) or by returning a +** Select object equivalent to the following (the "UNION ALL" method): +** +** "pLeft UNION ALL SELECT pRow" +** +** If the VALUES clause contains a lot of rows, this compound Select +** object may consume a lot of memory. +** +** When the co-routine method is used, each row that will be returned +** by the VALUES clause is coded into part of a co-routine as it is +** passed to this function. The returned Select object is equivalent to: +** +** SELECT * FROM ( +** Select object to read co-routine +** ) +** +** The co-routine method is used in most cases. Exceptions are: +** +** a) If the current statement has a WITH clause. This is to avoid +** statements like: +** +** WITH cte AS ( VALUES('x'), ('y') ... ) +** SELECT * FROM cte AS a, cte AS b; +** +** This will not work, as the co-routine uses a hard-coded register +** for its OP_Yield instructions, and so it is not possible for two +** cursors to iterate through it concurrently. +** +** b) The schema is currently being parsed (i.e. the VALUES clause is part +** of a schema item like a VIEW or TRIGGER). In this case there is no VM +** being generated when parsing is taking place, and so generating +** a co-routine is not possible. +** +** c) There are non-constant expressions in the VALUES clause (e.g. +** the VALUES clause is part of a correlated sub-query). +** +** d) One or more of the values in the first row of the VALUES clause +** has an affinity (i.e. is a CAST expression). This causes problems +** because the complex rules SQLite uses (see function +** sqlite3SubqueryColumnTypes() in select.c) to determine the effective +** affinity of such a column for all rows require access to all values in +** the column simultaneously. +*/ +SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){ + + if( pParse->bHasWith /* condition (a) above */ + || pParse->db->init.busy /* condition (b) above */ + || exprListIsConstant(pParse,pRow)==0 /* condition (c) above */ + || (pLeft->pSrc->nSrc==0 && + exprListIsNoAffinity(pParse,pLeft->pEList)==0) /* condition (d) above */ + || IN_SPECIAL_PARSE + ){ + /* The co-routine method cannot be used. Fall back to UNION ALL. */ + Select *pSelect = 0; + int f = SF_Values | SF_MultiValue; + if( pLeft->pSrc->nSrc ){ + sqlite3MultiValuesEnd(pParse, pLeft); + f = SF_Values; + }else if( pLeft->pPrior ){ + /* In this case set the SF_MultiValue flag only if it was set on pLeft */ + f = (f & pLeft->selFlags); + } + pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); + pLeft->selFlags &= ~SF_MultiValue; + if( pSelect ){ + pSelect->op = TK_ALL; + pSelect->pPrior = pLeft; + pLeft = pSelect; + } + }else{ + SrcItem *p = 0; /* SrcItem that reads from co-routine */ + + if( pLeft->pSrc->nSrc==0 ){ + /* Co-routine has not yet been started and the special Select object + ** that accesses the co-routine has not yet been created. This block + ** does both those things. */ + Vdbe *v = sqlite3GetVdbe(pParse); + Select *pRet = sqlite3SelectNew(pParse, 0, 0, 0, 0, 0, 0, 0, 0); + + /* Ensure the database schema has been read. This is to ensure we have + ** the correct text encoding. */ + if( (pParse->db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ){ + sqlite3ReadSchema(pParse); + } + + if( pRet ){ + SelectDest dest; + Subquery *pSubq; + pRet->pSrc->nSrc = 1; + pRet->pPrior = pLeft->pPrior; + pRet->op = pLeft->op; + if( pRet->pPrior ) pRet->selFlags |= SF_Values; + pLeft->pPrior = 0; + pLeft->op = TK_SELECT; + assert( pLeft->pNext==0 ); + assert( pRet->pNext==0 ); + p = &pRet->pSrc->a[0]; + p->fg.viaCoroutine = 1; + p->iCursor = -1; + assert( !p->fg.isIndexedBy && !p->fg.isTabFunc ); + p->u1.nRow = 2; + if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){ + pSubq = p->u4.pSubq; + pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; + pSubq->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, + pSubq->regReturn, 0, pSubq->addrFillSub); + sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); + + /* Allocate registers for the output of the co-routine. Do so so + ** that there are two unused registers immediately before those + ** used by the co-routine. This allows the code in sqlite3Insert() + ** to use these registers directly, instead of copying the output + ** of the co-routine to a separate array for processing. */ + dest.iSdst = pParse->nMem + 3; + dest.nSdst = pLeft->pEList->nExpr; + pParse->nMem += 2 + dest.nSdst; + + pLeft->selFlags |= SF_MultiValue; + sqlite3Select(pParse, pLeft, &dest); + pSubq->regResult = dest.iSdst; + assert( pParse->nErr || dest.iSdst>0 ); + } + pLeft = pRet; + } + }else{ + p = &pLeft->pSrc->a[0]; + assert( !p->fg.isTabFunc && !p->fg.isIndexedBy ); + p->u1.nRow++; + } + + if( pParse->nErr==0 ){ + Subquery *pSubq; + assert( p!=0 ); + assert( p->fg.isSubquery ); + pSubq = p->u4.pSubq; + assert( pSubq!=0 ); + assert( pSubq->pSelect!=0 ); + assert( pSubq->pSelect->pEList!=0 ); + if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){ + sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect); + }else{ + sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0); + sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn); + } + } + sqlite3ExprListDelete(pParse->db, pRow); + } + + return pLeft; +} /* Forward declaration */ static int xferOptimization( @@ -132593,25 +134872,45 @@ SQLITE_PRIVATE void sqlite3Insert( if( pSelect ){ /* Data is coming from a SELECT or from a multi-row VALUES clause. ** Generate a co-routine to run the SELECT. */ - int regYield; /* Register holding co-routine entry-point */ - int addrTop; /* Top of the co-routine */ int rc; /* Result code */ - regYield = ++pParse->nMem; - addrTop = sqlite3VdbeCurrentAddr(v) + 1; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); - sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); - dest.iSdst = bIdListInOrder ? regData : 0; - dest.nSdst = pTab->nCol; - rc = sqlite3Select(pParse, pSelect, &dest); - regFromSelect = dest.iSdst; - assert( db->pParse==pParse ); - if( rc || pParse->nErr ) goto insert_cleanup; - assert( db->mallocFailed==0 ); - sqlite3VdbeEndCoroutine(v, regYield); - sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ - assert( pSelect->pEList ); - nColumn = pSelect->pEList->nExpr; + if( pSelect->pSrc->nSrc==1 + && pSelect->pSrc->a[0].fg.viaCoroutine + && pSelect->pPrior==0 + ){ + SrcItem *pItem = &pSelect->pSrc->a[0]; + Subquery *pSubq; + assert( pItem->fg.isSubquery ); + pSubq = pItem->u4.pSubq; + dest.iSDParm = pSubq->regReturn; + regFromSelect = pSubq->regResult; + assert( pSubq->pSelect!=0 ); + assert( pSubq->pSelect->pEList!=0 ); + nColumn = pSubq->pSelect->pEList->nExpr; + ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); + if( bIdListInOrder && nColumn==pTab->nCol ){ + regData = regFromSelect; + regRowid = regData - 1; + regIns = regRowid - (IsVirtual(pTab) ? 1 : 0); + } + }else{ + int addrTop; /* Top of the co-routine */ + int regYield = ++pParse->nMem; + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + dest.iSdst = bIdListInOrder ? regData : 0; + dest.nSdst = pTab->nCol; + rc = sqlite3Select(pParse, pSelect, &dest); + regFromSelect = dest.iSdst; + assert( db->pParse==pParse ); + if( rc || pParse->nErr ) goto insert_cleanup; + assert( db->mallocFailed==0 ); + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ + assert( pSelect->pEList ); + nColumn = pSelect->pEList->nExpr; + } /* Set useTempTable to TRUE if the result of the SELECT statement ** should be written into a temporary table (template 4). Set to @@ -132766,7 +135065,7 @@ SQLITE_PRIVATE void sqlite3Insert( pNx->iDataCur = iDataCur; pNx->iIdxCur = iIdxCur; if( pNx->pUpsertTarget ){ - if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){ + if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){ goto insert_cleanup; } } @@ -134507,7 +136806,7 @@ static int xferOptimization( if( pSelect->pSrc->nSrc!=1 ){ return 0; /* FROM clause must have exactly one term */ } - if( pSelect->pSrc->a[0].pSelect ){ + if( pSelect->pSrc->a[0].fg.isSubquery ){ return 0; /* FROM clause cannot contain a subquery */ } if( pSelect->pWhere ){ @@ -134658,7 +136957,10 @@ static int xferOptimization( } } #ifndef SQLITE_OMIT_CHECK - if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ + if( pDest->pCheck + && (db->mDbFlags & DBFLAG_Vacuum)==0 + && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) + ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif @@ -137333,6 +139635,34 @@ static const PragmaName aPragmaName[] = { /************** End of pragma.h **********************************************/ /************** Continuing where we left off in pragma.c *********************/ +/* +** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands +** will be run with an analysis_limit set to the lessor of the value of +** the following macro or to the actual analysis_limit if it is non-zero, +** in order to prevent PRAGMA optimize from running for too long. +** +** The value of 2000 is chosen emperically so that the worst-case run-time +** for PRAGMA optimize does not exceed 100 milliseconds against a variety +** of test databases on a RaspberryPI-4 compiled using -Os and without +** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of +** this paragraph, "worst-case" means that ANALYZE ends up being +** run on every table in the database. The worst case typically only +** happens if PRAGMA optimize is run on a database file for which ANALYZE +** has not been previously run and the 0x10000 flag is included so that +** all tables are analyzed. The usual case for PRAGMA optimize is that +** no ANALYZE commands will be run at all, or if any ANALYZE happens it +** will be against a single table, so that expected timing for PRAGMA +** optimize on a PI-4 is more like 1 millisecond or less with the 0x10000 +** flag or less than 100 microseconds without the 0x10000 flag. +** +** An analysis limit of 2000 is almost always sufficient for the query +** planner to fully characterize an index. The additional accuracy from +** a larger analysis is not usually helpful. +*/ +#ifndef SQLITE_DEFAULT_OPTIMIZE_LIMIT +# define SQLITE_DEFAULT_OPTIMIZE_LIMIT 2000 +#endif + /* ** Interpret the given string as a safety level. Return 0 for OFF, ** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or @@ -138419,12 +140749,6 @@ SQLITE_PRIVATE void sqlite3Pragma( ** in auto-commit mode. */ mask &= ~(SQLITE_ForeignKeys); } -#if SQLITE_USER_AUTHENTICATION - if( db->auth.authLevel==UAUTH_User ){ - /* Do not allow non-admin users to modify the schema arbitrarily */ - mask &= ~(SQLITE_WriteSchema); - } -#endif if( sqlite3GetBoolean(zRight, 0) ){ if( (mask & SQLITE_WriteSchema)==0 @@ -138560,7 +140884,8 @@ SQLITE_PRIVATE void sqlite3Pragma( char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName); if( zSql ){ sqlite3_stmt *pDummy = 0; - (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0); + (void)sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_DONT_LOG, + &pDummy, 0); (void)sqlite3_finalize(pDummy); sqlite3DbFree(db, zSql); } @@ -138978,7 +141303,7 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Set the maximum error count */ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; if( zRight ){ - if( sqlite3GetInt32(zRight, &mxErr) ){ + if( sqlite3GetInt32(pValue->z, &mxErr) ){ if( mxErr<=0 ){ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } @@ -138995,7 +141320,6 @@ SQLITE_PRIVATE void sqlite3Pragma( Hash *pTbls; /* Set of all tables in the schema */ int *aRoot; /* Array of root page numbers of all btrees */ int cnt = 0; /* Number of entries in aRoot[] */ - int mxIdx = 0; /* Maximum number of indexes for any table */ if( OMIT_TEMPDB && i==1 ) continue; if( iDb>=0 && i!=iDb ) continue; @@ -139017,7 +141341,6 @@ SQLITE_PRIVATE void sqlite3Pragma( if( pObjTab && pObjTab!=pTab ) continue; if( HasRowid(pTab) ) cnt++; for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } - if( nIdx>mxIdx ) mxIdx = nIdx; } if( cnt==0 ) continue; if( pObjTab ) cnt++; @@ -139037,12 +141360,13 @@ SQLITE_PRIVATE void sqlite3Pragma( aRoot[0] = cnt; /* Make sure sufficient number of registers have been allocated */ - sqlite3TouchRegister(pParse, 8+mxIdx); + sqlite3TouchRegister(pParse, 8+cnt); + sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt); sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ - sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); - sqlite3VdbeChangeP5(v, (u8)i); + sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); + sqlite3VdbeChangeP5(v, (u16)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), @@ -139051,6 +141375,36 @@ SQLITE_PRIVATE void sqlite3Pragma( integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, addr); + /* Check that the indexes all have the right number of rows */ + cnt = pObjTab ? 1 : 0; + sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + int iTab = 0; + Table *pTab = sqliteHashData(x); + Index *pIdx; + if( pObjTab && pObjTab!=pTab ) continue; + if( HasRowid(pTab) ){ + iTab = cnt++; + }else{ + iTab = cnt; + for(pIdx=pTab->pIndex; ALWAYS(pIdx); pIdx=pIdx->pNext){ + if( IsPrimaryKeyIndex(pIdx) ) break; + iTab++; + } + } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->pPartIdxWhere==0 ){ + addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+cnt, 0, 8+iTab); + VdbeCoverageNeverNull(v); + sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, addr); + } + cnt++; + } + } + /* Make sure all the indices are constructed correctly. */ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ @@ -139065,30 +141419,7 @@ SQLITE_PRIVATE void sqlite3Pragma( int mxCol; /* Maximum non-virtual column number */ if( pObjTab && pObjTab!=pTab ) continue; - if( !IsOrdinaryTable(pTab) ){ -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_vtab *pVTab; - int a1; - if( !IsVirtual(pTab) ) continue; - if( pTab->nCol<=0 ){ - const char *zMod = pTab->u.vtab.azArg[0]; - if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; - } - sqlite3ViewGetColumnNames(pParse, pTab); - if( pTab->u.vtab.p==0 ) continue; - pVTab = pTab->u.vtab.p->pVtab; - if( NEVER(pVTab==0) ) continue; - if( NEVER(pVTab->pModule==0) ) continue; - if( pVTab->pModule->iVersion<4 ) continue; - if( pVTab->pModule->xIntegrity==0 ) continue; - sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); - sqlite3VdbeAppendP4(v, pTab, P4_TABLE); - a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, a1); -#endif - continue; - } + if( !IsOrdinaryTable(pTab) ) continue; if( isQuick || HasRowid(pTab) ){ pPk = 0; r2 = 0; @@ -139223,6 +141554,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** is REAL, we have to load the actual data using OP_Column ** to reliably determine if the value is a NULL. */ sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); + sqlite3ColumnDefault(v, pTab, j, 3); jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); VdbeCoverage(v); } @@ -139396,23 +141728,43 @@ SQLITE_PRIVATE void sqlite3Pragma( } sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); sqlite3VdbeJumpHere(v, loopTop-1); - if( !isQuick ){ - sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - if( pPk==pIdx ) continue; - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - sqlite3VdbeLoadString(v, 4, pIdx->zName); - sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, addr); - } - if( pPk ){ - sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); - } + if( pPk ){ + assert( !isQuick ); + sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); } } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Second pass to invoke the xIntegrity method on all virtual + ** tables. + */ + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + sqlite3_vtab *pVTab; + int a1; + if( pObjTab && pObjTab!=pTab ) continue; + if( IsOrdinaryTable(pTab) ) continue; + if( !IsVirtual(pTab) ) continue; + if( pTab->nCol<=0 ){ + const char *zMod = pTab->u.vtab.azArg[0]; + if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; + } + sqlite3ViewGetColumnNames(pParse, pTab); + if( pTab->u.vtab.p==0 ) continue; + pVTab = pTab->u.vtab.p->pVtab; + if( NEVER(pVTab==0) ) continue; + if( NEVER(pVTab->pModule==0) ) continue; + if( pVTab->pModule->iVersion<4 ) continue; + if( pVTab->pModule->xIntegrity==0 ) continue; + sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); + pTab->nTabRef++; + sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF); + a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); + continue; + } +#endif } { static const int iLn = VDBE_OFFSET_LINENO(2); @@ -139676,44 +142028,63 @@ SQLITE_PRIVATE void sqlite3Pragma( ** ** The optional argument is a bitmask of optimizations to perform: ** - ** 0x0001 Debugging mode. Do not actually perform any optimizations - ** but instead return one line of text for each optimization - ** that would have been done. Off by default. + ** 0x00001 Debugging mode. Do not actually perform any optimizations + ** but instead return one line of text for each optimization + ** that would have been done. Off by default. ** - ** 0x0002 Run ANALYZE on tables that might benefit. On by default. - ** See below for additional information. + ** 0x00002 Run ANALYZE on tables that might benefit. On by default. + ** See below for additional information. ** - ** 0x0004 (Not yet implemented) Record usage and performance - ** information from the current session in the - ** database file so that it will be available to "optimize" - ** pragmas run by future database connections. + ** 0x00010 Run all ANALYZE operations using an analysis_limit that + ** is the lessor of the current analysis_limit and the + ** SQLITE_DEFAULT_OPTIMIZE_LIMIT compile-time option. + ** The default value of SQLITE_DEFAULT_OPTIMIZE_LIMIT is + ** currently (2024-02-19) set to 2000, which is such that + ** the worst case run-time for PRAGMA optimize on a 100MB + ** database will usually be less than 100 milliseconds on + ** a RaspberryPI-4 class machine. On by default. ** - ** 0x0008 (Not yet implemented) Create indexes that might have - ** been helpful to recent queries + ** 0x10000 Look at tables to see if they need to be reanalyzed + ** due to growth or shrinkage even if they have not been + ** queried during the current connection. Off by default. ** - ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all - ** of the optimizations listed above except Debug Mode, including new - ** optimizations that have not yet been invented. If new optimizations are - ** ever added that should be off by default, those off-by-default - ** optimizations will have bitmasks of 0x10000 or larger. + ** The default MASK is and always shall be 0x0fffe. In the current + ** implementation, the default mask only covers the 0x00002 optimization, + ** though additional optimizations that are covered by 0x0fffe might be + ** added in the future. Optimizations that are off by default and must + ** be explicitly requested have masks of 0x10000 or greater. ** ** DETERMINATION OF WHEN TO RUN ANALYZE ** ** In the current implementation, a table is analyzed if only if all of ** the following are true: ** - ** (1) MASK bit 0x02 is set. + ** (1) MASK bit 0x00002 is set. + ** + ** (2) The table is an ordinary table, not a virtual table or view. ** - ** (2) The query planner used sqlite_stat1-style statistics for one or - ** more indexes of the table at some point during the lifetime of - ** the current connection. + ** (3) The table name does not begin with "sqlite_". ** - ** (3) One or more indexes of the table are currently unanalyzed OR - ** the number of rows in the table has increased by 25 times or more - ** since the last time ANALYZE was run. + ** (4) One or more of the following is true: + ** (4a) The 0x10000 MASK bit is set. + ** (4b) One or more indexes on the table lacks an entry + ** in the sqlite_stat1 table. + ** (4c) The query planner used sqlite_stat1-style statistics for one + ** or more indexes of the table at some point during the lifetime + ** of the current connection. + ** + ** (5) One or more of the following is true: + ** (5a) One or more indexes on the table lacks an entry + ** in the sqlite_stat1 table. (Same as 4a) + ** (5b) The number of rows in the table has increased or decreased by + ** 10-fold. In other words, the current size of the table is + ** 10 times larger than the size in sqlite_stat1 or else the + ** current size is less than 1/10th the size in sqlite_stat1. ** ** The rules for when tables are analyzed are likely to change in - ** future releases. + ** future releases. Future versions of SQLite might accept a string + ** literal argument to this pragma that contains a mnemonic description + ** of the options rather than a bitmap. */ case PragTyp_OPTIMIZE: { int iDbLast; /* Loop termination point for the schema loop */ @@ -139725,6 +142096,10 @@ SQLITE_PRIVATE void sqlite3Pragma( LogEst szThreshold; /* Size threshold above which reanalysis needed */ char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ u32 opMask; /* Mask of operations to perform */ + int nLimit; /* Analysis limit to use */ + int nCheck = 0; /* Number of tables to be optimized */ + int nBtree = 0; /* Number of btrees to scan */ + int nIndex; /* Number of indexes on the current table */ if( zRight ){ opMask = (u32)sqlite3Atoi(zRight); @@ -139732,6 +142107,14 @@ SQLITE_PRIVATE void sqlite3Pragma( }else{ opMask = 0xfffe; } + if( (opMask & 0x10)==0 ){ + nLimit = 0; + }else if( db->nAnalysisLimit>0 + && db->nAnalysisLimit<SQLITE_DEFAULT_OPTIMIZE_LIMIT ){ + nLimit = 0; + }else{ + nLimit = SQLITE_DEFAULT_OPTIMIZE_LIMIT; + } iTabCur = pParse->nTab++; for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ if( iDb==1 ) continue; @@ -139740,23 +142123,61 @@ SQLITE_PRIVATE void sqlite3Pragma( for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ pTab = (Table*)sqliteHashData(k); - /* If table pTab has not been used in a way that would benefit from - ** having analysis statistics during the current session, then skip it. - ** This also has the effect of skipping virtual tables and views */ - if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue; + /* This only works for ordinary tables */ + if( !IsOrdinaryTable(pTab) ) continue; - /* Reanalyze if the table is 25 times larger than the last analysis */ - szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); + /* Do not scan system tables */ + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ) continue; + + /* Find the size of the table as last recorded in sqlite_stat1. + ** If any index is unanalyzed, then the threshold is -1 to + ** indicate a new, unanalyzed index + */ + szThreshold = pTab->nRowLogEst; + nIndex = 0; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + nIndex++; if( !pIdx->hasStat1 ){ - szThreshold = 0; /* Always analyze if any index lacks statistics */ - break; + szThreshold = -1; /* Always analyze if any index lacks statistics */ } } - if( szThreshold ){ - sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); - sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, - sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold); + + /* If table pTab has not been used in a way that would benefit from + ** having analysis statistics during the current session, then skip it, + ** unless the 0x10000 MASK bit is set. */ + if( (pTab->tabFlags & TF_MaybeReanalyze)!=0 ){ + /* Check for size change if stat1 has been used for a query */ + }else if( opMask & 0x10000 ){ + /* Check for size change if 0x10000 is set */ + }else if( pTab->pIndex!=0 && szThreshold<0 ){ + /* Do analysis if unanalyzed indexes exists */ + }else{ + /* Otherwise, we can skip this table */ + continue; + } + + nCheck++; + if( nCheck==2 ){ + /* If ANALYZE might be invoked two or more times, hold a write + ** transaction for efficiency */ + sqlite3BeginWriteOperation(pParse, 0, iDb); + } + nBtree += nIndex+1; + + /* Reanalyze if the table is 10 times larger or smaller than + ** the last analysis. Unconditional reanalysis if there are + ** unanalyzed indexes. */ + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + if( szThreshold>=0 ){ + const LogEst iRange = 33; /* 10x size change */ + sqlite3VdbeAddOp4Int(v, OP_IfSizeBetween, iTabCur, + sqlite3VdbeCurrentAddr(v)+2+(opMask&1), + szThreshold>=iRange ? szThreshold-iRange : -1, + szThreshold+iRange); + VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Rewind, iTabCur, + sqlite3VdbeCurrentAddr(v)+2+(opMask&1)); VdbeCoverage(v); } zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", @@ -139766,11 +142187,27 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); }else{ - sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); + sqlite3VdbeAddOp4(v, OP_SqlExec, nLimit ? 0x02 : 00, nLimit, 0, + zSubSql, P4_DYNAMIC); } } } sqlite3VdbeAddOp0(v, OP_Expire); + + /* In a schema with a large number of tables and indexes, scale back + ** the analysis_limit to avoid excess run-time in the worst case. + */ + if( !db->mallocFailed && nLimit>0 && nBtree>100 ){ + int iAddr, iEnd; + VdbeOp *aOp; + nLimit = 100*nLimit/nBtree; + if( nLimit<100 ) nLimit = 100; + aOp = sqlite3VdbeGetOp(v, 0); + iEnd = sqlite3VdbeCurrentAddr(v); + for(iAddr=0; iAddr<iEnd; iAddr++){ + if( aOp[iAddr].opcode==OP_SqlExec ) aOp[iAddr].p2 = nLimit; + } + } break; } @@ -140034,9 +142471,9 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ seen[0] = 0; seen[1] = 0; for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ - if( pConstraint->usable==0 ) continue; - if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; if( pConstraint->iColumn < pTab->iHidden ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( pConstraint->usable==0 ) return SQLITE_CONSTRAINT; j = pConstraint->iColumn - pTab->iHidden; assert( j < 2 ); seen[j] = i+1; @@ -140049,12 +142486,13 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ j = seen[0]-1; pIdxInfo->aConstraintUsage[j].argvIndex = 1; pIdxInfo->aConstraintUsage[j].omit = 1; - if( seen[1]==0 ) return SQLITE_OK; pIdxInfo->estimatedCost = (double)20; pIdxInfo->estimatedRows = 20; - j = seen[1]-1; - pIdxInfo->aConstraintUsage[j].argvIndex = 2; - pIdxInfo->aConstraintUsage[j].omit = 1; + if( seen[1] ){ + j = seen[1]-1; + pIdxInfo->aConstraintUsage[j].argvIndex = 2; + pIdxInfo->aConstraintUsage[j].omit = 1; + } return SQLITE_OK; } @@ -140074,6 +142512,7 @@ static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ int i; sqlite3_finalize(pCsr->pPragma); pCsr->pPragma = 0; + pCsr->iRowid = 0; for(i=0; i<ArraySize(pCsr->azArg); i++){ sqlite3_free(pCsr->azArg[i]); pCsr->azArg[i] = 0; @@ -140547,14 +142986,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl #else encoding = SQLITE_UTF8; #endif - if( db->nVdbeActive>0 && encoding!=ENC(db) - && (db->mDbFlags & DBFLAG_Vacuum)==0 - ){ - rc = SQLITE_LOCKED; - goto initone_error_out; - }else{ - sqlite3SetTextEncoding(db, encoding); - } + sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ @@ -140874,7 +143306,13 @@ SQLITE_PRIVATE void *sqlite3ParserAddCleanup( void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ void *pPtr /* Pointer to object to be cleaned up */ ){ - ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + ParseCleanup *pCleanup; + if( sqlite3FaultSim(300) ){ + pCleanup = 0; + sqlite3OomFault(pParse->db); + }else{ + pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + } if( pCleanup ){ pCleanup->pNext = pParse->pCleanup; pParse->pCleanup = pCleanup; @@ -141109,6 +143547,7 @@ static int sqlite3LockAndPrepare( assert( (rc&db->errMask)==rc ); db->busyHandler.nBusy = 0; sqlite3_mutex_leave(db->mutex); + assert( rc==SQLITE_OK || (*ppStmt)==0 ); return rc; } @@ -141241,12 +143680,24 @@ static int sqlite3Prepare16( if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; } + + /* Make sure nBytes is non-negative and correct. It should be the + ** number of bytes until the end of the input buffer or until the first + ** U+0000 character. If the input nBytes is odd, convert it into + ** an even number. If the input nBytes is negative, then the input + ** must be terminated by at least one U+0000 character */ if( nBytes>=0 ){ int sz; const char *z = (const char*)zSql; for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){} nBytes = sz; + }else{ + int sz; + const char *z = (const char*)zSql; + for(sz=0; z[sz]!=0 || z[sz+1]!=0; sz += 2){} + nBytes = sz; } + sqlite3_mutex_enter(db->mutex); zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); if( zSql8 ){ @@ -141260,7 +143711,7 @@ static int sqlite3Prepare16( ** the same number of characters into the UTF-16 string. */ int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); - *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); + *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, nBytes, chars_parsed); } sqlite3DbFree(db, zSql8); rc = sqlite3ApiExit(db, rc); @@ -141506,6 +143957,9 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); } +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) clearSelect(db, (Select*)p, 1); +} /* ** Return a pointer to the right-most SELECT statement in a compound. @@ -141651,11 +144105,13 @@ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ */ SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ assert( pItem!=0 ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); if( pItem->fg.isNestedFrom ){ ExprList *pResults; - assert( pItem->pSelect!=0 ); - pResults = pItem->pSelect->pEList; + assert( pItem->fg.isSubquery ); + assert( pItem->u4.pSubq!=0 ); + assert( pItem->u4.pSubq->pSelect!=0 ); + pResults = pItem->u4.pSubq->pSelect->pEList; assert( pResults!=0 ); assert( iCol>=0 && iCol<pResults->nExpr ); pResults->a[iCol].fg.bUsed = 1; @@ -141689,9 +144145,9 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=iStart; i<=iEnd; i++){ - iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol); if( iCol>=0 - && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) + && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0) ){ if( piTab ){ sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); @@ -141820,10 +144276,10 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ - Table *pRightTab = pRight->pTab; + Table *pRightTab = pRight->pSTab; u32 joinType; - if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; + if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue; joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; /* If this is a NATURAL join, synthesize an appropriate USING clause @@ -142696,12 +145152,18 @@ static void selectInnerLoop( ** case the order does matter */ pushOntoSorter( pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + pDest->iSDParm2 = 0; /* Signal that any Bloom filter is unpopulated */ }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + if( pDest->iSDParm2 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + regResult, nResultCol); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } sqlite3ReleaseTempReg(pParse, r1); } break; @@ -142992,9 +145454,16 @@ static void generateSortTail( int addrExplain; /* Address of OP_Explain instruction */ #endif - ExplainQueryPlan2(addrExplain, (pParse, 0, - "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"") - ); + nKey = pOrderBy->nExpr - pSort->nOBSat; + if( pSort->nOBSat==0 || nKey==1 ){ + ExplainQueryPlan2(addrExplain, (pParse, 0, + "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat?"LAST TERM OF ":"" + )); + }else{ + ExplainQueryPlan2(addrExplain, (pParse, 0, + "USE TEMP B-TREE FOR LAST %d TERMS OF ORDER BY", nKey + )); + } sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); @@ -143032,7 +145501,6 @@ static void generateSortTail( regRow = sqlite3GetTempRange(pParse, nColumn); } } - nKey = pOrderBy->nExpr - pSort->nOBSat; if( pSort->sortFlags & SORTFLAG_UseSorter ){ int regSortOut = ++pParse->nMem; iSortTab = pParse->nTab++; @@ -143237,8 +145705,12 @@ static const char *columnTypeImpl( SrcList *pTabList = pNC->pSrcList; for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); if( j<pTabList->nSrc ){ - pTab = pTabList->a[j].pTab; - pS = pTabList->a[j].pSelect; + pTab = pTabList->a[j].pSTab; + if( pTabList->a[j].fg.isSubquery ){ + pS = pTabList->a[j].u4.pSubq->pSelect; + }else{ + pS = 0; + } }else{ pNC = pNC->pNext; } @@ -143272,11 +145744,7 @@ static const char *columnTypeImpl( ** data for the result-set column of the sub-select. */ if( iCol<pS->pEList->nExpr -#ifdef SQLITE_ALLOW_ROWID_IN_VIEW - && iCol>=0 -#else - && ALWAYS(iCol>=0) -#endif + && (!ViewCanHaveRowid || iCol>=0) ){ /* If iCol is less than zero, then the expression requests the ** rowid of the sub-select or view. This expression is legal (see @@ -143641,8 +146109,7 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( NameContext sNC; assert( pSelect!=0 ); - testcase( (pSelect->selFlags & SF_Resolved)==0 ); - assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT ); + assert( (pSelect->selFlags & SF_Resolved)!=0 ); assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); if( db->mallocFailed || IN_RENAME_OBJECT ) return; @@ -143653,17 +146120,22 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ const char *zType; i64 n; + int m = 0; + Select *pS2 = pSelect; pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); p = a[i].pExpr; /* pCol->szEst = ... // Column size est for SELECT tables never used */ pCol->affinity = sqlite3ExprAffinity(p); + while( pCol->affinity<=SQLITE_AFF_NONE && pS2->pNext!=0 ){ + m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); + pS2 = pS2->pNext; + pCol->affinity = sqlite3ExprAffinity(pS2->pEList->a[i].pExpr); + } if( pCol->affinity<=SQLITE_AFF_NONE ){ pCol->affinity = aff; } - if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){ - int m = 0; - Select *pS2; - for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){ + if( pCol->affinity>=SQLITE_AFF_TEXT && (pS2->pNext || pS2!=pSelect) ){ + for(pS2=pS2->pNext; pS2; pS2=pS2->pNext){ m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); } if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ @@ -143693,12 +146165,12 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( } } if( zType ){ - i64 m = sqlite3Strlen30(zType); + const i64 k = sqlite3Strlen30(zType); n = sqlite3Strlen30(pCol->zCnName); - pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2); pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); if( pCol->zCnName ){ - memcpy(&pCol->zCnName[n+1], zType, m+1); + memcpy(&pCol->zCnName[n+1], zType, k+1); pCol->colFlags |= COLFLAG_HASTYPE; } } @@ -143805,7 +146277,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); assert( v!=0 ); - if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ + if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse) ){ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); if( n==0 ){ @@ -144285,7 +146757,7 @@ static int multiSelect( p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); if( p->pLimit - && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit) + && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse) && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ p->nSelectRow = sqlite3LogEst((u64)nLimit); @@ -144526,9 +146998,7 @@ static int multiSelect( pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; if( pDelete ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3SelectDelete, - pDelete); + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); } return rc; } @@ -144631,6 +147101,11 @@ static int generateOutputSubroutine( r1, pDest->zAffSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); + if( pDest->iSDParm2>0 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + pIn->iSdst, pIn->nSdst); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } sqlite3ReleaseTempReg(pParse, r1); break; } @@ -145079,8 +147554,7 @@ static int multiSelectOrderBy( /* Make arrangements to free the 2nd and subsequent arms of the compound ** after the parse has finished */ if( pSplit->pPrior ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSplit->pPrior); } pSplit->pPrior = pPrior; pPrior->pNext = pSplit; @@ -145210,32 +147684,32 @@ static Expr *substExpr( if( pSubst->isOuterJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } - if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ - sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, - pExpr->flags & (EP_OuterON|EP_InnerON)); - } - sqlite3ExprDelete(db, pExpr); - pExpr = pNew; - if( pExpr->op==TK_TRUEFALSE ){ - pExpr->u.iValue = sqlite3ExprTruthValue(pExpr); - pExpr->op = TK_INTEGER; - ExprSetProperty(pExpr, EP_IntValue); + if( pNew->op==TK_TRUEFALSE ){ + pNew->u.iValue = sqlite3ExprTruthValue(pNew); + pNew->op = TK_INTEGER; + ExprSetProperty(pNew, EP_IntValue); } /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ { - CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pNew); CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pSubst->pCList->a[iColumn].pExpr ); - if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){ - pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + if( pNat!=pColl || (pNew->op!=TK_COLUMN && pNew->op!=TK_COLLATE) ){ + pNew = sqlite3ExprAddCollateString(pSubst->pParse, pNew, (pColl ? pColl->zName : "BINARY") ); } } - ExprClearProperty(pExpr, EP_Collate); + ExprClearProperty(pNew, EP_Collate); + if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, + pExpr->flags & (EP_OuterON|EP_InnerON)); + } + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; } } }else{ @@ -145288,7 +147762,9 @@ static void substSelect( pSrc = p->pSrc; assert( pSrc!=0 ); for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - substSelect(pSubst, pItem->pSelect, 1); + if( pItem->fg.isSubquery ){ + substSelect(pSubst, pItem->u4.pSubq->pSelect, 1); + } if( pItem->fg.isTabFunc ){ substExprList(pSubst, pItem->u1.pFuncArg); } @@ -145319,7 +147795,7 @@ static void recomputeColumnsUsed( SrcItem *pSrcItem /* Which FROM clause item to recompute */ ){ Walker w; - if( NEVER(pSrcItem->pTab==0) ) return; + if( NEVER(pSrcItem->pSTab==0) ) return; memset(&w, 0, sizeof(w)); w.xExprCallback = recomputeColumnsUsedExpr; w.xSelectCallback = sqlite3SelectWalkNoop; @@ -145359,8 +147835,10 @@ static void srclistRenumberCursors( aCsrMap[pItem->iCursor+1] = pParse->nTab++; } pItem->iCursor = aCsrMap[pItem->iCursor+1]; - for(p=pItem->pSelect; p; p=p->pPrior){ - srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + if( pItem->fg.isSubquery ){ + for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } } } } @@ -145671,7 +148149,8 @@ static int flattenSubquery( assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); pSubitem = &pSrc->a[iFrom]; iParent = pSubitem->iCursor; - pSub = pSubitem->pSelect; + assert( pSubitem->fg.isSubquery ); + pSub = pSubitem->u4.pSubq->pSelect; assert( pSub!=0 ); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -145724,7 +148203,7 @@ static int flattenSubquery( */ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ - || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ + || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ ){ @@ -145810,14 +148289,18 @@ static int flattenSubquery( pParse->zAuthContext = zSavedAuthContext; /* Delete the transient structures associated with the subquery */ - pSub1 = pSubitem->pSelect; - sqlite3DbFree(db, pSubitem->zDatabase); + + if( ALWAYS(pSubitem->fg.isSubquery) ){ + pSub1 = sqlite3SubqueryDetach(db, pSubitem); + }else{ + pSub1 = 0; + } + assert( pSubitem->fg.isSubquery==0 ); + assert( pSubitem->fg.fixedSchema==0 ); sqlite3DbFree(db, pSubitem->zName); sqlite3DbFree(db, pSubitem->zAlias); - pSubitem->zDatabase = 0; pSubitem->zName = 0; pSubitem->zAlias = 0; - pSubitem->pSelect = 0; assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); /* If the sub-query is a compound SELECT statement, then (by restrictions @@ -145858,8 +148341,8 @@ static int flattenSubquery( ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; Select *pPrior = p->pPrior; - Table *pItemTab = pSubitem->pTab; - pSubitem->pTab = 0; + Table *pItemTab = pSubitem->pSTab; + pSubitem->pSTab = 0; p->pOrderBy = 0; p->pPrior = 0; p->pLimit = 0; @@ -145867,7 +148350,7 @@ static int flattenSubquery( p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->op = TK_ALL; - pSubitem->pTab = pItemTab; + pSubitem->pSTab = pItemTab; if( pNew==0 ){ p->pPrior = pPrior; }else{ @@ -145882,11 +148365,14 @@ static int flattenSubquery( TREETRACE(0x4,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } - assert( pSubitem->pSelect==0 ); + assert( pSubitem->fg.isSubquery==0 ); } sqlite3DbFree(db, aCsrMap); if( db->mallocFailed ){ - pSubitem->pSelect = pSub1; + assert( pSubitem->fg.fixedSchema==0 ); + assert( pSubitem->fg.isSubquery==0 ); + assert( pSubitem->u4.zDatabase==0 ); + sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0); return 1; } @@ -145897,18 +148383,16 @@ static int flattenSubquery( ** ** pSubitem->pTab is always non-NULL by test restrictions and tests above. */ - if( ALWAYS(pSubitem->pTab!=0) ){ - Table *pTabToDel = pSubitem->pTab; + if( ALWAYS(pSubitem->pSTab!=0) ){ + Table *pTabToDel = pSubitem->pSTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - sqlite3ParserAddCleanup(pToplevel, - (void(*)(sqlite3*,void*))sqlite3DeleteTable, - pTabToDel); + sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); testcase( pToplevel->earlyCleanup ); }else{ pTabToDel->nTabRef--; } - pSubitem->pTab = 0; + pSubitem->pSTab = 0; } /* The following loop runs once for each term in a compound-subquery @@ -145962,13 +148446,16 @@ static int flattenSubquery( /* Transfer the FROM clause terms from the subquery into the ** outer query. */ + iNewParent = pSubSrc->a[0].iCursor; for(i=0; i<nSubSrc; i++){ SrcItem *pItem = &pSrc->a[i+iFrom]; - if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); assert( pItem->fg.isTabFunc==0 ); + assert( pItem->fg.isSubquery + || pItem->fg.fixedSchema + || pItem->u4.zDatabase==0 ); + if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); *pItem = pSubSrc->a[i]; pItem->fg.jointype |= ltorj; - iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].fg.jointype &= JT_LTORJ; @@ -146008,6 +148495,7 @@ static int flattenSubquery( pWhere = pSub->pWhere; pSub->pWhere = 0; if( isOuterJoin>0 ){ + assert( pSubSrc->nSrc==1 ); sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON); } if( pWhere ){ @@ -146100,7 +148588,7 @@ static void constInsert( ){ int i; assert( pColumn->op==TK_COLUMN ); - assert( sqlite3ExprIsConstant(pValue) ); + assert( sqlite3ExprIsConstant(pConst->pParse, pValue) ); if( ExprHasProperty(pColumn, EP_FixedCol) ) return; if( sqlite3ExprAffinity(pValue)!=0 ) return; @@ -146158,10 +148646,10 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ pLeft = pExpr->pLeft; assert( pRight!=0 ); assert( pLeft!=0 ); - if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){ + if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pLeft) ){ constInsert(pConst,pRight,pLeft,pExpr); } - if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){ + if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pRight) ){ constInsert(pConst,pLeft,pRight,pExpr); } } @@ -146382,6 +148870,19 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** The hope is that the terms added to the inner query will make it more ** efficient. ** +** NAME AMBIGUITY +** +** This optimization is called the "WHERE-clause push-down optimization" +** or sometimes the "predicate push-down optimization". +** +** Do not confuse this optimization with another unrelated optimization +** with a similar name: The "MySQL push-down optimization" causes WHERE +** clause terms that can be evaluated using only the index and without +** reference to the table are run first, so that if they are false, +** unnecessary table seeks are avoided. +** +** RULES +** ** Do not attempt this optimization if: ** ** (1) (** This restriction was removed on 2017-09-29. We used to @@ -146447,15 +148948,19 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING ** clause and the subquery. ** -** Without this restriction, the push-down optimization might move -** the ON/USING filter expression from the left side of a RIGHT JOIN -** over to the right side, which leads to incorrect answers. See -** also restriction (6) in sqlite3ExprIsSingleTableConstraint(). +** Without this restriction, the WHERE-clause push-down optimization +** might move the ON/USING filter expression from the left side of a +** RIGHT JOIN over to the right side, which leads to incorrect answers. +** See also restriction (6) in sqlite3ExprIsSingleTableConstraint(). ** ** (10) The inner query is not the right-hand table of a RIGHT JOIN. ** ** (11) The subquery is not a VALUES clause ** +** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This +** case only comes up if SQLite is compiled using +** SQLITE_ALLOW_ROWID_IN_VIEW. +** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. */ @@ -146566,7 +149071,19 @@ static int pushDownWhereTerms( } #endif - if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( ViewCanHaveRowid && (pWhere->op==TK_ISNULL || pWhere->op==TK_NOTNULL) ){ + Expr *pLeft = pWhere->pLeft; + if( ALWAYS(pLeft) + && pLeft->op==TK_COLUMN + && pLeft->iColumn < 0 + ){ + return 0; /* Restriction (12) */ + } + } +#endif + + if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ @@ -146620,10 +149137,10 @@ static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ if( pItem->fg.isCorrelated || pItem->fg.isCte ){ return 0; } - assert( pItem->pTab!=0 ); - pTab = pItem->pTab; - assert( pItem->pSelect!=0 ); - pSub = pItem->pSelect; + assert( pItem->pSTab!=0 ); + pTab = pItem->pSTab; + assert( pItem->fg.isSubquery ); + pSub = pItem->u4.pSubq->pSelect; assert( pSub->pEList->nExpr==pTab->nCol ); for(pX=pSub; pX; pX=pX->pPrior){ if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ @@ -146752,13 +149269,13 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ if( p->pWhere || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 - || p->pSrc->a[0].pSelect + || p->pSrc->a[0].fg.isSubquery || pAggInfo->nFunc!=1 || p->pHaving ){ return 0; } - pTab = p->pSrc->a[0].pTab; + pTab = p->pSrc->a[0].pSTab; assert( pTab!=0 ); assert( !IsView(pTab) ); if( !IsOrdinaryTable(pTab) ) return 0; @@ -146783,7 +149300,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** pFrom->pIndex and return SQLITE_OK. */ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ - Table *pTab = pFrom->pTab; + Table *pTab = pFrom->pSTab; char *zIndexedBy = pFrom->u1.zIndexedBy; Index *pIdx; assert( pTab!=0 ); @@ -146860,7 +149377,11 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ if( pNew==0 ) return WRC_Abort; memset(&dummy, 0, sizeof(dummy)); pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); - if( pNewSrc==0 ) return WRC_Abort; + assert( pNewSrc!=0 || pParse->nErr ); + if( pParse->nErr ){ + sqlite3SrcListDelete(db, pNewSrc); + return WRC_Abort; + } *pNew = *p; p->pSrc = pNewSrc; p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); @@ -146915,7 +149436,7 @@ static struct Cte *searchWith( ){ const char *zName = pItem->zName; With *p; - assert( pItem->zDatabase==0 ); + assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 ); assert( zName!=0 ); for(p=pWith; p; p=p->pOuter){ int i; @@ -146950,8 +149471,7 @@ static struct Cte *searchWith( SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ if( pWith ){ if( bFree ){ - pWith = (With*)sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith = (With*)sqlite3ParserAddCleanup(pParse, sqlite3WithDeleteGeneric, pWith); if( pWith==0 ) return 0; } @@ -146986,7 +149506,7 @@ static int resolveFromTermToCte( Cte *pCte; /* Matched CTE (or NULL if no match) */ With *pWith; /* The matching WITH */ - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); if( pParse->pWith==0 ){ /* There are no WITH clauses in the stack. No match is possible */ return 0; @@ -146996,7 +149516,8 @@ static int resolveFromTermToCte( ** go no further. */ return 0; } - if( pFrom->zDatabase!=0 ){ + assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 ); + if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){ /* The FROM term contains a schema qualifier (ex: main.t1) and so ** it cannot possibly be a CTE reference. */ return 0; @@ -147032,7 +149553,7 @@ static int resolveFromTermToCte( } if( cannotBeFunction(pParse, pFrom) ) return 2; - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return 2; pCteUse = pCte->pUse; @@ -147046,26 +149567,29 @@ static int resolveFromTermToCte( } pCteUse->eM10d = pCte->eM10d; } - pFrom->pTab = pTab; + pFrom->pSTab = pTab; pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; - pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); + sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1); if( db->mallocFailed ) return 2; - pFrom->pSelect->selFlags |= SF_CopyCte; - assert( pFrom->pSelect ); + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); + pSel = pFrom->u4.pSubq->pSelect; + assert( pSel!=0 ); + pSel->selFlags |= SF_CopyCte; if( pFrom->fg.isIndexedBy ){ sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); return 2; } + assert( !pFrom->fg.isIndexedBy ); pFrom->fg.isCte = 1; pFrom->u2.pCteUse = pCteUse; pCteUse->nUse++; /* Check if this is a recursive CTE. */ - pRecTerm = pSel = pFrom->pSelect; + pRecTerm = pSel; bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); while( bMayRecursive && pRecTerm->op==pSel->op ){ int i; @@ -147073,11 +149597,13 @@ static int resolveFromTermToCte( assert( pRecTerm->pPrior!=0 ); for(i=0; i<pSrc->nSrc; i++){ SrcItem *pItem = &pSrc->a[i]; - if( pItem->zDatabase==0 - && pItem->zName!=0 + if( pItem->zName!=0 + && !pItem->fg.hadSchema + && ALWAYS( !pItem->fg.isSubquery ) + && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0) && 0==sqlite3StrICmp(pItem->zName, pCte->zName) ){ - pItem->pTab = pTab; + pItem->pSTab = pTab; pTab->nTabRef++; pItem->fg.isRecursive = 1; if( pRecTerm->selFlags & SF_Recursive ){ @@ -147179,11 +149705,14 @@ SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){ ** SQLITE_NOMEM. */ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ - Select *pSel = pFrom->pSelect; + Select *pSel; Table *pTab; + assert( pFrom->fg.isSubquery ); + assert( pFrom->u4.pSubq!=0 ); + pSel = pFrom->u4.pSubq->pSelect; assert( pSel ); - pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); + pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); if( pTab==0 ) return SQLITE_NOMEM; pTab->nTabRef = 1; if( pFrom->zAlias ){ @@ -147194,12 +149723,14 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ while( pSel->pPrior ){ pSel = pSel->pPrior; } sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); pTab->iPKey = -1; + pTab->eTabType = TABTYP_VIEW; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); #ifndef SQLITE_ALLOW_ROWID_IN_VIEW /* The usual case - do not allow ROWID on a subquery */ pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; #else - pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */ + /* Legacy compatibility mode */ + pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid; #endif return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; } @@ -147301,33 +149832,35 @@ static int selectExpander(Walker *pWalker, Select *p){ */ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ Table *pTab; - assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); - if( pFrom->pTab ) continue; + assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 ); + if( pFrom->pSTab ) continue; assert( pFrom->fg.isRecursive==0 ); if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY - Select *pSel = pFrom->pSelect; + Select *pSel; + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 ); + pSel = pFrom->u4.pSubq->pSelect; /* A sub-query in the FROM clause of a SELECT */ assert( pSel!=0 ); - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; #endif #ifndef SQLITE_OMIT_CTE }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ if( rc>1 ) return WRC_Abort; - pTab = pFrom->pTab; + pTab = pFrom->pSTab; assert( pTab!=0 ); #endif }else{ /* An ordinary table or view name in the FROM clause */ - assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); + assert( pFrom->pSTab==0 ); + pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); if( pTab==0 ) return WRC_Abort; if( pTab->nTabRef>=0xffff ){ sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", pTab->zName); - pFrom->pTab = 0; + pFrom->pSTab = 0; return WRC_Abort; } pTab->nTabRef++; @@ -147339,7 +149872,7 @@ static int selectExpander(Walker *pWalker, Select *p){ i16 nCol; u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; - assert( pFrom->pSelect==0 ); + assert( pFrom->fg.isSubquery==0 ); if( IsView(pTab) ){ if( (db->flags & SQLITE_EnableView)==0 && pTab->pSchema!=db->aDb[1].pSchema @@ -147347,7 +149880,7 @@ static int selectExpander(Walker *pWalker, Select *p){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } - pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0); + sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( ALWAYS(IsVirtual(pTab)) @@ -147363,7 +149896,9 @@ static int selectExpander(Walker *pWalker, Select *p){ nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ - sqlite3WalkSelect(pWalker, pFrom->pSelect); + if( pFrom->fg.isSubquery ){ + sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect); + } pWalker->eCode = eCodeOrig; pTab->nCol = nCol; } @@ -147450,7 +149985,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ int nAdd; /* Number of cols including rowid */ - Table *pTab = pFrom->pTab; /* Table for this data source */ + Table *pTab = pFrom->pSTab; /* Table for this data source */ ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ char *zTabName; /* AS name for this data source */ const char *zSchemaName = 0; /* Schema name for this data source */ @@ -147461,13 +149996,14 @@ static int selectExpander(Walker *pWalker, Select *p){ zTabName = pTab->zName; } if( db->mallocFailed ) break; - assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); + assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) ); if( pFrom->fg.isNestedFrom ){ - assert( pFrom->pSelect!=0 ); - pNestedFrom = pFrom->pSelect->pEList; + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); + assert( pFrom->u4.pSubq->pSelect!=0 ); + pNestedFrom = pFrom->u4.pSubq->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); - assert( VisibleRowid(pTab)==0 ); + assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); }else{ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; @@ -147499,7 +150035,8 @@ static int selectExpander(Walker *pWalker, Select *p){ pUsing = 0; } - nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom)); + nAdd = pTab->nCol; + if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++; for(j=0; j<nAdd; j++){ const char *zName; struct ExprList_item *pX; /* Newly added ExprList term */ @@ -147581,7 +150118,8 @@ static int selectExpander(Walker *pWalker, Select *p){ pX = &pNew->a[pNew->nExpr-1]; assert( pX->zEName==0 ); if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ - if( pNestedFrom ){ + if( pNestedFrom && (!ViewCanHaveRowid || j<pNestedFrom->nExpr) ){ + assert( j<pNestedFrom->nExpr ); pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName); testcase( pX->zEName==0 ); }else{ @@ -147698,18 +150236,15 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ if( p->selFlags & SF_HasTypeInfo ) return; p->selFlags |= SF_HasTypeInfo; pParse = pWalker->pParse; - testcase( (p->selFlags & SF_Resolved)==0 ); - assert( (p->selFlags & SF_Resolved) || IN_RENAME_OBJECT ); + assert( (p->selFlags & SF_Resolved) ); pTabList = p->pSrc; for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ - Table *pTab = pFrom->pTab; + Table *pTab = pFrom->pSTab; assert( pTab!=0 ); - if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ + if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){ /* A sub-query in the FROM clause of a SELECT */ - Select *pSel = pFrom->pSelect; - if( pSel ){ - sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); - } + Select *pSel = pFrom->u4.pSubq->pSelect; + sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); } } } @@ -147769,6 +150304,8 @@ SQLITE_PRIVATE void sqlite3SelectPrep( */ static void printAggInfo(AggInfo *pAggInfo){ int ii; + sqlite3DebugPrintf("AggInfo %d/%p:\n", + pAggInfo->selId, pAggInfo); for(ii=0; ii<pAggInfo->nColumn; ii++){ struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; sqlite3DebugPrintf( @@ -147984,6 +150521,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ assert( pFunc->pFExpr->pLeft!=0 ); assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); assert( ExprUseXList(pFunc->pFExpr->pLeft) ); + assert( pFunc->pFunc!=0 ); pOBList = pFunc->pFExpr->pLeft->x.pList; if( !pFunc->bOBUnique ){ nExtra++; /* One extra column for the OP_Sequence */ @@ -147993,6 +150531,9 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ assert( ExprUseXList(pFunc->pFExpr) ); nExtra += pFunc->pFExpr->x.pList->nExpr; } + if( pFunc->bUseSubtype ){ + nExtra += pFunc->pFExpr->x.pList->nExpr; + } pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); if( !pFunc->bOBUnique && pParse->nErr==0 ){ pKeyInfo->nKeyField++; @@ -148017,11 +150558,12 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); + if( pParse->nErr ) return; pList = pF->pFExpr->x.pList; if( pF->iOBTab>=0 ){ - /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and - ** all content was stored in emphermal table pF->iOBTab. Extract that - ** content now (in ORDER BY order) and make all calls to OP_AggStep + /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs + ** were stored in emphermal table pF->iOBTab. Here, we extract those + ** inputs (in ORDER BY order) and make all calls to OP_AggStep ** before doing the OP_AggFinal call. */ int iTop; /* Start of loop for extracting columns */ int nArg; /* Number of columns to extract */ @@ -148029,6 +150571,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ int regAgg; /* Extract into this array */ int j; /* Loop counter */ + assert( pF->pFunc!=0 ); nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); @@ -148045,9 +150588,18 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ for(j=nArg-1; j>=0; j--){ sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); } + if( pF->bUseSubtype ){ + int regSubtype = sqlite3GetTempReg(pParse); + int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype); + sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j); + } + sqlite3ReleaseTempReg(pParse, regSubtype); + } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, iTop); sqlite3ReleaseTempRange(pParse, regAgg, nArg); @@ -148099,6 +150651,7 @@ static void updateAccumulator( ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); assert( !IsWindowFunc(pF->pFExpr) ); + assert( pF->pFunc!=0 ); pList = pF->pFExpr->x.pList; if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ Expr *pFilter = pF->pFExpr->y.pWin->pFilter; @@ -148143,6 +150696,9 @@ static void updateAccumulator( if( pF->bOBPayload ){ regAggSz += nArg; } + if( pF->bUseSubtype ){ + regAggSz += nArg; + } regAggSz++; /* One extra register to hold result of MakeRecord */ regAgg = sqlite3GetTempRange(pParse, regAggSz); regDistinct = regAgg; @@ -148155,6 +150711,14 @@ static void updateAccumulator( if( pF->bOBPayload ){ regDistinct = regAgg+jj; sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); + jj += nArg; + } + if( pF->bUseSubtype ){ + int kk; + int regBase = pF->bOBPayload ? regDistinct : regAgg; + for(kk=0; kk<nArg; kk++, jj++){ + sqlite3VdbeAddOp2(v, OP_GetSubtype, regBase+kk, regAgg+jj); + } } }else if( pList ){ nArg = pList->nExpr; @@ -148198,12 +150762,13 @@ static void updateAccumulator( } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); } if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } + if( pParse->nErr ) return; } if( regHit==0 && pAggInfo->nAccumulator ){ regHit = regAcc; @@ -148213,6 +150778,7 @@ static void updateAccumulator( } for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); + if( pParse->nErr ) return; } pAggInfo->directMode = 0; @@ -148328,25 +150894,28 @@ static SrcItem *isSelfJoinView( int iFirst, int iEnd /* Range of FROM-clause entries to search. */ ){ SrcItem *pItem; - assert( pThis->pSelect!=0 ); - if( pThis->pSelect->selFlags & SF_PushDown ) return 0; + Select *pSel; + assert( pThis->fg.isSubquery ); + pSel = pThis->u4.pSubq->pSelect; + assert( pSel!=0 ); + if( pSel->selFlags & SF_PushDown ) return 0; while( iFirst<iEnd ){ Select *pS1; pItem = &pTabList->a[iFirst++]; - if( pItem->pSelect==0 ) continue; + if( !pItem->fg.isSubquery ) continue; if( pItem->fg.viaCoroutine ) continue; if( pItem->zName==0 ) continue; - assert( pItem->pTab!=0 ); - assert( pThis->pTab!=0 ); - if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue; + assert( pItem->pSTab!=0 ); + assert( pThis->pSTab!=0 ); + if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue; if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; - pS1 = pItem->pSelect; - if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){ + pS1 = pItem->u4.pSubq->pSelect; + if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){ /* The query flattener left two different CTE tables with identical ** names in the same FROM clause. */ continue; } - if( pItem->pSelect->selFlags & SF_PushDown ){ + if( pS1->selFlags & SF_PushDown ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; @@ -148359,7 +150928,8 @@ static SrcItem *isSelfJoinView( /* ** Deallocate a single AggInfo object */ -static void agginfoFree(sqlite3 *db, AggInfo *p){ +static void agginfoFree(sqlite3 *db, void *pArg){ + AggInfo *p = (AggInfo*)pArg; sqlite3DbFree(db, p->aCol); sqlite3DbFree(db, p->aFunc); sqlite3DbFreeNN(db, p); @@ -148389,6 +150959,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ Expr *pExpr; Expr *pCount; sqlite3 *db; + SrcItem *pFrom; if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ if( p->pWhere ) return 0; @@ -148403,8 +150974,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ - pSub = p->pSrc->a[0].pSelect; - if( pSub==0 ) return 0; /* The FROM is a subquery */ + pFrom = p->pSrc->a; + if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */ + pSub = pFrom->u4.pSubq->pSelect; if( pSub->pPrior==0 ) return 0; /* Must be a compound */ if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ do{ @@ -148413,7 +150985,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ assert( pSub->pHaving==0 ); /* Due to the previous */ - pSub = pSub->pPrior; /* Repeat over compound */ + pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); /* If we reach this point then it is OK to perform the transformation */ @@ -148421,8 +150993,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ db = pParse->db; pCount = pExpr; pExpr = 0; - pSub = p->pSrc->a[0].pSelect; - p->pSrc->a[0].pSelect = 0; + pSub = sqlite3SubqueryDetach(db, pFrom); sqlite3SrcListDelete(db, p->pSrc); p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); while( pSub ){ @@ -148433,7 +151004,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pSub->selFlags |= SF_Aggregate; pSub->selFlags &= ~SF_Compound; pSub->nSelectRow = 0; - sqlite3ExprListDelete(db, pSub->pEList); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); @@ -148467,12 +151038,12 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ for(i=0; i<pSrc->nSrc; i++){ SrcItem *p1 = &pSrc->a[i]; if( p1==p0 ) continue; - if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ + if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ return 1; } - if( p1->pSelect - && (p1->pSelect->selFlags & SF_NestedFrom)!=0 - && sameSrcAlias(p0, p1->pSelect->pSrc) + if( p1->fg.isSubquery + && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 + && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc) ){ return 1; } @@ -148537,13 +151108,13 @@ static int fromClauseTermCanBeCoroutine( if( i==0 ) break; i--; pItem--; - if( pItem->pSelect!=0 ) return 0; /* (1c-i) */ + if( pItem->fg.isSubquery ) return 0; /* (1c-i) */ } return 1; } /* -** Generate code for the SELECT statement given in the p argument. +** Generate byte-code for the SELECT statement given in the p argument. ** ** The results are returned according to the SelectDest structure. ** See comments in sqliteInt.h for further information. @@ -148554,6 +151125,40 @@ static int fromClauseTermCanBeCoroutine( ** ** This routine does NOT free the Select structure passed in. The ** calling function needs to do that. +** +** This is a long function. The following is an outline of the processing +** steps, with tags referencing various milestones: +** +** * Resolve names and similar preparation tag-select-0100 +** * Scan of the FROM clause tag-select-0200 +** + OUTER JOIN strength reduction tag-select-0220 +** + Sub-query ORDER BY removal tag-select-0230 +** + Query flattening tag-select-0240 +** * Separate subroutine for compound-SELECT tag-select-0300 +** * WHERE-clause constant propagation tag-select-0330 +** * Count()-of-VIEW optimization tag-select-0350 +** * Scan of the FROM clause again tag-select-0400 +** + Authorize unreferenced tables tag-select-0410 +** + Predicate push-down optimization tag-select-0420 +** + Omit unused subquery columns optimization tag-select-0440 +** + Generate code to implement subqueries tag-select-0480 +** - Co-routines tag-select-0482 +** - Reuse previously computed CTE tag-select-0484 +** - REuse previously computed VIEW tag-select-0486 +** - Materialize a VIEW or CTE tag-select-0488 +** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500 +** * Set up for ORDER BY tag-select-0600 +** * Create output table tag-select-0630 +** * Prepare registers for LIMIT tag-select-0650 +** * Setup for DISTINCT tag-select-0680 +** * Generate code for non-aggregate and non-GROUP BY tag-select-0700 +** * Generate code for aggregate and/or GROUP BY tag-select-0800 +** + GROUP BY queries tag-select-0810 +** + non-GROUP BY queries tag-select-0820 +** - Special case of count() w/o GROUP BY tag-select-0821 +** - General case of non-GROUP BY aggregates tag-select-0822 +** * Sort results, as needed tag-select-0900 +** * Internal self-checks tag-select-1000 */ SQLITE_PRIVATE int sqlite3Select( Parse *pParse, /* The parser context */ @@ -148597,6 +151202,7 @@ SQLITE_PRIVATE int sqlite3Select( } #endif + /* tag-select-0100 */ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); @@ -148613,9 +151219,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); } #endif - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - p->pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + p->pOrderBy); testcase( pParse->earlyCleanup ); p->pOrderBy = 0; } @@ -148649,7 +151254,7 @@ SQLITE_PRIVATE int sqlite3Select( if( sameSrcAlias(p0, p->pSrc) ){ sqlite3ErrorMsg(pParse, "target object/alias may not appear in FROM clause: %s", - p0->zAlias ? p0->zAlias : p0->pTab->zName + p0->zAlias ? p0->zAlias : p0->pSTab->zName ); goto select_end; } @@ -148684,12 +151289,13 @@ SQLITE_PRIVATE int sqlite3Select( /* Try to do various optimizations (flattening subqueries, and strength ** reduction of join operators) in the FROM clause up into the main query + ** tag-select-0200 */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ SrcItem *pItem = &pTabList->a[i]; - Select *pSub = pItem->pSelect; - Table *pTab = pItem->pTab; + Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0; + Table *pTab = pItem->pSTab; /* The expander should have already created transient Table objects ** even for FROM clause elements such as subqueries that do not correspond @@ -148706,6 +151312,7 @@ SQLITE_PRIVATE int sqlite3Select( ** way that the i-th table cannot be the NULL row of a join, then ** perform the appropriate simplification. This is called ** "OUTER JOIN strength reduction" in the SQLite documentation. + ** tag-select-0220 */ if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, @@ -148776,7 +151383,8 @@ SQLITE_PRIVATE int sqlite3Select( if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; assert( pSub->pGroupBy==0 ); - /* If a FROM-clause subquery has an ORDER BY clause that is not + /* tag-select-0230: + ** If a FROM-clause subquery has an ORDER BY clause that is not ** really doing anything, then delete it now so that it does not ** interfere with query flattening. See the discussion at ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a @@ -148795,21 +151403,23 @@ SQLITE_PRIVATE int sqlite3Select( ** (a) The outer query has a different ORDER BY clause ** (b) The subquery is part of a join ** See forum post 062d576715d277c8 + ** (6) The subquery is not a recursive CTE. ORDER BY has a different + ** meaning for recursive CTEs and this optimization does not + ** apply. ** ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. */ if( pSub->pOrderBy!=0 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ && pSub->pLimit==0 /* Condition (1) */ - && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ + && (pSub->selFlags & (SF_OrderByReqd|SF_Recursive))==0 /* (2) and (6) */ && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ && OptimizationEnabled(db, SQLITE_OmitOrderBy) ){ TREETRACE(0x800,pParse,p, ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pSub->pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + pSub->pOrderBy); pSub->pOrderBy = 0; } @@ -148840,6 +151450,7 @@ SQLITE_PRIVATE int sqlite3Select( continue; } + /* tag-select-0240 */ if( flattenSubquery(pParse, p, i, isAgg) ){ if( pParse->nErr ) goto select_end; /* This subquery can be absorbed into its parent. */ @@ -148855,7 +151466,7 @@ SQLITE_PRIVATE int sqlite3Select( #ifndef SQLITE_OMIT_COMPOUND_SELECT /* Handle compound SELECT statements using the separate multiSelect() - ** procedure. + ** procedure. tag-select-0300 */ if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); @@ -148871,9 +151482,9 @@ SQLITE_PRIVATE int sqlite3Select( #endif /* Do the WHERE-clause constant propagation optimization if this is - ** a join. No need to speed time on this operation for non-join queries + ** a join. No need to spend time on this operation for non-join queries ** as the equivalent optimization will be handled by query planner in - ** sqlite3WhereBegin(). + ** sqlite3WhereBegin(). tag-select-0330 */ if( p->pWhere!=0 && p->pWhere->op==TK_AND @@ -148890,6 +151501,7 @@ SQLITE_PRIVATE int sqlite3Select( TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); } + /* tag-select-0350 */ if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) && countOfViewOptimization(pParse, p) ){ @@ -148897,20 +151509,26 @@ SQLITE_PRIVATE int sqlite3Select( pTabList = p->pSrc; } - /* For each term in the FROM clause, do two things: - ** (1) Authorized unreferenced tables - ** (2) Generate code for all sub-queries + /* Loop over all terms in the FROM clause and do two things for each term: + ** + ** (1) Authorize unreferenced tables + ** (2) Generate code for all sub-queries + ** + ** tag-select-0400 */ for(i=0; i<pTabList->nSrc; i++){ SrcItem *pItem = &pTabList->a[i]; SrcItem *pPrior; SelectDest dest; + Subquery *pSubq; Select *pSub; #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) const char *zSavedAuthContext; #endif - /* Issue SQLITE_READ authorizations with a fake column name for any + /* Authorized unreferenced tables. tag-select-0410 + ** + ** Issue SQLITE_READ authorizations with a fake column name for any ** tables that are referenced but from which no values are extracted. ** Examples of where these kinds of null SQLITE_READ authorizations ** would occur: @@ -148927,17 +151545,28 @@ SQLITE_PRIVATE int sqlite3Select( ** string for the fake column name seems safer. */ if( pItem->colUsed==0 && pItem->zName!=0 ){ - sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); + const char *zDb; + if( pItem->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema); + zDb = db->aDb[iDb].zDbSName; + }else if( pItem->fg.isSubquery ){ + zDb = 0; + }else{ + zDb = pItem->u4.zDatabase; + } + sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb); } #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* Generate code for all sub-queries in the FROM clause */ - pSub = pItem->pSelect; - if( pSub==0 ) continue; + if( pItem->fg.isSubquery==0 ) continue; + pSubq = pItem->u4.pSubq; + assert( pSubq!=0 ); + pSub = pSubq->pSelect; /* The code for a subquery should only be generated once. */ - assert( pItem->addrFillSub==0 ); + if( pSubq->addrFillSub!=0 ) continue; /* Increment Parse.nHeight by the height of the largest expression ** tree referred to by this, the parent select. The child select @@ -148950,6 +151579,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Make copies of constant WHERE-clause terms in the outer query down ** inside the subquery. This can help the subquery to run more efficiently. + ** This is the "predicate push-down optimization". tag-select-0420 */ if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 @@ -148963,13 +151593,14 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3TreeViewSelect(0, p, 0); } #endif - assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); + assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); }else{ - TREETRACE(0x4000,pParse,p,("Push-down not possible\n")); + TREETRACE(0x4000,pParse,p,("WHERE-clause push-down not possible\n")); } /* Convert unused result columns of the subquery into simple NULL ** expressions, to avoid unneeded searching and computation. + ** tag-select-0440 */ if( OptimizationEnabled(db, SQLITE_NullUnusedCols) && disableUnusedSubqueryResultColumns(pItem) @@ -148987,32 +151618,33 @@ SQLITE_PRIVATE int sqlite3Select( zSavedAuthContext = pParse->zAuthContext; pParse->zAuthContext = pItem->zName; - /* Generate code to implement the subquery + /* Generate byte-code to implement the subquery tag-select-0480 */ if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ /* Implement a co-routine that will return a single row of the result - ** set on each invocation. + ** set on each invocation. tag-select-0482 */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; - pItem->regReturn = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); + pSubq->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop); VdbeComment((v, "%!S", pItem)); - pItem->addrFillSub = addrTop; - sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); + pSubq->addrFillSub = addrTop; + sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; + pItem->pSTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; - pItem->regResult = dest.iSdst; - sqlite3VdbeEndCoroutine(v, pItem->regReturn); + pSubq->regResult = dest.iSdst; + sqlite3VdbeEndCoroutine(v, pSubq->regReturn); + VdbeComment((v, "end %!S", pItem)); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ /* This is a CTE for which materialization code has already been ** generated. Invoke the subroutine to compute the materialization, - ** the make the pItem->iCursor be a copy of the ephemeral table that - ** holds the result of the materialization. */ + ** then make the pItem->iCursor be a copy of the ephemeral table that + ** holds the result of the materialization. tag-select-0484 */ CteUse *pCteUse = pItem->u2.pCteUse; sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); if( pItem->iCursor!=pCteUse->iCur ){ @@ -149022,25 +151654,30 @@ SQLITE_PRIVATE int sqlite3Select( pSub->nSelectRow = pCteUse->nRowEst; }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ /* This view has already been materialized by a prior entry in - ** this same FROM clause. Reuse it. */ - if( pPrior->addrFillSub ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); + ** this same FROM clause. Reuse it. tag-select-0486 */ + Subquery *pPriorSubq; + assert( pPrior->fg.isSubquery ); + pPriorSubq = pPrior->u4.pSubq; + assert( pPriorSubq!=0 ); + if( pPriorSubq->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn, + pPriorSubq->addrFillSub); } sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); - pSub->nSelectRow = pPrior->pSelect->nSelectRow; + pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow; }else{ /* Materialize the view. If the view is not correlated, generate a ** subroutine to do the materialization so that subsequent uses of - ** the same view can reuse the materialization. */ + ** the same view can reuse the materialization. tag-select-0488 */ int topAddr; int onceAddr = 0; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS int addrExplain; #endif - pItem->regReturn = ++pParse->nMem; + pSubq->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp0(v, OP_Goto); - pItem->addrFillSub = topAddr+1; + pSubq->addrFillSub = topAddr+1; pItem->fg.isMaterialized = 1; if( pItem->fg.isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of @@ -149055,17 +151692,17 @@ SQLITE_PRIVATE int sqlite3Select( ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; + pItem->pSTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); - sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); + sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1); VdbeComment((v, "end %!S", pItem)); sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); sqlite3VdbeJumpHere(v, topAddr); sqlite3ClearTempRegCache(pParse); if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ CteUse *pCteUse = pItem->u2.pCteUse; - pCteUse->addrM9e = pItem->addrFillSub; - pCteUse->regRtn = pItem->regReturn; + pCteUse->addrM9e = pSubq->addrFillSub; + pCteUse->regRtn = pSubq->regReturn; pCteUse->iCur = pItem->iCursor; pCteUse->nRowEst = pSub->nSelectRow; } @@ -149091,7 +151728,9 @@ SQLITE_PRIVATE int sqlite3Select( } #endif - /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and + /* tag-select-0500 + ** + ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and ** if the select-list is the same as the ORDER BY list, then this query ** can be rewritten as a GROUP BY. In other words, this: ** @@ -149108,12 +151747,18 @@ SQLITE_PRIVATE int sqlite3Select( */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 + && OptimizationEnabled(db, SQLITE_GroupByOrder) #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 #endif ){ p->selFlags &= ~SF_Distinct; pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); + if( pGroupBy ){ + for(i=0; i<pGroupBy->nExpr; i++){ + pGroupBy->a[i].u.x.iOrderByCol = i+1; + } + } p->selFlags |= SF_Aggregate; /* Notice that even thought SF_Distinct has been cleared from p->selFlags, ** the sDistinct.isTnct is still set. Hence, isTnct represents the @@ -149135,7 +151780,7 @@ SQLITE_PRIVATE int sqlite3Select( ** If that is the case, then the OP_OpenEphemeral instruction will be ** changed to an OP_Noop once we figure out that the sorting index is ** not needed. The sSort.addrSortIndex variable is used to facilitate - ** that change. + ** that change. tag-select-0600 */ if( sSort.pOrderBy ){ KeyInfo *pKeyInfo; @@ -149152,6 +151797,7 @@ SQLITE_PRIVATE int sqlite3Select( } /* If the output is destined for a temporary table, open that table. + ** tag-select-0630 */ if( pDest->eDest==SRT_EphemTab ){ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); @@ -149169,7 +151815,7 @@ SQLITE_PRIVATE int sqlite3Select( } } - /* Set the limiter. + /* Set the limiter. tag-select-0650 */ iEnd = sqlite3VdbeMakeLabel(pParse); if( (p->selFlags & SF_FixedLimit)==0 ){ @@ -149181,7 +151827,7 @@ SQLITE_PRIVATE int sqlite3Select( sSort.sortFlags |= SORTFLAG_UseSorter; } - /* Open an ephemeral index to use for the distinct set. + /* Open an ephemeral index to use for the distinct set. tag-select-0680 */ if( p->selFlags & SF_Distinct ){ sDistinct.tabTnct = pParse->nTab++; @@ -149196,7 +151842,7 @@ SQLITE_PRIVATE int sqlite3Select( } if( !isAgg && pGroupBy==0 ){ - /* No aggregate functions and no GROUP BY clause */ + /* No aggregate functions and no GROUP BY clause. tag-select-0700 */ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) | (p->selFlags & SF_FixedLimit); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -149269,8 +151915,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3WhereEnd(pWInfo); } }else{ - /* This case when there exist aggregate functions or a GROUP BY clause - ** or both */ + /* This case is for when there exist aggregate functions or a GROUP BY + ** clause or both. tag-select-0800 */ NameContext sNC; /* Name context for processing aggregate information */ int iAMem; /* First Mem address for storing current GROUP BY */ int iBMem; /* First Mem address for previous GROUP BY */ @@ -149338,8 +151984,7 @@ SQLITE_PRIVATE int sqlite3Select( */ pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); if( pAggInfo ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))agginfoFree, pAggInfo); + sqlite3ParserAddCleanup(pParse, agginfoFree, pAggInfo); testcase( pParse->earlyCleanup ); } if( db->mallocFailed ){ @@ -149390,7 +152035,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Processing for aggregates with GROUP BY is very different and - ** much more complex than aggregates without a GROUP BY. + ** much more complex than aggregates without a GROUP BY. tag-select-0810 */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ @@ -149577,12 +152222,25 @@ SQLITE_PRIVATE int sqlite3Select( sortOut, sortPTab); } for(j=0; j<pGroupBy->nExpr; j++){ + int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol; + if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); }else{ pAggInfo->directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); } + + if( iOrderByCol ){ + Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; + Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); + if( ALWAYS(pBase!=0) + && pBase->op!=TK_AGG_COLUMN + && pBase->op!=TK_REGISTER + ){ + sqlite3ExprToRegister(pX, iAMem+j); + } + } } sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); @@ -149598,9 +152256,9 @@ SQLITE_PRIVATE int sqlite3Select( ** and resets the aggregate accumulator registers in preparation ** for the next GROUP BY batch. */ - sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output one row")); + sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); VdbeComment((v, "check abort flag")); sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); @@ -149674,9 +152332,12 @@ SQLITE_PRIVATE int sqlite3Select( } } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { + /* Aggregate functions without GROUP BY. tag-select-0820 */ Table *pTab; if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ - /* If isSimpleCount() returns a pointer to a Table structure, then + /* tag-select-0821 + ** + ** If isSimpleCount() returns a pointer to a Table structure, then ** the SQL statement is of the form: ** ** SELECT count(*) FROM <tbl> @@ -149735,6 +152396,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else{ + /* The general case of an aggregate query without GROUP BY + ** tag-select-0822 */ int regAcc = 0; /* "populate accumulators" flag */ ExprList *pDistinct = 0; u16 distFlag = 0; @@ -149823,7 +152486,7 @@ SQLITE_PRIVATE int sqlite3Select( } /* If there is an ORDER BY clause, then we need to sort the results - ** and send them to the callback one by one. + ** and send them to the callback one by one. tag-select-0900 */ if( sSort.pOrderBy ){ assert( p->pEList==pEList ); @@ -149846,7 +152509,14 @@ SQLITE_PRIVATE int sqlite3Select( assert( db->mallocFailed==0 || pParse->nErr!=0 ); sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG + /* Internal self-checks. tag-select-1000 */ if( pAggInfo && !db->mallocFailed ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + TREETRACE(0x20,pParse,p,("Finished with AggInfo\n")); + printAggInfo(pAggInfo); + } +#endif for(i=0; i<pAggInfo->nColumn; i++){ Expr *pExpr = pAggInfo->aCol[i].pCExpr; if( pExpr==0 ) continue; @@ -150229,8 +152899,10 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( ** name on pTableName if we are reparsing out of the schema table */ if( db->init.busy && iDb!=1 ){ - sqlite3DbFree(db, pTableName->a[0].zDatabase); - pTableName->a[0].zDatabase = 0; + assert( pTableName->a[0].fg.fixedSchema==0 ); + assert( pTableName->a[0].fg.isSubquery==0 ); + sqlite3DbFree(db, pTableName->a[0].u4.zDatabase); + pTableName->a[0].u4.zDatabase = 0; } /* If the trigger name was unqualified, and the table is a temp table, @@ -150708,7 +153380,8 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr) } assert( pName->nSrc==1 ); - zDb = pName->a[0].zDatabase; + assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 ); + zDb = pName->a[0].u4.zDatabase; zName = pName->a[0].zName; assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; i<db->nDb; i++){ @@ -150945,7 +153618,9 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( Schema *pSchema = pStep->pTrig->pSchema; pSrc->a[0].zName = zName; if( pSchema!=db->aDb[1].pSchema ){ - pSrc->a[0].pSchema = pSchema; + assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 ); + pSrc->a[0].u4.pSchema = pSchema; + pSrc->a[0].fg.fixedSchema = 1; } if( pStep->pFrom ){ SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); @@ -151028,6 +153703,72 @@ static ExprList *sqlite3ExpandReturning( return pNew; } +/* If the Expr node is a subquery or an EXISTS operator or an IN operator that +** uses a subquery, and if the subquery is SF_Correlated, then mark the +** expression as EP_VarSelect. +*/ +static int sqlite3ReturningSubqueryVarSelect(Walker *NotUsed, Expr *pExpr){ + UNUSED_PARAMETER(NotUsed); + if( ExprUseXSelect(pExpr) + && (pExpr->x.pSelect->selFlags & SF_Correlated)!=0 + ){ + testcase( ExprHasProperty(pExpr, EP_VarSelect) ); + ExprSetProperty(pExpr, EP_VarSelect); + } + return WRC_Continue; +} + + +/* +** If the SELECT references the table pWalker->u.pTab, then do two things: +** +** (1) Mark the SELECT as as SF_Correlated. +** (2) Set pWalker->eCode to non-zero so that the caller will know +** that (1) has happened. +*/ +static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ + int i; + SrcList *pSrc; + assert( pSelect!=0 ); + pSrc = pSelect->pSrc; + assert( pSrc!=0 ); + for(i=0; i<pSrc->nSrc; i++){ + if( pSrc->a[i].pSTab==pWalker->u.pTab ){ + testcase( pSelect->selFlags & SF_Correlated ); + pSelect->selFlags |= SF_Correlated; + pWalker->eCode = 1; + break; + } + } + return WRC_Continue; +} + +/* +** Scan the expression list that is the argument to RETURNING looking +** for subqueries that depend on the table which is being modified in the +** statement that is hosting the RETURNING clause (pTab). Mark all such +** subqueries as SF_Correlated. If the subqueries are part of an +** expression, mark the expression as EP_VarSelect. +** +** https://sqlite.org/forum/forumpost/2c83569ce8945d39 +*/ +static void sqlite3ProcessReturningSubqueries( + ExprList *pEList, + Table *pTab +){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = sqlite3ExprWalkNoop; + w.xSelectCallback = sqlite3ReturningSubqueryCorrelated; + w.u.pTab = pTab; + sqlite3WalkExprList(&w, pEList); + if( w.eCode ){ + w.xExprCallback = sqlite3ReturningSubqueryVarSelect; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkExprList(&w, pEList); + } +} + /* ** Generate code for the RETURNING trigger. Unlike other triggers ** that invoke a subprogram in the bytecode, the code for RETURNING @@ -151063,7 +153804,8 @@ static void codeReturningTrigger( sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); sSelect.pSrc = &sFrom; sFrom.nSrc = 1; - sFrom.a[0].pTab = pTab; + sFrom.a[0].pSTab = pTab; + sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ sFrom.a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); if( pParse->nErr==0 ){ @@ -151090,6 +153832,7 @@ static void codeReturningTrigger( int i; int nCol = pNew->nExpr; int reg = pParse->nMem+1; + sqlite3ProcessReturningSubqueries(pNew, pTab); pParse->nMem += nCol+2; pReturning->iRetReg = reg; for(i=0; i<nCol; i++){ @@ -151413,7 +154156,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ - sqlite3VdbeChangeP5(v, (u8)bRecursive); + sqlite3VdbeChangeP5(v, (u16)bRecursive); } } @@ -151772,7 +154515,7 @@ static void updateFromSelect( Expr *pLimit2 = 0; ExprList *pOrderBy2 = 0; sqlite3 *db = pParse->db; - Table *pTab = pTabList->a[0].pTab; + Table *pTab = pTabList->a[0].pSTab; SrcList *pSrc; Expr *pWhere2; int eDest; @@ -151796,8 +154539,8 @@ static void updateFromSelect( if( pSrc ){ assert( pSrc->a[0].fg.notCte ); pSrc->a[0].iCursor = -1; - pSrc->a[0].pTab->nTabRef--; - pSrc->a[0].pTab = 0; + pSrc->a[0].pSTab->nTabRef--; + pSrc->a[0].pSTab = 0; } if( pPk ){ for(i=0; i<pPk->nKeyCol; i++){ @@ -152491,6 +155234,9 @@ SQLITE_PRIVATE void sqlite3Update( } } if( chngRowid==0 && pPk==0 ){ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); +#endif sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); } } @@ -153028,7 +155774,8 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertNew( SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( Parse *pParse, /* The parsing context */ SrcList *pTabList, /* Table into which we are inserting */ - Upsert *pUpsert /* The ON CONFLICT clauses */ + Upsert *pUpsert, /* The ON CONFLICT clauses */ + Upsert *pAll /* Complete list of all ON CONFLICT clauses */ ){ Table *pTab; /* That table into which we are inserting */ int rc; /* Result code */ @@ -153041,7 +155788,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); - assert( pTabList->a[0].pTab!=0 ); + assert( pTabList->a[0].pSTab!=0 ); assert( pUpsert!=0 ); assert( pUpsert->pUpsertTarget!=0 ); @@ -153060,7 +155807,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( if( rc ) return rc; /* Check to see if the conflict target matches the rowid. */ - pTab = pTabList->a[0].pTab; + pTab = pTabList->a[0].pSTab; pTarget = pUpsert->pUpsertTarget; iCursor = pTabList->a[0].iCursor; if( HasRowid(pTab) @@ -153131,6 +155878,14 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( continue; } pUpsert->pUpsertIdx = pIdx; + if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){ + /* Really this should be an error. The isDup ON CONFLICT clause will + ** never fire. But this problem was not discovered until three years + ** after multi-CONFLICT upsert was added, and so we silently ignore + ** the problem to prevent breaking applications that might actually + ** have redundant ON CONFLICT clauses. */ + pUpsert->isDup = 1; + } break; } if( pUpsert->pUpsertIdx==0 ){ @@ -153157,9 +155912,13 @@ SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ Upsert *pNext; if( NEVER(pUpsert==0) ) return 0; pNext = pUpsert->pNextUpsert; - if( pNext==0 ) return 1; - if( pNext->pUpsertTarget==0 ) return 1; - if( pNext->pUpsertIdx==0 ) return 1; + while( 1 /*exit-by-return*/ ){ + if( pNext==0 ) return 1; + if( pNext->pUpsertTarget==0 ) return 1; + if( pNext->pUpsertIdx==0 ) return 1; + if( !pNext->isDup ) return 0; + pNext = pNext->pNextUpsert; + } return 0; } @@ -153419,6 +156178,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ + u64 iRandom; /* Random value used for zDbVacuum[] */ + char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */ + if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); @@ -153459,27 +156221,29 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( pMain = db->aDb[iDb].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); - /* Attach the temporary database as 'vacuum_db'. The synchronous pragma + /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** ** An optimization would be to use a non-journaled pager. - ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but + ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but ** that actually made the VACUUM run slower. Very little journalling ** actually occurs when doing a vacuum since the vacuum_db is initially ** empty. Only the journal header is written. Apparently it takes more ** time to parse and run the PRAGMA to turn journalling off than it does ** to write the journal header file. */ + sqlite3_randomness(sizeof(iRandom),&iRandom); + sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom); nDb = db->nDb; - rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut); + rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum); db->openFlags = saved_openFlags; if( rc!=SQLITE_OK ) goto end_of_vacuum; assert( (db->nDb-1)==nDb ); pDb = &db->aDb[nDb]; - assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); + assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); pTemp = pDb->pBt; if( pOut ){ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); @@ -153498,6 +156262,15 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( } nRes = sqlite3BtreeGetRequestedReserve(pMain); + /* A VACUUM cannot change the pagesize of an encrypted database. */ + if( db->nextPagesize ){ + extern void sqlite3mcCodecGetKey(sqlite3*, int, void**, int*); + int nKey; + char *zKey; + sqlite3mcCodecGetKey(db, iDb, (void**)&zKey, &nKey); + if( nKey ) db->nextPagesize = 0; + } + sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); sqlite3BtreeSetPagerFlags(pTemp, pgflags|PAGER_CACHESPILL); @@ -153556,11 +156329,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( ** the contents to the temporary database. */ rc = execSqlF(db, pzErrMsg, - "SELECT'INSERT INTO vacuum_db.'||quote(name)" + "SELECT'INSERT INTO %s.'||quote(name)" "||' SELECT*FROM\"%w\".'||quote(name)" - "FROM vacuum_db.sqlite_schema " + "FROM %s.sqlite_schema " "WHERE type='table'AND coalesce(rootpage,1)>0", - zDbMain + zDbVacuum, zDbMain, zDbVacuum ); assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); db->mDbFlags &= ~DBFLAG_Vacuum; @@ -153572,11 +156345,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( ** from the schema table. */ rc = execSqlF(db, pzErrMsg, - "INSERT INTO vacuum_db.sqlite_schema" + "INSERT INTO %s.sqlite_schema" " SELECT*FROM \"%w\".sqlite_schema" " WHERE type IN('view','trigger')" " OR(type='table'AND rootpage=0)", - zDbMain + zDbVacuum, zDbMain ); if( rc ) goto end_of_vacuum; @@ -153988,7 +156761,6 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ if( p ){ db->pDisconnect = 0; - sqlite3ExpirePreparedStatements(db, 0); do { VTable *pNext = p->pNext; sqlite3VtabUnlock(p); @@ -154285,6 +157057,8 @@ static int vtabCallConstructor( db->pVtabCtx = &sCtx; pTab->nTabRef++; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); + assert( pTab!=0 ); + assert( pTab->nTabRef>1 || rc!=SQLITE_OK ); sqlite3DeleteTable(db, pTab); db->pVtabCtx = sCtx.pPrior; if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); @@ -154307,7 +157081,7 @@ static int vtabCallConstructor( pVTable->nRef = 1; if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; - *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); + *pzErr = sqlite3MPrintf(db, zFormat, zModuleName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ @@ -154485,12 +157259,30 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pTab; Parse sParse; int initBusy; + int i; + const unsigned char *z; + static const u8 aKeyword[] = { TK_CREATE, TK_TABLE, 0 }; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ return SQLITE_MISUSE_BKPT; } #endif + + /* Verify that the first two keywords in the CREATE TABLE statement + ** really are "CREATE" and "TABLE". If this is not the case, then + ** sqlite3_declare_vtab() is being misused. + */ + z = (const unsigned char*)zCreateTable; + for(i=0; aKeyword[i]; i++){ + int tokenType = 0; + do{ z += sqlite3GetToken(z, &tokenType); }while( tokenType==TK_SPACE ); + if( tokenType!=aKeyword[i] ){ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "syntax error"); + return SQLITE_ERROR; + } + } + sqlite3_mutex_enter(db->mutex); pCtx = db->pVtabCtx; if( !pCtx || pCtx->bDeclared ){ @@ -154498,6 +157290,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE_BKPT; } + pTab = pCtx->pTab; assert( IsVirtual(pTab) ); @@ -154511,16 +157304,16 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ initBusy = db->init.busy; db->init.busy = 0; sParse.nQueryLoop = 1; - if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) - && ALWAYS(sParse.pNewTable!=0) - && ALWAYS(!db->mallocFailed) - && IsOrdinaryTable(sParse.pNewTable) - ){ + if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) ){ + assert( sParse.pNewTable!=0 ); + assert( !db->mallocFailed ); + assert( IsOrdinaryTable(sParse.pNewTable) ); assert( sParse.zErrMsg==0 ); if( !pTab->aCol ){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; + assert( IsOrdinaryTable(pNew) ); sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); @@ -155195,11 +157988,13 @@ struct WhereLoop { u16 nTop; /* Size of TOP vector */ u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ Index *pIndex; /* Index used, or NULL */ + ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */ } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ u32 bOmitOffset : 1; /* True to let virtual table handle offset */ + u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ char *idxStr; /* Index identifier string */ @@ -155212,6 +158007,8 @@ struct WhereLoop { /**** whereLoopXfer() copies fields above ***********************/ # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) u16 nLSlot; /* Number of slots allocated for aLTerm[] */ + LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not + ** initialized unless pWInfo->nOutStarDelta>0 */ WhereTerm **aLTerm; /* WhereTerms used */ WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ @@ -155534,6 +158331,7 @@ struct WhereInfo { unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ unsigned sorted :1; /* True if really sorted (not just grouped) */ + LogEst nOutStarDelta; /* Artifical nOut reduction for star-query */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ @@ -155554,7 +158352,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); #ifdef WHERETRACE_ENABLED SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); -SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC); +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC); #endif SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( WhereClause *pWC, /* The WHERE clause to be searched */ @@ -155580,9 +158378,17 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( const WhereInfo *pWInfo, /* WHERE clause */ const WhereLevel *pLevel /* Bloom filter on this level */ ); +SQLITE_PRIVATE void sqlite3WhereAddExplainText( + Parse *pParse, /* Parse context */ + int addr, + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +); #else # define sqlite3WhereExplainOneScan(u,v,w,x) 0 # define sqlite3WhereExplainBloomFilter(u,v,w) 0 +# define sqlite3WhereAddExplainText(u,v,w,x,y) #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS SQLITE_PRIVATE void sqlite3WhereAddScanStatus( @@ -155685,7 +158491,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ - /* 0x02000000 -- available for reuse */ +#define WHERE_COROUTINE 0x02000000 /* Implemented by co-routine. + ** NB: False-negatives are possible */ #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #endif /* !defined(SQLITE_WHEREINT_H) */ @@ -155783,38 +158590,38 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ } /* -** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN -** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG -** was defined at compile-time. If it is not a no-op, a single OP_Explain -** opcode is added to the output to describe the table scan strategy in pLevel. -** -** If an OP_Explain opcode is added to the VM, its address is returned. -** Otherwise, if no OP_Explain is coded, zero is returned. +** This function sets the P4 value of an existing OP_Explain opcode to +** text describing the loop in pLevel. If the OP_Explain opcode already has +** a P4 value, it is freed before it is overwritten. */ -SQLITE_PRIVATE int sqlite3WhereExplainOneScan( +SQLITE_PRIVATE void sqlite3WhereAddExplainText( Parse *pParse, /* Parse context */ + int addr, /* Address of OP_Explain opcode */ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ - int ret = 0; #if !defined(SQLITE_DEBUG) if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) #endif { + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr); + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; - Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ WhereLoop *pLoop; /* The controlling WhereLoop object */ u32 flags; /* Flags that describe this loop */ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) char *zMsg; /* Text to add to EQP output */ +#endif StrAccum str; /* EQP output string */ char zBuf[100]; /* Initial space for EQP output string */ + if( db->mallocFailed ) return; + pLoop = pLevel->pWLoop; flags = pLoop->wsFlags; - if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0; isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) @@ -155830,7 +158637,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( assert( pLoop->u.btree.pIndex!=0 ); pIdx = pLoop->u.btree.pIndex; assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); - if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ + if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){ if( isSearch ){ zFmt = "PRIMARY KEY"; } @@ -155838,7 +158645,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; }else if( flags & WHERE_AUTO_INDEX ){ zFmt = "AUTOMATIC COVERING INDEX"; - }else if( flags & WHERE_IDX_ONLY ){ + }else if( flags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ zFmt = "COVERING INDEX %s"; }else{ zFmt = "INDEX %s"; @@ -155873,7 +158680,9 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ - sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", + sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX "); + sqlite3_str_appendf(&str, + pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif @@ -155888,10 +158697,50 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( sqlite3_str_append(&str, " (~1 row)", 9); } #endif +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) zMsg = sqlite3StrAccumFinish(&str); sqlite3ExplainBreakpoint("",zMsg); - ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), - pParse->addrExplain, 0, zMsg,P4_DYNAMIC); +#endif + + assert( pOp->opcode==OP_Explain ); + assert( pOp->p4type==P4_DYNAMIC || pOp->p4.z==0 ); + sqlite3DbFree(db, pOp->p4.z); + pOp->p4type = P4_DYNAMIC; + pOp->p4.z = sqlite3StrAccumFinish(&str); + } +} + + +/* +** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN +** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG +** was defined at compile-time. If it is not a no-op, a single OP_Explain +** opcode is added to the output to describe the table scan strategy in pLevel. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ + int ret = 0; +#if !defined(SQLITE_DEBUG) + if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + if( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + ){ + Vdbe *v = pParse->pVdbe; + int addr = sqlite3VdbeCurrentAddr(v); + ret = sqlite3VdbeAddOp3( + v, OP_Explain, addr, pParse->addrExplain, pLevel->pWLoop->rRun + ); + sqlite3WhereAddExplainText(pParse, addr, pTabList, pLevel, wctrlFlags); + } } return ret; } @@ -155926,7 +158775,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); pLoop = pLevel->pWLoop; if( pLoop->wsFlags & WHERE_IPK ){ - const Table *pTab = pItem->pTab; + const Table *pTab = pItem->pSTab; if( pTab->iPKey>=0 ){ sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); }else{ @@ -155989,8 +158838,11 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); } }else{ - int addr = pSrclist->a[pLvl->iFrom].addrFillSub; - VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); + int addr; + VdbeOp *pOp; + assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); + addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; + pOp = sqlite3VdbeGetOp(v, addr-1); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); @@ -156133,6 +158985,39 @@ static void updateRangeAffinityStr( } } +/* +** The pOrderBy->a[].u.x.iOrderByCol values might be incorrect because +** columns might have been rearranged in the result set. This routine +** fixes them up. +** +** pEList is the new result set. The pEList->a[].u.x.iOrderByCol values +** contain the *old* locations of each expression. This is a temporary +** use of u.x.iOrderByCol, not its intended use. The caller must reset +** u.x.iOrderByCol back to zero for all entries in pEList before the +** caller returns. +** +** This routine changes pOrderBy->a[].u.x.iOrderByCol values from +** pEList->a[N].u.x.iOrderByCol into N+1. (The "+1" is because of the 1-based +** indexing used by iOrderByCol.) Or if no match, iOrderByCol is set to zero. +*/ +static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){ + int i, j; + if( pOrderBy==0 ) return; + for(i=0; i<pOrderBy->nExpr; i++){ + int t = pOrderBy->a[i].u.x.iOrderByCol; + if( t==0 ) continue; + for(j=0; j<pEList->nExpr; j++){ + if( pEList->a[j].u.x.iOrderByCol==t ){ + pOrderBy->a[i].u.x.iOrderByCol = j+1; + break; + } + } + if( j>=pEList->nExpr ){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + } +} + /* ** pX is an expression of the form: (vector) IN (SELECT ...) @@ -156196,6 +159081,7 @@ static Expr *removeUnindexableInClauseTerms( if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; + if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; if( pOrigLhs ){ assert( pOrigLhs->a[iField].pExpr!=0 ); pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); @@ -156209,6 +159095,7 @@ static Expr *removeUnindexableInClauseTerms( pNew->pLeft->x.pList = pLhs; } pSelect->pEList = pRhs; + pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */ if( pLhs && pLhs->nExpr==1 ){ /* Take care here not to generate a TK_VECTOR containing only a ** single value. Since the parser never creates such a vector, some @@ -156218,18 +159105,16 @@ static Expr *removeUnindexableInClauseTerms( sqlite3ExprDelete(db, pNew->pLeft); pNew->pLeft = p; } - if( pSelect->pOrderBy ){ - /* If the SELECT statement has an ORDER BY clause, zero the - ** iOrderByCol variables. These are set to non-zero when an - ** ORDER BY term exactly matches one of the terms of the - ** result-set. Since the result-set of the SELECT statement may - ** have been modified or reordered, these variables are no longer - ** set correctly. Since setting them is just an optimization, - ** it's easiest just to zero them here. */ - ExprList *pOrderBy = pSelect->pOrderBy; - for(i=0; i<pOrderBy->nExpr; i++){ - pOrderBy->a[i].u.x.iOrderByCol = 0; - } + + /* If either the ORDER BY clause or the GROUP BY clause contains + ** references to result-set columns, those references might now be + ** obsolete. So fix them up. + */ + assert( pRhs!=0 || db->mallocFailed ); + if( pRhs ){ + adjustOrderByCol(pSelect->pOrderBy, pRhs); + adjustOrderByCol(pSelect->pGroupBy, pRhs); + for(i=0; i<pRhs->nExpr; i++) pRhs->a[i].u.x.iOrderByCol = 0; } #if 0 @@ -156244,6 +159129,147 @@ static Expr *removeUnindexableInClauseTerms( } +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code for a single X IN (....) term of the WHERE clause. +** +** This is a special-case of codeEqualityTerm() that works for IN operators +** only. It is broken out into a subroutine because this case is +** uncommon and by splitting it off into a subroutine, the common case +** runs faster. +** +** The current value for the constraint is left in register iTarget. +** This routine sets up a loop that will iterate over all values of X. +*/ +static SQLITE_NOINLINE void codeINTerm( + Parse *pParse, /* The parsing context */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ + int bRev, /* True for reverse-order IN operations */ + int iTarget /* Attempt to leave results in this register */ +){ + Expr *pX = pTerm->pExpr; + int eType = IN_INDEX_NOOP; + int iTab; + struct InLoop *pIn; + WhereLoop *pLoop = pLevel->pWLoop; + Vdbe *v = pParse->pVdbe; + int i; + int nEq = 0; + int *aiMap = 0; + + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && pLoop->u.btree.pIndex!=0 + && pLoop->u.btree.pIndex->aSortOrder[iEq] + ){ + testcase( iEq==0 ); + testcase( bRev ); + bRev = !bRev; + } + assert( pX->op==TK_IN ); + + for(i=0; i<iEq; i++){ + if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ + disableTerm(pLevel, pTerm); + return; + } + } + for(i=iEq;i<pLoop->nLTerm; i++){ + assert( pLoop->aLTerm[i]!=0 ); + if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; + } + + iTab = 0; + if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); + }else{ + Expr *pExpr = pTerm->pExpr; + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3 *db = pParse->db; + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); + pExpr->iTable = iTab; + } + sqlite3ExprDelete(db, pX); + }else{ + int n = sqlite3ExprVectorSize(pX->pLeft); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); + } + pX = pExpr; + } + + if( eType==IN_INDEX_INDEX_DESC ){ + testcase( bRev ); + bRev = !bRev; + } + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + VdbeCoverageIf(v, bRev); + VdbeCoverageIf(v, !bRev); + + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + pLoop->wsFlags |= WHERE_IN_ABLE; + if( pLevel->u.in.nIn==0 ){ + pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + } + if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + } + + i = pLevel->u.in.nIn; + pLevel->u.in.nIn += nEq; + pLevel->u.in.aInLoop = + sqlite3WhereRealloc(pTerm->pWC->pWInfo, + pLevel->u.in.aInLoop, + sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); + pIn = pLevel->u.in.aInLoop; + if( pIn ){ + int iMap = 0; /* Index in aiMap[] */ + pIn += i; + for(i=iEq;i<pLoop->nLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iOut = iTarget + i - iEq; + if( eType==IN_INDEX_ROWID ){ + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); + }else{ + int iCol = aiMap ? aiMap[iMap++] : 0; + pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); + } + sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); + if( i==iEq ){ + pIn->iCur = iTab; + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; + if( iEq>0 ){ + pIn->iBase = iTarget - i; + pIn->nPrefix = i; + }else{ + pIn->nPrefix = 0; + } + }else{ + pIn->eEndLoopOp = OP_Noop; + } + pIn++; + } + } + testcase( iEq>0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); + if( iEq>0 + && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 + ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); + } + }else{ + pLevel->u.in.nIn = 0; + } + sqlite3DbFree(pParse->db, aiMap); +} +#endif + + /* ** Generate code for a single equality term of the WHERE clause. An equality ** term can be either X=expr or X IN (...). pTerm is the term to be @@ -156268,7 +159294,6 @@ static int codeEqualityTerm( int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; - Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); @@ -156277,125 +159302,12 @@ static int codeEqualityTerm( iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; - sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ - int eType = IN_INDEX_NOOP; - int iTab; - struct InLoop *pIn; - WhereLoop *pLoop = pLevel->pWLoop; - int i; - int nEq = 0; - int *aiMap = 0; - - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 - && pLoop->u.btree.pIndex!=0 - && pLoop->u.btree.pIndex->aSortOrder[iEq] - ){ - testcase( iEq==0 ); - testcase( bRev ); - bRev = !bRev; - } assert( pX->op==TK_IN ); iReg = iTarget; - - for(i=0; i<iEq; i++){ - if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ - disableTerm(pLevel, pTerm); - return iTarget; - } - } - for(i=iEq;i<pLoop->nLTerm; i++){ - assert( pLoop->aLTerm[i]!=0 ); - if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; - } - - iTab = 0; - if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); - }else{ - Expr *pExpr = pTerm->pExpr; - if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ - sqlite3 *db = pParse->db; - pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - if( !db->mallocFailed ){ - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); - pExpr->iTable = iTab; - } - sqlite3ExprDelete(db, pX); - }else{ - int n = sqlite3ExprVectorSize(pX->pLeft); - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); - } - pX = pExpr; - } - - if( eType==IN_INDEX_INDEX_DESC ){ - testcase( bRev ); - bRev = !bRev; - } - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); - VdbeCoverageIf(v, bRev); - VdbeCoverageIf(v, !bRev); - - assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); - pLoop->wsFlags |= WHERE_IN_ABLE; - if( pLevel->u.in.nIn==0 ){ - pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); - } - if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ - pLoop->wsFlags |= WHERE_IN_EARLYOUT; - } - - i = pLevel->u.in.nIn; - pLevel->u.in.nIn += nEq; - pLevel->u.in.aInLoop = - sqlite3WhereRealloc(pTerm->pWC->pWInfo, - pLevel->u.in.aInLoop, - sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); - pIn = pLevel->u.in.aInLoop; - if( pIn ){ - int iMap = 0; /* Index in aiMap[] */ - pIn += i; - for(i=iEq;i<pLoop->nLTerm; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - int iOut = iReg + i - iEq; - if( eType==IN_INDEX_ROWID ){ - pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); - }else{ - int iCol = aiMap ? aiMap[iMap++] : 0; - pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); - } - sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); - if( i==iEq ){ - pIn->iCur = iTab; - pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; - if( iEq>0 ){ - pIn->iBase = iReg - i; - pIn->nPrefix = i; - }else{ - pIn->nPrefix = 0; - } - }else{ - pIn->eEndLoopOp = OP_Noop; - } - pIn++; - } - } - testcase( iEq>0 - && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 - && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); - if( iEq>0 - && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 - ){ - sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); - } - }else{ - pLevel->u.in.nIn = 0; - } - sqlite3DbFree(pParse->db, aiMap); + codeINTerm(pParse, pTerm, pLevel, iEq, bRev, iTarget); #endif } @@ -157010,6 +159922,27 @@ static SQLITE_NOINLINE void filterPullDown( } } +/* +** Loop pLoop is a WHERE_INDEXED level that uses at least one IN(...) +** operator. Return true if level pLoop is guaranteed to visit only one +** row for each key generated for the index. +*/ +static int whereLoopIsOneRow(WhereLoop *pLoop){ + if( pLoop->u.btree.pIndex->onError + && pLoop->nSkip==0 + && pLoop->u.btree.nEq==pLoop->u.btree.pIndex->nKeyCol + ){ + int ii; + for(ii=0; ii<pLoop->u.btree.nEq; ii++){ + if( pLoop->aLTerm[ii]->eOperator & (WO_IS|WO_ISNULL) ){ + return 0; + } + } + return 1; + } + return 0; +} + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -157046,7 +159979,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( iCur = pTabItem->iCursor; pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; - VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); + VdbeModuleComment((v, "Begin WHERE-loop%d: %s", + iLevel, pTabItem->pSTab->zName)); #if WHERETRACE_ENABLED /* 0x4001 */ if( sqlite3WhereTrace & 0x1 ){ sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", @@ -157088,7 +160022,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); - VdbeComment((v, "init LEFT JOIN no-match flag")); + VdbeComment((v, "init LEFT JOIN match flag")); } /* Compute a safe address to jump to if we discover that the table for @@ -157101,11 +160035,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ - int regYield = pTabItem->regReturn; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); + int regYield; + Subquery *pSubq; + assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 ); + pSubq = pTabItem->u4.pSubq; + regYield = pSubq->regReturn; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeCoverage(v); - VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); + VdbeComment((v, "next row of %s", pTabItem->pSTab->zName)); pLevel->op = OP_Goto; }else @@ -157757,7 +160695,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( } /* Record the instruction used to terminate the loop. */ - if( pLoop->wsFlags & WHERE_ONEROW ){ + if( (pLoop->wsFlags & WHERE_ONEROW) + || (pLevel->u.in.nIn && regBignull==0 && whereLoopIsOneRow(pLoop)) + ){ pLevel->op = OP_Noop; }else if( bRev ){ pLevel->op = OP_Prev; @@ -157832,7 +160772,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; pTerm = pLoop->aLTerm[0]; assert( pTerm!=0 ); @@ -158147,6 +161087,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** iLoop==3: Code all remaining expressions. ** ** An effort is made to skip unnecessary iterations of the loop. + ** + ** This optimization of causing simple query restrictions to occur before + ** more complex one is call the "push-down" optimization in MySQL. Here + ** in SQLite, the name is "MySQL push-down", since there is also another + ** totally unrelated optimization called "WHERE-clause push-down". + ** Sometimes the qualifier is omitted, resulting in an ambiguity, so beware. */ iLoop = (pIdx ? 1 : 2); do{ @@ -158285,7 +161231,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** least once. This is accomplished by storing the PK for the row in ** both the iMatch index and the regBloom Bloom filter. */ - pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab; + pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab; if( HasRowid(pTab) ){ r = sqlite3GetTempRange(pParse, 2); sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); @@ -158392,12 +161338,25 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( Bitmask mAll = 0; int k; - ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); + ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName)); sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, pRJ->regReturn); for(k=0; k<iLevel; k++){ int iIdxCur; + SrcItem *pRight; + assert( pWInfo->a[k].pWLoop->iTab == pWInfo->a[k].iFrom ); + pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; mAll |= pWInfo->a[k].pWLoop->maskSelf; + if( pRight->fg.viaCoroutine ){ + Subquery *pSubq; + assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 ); + pSubq = pRight->u4.pSubq; + assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 ); + sqlite3VdbeAddOp3( + v, OP_Null, 0, pSubq->regResult, + pSubq->regResult + pSubq->pSelect->pEList->nExpr-1 + ); + } sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); iIdxCur = pWInfo->a[k].iIdxCur; if( iIdxCur ){ @@ -158433,7 +161392,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( int nPk; int jmp; int addrCont = sqlite3WhereContinueLabel(pSubWInfo); - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; if( HasRowid(pTab) ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); nPk = 1; @@ -158566,7 +161525,12 @@ static int allowedOp(int op){ assert( TK_LT>TK_EQ && TK_LT<TK_GE ); assert( TK_LE>TK_EQ && TK_LE<TK_GE ); assert( TK_GE==TK_EQ+4 ); - return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS; + assert( TK_IN<TK_EQ ); + assert( TK_IS<TK_EQ ); + assert( TK_ISNULL<TK_EQ ); + if( op>TK_GE ) return 0; + if( op>=TK_EQ ) return 1; + return op==TK_IN || op==TK_ISNULL || op==TK_IS; } /* @@ -158599,15 +161563,16 @@ static u16 exprCommute(Parse *pParse, Expr *pExpr){ static u16 operatorMask(int op){ u16 c; assert( allowedOp(op) ); - if( op==TK_IN ){ + if( op>=TK_EQ ){ + assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); + c = (u16)(WO_EQ<<(op-TK_EQ)); + }else if( op==TK_IN ){ c = WO_IN; }else if( op==TK_ISNULL ){ c = WO_ISNULL; - }else if( op==TK_IS ){ - c = WO_IS; }else{ - assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); - c = (u16)(WO_EQ<<(op-TK_EQ)); + assert( op==TK_IS ); + c = WO_IS; } assert( op!=TK_ISNULL || c==WO_ISNULL ); assert( op!=TK_IN || c==WO_IN ); @@ -158678,12 +161643,26 @@ static int isLikeOrGlob( z = (u8*)pRight->u.zToken; } if( z ){ - - /* Count the number of prefix characters prior to the first wildcard */ + /* Count the number of prefix bytes prior to the first wildcard. + ** or U+fffd character. If the underlying database has a UTF16LE + ** encoding, then only consider ASCII characters. Note that the + ** encoding of z[] is UTF8 - we are dealing with only UTF8 here in + ** this code, but the database engine itself might be processing + ** content using a different encoding. */ cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; - if( c==wc[3] && z[cnt]!=0 ) cnt++; + if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){ + cnt++; + }else if( c>=0x80 ){ + const u8 *z2 = z+cnt-1; + if( sqlite3Utf8Read(&z2)==0xfffd || ENC(db)==SQLITE_UTF16LE ){ + cnt--; + break; + }else{ + cnt = (int)(z2-z); + } + } } /* The optimization is possible only if (1) the pattern does not begin @@ -158694,11 +161673,11 @@ static int isLikeOrGlob( ** range search. The third is because the caller assumes that the pattern ** consists of at least one character after all escapes have been ** removed. */ - if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ + if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && ALWAYS(255!=(u8)z[cnt-1]) ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ - *pisComplete = c==wc[0] && z[cnt+1]==0; + *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE; /* Get the pattern prefix. Remove all escapes from the prefix. */ pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); @@ -158894,6 +161873,13 @@ static int isAuxiliaryVtabOperator( } } } + }else if( pExpr->op>=TK_EQ ){ + /* Comparison operators are a common case. Save a few comparisons for + ** that common case by terminating early. */ + assert( TK_NE < TK_EQ ); + assert( TK_ISNOT < TK_EQ ); + assert( TK_NOTNULL < TK_EQ ); + return 0; }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; @@ -159410,7 +162396,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ if( ALWAYS(pSrc!=0) ){ int i; for(i=0; i<pSrc->nSrc; i++){ - mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); + if( pSrc->a[i].fg.isSubquery ){ + mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect); + } if( pSrc->a[i].fg.isUsing==0 ){ mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); } @@ -159448,13 +162436,13 @@ static SQLITE_NOINLINE int exprMightBeIndexed2( int iCur; do{ iCur = pFrom->a[j].iCursor; - for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr==0 ) continue; for(i=0; i<pIdx->nKeyCol; i++){ if( pIdx->aiColumn[i]!=XN_EXPR ) continue; assert( pIdx->bHasExpr ); if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 - && pExpr->op!=TK_STRING + && !sqlite3ExprIsConstant(0,pIdx->aColExpr->a[i].pExpr) ){ aiCurCol[0] = iCur; aiCurCol[1] = XN_EXPR; @@ -159492,7 +162480,7 @@ static int exprMightBeIndexed( for(i=0; i<pFrom->nSrc; i++){ Index *pIdx; - for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr ){ return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); } @@ -160035,7 +163023,7 @@ static void whereAddLimitExpr( Expr *pNew; int iVal = 0; - if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){ + if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){ Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); if( pVal==0 ) return; ExprSetProperty(pVal, EP_IntValue); @@ -160080,7 +163068,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ if( p->pGroupBy==0 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ - && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ + && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */ ){ ExprList *pOrderBy = p->pOrderBy; int iCsr = p->pSrc->a[0].iCursor; @@ -160103,6 +163091,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec continue; } if( pWC->a[ii].leftCursor!=iCsr ) return; + if( pWC->a[ii].prereqRight!=0 ) return; } /* Check condition (5). Return early if it is not met. */ @@ -160117,12 +163106,14 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec /* All conditions are met. Add the terms to the where-clause object. */ assert( p->pLimit->op==TK_LIMIT ); - whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, - iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); - if( p->iOffset>0 ){ + if( p->iOffset!=0 && (p->selFlags & SF_Compound)==0 ){ whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight, iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET); } + if( p->iOffset==0 || (p->selFlags & SF_Compound)==0 ){ + whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, + iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); + } } } @@ -160298,7 +163289,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( Expr *pColRef; Expr *pTerm; if( pItem->fg.isTabFunc==0 ) return; - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 ); pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; @@ -160640,6 +163631,42 @@ static Expr *whereRightSubexprIsColumn(Expr *p){ return 0; } +/* +** Term pTerm is guaranteed to be a WO_IN term. It may be a component term +** of a vector IN expression of the form "(x, y, ...) IN (SELECT ...)". +** This function checks to see if the term is compatible with an index +** column with affinity idxaff (one of the SQLITE_AFF_XYZ values). If so, +** it returns a pointer to the name of the collation sequence (e.g. "BINARY" +** or "NOCASE") used by the comparison in pTerm. If it is not compatible +** with affinity idxaff, NULL is returned. +*/ +static SQLITE_NOINLINE const char *indexInAffinityOk( + Parse *pParse, + WhereTerm *pTerm, + u8 idxaff +){ + Expr *pX = pTerm->pExpr; + Expr inexpr; + + assert( pTerm->eOperator & WO_IN ); + + if( sqlite3ExprIsVector(pX->pLeft) ){ + int iField = pTerm->u.x.iField - 1; + inexpr.flags = 0; + inexpr.op = TK_EQ; + inexpr.pLeft = pX->pLeft->x.pList->a[iField].pExpr; + assert( ExprUseXSelect(pX) ); + inexpr.pRight = pX->x.pSelect->pEList->a[iField].pExpr; + pX = &inexpr; + } + + if( sqlite3IndexAffinityOk(pX, idxaff) ){ + CollSeq *pRet = sqlite3ExprCompareCollSeq(pParse, pX); + return pRet ? pRet->zName : sqlite3StrBINARY; + } + return 0; +} + /* ** Advance to the next WhereTerm that matches according to the criteria ** established when the pScan object was initialized by whereScanInit(). @@ -160690,16 +163717,24 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ if( (pTerm->eOperator & pScan->opMask)!=0 ){ /* Verify the affinity and collating sequence match */ if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){ - CollSeq *pColl; + const char *zCollName; Parse *pParse = pWC->pWInfo->pParse; pX = pTerm->pExpr; - if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ - continue; + + if( (pTerm->eOperator & WO_IN) ){ + zCollName = indexInAffinityOk(pParse, pTerm, pScan->idxaff); + if( !zCollName ) continue; + }else{ + CollSeq *pColl; + if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ + continue; + } + assert(pX->pLeft); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); + zCollName = pColl ? pColl->zName : sqlite3StrBINARY; } - assert(pX->pLeft); - pColl = sqlite3ExprCompareCollSeq(pParse, pX); - if( pColl==0 ) pColl = pParse->db->pDfltColl; - if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ + + if( sqlite3StrICmp(zCollName, pScan->zCollName) ){ continue; } } @@ -160938,7 +163973,7 @@ static int isDistinctRedundant( ** clause is redundant. */ if( pTabList->nSrc!=1 ) return 0; iBase = pTabList->a[0].iCursor; - pTab = pTabList->a[0].pTab; + pTab = pTabList->a[0].pSTab; /* If any of the expressions is an IPK column on table iBase, then return ** true. Note: The (p->iTable==iBase) part of this test may be false if the @@ -161013,15 +164048,31 @@ static void translateColumnToCopy( VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); int iEnd = sqlite3VdbeCurrentAddr(v); if( pParse->db->mallocFailed ) return; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("CHECKING for column-to-copy on cursor %d for %d..%d\n", + iTabCur, iStart, iEnd); + } +#endif for(; iStart<iEnd; iStart++, pOp++){ if( pOp->p1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart); + } +#endif pOp->opcode = OP_Copy; pOp->p1 = pOp->p2 + iRegister; pOp->p2 = pOp->p3; pOp->p3 = 0; pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */ }else if( pOp->opcode==OP_Rowid ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart); + } +#endif pOp->opcode = OP_Sequence; pOp->p1 = iAutoidxCur; #ifdef SQLITE_ALLOW_ROWID_IN_VIEW @@ -161041,9 +164092,13 @@ static void translateColumnToCopy( ** are no-ops. */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) -static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ +static void whereTraceIndexInfoInputs( + sqlite3_index_info *p, /* The IndexInfo object */ + Table *pTab /* The TABLE that is the virtual table */ +){ int i; if( (sqlite3WhereTrace & 0x10)==0 ) return; + sqlite3DebugPrintf("sqlite3_index_info inputs for %s:\n", pTab->zName); for(i=0; i<p->nConstraint; i++){ sqlite3DebugPrintf( " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", @@ -161061,9 +164116,13 @@ static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ p->aOrderBy[i].desc); } } -static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ +static void whereTraceIndexInfoOutputs( + sqlite3_index_info *p, /* The IndexInfo object */ + Table *pTab /* The TABLE that is the virtual table */ +){ int i; if( (sqlite3WhereTrace & 0x10)==0 ) return; + sqlite3DebugPrintf("sqlite3_index_info outputs for %s:\n", pTab->zName); for(i=0; i<p->nConstraint; i++){ sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", i, @@ -161077,8 +164136,8 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); } #else -#define whereTraceIndexInfoInputs(A) -#define whereTraceIndexInfoOutputs(A) +#define whereTraceIndexInfoInputs(A,B) +#define whereTraceIndexInfoOutputs(A,B) #endif /* @@ -161109,13 +164168,52 @@ static int constraintCompatibleWithOuterJoin( return 0; } if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 - && ExprHasProperty(pTerm->pExpr, EP_InnerON) + && NEVER(ExprHasProperty(pTerm->pExpr, EP_InnerON)) ){ return 0; } return 1; } +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** Return true if column iCol of table pTab seem like it might be a +** good column to use as part of a query-time index. +** +** Current algorithm (subject to improvement!): +** +** 1. If iCol is already the left-most column of some other index, +** then return false. +** +** 2. If iCol is part of an existing index that has an aiRowLogEst of +** more than 20, then return false. +** +** 3. If no disqualifying conditions above are found, return true. +** +** 2025-01-03: I experimented with a new rule that returns false if the +** the datatype of the column is "BOOLEAN". This did not improve +** performance on any queries at hand, but it did burn CPU cycles, so the +** idea was not committed. +*/ +static SQLITE_NOINLINE int columnIsGoodIndexCandidate( + const Table *pTab, + int iCol +){ + const Index *pIdx; + for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){ + int j; + for(j=0; j<pIdx->nKeyCol; j++){ + if( pIdx->aiColumn[j]==iCol ){ + if( j==0 ) return 0; + if( pIdx->hasStat1 && pIdx->aiRowLogEst[j+1]>20 ) return 0; + break; + } + } + } + return 1; +} +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + #ifndef SQLITE_OMIT_AUTOMATIC_INDEX @@ -161130,6 +164228,8 @@ static int termCanDriveIndex( const Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; + int leftCol; + if( pTerm->leftCursor!=pSrc->iCursor ) return 0; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); @@ -161140,11 +164240,12 @@ static int termCanDriveIndex( } if( (pTerm->prereqRight & notReady)!=0 ) return 0; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); - if( pTerm->u.x.leftColumn<0 ) return 0; - aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; + leftCol = pTerm->u.x.leftColumn; + if( leftCol<0 ) return 0; + aff = pSrc->pSTab->aCol[leftCol].affinity; if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; testcase( pTerm->pExpr->op==TK_IS ); - return 1; + return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol); } #endif @@ -161252,7 +164353,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( nKeyCol = 0; pTabList = pWC->pWInfo->pTabList; pSrc = &pTabList->a[pLevel->iFrom]; - pTable = pSrc->pTab; + pTable = pSrc->pSTab; pWCEnd = &pWC->a[pWC->nTerm]; pLoop = pLevel->pWLoop; idxCols = 0; @@ -161262,7 +164363,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** WHERE clause (or the ON clause of a LEFT join) that constrain which ** rows of the target table (pSrc) that can be used. */ if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom) + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom, 0) ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); @@ -161304,7 +164405,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** if they go out of sync. */ if( IsView(pTable) ){ - extraCols = ALLBITS; + extraCols = ALLBITS & ~idxCols; }else{ extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); } @@ -161394,12 +164495,17 @@ static SQLITE_NOINLINE void constructAutomaticIndex( /* Fill the automatic index with content */ assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); if( pSrc->fg.viaCoroutine ){ - int regYield = pSrc->regReturn; + int regYield; + Subquery *pSubq; + assert( pSrc->fg.isSubquery ); + pSubq = pSrc->u4.pSubq; + assert( pSubq!=0 ); + regYield = pSubq->regReturn; addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); VdbeCoverage(v); - VdbeComment((v, "next row of %s", pSrc->pTab->zName)); + VdbeComment((v, "next row of %s", pSrc->pSTab->zName)); }else{ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } @@ -161421,11 +164527,12 @@ static SQLITE_NOINLINE void constructAutomaticIndex( sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pSrc->fg.viaCoroutine ){ + assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 ); sqlite3VdbeChangeP2(v, addrCounter, regBase+n); testcase( pParse->db->mallocFailed ); assert( pLevel->iIdxCur>0 ); translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, - pSrc->regResult, pLevel->iIdxCur); + pSrc->u4.pSubq->regResult, pLevel->iIdxCur); sqlite3VdbeGoto(v, addrTop); pSrc->fg.viaCoroutine = 0; }else{ @@ -161516,7 +164623,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( iSrc = pLevel->iFrom; pItem = &pTabList->a[iSrc]; assert( pItem!=0 ); - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 ); sz = sqlite3LogEstToInt(pTab->nRowLogEst); if( sz<10000 ){ @@ -161531,7 +164638,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){ Expr *pExpr = pTerm->pExpr; if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc) + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc, 0) ){ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); } @@ -161547,7 +164654,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( int r1 = sqlite3GetTempRange(pParse, n); int jj; for(jj=0; jj<n; jj++){ - assert( pIdx->pTable==pItem->pTab ); + assert( pIdx->pTable==pItem->pSTab ); sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); } sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); @@ -161585,6 +164692,20 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( #ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return term iTerm of the WhereClause passed as the first argument. Terms +** are numbered from 0 upwards, starting with the terms in pWC->a[], then +** those in pWC->pOuter->a[] (if any), and so on. +*/ +static WhereTerm *termFromWhereClause(WhereClause *pWC, int iTerm){ + WhereClause *p; + for(p=pWC; p; p=p->pOuter){ + if( iTerm<p->nTerm ) return &p->a[iTerm]; + iTerm -= p->nTerm; + } + return 0; +} + /* ** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure @@ -161611,9 +164732,10 @@ static sqlite3_index_info *allocateIndexInfo( const Table *pTab; int eDistinct = 0; ExprList *pOrderBy = pWInfo->pOrderBy; + WhereClause *p; assert( pSrc!=0 ); - pTab = pSrc->pTab; + pTab = pSrc->pSTab; assert( pTab!=0 ); assert( IsVirtual(pTab) ); @@ -161621,28 +164743,30 @@ static sqlite3_index_info *allocateIndexInfo( ** Mark each term with the TERM_OK flag. Set nTerm to the number of ** terms found. */ - for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ - pTerm->wtFlags &= ~TERM_OK; - if( pTerm->leftCursor != pSrc->iCursor ) continue; - if( pTerm->prereqRight & mUnusable ) continue; - assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); - testcase( pTerm->eOperator & WO_IN ); - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; + for(p=pWC, nTerm=0; p; p=p->pOuter){ + for(i=0, pTerm=p->a; i<p->nTerm; i++, pTerm++){ + pTerm->wtFlags &= ~TERM_OK; + if( pTerm->leftCursor != pSrc->iCursor ) continue; + if( pTerm->prereqRight & mUnusable ) continue; + assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); + testcase( pTerm->eOperator & WO_IN ); + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_IS ); + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; - assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); - assert( pTerm->u.x.leftColumn>=XN_ROWID ); - assert( pTerm->u.x.leftColumn<pTab->nCol ); - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) - ){ - continue; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + assert( pTerm->u.x.leftColumn>=XN_ROWID ); + assert( pTerm->u.x.leftColumn<pTab->nCol ); + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + continue; + } + nTerm++; + pTerm->wtFlags |= TERM_OK; } - nTerm++; - pTerm->wtFlags |= TERM_OK; } /* If the ORDER BY clause contains only columns in the current @@ -161657,7 +164781,7 @@ static sqlite3_index_info *allocateIndexInfo( Expr *pE2; /* Skip over constant terms in the ORDER BY clause */ - if( sqlite3ExprIsConstant(pExpr) ){ + if( sqlite3ExprIsConstant(0, pExpr) ){ continue; } @@ -161692,7 +164816,7 @@ static sqlite3_index_info *allocateIndexInfo( } if( i==n ){ nOrderBy = n; - if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){ + if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) && !pSrc->fg.rowidUsed ){ eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ eDistinct = 1; @@ -161717,59 +164841,75 @@ static sqlite3_index_info *allocateIndexInfo( pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aConstraintUsage = pUsage; + pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; + if( HasRowid(pTab)==0 ){ + /* Ensure that all bits associated with PK columns are set. This is to + ** ensure they are available for cases like RIGHT joins or OR loops. */ + Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab); + assert( pPk!=0 ); + for(i=0; i<pPk->nKeyCol; i++){ + int iCol = pPk->aiColumn[i]; + assert( iCol>=0 ); + if( iCol>=BMS-1 ) iCol = BMS-1; + pIdxInfo->colUsed |= MASKBIT(iCol); + } + } pHidden->pWC = pWC; pHidden->pParse = pParse; pHidden->eDistinct = eDistinct; pHidden->mIn = 0; - for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ - u16 op; - if( (pTerm->wtFlags & TERM_OK)==0 ) continue; - pIdxCons[j].iColumn = pTerm->u.x.leftColumn; - pIdxCons[j].iTermOffset = i; - op = pTerm->eOperator & WO_ALL; - if( op==WO_IN ){ - if( (pTerm->wtFlags & TERM_SLICE)==0 ){ - pHidden->mIn |= SMASKBIT32(j); - } - op = WO_EQ; - } - if( op==WO_AUX ){ - pIdxCons[j].op = pTerm->eMatchOp; - }else if( op & (WO_ISNULL|WO_IS) ){ - if( op==WO_ISNULL ){ - pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; - }else{ - pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; - } - }else{ - pIdxCons[j].op = (u8)op; - /* The direct assignment in the previous line is possible only because - ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The - ** following asserts verify this fact. */ - assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); - assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); - assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); - assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); - assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); - assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); - - if( op & (WO_LT|WO_LE|WO_GT|WO_GE) - && sqlite3ExprIsVector(pTerm->pExpr->pRight) - ){ - testcase( j!=i ); - if( j<16 ) mNoOmit |= (1 << j); - if( op==WO_LT ) pIdxCons[j].op = WO_LE; - if( op==WO_GT ) pIdxCons[j].op = WO_GE; + for(p=pWC, i=j=0; p; p=p->pOuter){ + int nLast = i+p->nTerm;; + for(pTerm=p->a; i<nLast; i++, pTerm++){ + u16 op; + if( (pTerm->wtFlags & TERM_OK)==0 ) continue; + pIdxCons[j].iColumn = pTerm->u.x.leftColumn; + pIdxCons[j].iTermOffset = i; + op = pTerm->eOperator & WO_ALL; + if( op==WO_IN ){ + if( (pTerm->wtFlags & TERM_SLICE)==0 ){ + pHidden->mIn |= SMASKBIT32(j); + } + op = WO_EQ; + } + if( op==WO_AUX ){ + pIdxCons[j].op = pTerm->eMatchOp; + }else if( op & (WO_ISNULL|WO_IS) ){ + if( op==WO_ISNULL ){ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; + }else{ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; + } + }else{ + pIdxCons[j].op = (u8)op; + /* The direct assignment in the previous line is possible only because + ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The + ** following asserts verify this fact. */ + assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); + assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); + assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); + assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); + assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); + assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); + + if( op & (WO_LT|WO_LE|WO_GT|WO_GE) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) + ){ + testcase( j!=i ); + if( j<16 ) mNoOmit |= (1 << j); + if( op==WO_LT ) pIdxCons[j].op = WO_LE; + if( op==WO_GT ) pIdxCons[j].op = WO_GE; + } } - } - j++; + j++; + } } assert( j==nTerm ); pIdxInfo->nConstraint = j; for(i=j=0; i<nOrderBy; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; - if( sqlite3ExprIsConstant(pExpr) ) continue; + if( sqlite3ExprIsConstant(0, pExpr) ) continue; assert( pExpr->op==TK_COLUMN || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN && pExpr->iColumn==pExpr->pLeft->iColumn) ); @@ -161783,6 +164923,17 @@ static sqlite3_index_info *allocateIndexInfo( return pIdxInfo; } +/* +** Free and zero the sqlite3_index_info.idxStr value if needed. +*/ +static void freeIdxStr(sqlite3_index_info *pIdxInfo){ + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); + pIdxInfo->idxStr = 0; + pIdxInfo->needToFreeIdxStr = 0; + } +} + /* ** Free an sqlite3_index_info structure allocated by allocateIndexInfo() ** and possibly modified by xBestIndex methods. @@ -161798,6 +164949,7 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ pHidden->aRhs[i] = 0; } + freeIdxStr(pIdxInfo); sqlite3DbFree(db, pIdxInfo); } @@ -161818,14 +164970,16 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ ** that this is required. */ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ - sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; int rc; + sqlite3_vtab *pVtab; - whereTraceIndexInfoInputs(p); + assert( IsVirtual(pTab) ); + pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; + whereTraceIndexInfoInputs(p, pTab); pParse->db->nSchemaLock++; rc = pVtab->pModule->xBestIndex(pVtab, p); pParse->db->nSchemaLock--; - whereTraceIndexInfoOutputs(p); + whereTraceIndexInfoOutputs(p, pTab); if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ if( rc==SQLITE_NOMEM ){ @@ -162348,7 +165502,8 @@ static int whereRangeScanEst( ** sample, then assume they are 4x more selective. This brings ** the estimated selectivity more in line with what it would be ** if estimated without the use of STAT4 tables. */ - if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) ); + if( iLwrIdx==iUprIdx ){ nNew -= 20; } + assert( 20==sqlite3LogEst(4) ); }else{ nNew = 10; assert( 10==sqlite3LogEst(2) ); } @@ -162511,7 +165666,7 @@ static int whereInScanEst( #endif /* SQLITE_ENABLE_STAT4 */ -#ifdef WHERETRACE_ENABLED +#if defined(WHERETRACE_ENABLED) || defined(SQLITE_DEBUG) /* ** Print the content of a WhereTerm object */ @@ -162555,6 +165710,9 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } +SQLITE_PRIVATE void sqlite3ShowWhereTerm(WhereTerm *pTerm){ + sqlite3WhereTermPrint(pTerm, 0); +} #endif #ifdef WHERETRACE_ENABLED @@ -162572,17 +165730,34 @@ SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ #ifdef WHERETRACE_ENABLED /* ** Print a WhereLoop object for debugging purposes -*/ -SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ - WhereInfo *pWInfo = pWC->pWInfo; - int nb = 1+(pWInfo->pTabList->nSrc+3)/4; - SrcItem *pItem = pWInfo->pTabList->a + p->iTab; - Table *pTab = pItem->pTab; - Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; - sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, - p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); - sqlite3DebugPrintf(" %12s", - pItem->zAlias ? pItem->zAlias : pTab->zName); +** +** Format example: +** +** .--- Position in WHERE clause rSetup, rRun, nOut ---. +** | | +** | .--- selfMask nTerm ------. | +** | | | | +** | | .-- prereq Idx wsFlags----. | | +** | | | Name | | | +** | | | __|__ nEq ---. ___|__ | __|__ +** | / \ / \ / \ | / \ / \ / \ +** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31 +*/ +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ + if( pWC ){ + WhereInfo *pWInfo = pWC->pWInfo; + int nb = 1+(pWInfo->pTabList->nSrc+3)/4; + SrcItem *pItem = pWInfo->pTabList->a + p->iTab; + Table *pTab = pItem->pSTab; + Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, + p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); + sqlite3DebugPrintf(" %12s", + pItem->zAlias ? pItem->zAlias : pTab->zName); + }else{ + sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d", + p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab); + } if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ const char *zName; if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ @@ -162619,6 +165794,15 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ } } } +SQLITE_PRIVATE void sqlite3ShowWhereLoop(const WhereLoop *p){ + if( p ) sqlite3WhereLoopPrint(p, 0); +} +SQLITE_PRIVATE void sqlite3ShowWhereLoopList(const WhereLoop *p){ + while( p ){ + sqlite3ShowWhereLoop(p); + p = p->pNextLoop; + } +} #endif /* @@ -162731,46 +165915,60 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ } /* -** Return TRUE if all of the following are true: +** Return TRUE if X is a proper subset of Y but is of equal or less cost. +** In other words, return true if all constraints of X are also part of Y +** and Y has additional constraints that might speed the search that X lacks +** but the cost of running X is not more than the cost of running Y. +** +** In other words, return true if the cost relationship between X and Y +** is inverted and needs to be adjusted. ** -** (1) X has the same or lower cost, or returns the same or fewer rows, -** than Y. -** (2) X uses fewer WHERE clause terms than Y -** (3) Every WHERE clause term used by X is also used by Y -** (4) X skips at least as many columns as Y -** (5) If X is a covering index, than Y is too +** Case 1: ** -** Conditions (2) and (3) mean that X is a "proper subset" of Y. -** If X is a proper subset of Y then Y is a better choice and ought -** to have a lower cost. This routine returns TRUE when that cost -** relationship is inverted and needs to be adjusted. Constraint (4) -** was added because if X uses skip-scan less than Y it still might -** deserve a lower cost even if it is a proper subset of Y. Constraint (5) -** was added because a covering index probably deserves to have a lower cost -** than a non-covering index even if it is a proper subset. +** (1a) X and Y use the same index. +** (1b) X has fewer == terms than Y +** (1c) Neither X nor Y use skip-scan +** (1d) X does not have a a greater cost than Y +** +** Case 2: +** +** (2a) X has the same or lower cost, or returns the same or fewer rows, +** than Y. +** (2b) X uses fewer WHERE clause terms than Y +** (2c) Every WHERE clause term used by X is also used by Y +** (2d) X skips at least as many columns as Y +** (2e) If X is a covering index, than Y is too */ static int whereLoopCheaperProperSubset( const WhereLoop *pX, /* First WhereLoop to compare */ const WhereLoop *pY /* Compare against this WhereLoop */ ){ int i, j; + if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; /* (1d) and (2a) */ + assert( (pX->wsFlags & WHERE_VIRTUALTABLE)==0 ); + assert( (pY->wsFlags & WHERE_VIRTUALTABLE)==0 ); + if( pX->u.btree.nEq < pY->u.btree.nEq /* (1b) */ + && pX->u.btree.pIndex==pY->u.btree.pIndex /* (1a) */ + && pX->nSkip==0 && pY->nSkip==0 /* (1c) */ + ){ + return 1; /* Case 1 is true */ + } if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ - return 0; /* X is not a subset of Y */ + return 0; /* (2b) */ } - if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; - if( pY->nSkip > pX->nSkip ) return 0; + if( pY->nSkip > pX->nSkip ) return 0; /* (2d) */ for(i=pX->nLTerm-1; i>=0; i--){ if( pX->aLTerm[i]==0 ) continue; for(j=pY->nLTerm-1; j>=0; j--){ if( pY->aLTerm[j]==pX->aLTerm[i] ) break; } - if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ + if( j<0 ) return 0; /* (2c) */ } if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ - return 0; /* Constraint (5) */ + return 0; /* (2e) */ } - return 1; /* All conditions meet */ + return 1; /* Case 2 is true */ } /* @@ -163108,7 +166306,7 @@ static void whereLoopOutputAdjust( Expr *pRight = pTerm->pExpr->pRight; int k = 0; testcase( pTerm->pExpr->op==TK_IS ); - if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ + if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ k = 10; }else{ k = 20; @@ -163260,7 +166458,12 @@ static int whereLoopAddBtreeIndex( assert( pNew->u.btree.nBtm==0 ); opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; } - if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bUnordered || pProbe->bLowQual ){ + if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bLowQual && pSrc->fg.isIndexedBy==0 ){ + opMask &= ~(WO_EQ|WO_IN|WO_IS); + } + } assert( pNew->u.btree.nEq<pProbe->nColumn ); assert( pNew->u.btree.nEq<pProbe->nKeyCol @@ -163400,7 +166603,7 @@ static int whereLoopAddBtreeIndex( || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ if( iCol==XN_ROWID || pProbe->uniqNotNull - || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) + || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ)) ){ pNew->wsFlags |= WHERE_ONEROW; }else{ @@ -163526,11 +166729,14 @@ static int whereLoopAddBtreeIndex( } } - /* Set rCostIdx to the cost of visiting selected rows in index. Add - ** it to pNew->rRun, which is currently set to the cost of the index - ** seek only. Then, if this is a non-covering index, add the cost of - ** visiting the rows in the main table. */ - assert( pSrc->pTab->szTabRow>0 ); + /* Set rCostIdx to the estimated cost of visiting selected rows in the + ** index. The estimate is the sum of two values: + ** 1. The cost of doing one search-by-key to find the first matching + ** entry + ** 2. Stepping forward in the index pNew->nOut times to find all + ** additional matching entries. + */ + assert( pSrc->pSTab->szTabRow>0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* The pProbe->szIdxRow is low for an IPK table since the interior ** pages are small. Thus szIdxRow gives a good estimate of seek cost. @@ -163538,9 +166744,17 @@ static int whereLoopAddBtreeIndex( ** under-estimate the scanning cost. */ rCostIdx = pNew->nOut + 16; }else{ - rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow; } - pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); + rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); + + /* Estimate the cost of running the loop. If all data is coming + ** from the index, then this is just the cost of doing the index + ** lookup and scan. But if some data is coming out of the main table, + ** we also have to add in the cost of doing pNew->nOut searches to + ** locate the row in the main table that corresponds to the index entry. + */ + pNew->rRun = rCostIdx; if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); } @@ -163646,7 +166860,9 @@ static int indexMightHelpWithOrderBy( for(ii=0; ii<pOB->nExpr; ii++){ Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); if( NEVER(pExpr==0) ) continue; - if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ + if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) + && pExpr->iTable==iCursor + ){ if( pExpr->iColumn<0 ) return 1; for(jj=0; jj<pIndex->nKeyCol; jj++){ if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; @@ -163682,7 +166898,6 @@ static int whereUsablePartialIndex( if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } - if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ Expr *pExpr; pExpr = pTerm->pExpr; @@ -163903,7 +167118,7 @@ static void wherePartIdxExpr( u8 aff; if( pLeft->op!=TK_COLUMN ) return; - if( !sqlite3ExprIsConstant(pRight) ) return; + if( !sqlite3ExprIsConstant(0, pRight) ) return; if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; if( pLeft->iColumn<0 ) return; aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; @@ -163993,9 +167208,9 @@ static int whereLoopAddBtree( pWInfo = pBuilder->pWInfo; pTabList = pWInfo->pTabList; pSrc = pTabList->a + pNew->iTab; - pTab = pSrc->pTab; + pTab = pSrc->pSTab; pWC = pBuilder->pWC; - assert( !IsVirtual(pSrc->pTab) ); + assert( !IsVirtual(pSrc->pSTab) ); if( pSrc->fg.isIndexedBy ){ assert( pSrc->fg.isCte==0 ); @@ -164020,7 +167235,7 @@ static int whereLoopAddBtree( sPk.idxType = SQLITE_IDXTYPE_IPK; aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; - pFirst = pSrc->pTab->pIndex; + pFirst = pSrc->pSTab->pIndex; if( pSrc->fg.notIndexed==0 ){ /* The real indices of the table are only considered if the ** NOT INDEXED qualifier is omitted from the FROM clause */ @@ -164110,6 +167325,7 @@ static int whereLoopAddBtree( pNew->prereq = mPrereq; pNew->nOut = rSize; pNew->u.btree.pIndex = pProbe; + pNew->u.btree.pOrderBy = 0; b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ @@ -164139,6 +167355,10 @@ static int whereLoopAddBtree( #endif ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); + if( pSrc->fg.isSubquery ){ + if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; + pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; + } rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; @@ -164176,7 +167396,9 @@ static int whereLoopAddBtree( " according to whereIsCoveringIndex()\n", pProbe->zName)); } } - }else if( m==0 ){ + }else if( m==0 + && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700)) + ){ WHERETRACE(0x200, ("-> %s a covering index according to bitmasks\n", pProbe->zName, m==0 ? "is" : "is not")); @@ -164252,7 +167474,7 @@ static int whereLoopAddBtree( ** unique index is used (making the index functionally non-unique) ** then the sqlite_stat1 data becomes important for scoring the ** plan */ - pTab->tabFlags |= TF_StatsUsed; + pTab->tabFlags |= TF_MaybeReanalyze; } #ifdef SQLITE_ENABLE_STAT4 sqlite3Stat4ProbeFree(pBuilder->pRec); @@ -164274,6 +167496,21 @@ static int isLimitTerm(WhereTerm *pTerm){ && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET; } +/* +** Return true if the first nCons constraints in the pUsage array are +** marked as in-use (have argvIndex>0). False otherwise. +*/ +static int allConstraintsUsed( + struct sqlite3_index_constraint_usage *aUsage, + int nCons +){ + int ii; + for(ii=0; ii<nCons; ii++){ + if( aUsage[ii].argvIndex<=0 ) return 0; + } + return 1; +} + /* ** Argument pIdxInfo is already populated with all constraints that may ** be used by the virtual table identified by pBuilder->pNew->iTab. This @@ -164324,7 +167561,7 @@ static int whereLoopAddVirtualOne( ** arguments mUsable and mExclude. */ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; i<nConstraint; i++, pIdxCons++){ - WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset]; + WhereTerm *pTerm = termFromWhereClause(pWC, pIdxCons->iTermOffset); pIdxCons->usable = 0; if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight && (pTerm->eOperator & mExclude)==0 @@ -164343,11 +167580,10 @@ static int whereLoopAddVirtualOne( pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; - pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; pHidden->mHandleIn = 0; /* Invoke the virtual table xBestIndex() method */ - rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); + rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo); if( rc ){ if( rc==SQLITE_CONSTRAINT ){ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means @@ -164355,6 +167591,7 @@ static int whereLoopAddVirtualOne( ** Make no entries in the loop table. */ WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); + freeIdxStr(pIdxInfo); return SQLITE_OK; } return rc; @@ -164372,18 +167609,17 @@ static int whereLoopAddVirtualOne( int j = pIdxCons->iTermOffset; if( iTerm>=nConstraint || j<0 - || j>=pWC->nTerm + || (pTerm = termFromWhereClause(pWC, j))==0 || pNew->aLTerm[iTerm]!=0 || pIdxCons->usable==0 ){ - sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); - testcase( pIdxInfo->needToFreeIdxStr ); + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); + freeIdxStr(pIdxInfo); return SQLITE_ERROR; } testcase( iTerm==nConstraint-1 ); testcase( j==0 ); testcase( j==pWC->nTerm-1 ); - pTerm = &pWC->a[j]; pNew->prereq |= pTerm->prereqRight; assert( iTerm<pNew->nLSlot ); pNew->aLTerm[iTerm] = pTerm; @@ -164414,18 +167650,21 @@ static int whereLoopAddVirtualOne( *pbIn = 1; assert( (mExclude & WO_IN)==0 ); } + /* Unless pbRetryLimit is non-NULL, there should be no LIMIT/OFFSET + ** terms. And if there are any, they should follow all other terms. */ assert( pbRetryLimit || !isLimitTerm(pTerm) ); - if( isLimitTerm(pTerm) && *pbIn ){ + assert( !isLimitTerm(pTerm) || i>=nConstraint-2 ); + assert( !isLimitTerm(pTerm) || i==nConstraint-1 || isLimitTerm(pTerm+1) ); + + if( isLimitTerm(pTerm) && (*pbIn || !allConstraintsUsed(pUsage, i)) ){ /* If there is an IN(...) term handled as an == (separate call to ** xFilter for each value on the RHS of the IN) and a LIMIT or - ** OFFSET term handled as well, the plan is unusable. Set output - ** variable *pbRetryLimit to true to tell the caller to retry with - ** LIMIT and OFFSET disabled. */ - if( pIdxInfo->needToFreeIdxStr ){ - sqlite3_free(pIdxInfo->idxStr); - pIdxInfo->idxStr = 0; - pIdxInfo->needToFreeIdxStr = 0; - } + ** OFFSET term handled as well, the plan is unusable. Similarly, + ** if there is a LIMIT/OFFSET and there are other unused terms, + ** the plan cannot be used. In these cases set variable *pbRetryLimit + ** to true to tell the caller to retry with LIMIT and OFFSET + ** disabled. */ + freeIdxStr(pIdxInfo); *pbRetryLimit = 1; return SQLITE_OK; } @@ -164437,8 +167676,8 @@ static int whereLoopAddVirtualOne( if( pNew->aLTerm[i]==0 ){ /* The non-zero argvIdx values must be contiguous. Raise an ** error if they are not */ - sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); - testcase( pIdxInfo->needToFreeIdxStr ); + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); + freeIdxStr(pIdxInfo); return SQLITE_ERROR; } } @@ -164449,6 +167688,7 @@ static int whereLoopAddVirtualOne( pNew->u.vtab.idxStr = pIdxInfo->idxStr; pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? pIdxInfo->nOrderBy : 0); + pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0; pNew->rSetup = 0; pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); @@ -164493,7 +167733,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int if( iCons>=0 && iCons<pIdxInfo->nConstraint ){ CollSeq *pC = 0; int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; - Expr *pX = pHidden->pWC->a[iTerm].pExpr; + Expr *pX = termFromWhereClause(pHidden->pWC, iTerm)->pExpr; if( pX->pLeft ){ pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); } @@ -164539,7 +167779,9 @@ SQLITE_API int sqlite3_vtab_rhs_value( rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ }else{ if( pH->aRhs[iCons]==0 ){ - WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; + WhereTerm *pTerm = termFromWhereClause( + pH->pWC, pIdxInfo->aConstraint[iCons].iTermOffset + ); rc = sqlite3ValueFromExpr( pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), SQLITE_AFF_BLOB, &pH->aRhs[iCons] @@ -164637,7 +167879,7 @@ static int whereLoopAddVirtual( pWC = pBuilder->pWC; pNew = pBuilder->pNew; pSrc = &pWInfo->pTabList->a[pNew->iTab]; - assert( IsVirtual(pSrc->pTab) ); + assert( IsVirtual(pSrc->pSTab) ); p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); if( p==0 ) return SQLITE_NOMEM_BKPT; pNew->rSetup = 0; @@ -164651,7 +167893,7 @@ static int whereLoopAddVirtual( } /* First call xBestIndex() with all constraints usable. */ - WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); + WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName)); WHERETRACE(0x800, (" VirtualOne: all usable\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry @@ -164695,9 +167937,8 @@ static int whereLoopAddVirtual( Bitmask mNext = ALLBITS; assert( mNext>0 ); for(i=0; i<nConstraint; i++){ - Bitmask mThis = ( - pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq - ); + int iTerm = p->aConstraint[i].iTermOffset; + Bitmask mThis = termFromWhereClause(pWC, iTerm)->prereqRight & ~mPrereq; if( mThis>mPrev && mThis<mNext ) mNext = mThis; } mPrev = mNext; @@ -164733,9 +167974,8 @@ static int whereLoopAddVirtual( } } - if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); freeIndexInfo(pParse->db, p); - WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); + WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc)); return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -164807,7 +168047,7 @@ static int whereLoopAddOr( } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pItem->pTab) ){ + if( IsVirtual(pItem->pSTab) ){ rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); }else #endif @@ -164921,7 +168161,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pItem->pTab) ){ + if( IsVirtual(pItem->pSTab) ){ SrcItem *p; for(p=&pItem[1]; p<pEnd; p++){ if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){ @@ -164953,6 +168193,97 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ return rc; } +/* Implementation of the order-by-subquery optimization: +** +** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really +** a subquery or CTE that has an ORDER BY clause. See if any of the terms +** in the subquery ORDER BY clause will satisfy pOrderBy from the outer +** query. Mark off all satisfied terms (by setting bits in *pOBSat) and +** return TRUE if they do. If not, return false. +** +** Example: +** +** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b)); +** CREATE TABLE t2(x,y); +** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y) +** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b; +** +** The CTE named "t3" comes out in the natural order of "p", so the first +** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3" +** and sorting only needs to occur on the second term "b". +** +** Limitations: +** +** (1) The optimization is not applied if the outer ORDER BY contains +** a COLLATE clause. The optimization might be applied if the +** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as +** long as the subquery ORDER BY does the same. But if the +** outer ORDER BY uses COLLATE, even a redundant COLLATE, the +** optimization is bypassed. +** +** (2) The subquery ORDER BY terms must exactly match subquery result +** columns, including any COLLATE annotations. This routine relies +** on iOrderByCol to do matching between order by terms and result +** columns, and iOrderByCol will not be set if the result column +** and ORDER BY collations differ. +** +** (3) The subquery and outer ORDER BY can be in opposite directions as +** long as the subquery is materialized. If the subquery is +** implemented as a co-routine, the sort orders must be in the same +** direction because there is no way to run a co-routine backwards. +*/ +static SQLITE_NOINLINE int wherePathMatchSubqueryOB( + WhereInfo *pWInfo, /* The WHERE clause */ + WhereLoop *pLoop, /* The nested loop term that is a subquery */ + int iLoop, /* Which level of the nested loop. 0==outermost */ + int iCur, /* Cursor used by the this loop */ + ExprList *pOrderBy, /* The ORDER BY clause on the whole query */ + Bitmask *pRevMask, /* When loops need to go in reverse order */ + Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */ +){ + int iOB; /* Index into pOrderBy->a[] */ + int jSub; /* Index into pSubOB->a[] */ + u8 rev = 0; /* True if iOB and jSub sort in opposite directions */ + u8 revIdx = 0; /* Sort direction for jSub */ + Expr *pOBExpr; /* Current term of outer ORDER BY */ + ExprList *pSubOB; /* Complete ORDER BY on the subquery */ + + pSubOB = pLoop->u.btree.pOrderBy; + assert( pSubOB!=0 ); + for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){} + for(jSub=0; jSub<pSubOB->nExpr && iOB<pOrderBy->nExpr; jSub++, iOB++){ + if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break; + pOBExpr = pOrderBy->a[iOB].pExpr; + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break; + if( pOBExpr->iTable!=iCur ) break; + if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break; + if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ + u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */ + u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */ + if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){ + break; + } + revIdx = sfSub & KEYINFO_ORDER_DESC; + if( jSub>0 ){ + if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){ + break; + } + }else{ + rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC); + if( rev ){ + if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){ + /* Cannot run a co-routine in reverse order */ + break; + } + *pRevMask |= MASKBIT(iLoop); + } + } + } + *pOBSat |= MASKBIT(iOB); + } + return jSub>0; +} + /* ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th ** parameters) to see if it outputs rows in the requested ORDER BY @@ -165098,9 +168429,18 @@ static i8 wherePathSatisfiesOrderBy( if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ if( pLoop->wsFlags & WHERE_IPK ){ + if( pLoop->u.btree.pOrderBy + && OptimizationEnabled(db, SQLITE_OrderBySubq) + && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur, + pOrderBy,pRevMask, &obSat) + ){ + nColumn = 0; + isOrderDistinct = 0; + }else{ + nColumn = 1; + } pIndex = 0; nKeyCol = 0; - nColumn = 1; }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ return 0; }else{ @@ -165110,7 +168450,7 @@ static i8 wherePathSatisfiesOrderBy( assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); /* All relevant terms of the index must also be non-NULL in order - ** for isOrderDistinct to be true. So the isOrderDistint value + ** for isOrderDistinct to be true. So the isOrderDistinct value ** computed here might be a false positive. Corrections will be ** made at tag-20210426-1 below */ isOrderDistinct = IsUniqueIndex(pIndex) @@ -165195,7 +168535,7 @@ static i8 wherePathSatisfiesOrderBy( } /* Find the ORDER BY term that corresponds to the j-th column - ** of the index and mark that ORDER BY term off + ** of the index and mark that ORDER BY term having been satisfied. */ isMatch = 0; for(i=0; bOnce && i<nOrderBy; i++){ @@ -165277,7 +168617,7 @@ static i8 wherePathSatisfiesOrderBy( if( MASKBIT(i) & obSat ) continue; p = pOrderBy->a[i].pExpr; mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p); - if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue; + if( mTerm==0 && !sqlite3ExprIsConstant(0,p) ) continue; if( (mTerm&~orderDistinctMask)==0 ){ obSat |= MASKBIT(i); } @@ -165402,6 +168742,83 @@ static LogEst whereSortingCost( return rSortCost; } +/* +** Compute the maximum number of paths in the solver algorithm, for +** queries that have three or more terms in the FROM clause. Queries with +** two or fewer FROM clause terms are handled by the caller. +** +** Query planning is NP-hard. We must limit the number of paths at +** each step of the solver search algorithm to avoid exponential behavior. +** +** The value returned is a tuning parameter. Currently the value is: +** +** 18 for star queries +** 12 otherwise +** +** For the purposes of SQLite, a star-query is defined as a query +** with a large central table that is joined against four or more +** smaller tables. The central table is called the "fact" table. +** The smaller tables that get joined are "dimension tables". +** +** SIDE EFFECT: (and really the whole point of this subroutine) +** +** If pWInfo describes a star-query, then the cost on WhereLoops for the +** fact table is reduced. This heuristic helps keep fact tables in +** outer loops. Without this heuristic, paths with fact tables in outer +** loops tend to get pruned by the mxChoice limit on the number of paths, +** resulting in poor query plans. The total amount of heuristic cost +** adjustment is stored in pWInfo->nOutStarDelta and the cost adjustment +** for each WhereLoop is stored in its rStarDelta field. +*/ +static int computeMxChoice(WhereInfo *pWInfo, LogEst nRowEst){ + int nLoop = pWInfo->nLevel; /* Number of terms in the join */ + if( nRowEst==0 && nLoop>=5 ){ + /* Check to see if we are dealing with a star schema and if so, reduce + ** the cost of fact tables relative to dimension tables, as a heuristic + ** to help keep the fact tables in outer loops. + */ + int iLoop; /* Counter over join terms */ + Bitmask m; /* Bitmask for current loop */ + assert( pWInfo->nOutStarDelta==0 ); + for(iLoop=0, m=1; iLoop<nLoop; iLoop++, m<<=1){ + WhereLoop *pWLoop; /* For looping over WhereLoops */ + int nDep = 0; /* Number of dimension tables */ + LogEst rDelta; /* Heuristic cost adjustment */ + Bitmask mSeen = 0; /* Mask of dimension tables */ + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( (pWLoop->prereq & m)!=0 && (pWLoop->maskSelf & mSeen)==0 ){ + nDep++; + mSeen |= pWLoop->maskSelf; + } + } + if( nDep<=3 ) continue; + rDelta = 15*(nDep-3); +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + SrcItem *pItem = pWInfo->pTabList->a + iLoop; + sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n", + pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName, + nDep, rDelta); + } +#endif + if( pWInfo->nOutStarDelta==0 ){ + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + pWLoop->rStarDelta = 0; + } + } + pWInfo->nOutStarDelta += rDelta; + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( pWLoop->maskSelf==m ){ + pWLoop->rRun -= rDelta; + pWLoop->nOut -= rDelta; + pWLoop->rStarDelta = rDelta; + } + } + } + } + return pWInfo->nOutStarDelta>0 ? 18 : 12; +} + /* ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine ** attempts to find the lowest cost path that visits each WhereLoop @@ -165437,13 +168854,25 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pParse = pWInfo->pParse; nLoop = pWInfo->nLevel; - /* TUNING: For simple queries, only the best path is tracked. - ** For 2-way joins, the 5 best paths are followed. - ** For joins of 3 or more tables, track the 10 best paths */ - mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); - assert( nLoop<=pWInfo->pTabList->nSrc ); WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", nRowEst, pParse->nQueryLoop)); + /* TUNING: mxChoice is the maximum number of possible paths to preserve + ** at each step. Based on the number of loops in the FROM clause: + ** + ** nLoop mxChoice + ** ----- -------- + ** 1 1 // the most common case + ** 2 5 + ** 3+ 12 or 18 // see computeMxChoice() + */ + if( nLoop<=1 ){ + mxChoice = 1; + }else if( nLoop==2 ){ + mxChoice = 5; + }else{ + mxChoice = computeMxChoice(pWInfo, nRowEst); + } + assert( nLoop<=pWInfo->pTabList->nSrc ); /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this ** case the purpose of this call is to estimate the number of rows returned @@ -165526,7 +168955,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ /* At this point, pWLoop is a candidate to be the next loop. ** Compute its cost */ - rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); + rUnsorted = pWLoop->rRun + pFrom->nRow; + if( pWLoop->rSetup ){ + rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup, rUnsorted); + } rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); nOut = pFrom->nRow + pWLoop->nOut; maskNew = pFrom->maskLoop | pWLoop->maskSelf; @@ -165571,6 +169003,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range ** of legal values for isOrdered, -1..64. */ + testcase( nTo==0 ); for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){ if( pTo->maskLoop==maskNew && ((pTo->isOrdered^isOrdered)&0x80)==0 @@ -165687,16 +169120,28 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ #ifdef WHERETRACE_ENABLED /* >=2 */ if( sqlite3WhereTrace & 0x02 ){ + LogEst rMin, rFloor = 0; + int nDone = 0; sqlite3DebugPrintf("---- after round %d ----\n", iLoop); - for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ - sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", - wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, - pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); - if( pTo->isOrdered>0 ){ - sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); - }else{ - sqlite3DebugPrintf("\n"); + while( nDone<nTo ){ + rMin = 0x7fff; + for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ + if( pTo->rCost>rFloor && pTo->rCost<rMin ) rMin = pTo->rCost; + } + for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ + if( pTo->rCost==rMin ){ + sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); + if( pTo->isOrdered>0 ){ + sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); + }else{ + sqlite3DebugPrintf("\n"); + } + nDone++; + } } + rFloor = rMin; } } #endif @@ -165746,10 +169191,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } - if( pWInfo->pSelect->pOrderBy - && pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){ - pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr; - } + /* vvv--- See check-in [12ad822d9b827777] on 2023-03-16 ---vvv */ + assert( pWInfo->pSelect->pOrderBy==0 + || pWInfo->nOBSat <= pWInfo->pSelect->pOrderBy->nExpr ); }else{ pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ @@ -165792,14 +169236,90 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } } - - pWInfo->nRowOut = pFrom->nRow; + pWInfo->nRowOut = pFrom->nRow + pWInfo->nOutStarDelta; /* Free temporary memory and return success */ sqlite3StackFreeNN(pParse->db, pSpace); return SQLITE_OK; } +/* +** This routine implements a heuristic designed to improve query planning. +** This routine is called in between the first and second call to +** wherePathSolver(). Hence the name "Interstage" "Heuristic". +** +** The first call to wherePathSolver() (hereafter just "solver()") computes +** the best path without regard to the order of the outputs. The second call +** to the solver() builds upon the first call to try to find an alternative +** path that satisfies the ORDER BY clause. +** +** This routine looks at the results of the first solver() run, and for +** every FROM clause term in the resulting query plan that uses an equality +** constraint against an index, disable other WhereLoops for that same +** FROM clause term that would try to do a full-table scan. This prevents +** an index search from being converted into a full-table scan in order to +** satisfy an ORDER BY clause, since even though we might get slightly better +** performance using the full-scan without sorting if the output size +** estimates are very precise, we might also get severe performance +** degradation using the full-scan if the output size estimate is too large. +** It is better to err on the side of caution. +** +** Except, if the first solver() call generated a full-table scan in an outer +** loop then stop this analysis at the first full-scan, since the second +** solver() run might try to swap that full-scan for another in order to +** get the output into the correct order. In other words, we allow a +** rewrite like this: +** +** First Solver() Second Solver() +** |-- SCAN t1 |-- SCAN t2 +** |-- SEARCH t2 `-- SEARCH t1 +** `-- SORT USING B-TREE +** +** The purpose of this routine is to disallow rewrites such as: +** +** First Solver() Second Solver() +** |-- SEARCH t1 |-- SCAN t2 <--- bad! +** |-- SEARCH t2 `-- SEARCH t1 +** `-- SORT USING B-TREE +** +** See test cases in test/whereN.test for the real-world query that +** originally provoked this heuristic. +*/ +static SQLITE_NOINLINE void whereInterstageHeuristic(WhereInfo *pWInfo){ + int i; +#ifdef WHERETRACE_ENABLED + int once = 0; +#endif + for(i=0; i<pWInfo->nLevel; i++){ + WhereLoop *p = pWInfo->a[i].pWLoop; + if( p==0 ) break; + if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ) continue; + if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){ + u8 iTab = p->iTab; + WhereLoop *pLoop; + for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){ + if( pLoop->iTab!=iTab ) continue; + if( (pLoop->wsFlags & (WHERE_CONSTRAINT|WHERE_AUTO_INDEX))!=0 ){ + /* Auto-index and index-constrained loops allowed to remain */ + continue; + } +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x80 ){ + if( once==0 ){ + sqlite3DebugPrintf("Loops disabled by interstage heuristic:\n"); + once = 1; + } + sqlite3WhereLoopPrint(pLoop, &pWInfo->sWC); + } +#endif /* WHERETRACE_ENABLED */ + pLoop->prereq = ALLBITS; /* Prevent 2nd solver() from using this one */ + } + }else{ + break; + } + } +} + /* ** Most queries use only a single table (they are not joins) and have ** simple == constraints against indexed fields. This routine attempts @@ -165827,7 +169347,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; assert( pWInfo->pTabList->nSrc>=1 ); pItem = pWInfo->pTabList->a; - pTab = pItem->pTab; + pTab = pItem->pSTab; if( IsVirtual(pTab) ) return 0; if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ testcase( pItem->fg.isIndexedBy ); @@ -165968,6 +169488,10 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ ** the right-most table of a subquery that was flattened into the ** main query and that subquery was the right-hand operand of an ** inner join that held an ON or USING clause. +** 6) The ORDER BY clause has 63 or fewer terms +** 7) The omit-noop-join optimization is enabled. +** +** Items (1), (6), and (7) are checked by the caller. ** ** For example, given: ** @@ -166013,6 +169537,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( WhereTerm *pTerm, *pEnd; SrcItem *pItem; WhereLoop *pLoop; + Bitmask m1; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; @@ -166033,13 +169558,16 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( } if( hasRightJoin && ExprHasProperty(pTerm->pExpr, EP_InnerON) - && pTerm->pExpr->w.iJoin==pItem->iCursor + && NEVER(pTerm->pExpr->w.iJoin==pItem->iCursor) ){ break; /* restriction (5) */ } } if( pTerm<pEnd ) continue; - WHERETRACE(0xffffffff, ("-> drop loop %c not used\n", pLoop->cId)); + WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId)); + m1 = MASKBIT(i)-1; + testcase( ((pWInfo->revMask>>1) & ~m1)!=0 ); + pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1); notReady &= ~pLoop->maskSelf; for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ @@ -166086,9 +169614,9 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( WhereLoop *pLoop = pWInfo->a[i].pWLoop; const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; - Table *pTab = pItem->pTab; + Table *pTab = pItem->pSTab; if( (pTab->tabFlags & TF_HasStat1)==0 ) break; - pTab->tabFlags |= TF_StatsUsed; + pTab->tabFlags |= TF_MaybeReanalyze; if( i>=1 && (pLoop->wsFlags & reqFlags)==reqFlags /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ @@ -166106,6 +169634,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( } } nSearch += pLoop->nOut; + if( pWInfo->nOutStarDelta ) nSearch += pLoop->rStarDelta; } } @@ -166134,34 +169663,14 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( for(i=0; i<pIdx->nColumn; i++){ Expr *pExpr; int j = pIdx->aiColumn[i]; - int bMaybeNullRow; if( j==XN_EXPR ){ pExpr = pIdx->aColExpr->a[i].pExpr; - testcase( pTabItem->fg.jointype & JT_LEFT ); - testcase( pTabItem->fg.jointype & JT_RIGHT ); - testcase( pTabItem->fg.jointype & JT_LTORJ ); - bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); - bMaybeNullRow = 0; }else{ continue; } - if( sqlite3ExprIsConstant(pExpr) ) continue; - if( pExpr->op==TK_FUNCTION ){ - /* Functions that might set a subtype should not be replaced by the - ** value taken from an expression index since the index omits the - ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */ - int n; - FuncDef *pDef; - sqlite3 *db = pParse->db; - assert( ExprUseXList(pExpr) ); - n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; - pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); - if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ - continue; - } - } + if( sqlite3ExprIsConstant(0,pExpr) ) continue; p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); if( p==0 ) break; p->pIENext = pParse->pIdxEpr; @@ -166175,7 +169684,7 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( p->iDataCur = pTabItem->iCursor; p->iIdxCur = iIdxCur; p->iIdxCol = i; - p->bMaybeNullRow = bMaybeNullRow; + p->bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){ p->aff = pIdx->zColAff[i]; } @@ -166204,8 +169713,8 @@ static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ SrcItem *pItem = &pWInfo->pTabList->a[ii]; if( !pItem->fg.isCte || pItem->u2.pCteUse->eM10d!=M10d_Yes - || NEVER(pItem->pSelect==0) - || pItem->pSelect->pOrderBy==0 + || NEVER(pItem->fg.isSubquery==0) + || pItem->u4.pSubq->pSelect->pOrderBy==0 ){ pWInfo->revMask |= MASKBIT(ii); } @@ -166340,7 +169849,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); - if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; + if( pOrderBy && pOrderBy->nExpr>=BMS ){ + pOrderBy = 0; + wctrlFlags &= ~WHERE_WANT_DISTINCT; + wctrlFlags |= WHERE_KEEP_ALL_JOINS; /* Disable omit-noop-join opt */ + } /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask @@ -166365,7 +169878,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** field (type Bitmask) it must be aligned on an 8-byte boundary on ** some architectures. Hence the ROUND8() below. */ - nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); + nByteWInfo = ROUND8P(sizeof(WhereInfo)); + if( nTabList>1 ){ + nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel)); + } pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); @@ -166419,7 +169935,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ){ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; } - ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); + if( ALWAYS(pWInfo->pSelect) + && (pWInfo->pSelect->selFlags & SF_MultiValue)==0 + ){ + ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); + } }else{ /* Assign a bit from the bitmask to every term in the FROM clause. ** @@ -166572,7 +170092,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( wherePathSolver(pWInfo, 0); if( db->mallocFailed ) goto whereBeginError; if( pWInfo->pOrderBy ){ - wherePathSolver(pWInfo, pWInfo->nRowOut+1); + whereInterstageHeuristic(pWInfo); + wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } @@ -166632,10 +170153,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. */ notReady = ~(Bitmask)0; - if( pWInfo->nLevel>=2 - && pResultSet!=0 /* these two combine to guarantee */ - && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */ - && OptimizationEnabled(db, SQLITE_OmitNoopJoin) + if( pWInfo->nLevel>=2 /* Must be a join, or this opt8n is pointless */ + && pResultSet!=0 /* Condition (1) */ + && 0==(wctrlFlags & (WHERE_AGG_DISTINCT|WHERE_KEEP_ALL_JOINS)) /* (1),(6) */ + && OptimizationEnabled(db, SQLITE_OmitNoopJoin) /* (7) */ ){ notReady = whereOmitNoopJoin(pWInfo, notReady); nTabList = pWInfo->nLevel; @@ -166683,15 +170204,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ int wsFlags = pWInfo->a[0].pWLoop->wsFlags; int bOnerow = (wsFlags & WHERE_ONEROW)!=0; - assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) ); + assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) ); if( bOnerow || ( 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) - && !IsVirtual(pTabList->a[0].pTab) + && !IsVirtual(pTabList->a[0].pSTab) && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) && OptimizationEnabled(db, SQLITE_OnePass) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; - if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ + if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){ if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ bFordelete = OPFLAG_FORDELETE; } @@ -166709,7 +170230,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( SrcItem *pTabItem; pTabItem = &pTabList->a[pLevel->iFrom]; - pTab = pTabItem->pTab; + pTab = pTabItem->pSTab; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ @@ -166780,7 +170301,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( iIndexCur = pLevel->iTabCur; op = 0; }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ - Index *pJ = pTabItem->pTab->pIndex; + Index *pJ = pTabItem->pSTab->pIndex; iIndexCur = iAuxArg; assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); while( ALWAYS(pJ) && pJ!=pIx ){ @@ -166847,7 +170368,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); - assert( pTab==pTabItem->pTab ); + assert( pTab==pTabItem->pSTab ); if( HasRowid(pTab) ){ KeyInfo *pInfo; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); @@ -166886,13 +170407,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( wsFlags = pLevel->pWLoop->wsFlags; pSrc = &pTabList->a[pLevel->iFrom]; if( pSrc->fg.isMaterialized ){ - if( pSrc->fg.isCorrelated ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); + Subquery *pSubq; + int iOnce = 0; + assert( pSrc->fg.isSubquery ); + pSubq = pSrc->u4.pSubq; + if( pSrc->fg.isCorrelated==0 ){ + iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); }else{ - int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); - sqlite3VdbeJumpHere(v, iOnce); + iOnce = 0; } + sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub); + VdbeComment((v, "materialize %!S", pSrc)); + if( iOnce ) sqlite3VdbeJumpHere(v, iOnce); } assert( pTabList == pWInfo->pTabList ); if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ @@ -166927,6 +170453,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); } +#ifdef WHERETRACE_ENABLED + /* Prevent harmless compiler warnings about debugging routines + ** being declared but never used */ + sqlite3ShowWhereLoopList(0); +#endif /* WHERETRACE_ENABLED */ return 0; } @@ -166947,29 +170478,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; sqlite3VdbePrintOp(0, pc, pOp); + sqlite3ShowWhereTerm(0); /* So compiler won't complain about unused func */ } #endif -#ifdef SQLITE_DEBUG -/* -** Return true if cursor iCur is opened by instruction k of the -** bytecode. Used inside of assert() only. -*/ -static int cursorIsOpen(Vdbe *v, int iCur, int k){ - while( k>=0 ){ - VdbeOp *pOp = sqlite3VdbeGetOp(v,k--); - if( pOp->p1!=iCur ) continue; - if( pOp->opcode==OP_Close ) return 0; - if( pOp->opcode==OP_OpenRead ) return 1; - if( pOp->opcode==OP_OpenWrite ) return 1; - if( pOp->opcode==OP_OpenDup ) return 1; - if( pOp->opcode==OP_OpenAutoindex ) return 1; - if( pOp->opcode==OP_OpenEphemeral ) return 1; - } - return 0; -} -#endif /* SQLITE_DEBUG */ - /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. @@ -167116,7 +170628,16 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); if( (ws & WHERE_IDX_ONLY)==0 ){ - assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor ); + SrcItem *pSrc = &pTabList->a[pLevel->iFrom]; + assert( pLevel->iTabCur==pSrc->iCursor ); + if( pSrc->fg.viaCoroutine ){ + int m, n; + assert( pSrc->fg.isSubquery ); + n = pSrc->u4.pSubq->regResult; + assert( pSrc->pSTab!=0 ); + m = pSrc->pSTab->nCol; + sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); + } sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); } if( (ws & WHERE_INDEXED) @@ -167138,7 +170659,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, addr); } VdbeModuleComment((v, "End WHERE-loop%d: %s", i, - pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); + pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName)); } assert( pWInfo->nLevel<=pTabList->nSrc ); @@ -167147,7 +170668,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeOp *pOp, *pLastOp; Index *pIdx = 0; SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; @@ -167166,8 +170687,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ */ if( pTabItem->fg.viaCoroutine ){ testcase( pParse->db->mallocFailed ); + assert( pTabItem->fg.isSubquery ); + assert( pTabItem->u4.pSubq->regResult>=0 ); translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, - pTabItem->regResult, 0); + pTabItem->u4.pSubq->regResult, 0); continue; } @@ -167255,21 +170778,29 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); - }else{ - /* Unable to translate the table reference into an index - ** reference. Verify that this is harmless - that the - ** table being referenced really is open. - */ -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - || cursorIsOpen(v,pOp->p1,k) - || pOp->opcode==OP_Offset - ); -#else - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - || cursorIsOpen(v,pOp->p1,k) - ); -#endif + }else if( pLoop->wsFlags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ + if( pLoop->wsFlags & WHERE_IDX_ONLY ){ + /* An error. pLoop is supposed to be a covering index loop, + ** and yet the VM code refers to a column of the table that + ** is not part of the index. */ + sqlite3ErrorMsg(pParse, "internal query planner error"); + pParse->rc = SQLITE_INTERNAL; + }else{ + /* The WHERE_EXPRIDX flag is set by the planner when it is likely + ** that pLoop is a covering index loop, but it is not possible + ** to be 100% sure. In this case, any OP_Explain opcode + ** corresponding to this loop describes the index as a "COVERING + ** INDEX". But, pOp proves that pLoop is not actually a covering + ** index loop. So clear the WHERE_EXPRIDX flag and rewrite the + ** text that accompanies the OP_Explain opcode, if any. */ + pLoop->wsFlags &= ~WHERE_EXPRIDX; + sqlite3WhereAddExplainText(pParse, + pLevel->addrBody-1, + pTabList, + pLevel, + pWInfo->wctrlFlags + ); + } } }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; @@ -168215,7 +171746,7 @@ static ExprList *exprListAppendList( int iDummy; Expr *pSub; pSub = sqlite3ExprSkipCollateAndLikely(pDup); - if( sqlite3ExprIsInteger(pSub, &iDummy) ){ + if( sqlite3ExprIsInteger(pSub, &iDummy, 0) ){ pSub->op = TK_NULL; pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); pSub->u.zToken = 0; @@ -168383,9 +171914,10 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside ** of sqlite3DbMallocRawNN() called from ** sqlite3SrcListAppend() */ - if( p->pSrc ){ + if( p->pSrc==0 ){ + sqlite3SelectDelete(db, pSub); + }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){ Table *pTab2; - p->pSrc->a[0].pSelect = pSub; p->pSrc->a[0].fg.isCorrelated = 1; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded|SF_OrderByReqd; @@ -168399,7 +171931,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ }else{ memcpy(pTab, pTab2, sizeof(Table)); pTab->tabFlags |= TF_Ephemeral; - p->pSrc->a[0].pTab = pTab; + p->pSrc->a[0].pSTab = pTab; pTab = pTab2; memset(&w, 0, sizeof(w)); w.xExprCallback = sqlite3WindowExtraAggFuncDepth; @@ -168407,8 +171939,6 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ w.xSelectCallback2 = sqlite3WalkerDepthDecrease; sqlite3WalkSelect(&w, pSub); } - }else{ - sqlite3SelectDelete(db, pSub); } if( db->mallocFailed ) rc = SQLITE_NOMEM; @@ -168470,7 +172000,7 @@ SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){ ** variable values in the expression tree. */ static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ - if( 0==sqlite3ExprIsConstant(pExpr) ){ + if( 0==sqlite3ExprIsConstant(0,pExpr) ){ if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr); sqlite3ExprDelete(pParse->db, pExpr); pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); @@ -168695,10 +172225,15 @@ SQLITE_PRIVATE int sqlite3WindowCompare( ** and initialize registers and cursors used by sqlite3WindowCodeStep(). */ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ - int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr; - Window *pMWin = pSelect->pWin; Window *pWin; - Vdbe *v = sqlite3GetVdbe(pParse); + int nEphExpr; + Window *pMWin; + Vdbe *v; + + assert( pSelect->pSrc->a[0].fg.isSubquery ); + nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr; + pMWin = pSelect->pWin; + v = sqlite3GetVdbe(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); @@ -168972,6 +172507,7 @@ static void windowAggStep( int regArg; int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); int i; + int addrIf = 0; assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); @@ -168988,6 +172524,18 @@ static void windowAggStep( } regArg = reg; + if( pWin->pFilter ){ + int regTmp; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); + assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regTmp); + } + if( pMWin->regStartRowid==0 && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) @@ -169007,25 +172555,13 @@ static void windowAggStep( } sqlite3VdbeJumpHere(v, addrIsNull); }else if( pWin->regApp ){ + assert( pWin->pFilter==0 ); assert( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ); assert( bInverse==0 || bInverse==1 ); sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); }else if( pFunc->xSFunc!=noopStepFunc ){ - int addrIf = 0; - if( pWin->pFilter ){ - int regTmp; - assert( ExprUseXList(pWin->pOwner) ); - assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); - assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); - regTmp = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); - addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); - VdbeCoverage(v); - sqlite3ReleaseTempReg(pParse, regTmp); - } - if( pWin->bExprArgs ){ int iOp = sqlite3VdbeCurrentAddr(v); int iEnd; @@ -169052,12 +172588,13 @@ static void windowAggStep( sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); if( pWin->bExprArgs ){ sqlite3ReleaseTempRange(pParse, regArg, nArg); } - if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } + + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } } @@ -170095,7 +173632,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( Vdbe *v = sqlite3GetVdbe(pParse); int csrWrite; /* Cursor used to write to eph. table */ int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ - int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */ + int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */ int iInput; /* To iterate through sub cols */ int addrNe; /* Address of OP_Ne */ int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */ @@ -170484,6 +174021,13 @@ struct TrigEvent { int a; IdList * b; }; struct FrameBound { int eType; Expr *pExpr; }; +/* +** Generate a syntax error +*/ +static void parserSyntaxError(Parse *pParse, Token *p){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", p); +} + /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. @@ -170540,9 +174084,9 @@ static void updateDeleteLimitError( break; } } - if( (p->selFlags & SF_MultiValue)==0 && - (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && - cnt>mxSelect + if( (p->selFlags & (SF_MultiValue|SF_Values))==0 + && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 + && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); } @@ -170562,6 +174106,14 @@ static void updateDeleteLimitError( return pSelect; } + /* Memory allocator for parser stack resizing. This is a thin wrapper around + ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate + ** testing. + */ + static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){ + return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); + } + /* Construct a new Expr object from a single token */ static Expr *tokenExpr(Parse *pParse, int op, Token t){ @@ -170684,135 +174236,135 @@ static void updateDeleteLimitError( #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 -#define TK_MATCH 46 -#define TK_LIKE_KW 47 -#define TK_BETWEEN 48 -#define TK_IN 49 -#define TK_ISNULL 50 -#define TK_NOTNULL 51 -#define TK_NE 52 -#define TK_EQ 53 -#define TK_GT 54 -#define TK_LE 55 -#define TK_LT 56 -#define TK_GE 57 -#define TK_ESCAPE 58 -#define TK_ID 59 -#define TK_COLUMNKW 60 -#define TK_DO 61 -#define TK_FOR 62 -#define TK_IGNORE 63 -#define TK_INITIALLY 64 -#define TK_INSTEAD 65 -#define TK_NO 66 -#define TK_KEY 67 -#define TK_OF 68 -#define TK_OFFSET 69 -#define TK_PRAGMA 70 -#define TK_RAISE 71 -#define TK_RECURSIVE 72 -#define TK_REPLACE 73 -#define TK_RESTRICT 74 -#define TK_ROW 75 -#define TK_ROWS 76 -#define TK_TRIGGER 77 -#define TK_VACUUM 78 -#define TK_VIEW 79 -#define TK_VIRTUAL 80 -#define TK_WITH 81 -#define TK_NULLS 82 -#define TK_FIRST 83 -#define TK_LAST 84 -#define TK_CURRENT 85 -#define TK_FOLLOWING 86 -#define TK_PARTITION 87 -#define TK_PRECEDING 88 -#define TK_RANGE 89 -#define TK_UNBOUNDED 90 -#define TK_EXCLUDE 91 -#define TK_GROUPS 92 -#define TK_OTHERS 93 -#define TK_TIES 94 -#define TK_GENERATED 95 -#define TK_ALWAYS 96 -#define TK_MATERIALIZED 97 -#define TK_REINDEX 98 -#define TK_RENAME 99 -#define TK_CTIME_KW 100 -#define TK_ANY 101 -#define TK_BITAND 102 -#define TK_BITOR 103 -#define TK_LSHIFT 104 -#define TK_RSHIFT 105 -#define TK_PLUS 106 -#define TK_MINUS 107 -#define TK_STAR 108 -#define TK_SLASH 109 -#define TK_REM 110 -#define TK_CONCAT 111 -#define TK_PTR 112 -#define TK_COLLATE 113 -#define TK_BITNOT 114 -#define TK_ON 115 -#define TK_INDEXED 116 -#define TK_STRING 117 -#define TK_JOIN_KW 118 -#define TK_CONSTRAINT 119 -#define TK_DEFAULT 120 -#define TK_NULL 121 -#define TK_PRIMARY 122 -#define TK_UNIQUE 123 -#define TK_CHECK 124 -#define TK_REFERENCES 125 -#define TK_AUTOINCR 126 -#define TK_INSERT 127 -#define TK_DELETE 128 -#define TK_UPDATE 129 -#define TK_SET 130 -#define TK_DEFERRABLE 131 -#define TK_FOREIGN 132 -#define TK_DROP 133 -#define TK_UNION 134 -#define TK_ALL 135 -#define TK_EXCEPT 136 -#define TK_INTERSECT 137 -#define TK_SELECT 138 -#define TK_VALUES 139 -#define TK_DISTINCT 140 -#define TK_DOT 141 -#define TK_FROM 142 -#define TK_JOIN 143 -#define TK_USING 144 -#define TK_ORDER 145 -#define TK_GROUP 146 -#define TK_HAVING 147 -#define TK_LIMIT 148 -#define TK_WHERE 149 -#define TK_RETURNING 150 -#define TK_INTO 151 -#define TK_NOTHING 152 -#define TK_FLOAT 153 -#define TK_BLOB 154 -#define TK_INTEGER 155 -#define TK_VARIABLE 156 -#define TK_CASE 157 -#define TK_WHEN 158 -#define TK_THEN 159 -#define TK_ELSE 160 -#define TK_INDEX 161 -#define TK_ALTER 162 -#define TK_ADD 163 -#define TK_WINDOW 164 -#define TK_OVER 165 -#define TK_FILTER 166 -#define TK_COLUMN 167 -#define TK_AGG_FUNCTION 168 -#define TK_AGG_COLUMN 169 -#define TK_TRUEFALSE 170 -#define TK_ISNOT 171 +#define TK_ISNOT 46 +#define TK_MATCH 47 +#define TK_LIKE_KW 48 +#define TK_BETWEEN 49 +#define TK_IN 50 +#define TK_ISNULL 51 +#define TK_NOTNULL 52 +#define TK_NE 53 +#define TK_EQ 54 +#define TK_GT 55 +#define TK_LE 56 +#define TK_LT 57 +#define TK_GE 58 +#define TK_ESCAPE 59 +#define TK_ID 60 +#define TK_COLUMNKW 61 +#define TK_DO 62 +#define TK_FOR 63 +#define TK_IGNORE 64 +#define TK_INITIALLY 65 +#define TK_INSTEAD 66 +#define TK_NO 67 +#define TK_KEY 68 +#define TK_OF 69 +#define TK_OFFSET 70 +#define TK_PRAGMA 71 +#define TK_RAISE 72 +#define TK_RECURSIVE 73 +#define TK_REPLACE 74 +#define TK_RESTRICT 75 +#define TK_ROW 76 +#define TK_ROWS 77 +#define TK_TRIGGER 78 +#define TK_VACUUM 79 +#define TK_VIEW 80 +#define TK_VIRTUAL 81 +#define TK_WITH 82 +#define TK_NULLS 83 +#define TK_FIRST 84 +#define TK_LAST 85 +#define TK_CURRENT 86 +#define TK_FOLLOWING 87 +#define TK_PARTITION 88 +#define TK_PRECEDING 89 +#define TK_RANGE 90 +#define TK_UNBOUNDED 91 +#define TK_EXCLUDE 92 +#define TK_GROUPS 93 +#define TK_OTHERS 94 +#define TK_TIES 95 +#define TK_GENERATED 96 +#define TK_ALWAYS 97 +#define TK_MATERIALIZED 98 +#define TK_REINDEX 99 +#define TK_RENAME 100 +#define TK_CTIME_KW 101 +#define TK_ANY 102 +#define TK_BITAND 103 +#define TK_BITOR 104 +#define TK_LSHIFT 105 +#define TK_RSHIFT 106 +#define TK_PLUS 107 +#define TK_MINUS 108 +#define TK_STAR 109 +#define TK_SLASH 110 +#define TK_REM 111 +#define TK_CONCAT 112 +#define TK_PTR 113 +#define TK_COLLATE 114 +#define TK_BITNOT 115 +#define TK_ON 116 +#define TK_INDEXED 117 +#define TK_STRING 118 +#define TK_JOIN_KW 119 +#define TK_CONSTRAINT 120 +#define TK_DEFAULT 121 +#define TK_NULL 122 +#define TK_PRIMARY 123 +#define TK_UNIQUE 124 +#define TK_CHECK 125 +#define TK_REFERENCES 126 +#define TK_AUTOINCR 127 +#define TK_INSERT 128 +#define TK_DELETE 129 +#define TK_UPDATE 130 +#define TK_SET 131 +#define TK_DEFERRABLE 132 +#define TK_FOREIGN 133 +#define TK_DROP 134 +#define TK_UNION 135 +#define TK_ALL 136 +#define TK_EXCEPT 137 +#define TK_INTERSECT 138 +#define TK_SELECT 139 +#define TK_VALUES 140 +#define TK_DISTINCT 141 +#define TK_DOT 142 +#define TK_FROM 143 +#define TK_JOIN 144 +#define TK_USING 145 +#define TK_ORDER 146 +#define TK_GROUP 147 +#define TK_HAVING 148 +#define TK_LIMIT 149 +#define TK_WHERE 150 +#define TK_RETURNING 151 +#define TK_INTO 152 +#define TK_NOTHING 153 +#define TK_FLOAT 154 +#define TK_BLOB 155 +#define TK_INTEGER 156 +#define TK_VARIABLE 157 +#define TK_CASE 158 +#define TK_WHEN 159 +#define TK_THEN 160 +#define TK_ELSE 161 +#define TK_INDEX 162 +#define TK_ALTER 163 +#define TK_ADD 164 +#define TK_WINDOW 165 +#define TK_OVER 166 +#define TK_FILTER 167 +#define TK_COLUMN 168 +#define TK_AGG_FUNCTION 169 +#define TK_AGG_COLUMN 170 +#define TK_TRUEFALSE 171 #define TK_FUNCTION 172 -#define TK_UMINUS 173 -#define TK_UPLUS 174 +#define TK_UPLUS 173 +#define TK_UMINUS 174 #define TK_TRUTH 175 #define TK_REGISTER 176 #define TK_VECTOR 177 @@ -170821,8 +174373,9 @@ static void updateDeleteLimitError( #define TK_ASTERISK 180 #define TK_SPAN 181 #define TK_ERROR 182 -#define TK_SPACE 183 -#define TK_ILLEGAL 184 +#define TK_QNUMBER 183 +#define TK_SPACE 184 +#define TK_ILLEGAL 185 #endif /**************** End token definitions ***************************************/ @@ -170863,6 +174416,9 @@ static void updateDeleteLimitError( ** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser ** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser ** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context +** YYREALLOC Name of the realloc() function to use +** YYFREE Name of the free() function to use +** YYDYNSTACK True if stack space should be extended on heap ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. ** YYNSTATE the combined number of states. @@ -170876,37 +174432,39 @@ static void updateDeleteLimitError( ** YY_NO_ACTION The yy_action[] code for no-op ** YY_MIN_REDUCE Minimum value for reduce actions ** YY_MAX_REDUCE Maximum value for reduce actions +** YY_MIN_DSTRCTR Minimum symbol value that has a destructor +** YY_MAX_DSTRCTR Maximum symbol value that has a destructor */ #ifndef INTERFACE # define INTERFACE 1 #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 319 +#define YYNOCODE 322 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 101 +#define YYWILDCARD 102 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - TriggerStep* yy33; - Window* yy41; - Select* yy47; - SrcList* yy131; - struct TrigEvent yy180; - struct {int value; int mask;} yy231; - IdList* yy254; - u32 yy285; - ExprList* yy322; - Cte* yy385; - int yy394; - Upsert* yy444; - u8 yy516; - With* yy521; - const char* yy522; - Expr* yy528; - OnOrUsing yy561; - struct FrameBound yy595; + ExprList* yy14; + With* yy59; + Cte* yy67; + Upsert* yy122; + IdList* yy132; + int yy144; + const char* yy168; + SrcList* yy203; + Window* yy211; + OnOrUsing yy269; + struct TrigEvent yy286; + struct {int value; int mask;} yy383; + u32 yy391; + TriggerStep* yy427; + Expr* yy454; + u8 yy462; + struct FrameBound yy509; + Select* yy555; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -170916,24 +174474,29 @@ typedef union { #define sqlite3ParserARG_PARAM #define sqlite3ParserARG_FETCH #define sqlite3ParserARG_STORE +#define YYREALLOC parserStackRealloc +#define YYFREE sqlite3_free +#define YYDYNSTACK 1 #define sqlite3ParserCTX_SDECL Parse *pParse; #define sqlite3ParserCTX_PDECL ,Parse *pParse #define sqlite3ParserCTX_PARAM ,pParse #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 579 -#define YYNRULE 405 -#define YYNRULE_WITH_ACTION 340 -#define YYNTOKEN 185 -#define YY_MAX_SHIFT 578 -#define YY_MIN_SHIFTREDUCE 838 -#define YY_MAX_SHIFTREDUCE 1242 -#define YY_ERROR_ACTION 1243 -#define YY_ACCEPT_ACTION 1244 -#define YY_NO_ACTION 1245 -#define YY_MIN_REDUCE 1246 -#define YY_MAX_REDUCE 1650 +#define YYNSTATE 583 +#define YYNRULE 409 +#define YYNRULE_WITH_ACTION 344 +#define YYNTOKEN 186 +#define YY_MAX_SHIFT 582 +#define YY_MIN_SHIFTREDUCE 845 +#define YY_MAX_SHIFTREDUCE 1253 +#define YY_ERROR_ACTION 1254 +#define YY_ACCEPT_ACTION 1255 +#define YY_NO_ACTION 1256 +#define YY_MIN_REDUCE 1257 +#define YY_MAX_REDUCE 1665 +#define YY_MIN_DSTRCTR 205 +#define YY_MAX_DSTRCTR 319 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -170949,6 +174512,22 @@ typedef union { # define yytestcase(X) #endif +/* Macro to determine if stack space has the ability to grow using +** heap memory. +*/ +#if YYSTACKDEPTH<=0 || YYDYNSTACK +# define YYGROWABLESTACK 1 +#else +# define YYGROWABLESTACK 0 +#endif + +/* Guarantee a minimum number of initial stack slots. +*/ +#if YYSTACKDEPTH<=0 +# undef YYSTACKDEPTH +# define YYSTACKDEPTH 2 /* Need a minimum stack size */ +#endif + /* Next are the tables used to determine what action to take based on the ** current state and lookahead token. These tables are used to implement @@ -171000,619 +174579,643 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2100) +#define YY_ACTTAB_COUNT (2207) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 572, 210, 572, 119, 116, 231, 572, 119, 116, 231, - /* 10 */ 572, 1317, 379, 1296, 410, 566, 566, 566, 572, 411, - /* 20 */ 380, 1317, 1279, 42, 42, 42, 42, 210, 1529, 72, - /* 30 */ 72, 974, 421, 42, 42, 495, 305, 281, 305, 975, - /* 40 */ 399, 72, 72, 126, 127, 81, 1217, 1217, 1054, 1057, - /* 50 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 480, 411, - /* 60 */ 1244, 1, 1, 578, 2, 1248, 554, 119, 116, 231, - /* 70 */ 319, 484, 147, 484, 528, 119, 116, 231, 533, 1330, - /* 80 */ 419, 527, 143, 126, 127, 81, 1217, 1217, 1054, 1057, - /* 90 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 119, 116, - /* 100 */ 231, 329, 123, 123, 123, 123, 122, 122, 121, 121, - /* 110 */ 121, 120, 117, 448, 286, 286, 286, 286, 446, 446, - /* 120 */ 446, 1568, 378, 1570, 1193, 377, 1164, 569, 1164, 569, - /* 130 */ 411, 1568, 541, 261, 228, 448, 102, 146, 453, 318, - /* 140 */ 563, 242, 123, 123, 123, 123, 122, 122, 121, 121, - /* 150 */ 121, 120, 117, 448, 126, 127, 81, 1217, 1217, 1054, - /* 160 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 143, - /* 170 */ 296, 1193, 341, 452, 121, 121, 121, 120, 117, 448, - /* 180 */ 128, 1193, 1194, 1193, 149, 445, 444, 572, 120, 117, - /* 190 */ 448, 125, 125, 125, 125, 118, 123, 123, 123, 123, - /* 200 */ 122, 122, 121, 121, 121, 120, 117, 448, 458, 114, - /* 210 */ 13, 13, 550, 123, 123, 123, 123, 122, 122, 121, - /* 220 */ 121, 121, 120, 117, 448, 424, 318, 563, 1193, 1194, - /* 230 */ 1193, 150, 1225, 411, 1225, 125, 125, 125, 125, 123, - /* 240 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, - /* 250 */ 448, 469, 344, 1041, 1041, 1055, 1058, 126, 127, 81, - /* 260 */ 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, - /* 270 */ 125, 125, 1282, 526, 224, 1193, 572, 411, 226, 519, - /* 280 */ 177, 83, 84, 123, 123, 123, 123, 122, 122, 121, - /* 290 */ 121, 121, 120, 117, 448, 1010, 16, 16, 1193, 134, - /* 300 */ 134, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, - /* 310 */ 124, 124, 125, 125, 125, 125, 123, 123, 123, 123, - /* 320 */ 122, 122, 121, 121, 121, 120, 117, 448, 1045, 550, - /* 330 */ 1193, 375, 1193, 1194, 1193, 254, 1438, 401, 508, 505, - /* 340 */ 504, 112, 564, 570, 4, 929, 929, 435, 503, 342, - /* 350 */ 464, 330, 362, 396, 1238, 1193, 1194, 1193, 567, 572, - /* 360 */ 123, 123, 123, 123, 122, 122, 121, 121, 121, 120, - /* 370 */ 117, 448, 286, 286, 371, 1581, 1607, 445, 444, 155, - /* 380 */ 411, 449, 72, 72, 1289, 569, 1222, 1193, 1194, 1193, - /* 390 */ 86, 1224, 273, 561, 547, 520, 520, 572, 99, 1223, - /* 400 */ 6, 1281, 476, 143, 126, 127, 81, 1217, 1217, 1054, - /* 410 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 554, - /* 420 */ 13, 13, 1031, 511, 1225, 1193, 1225, 553, 110, 110, - /* 430 */ 224, 572, 1239, 177, 572, 429, 111, 199, 449, 573, - /* 440 */ 449, 432, 1555, 1019, 327, 555, 1193, 272, 289, 370, - /* 450 */ 514, 365, 513, 259, 72, 72, 547, 72, 72, 361, - /* 460 */ 318, 563, 1613, 123, 123, 123, 123, 122, 122, 121, - /* 470 */ 121, 121, 120, 117, 448, 1019, 1019, 1021, 1022, 28, - /* 480 */ 286, 286, 1193, 1194, 1193, 1159, 572, 1612, 411, 904, - /* 490 */ 192, 554, 358, 569, 554, 940, 537, 521, 1159, 437, - /* 500 */ 415, 1159, 556, 1193, 1194, 1193, 572, 548, 548, 52, - /* 510 */ 52, 216, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, - /* 520 */ 1044, 124, 124, 125, 125, 125, 125, 1193, 478, 136, - /* 530 */ 136, 411, 286, 286, 1493, 509, 122, 122, 121, 121, - /* 540 */ 121, 120, 117, 448, 1010, 569, 522, 219, 545, 545, - /* 550 */ 318, 563, 143, 6, 536, 126, 127, 81, 1217, 1217, - /* 560 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, - /* 570 */ 1557, 123, 123, 123, 123, 122, 122, 121, 121, 121, - /* 580 */ 120, 117, 448, 489, 1193, 1194, 1193, 486, 283, 1270, - /* 590 */ 960, 254, 1193, 375, 508, 505, 504, 1193, 342, 574, - /* 600 */ 1193, 574, 411, 294, 503, 960, 879, 193, 484, 318, - /* 610 */ 563, 386, 292, 382, 123, 123, 123, 123, 122, 122, - /* 620 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, - /* 630 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 640 */ 125, 411, 396, 1139, 1193, 872, 101, 286, 286, 1193, - /* 650 */ 1194, 1193, 375, 1096, 1193, 1194, 1193, 1193, 1194, 1193, - /* 660 */ 569, 459, 33, 375, 235, 126, 127, 81, 1217, 1217, - /* 670 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, - /* 680 */ 1437, 962, 572, 230, 961, 123, 123, 123, 123, 122, - /* 690 */ 122, 121, 121, 121, 120, 117, 448, 1159, 230, 1193, - /* 700 */ 158, 1193, 1194, 1193, 1556, 13, 13, 303, 960, 1233, - /* 710 */ 1159, 154, 411, 1159, 375, 1584, 1177, 5, 371, 1581, - /* 720 */ 431, 1239, 3, 960, 123, 123, 123, 123, 122, 122, - /* 730 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, - /* 740 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 750 */ 125, 411, 210, 571, 1193, 1032, 1193, 1194, 1193, 1193, - /* 760 */ 390, 855, 156, 1555, 376, 404, 1101, 1101, 492, 572, - /* 770 */ 469, 344, 1322, 1322, 1555, 126, 127, 81, 1217, 1217, - /* 780 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, - /* 790 */ 130, 572, 13, 13, 532, 123, 123, 123, 123, 122, - /* 800 */ 122, 121, 121, 121, 120, 117, 448, 304, 572, 457, - /* 810 */ 229, 1193, 1194, 1193, 13, 13, 1193, 1194, 1193, 1300, - /* 820 */ 467, 1270, 411, 1320, 1320, 1555, 1015, 457, 456, 436, - /* 830 */ 301, 72, 72, 1268, 123, 123, 123, 123, 122, 122, - /* 840 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, - /* 850 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 860 */ 125, 411, 384, 1076, 1159, 286, 286, 421, 314, 280, - /* 870 */ 280, 287, 287, 461, 408, 407, 1539, 1159, 569, 572, - /* 880 */ 1159, 1196, 569, 409, 569, 126, 127, 81, 1217, 1217, - /* 890 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, - /* 900 */ 457, 1485, 13, 13, 1541, 123, 123, 123, 123, 122, - /* 910 */ 122, 121, 121, 121, 120, 117, 448, 202, 572, 462, - /* 920 */ 1587, 578, 2, 1248, 843, 844, 845, 1563, 319, 409, - /* 930 */ 147, 6, 411, 257, 256, 255, 208, 1330, 9, 1196, - /* 940 */ 264, 72, 72, 1436, 123, 123, 123, 123, 122, 122, - /* 950 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, - /* 960 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 970 */ 125, 572, 286, 286, 572, 1213, 411, 577, 315, 1248, - /* 980 */ 421, 371, 1581, 356, 319, 569, 147, 495, 529, 1644, - /* 990 */ 397, 935, 495, 1330, 71, 71, 934, 72, 72, 242, - /* 1000 */ 1328, 105, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, - /* 1010 */ 124, 125, 125, 125, 125, 123, 123, 123, 123, 122, - /* 1020 */ 122, 121, 121, 121, 120, 117, 448, 1117, 286, 286, - /* 1030 */ 1422, 452, 1528, 1213, 443, 286, 286, 1492, 1355, 313, - /* 1040 */ 478, 569, 1118, 454, 351, 495, 354, 1266, 569, 209, - /* 1050 */ 572, 418, 179, 572, 1031, 242, 385, 1119, 523, 123, - /* 1060 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, - /* 1070 */ 448, 1020, 108, 72, 72, 1019, 13, 13, 915, 572, - /* 1080 */ 1498, 572, 286, 286, 98, 530, 1537, 452, 916, 1334, - /* 1090 */ 1329, 203, 411, 286, 286, 569, 152, 211, 1498, 1500, - /* 1100 */ 426, 569, 56, 56, 57, 57, 569, 1019, 1019, 1021, - /* 1110 */ 447, 572, 411, 531, 12, 297, 126, 127, 81, 1217, - /* 1120 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 1130 */ 125, 572, 411, 867, 15, 15, 126, 127, 81, 1217, - /* 1140 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 1150 */ 125, 373, 529, 264, 44, 44, 126, 115, 81, 1217, - /* 1160 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, - /* 1170 */ 125, 1498, 478, 1271, 417, 123, 123, 123, 123, 122, - /* 1180 */ 122, 121, 121, 121, 120, 117, 448, 205, 1213, 495, - /* 1190 */ 430, 867, 468, 322, 495, 123, 123, 123, 123, 122, - /* 1200 */ 122, 121, 121, 121, 120, 117, 448, 572, 557, 1140, - /* 1210 */ 1642, 1422, 1642, 543, 572, 123, 123, 123, 123, 122, - /* 1220 */ 122, 121, 121, 121, 120, 117, 448, 572, 1422, 572, - /* 1230 */ 13, 13, 542, 323, 1325, 411, 334, 58, 58, 349, - /* 1240 */ 1422, 1170, 326, 286, 286, 549, 1213, 300, 895, 530, - /* 1250 */ 45, 45, 59, 59, 1140, 1643, 569, 1643, 565, 417, - /* 1260 */ 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, - /* 1270 */ 125, 125, 125, 125, 1367, 373, 500, 290, 1193, 512, - /* 1280 */ 1366, 427, 394, 394, 393, 275, 391, 896, 1138, 852, - /* 1290 */ 478, 258, 1422, 1170, 463, 1159, 12, 331, 428, 333, - /* 1300 */ 1117, 460, 236, 258, 325, 460, 544, 1544, 1159, 1098, - /* 1310 */ 491, 1159, 324, 1098, 440, 1118, 335, 516, 123, 123, - /* 1320 */ 123, 123, 122, 122, 121, 121, 121, 120, 117, 448, - /* 1330 */ 1119, 318, 563, 1138, 572, 1193, 1194, 1193, 112, 564, - /* 1340 */ 201, 4, 238, 433, 935, 490, 285, 228, 1517, 934, - /* 1350 */ 170, 560, 572, 142, 1516, 567, 572, 60, 60, 572, - /* 1360 */ 416, 572, 441, 572, 535, 302, 875, 8, 487, 572, - /* 1370 */ 237, 572, 416, 572, 485, 61, 61, 572, 449, 62, - /* 1380 */ 62, 332, 63, 63, 46, 46, 47, 47, 361, 572, - /* 1390 */ 561, 572, 48, 48, 50, 50, 51, 51, 572, 295, - /* 1400 */ 64, 64, 482, 295, 539, 412, 471, 1031, 572, 538, - /* 1410 */ 318, 563, 65, 65, 66, 66, 409, 475, 572, 1031, - /* 1420 */ 572, 14, 14, 875, 1020, 110, 110, 409, 1019, 572, - /* 1430 */ 474, 67, 67, 111, 455, 449, 573, 449, 98, 317, - /* 1440 */ 1019, 132, 132, 133, 133, 572, 1561, 572, 974, 409, - /* 1450 */ 6, 1562, 68, 68, 1560, 6, 975, 572, 6, 1559, - /* 1460 */ 1019, 1019, 1021, 6, 346, 218, 101, 531, 53, 53, - /* 1470 */ 69, 69, 1019, 1019, 1021, 1022, 28, 1586, 1181, 451, - /* 1480 */ 70, 70, 290, 87, 215, 31, 1363, 394, 394, 393, - /* 1490 */ 275, 391, 350, 109, 852, 107, 572, 112, 564, 483, - /* 1500 */ 4, 1212, 572, 239, 153, 572, 39, 236, 1299, 325, - /* 1510 */ 112, 564, 1298, 4, 567, 572, 32, 324, 572, 54, - /* 1520 */ 54, 572, 1135, 353, 398, 165, 165, 567, 166, 166, - /* 1530 */ 572, 291, 355, 572, 17, 357, 572, 449, 77, 77, - /* 1540 */ 1313, 55, 55, 1297, 73, 73, 572, 238, 470, 561, - /* 1550 */ 449, 472, 364, 135, 135, 170, 74, 74, 142, 163, - /* 1560 */ 163, 374, 561, 539, 572, 321, 572, 886, 540, 137, - /* 1570 */ 137, 339, 1353, 422, 298, 237, 539, 572, 1031, 572, - /* 1580 */ 340, 538, 101, 369, 110, 110, 162, 131, 131, 164, - /* 1590 */ 164, 1031, 111, 368, 449, 573, 449, 110, 110, 1019, - /* 1600 */ 157, 157, 141, 141, 572, 111, 572, 449, 573, 449, - /* 1610 */ 412, 288, 1019, 572, 882, 318, 563, 572, 219, 572, - /* 1620 */ 241, 1012, 477, 263, 263, 894, 893, 140, 140, 138, - /* 1630 */ 138, 1019, 1019, 1021, 1022, 28, 139, 139, 525, 455, - /* 1640 */ 76, 76, 78, 78, 1019, 1019, 1021, 1022, 28, 1181, - /* 1650 */ 451, 572, 1083, 290, 112, 564, 1575, 4, 394, 394, - /* 1660 */ 393, 275, 391, 572, 1023, 852, 572, 479, 345, 263, - /* 1670 */ 101, 567, 882, 1376, 75, 75, 1421, 501, 236, 260, - /* 1680 */ 325, 112, 564, 359, 4, 101, 43, 43, 324, 49, - /* 1690 */ 49, 901, 902, 161, 449, 101, 977, 978, 567, 1079, - /* 1700 */ 1349, 260, 965, 932, 263, 114, 561, 1095, 517, 1095, - /* 1710 */ 1083, 1094, 865, 1094, 151, 933, 1144, 114, 238, 1361, - /* 1720 */ 558, 449, 1023, 559, 1426, 1278, 170, 1269, 1257, 142, - /* 1730 */ 1601, 1256, 1258, 561, 1594, 1031, 496, 278, 213, 1346, - /* 1740 */ 310, 110, 110, 939, 311, 312, 237, 11, 234, 111, - /* 1750 */ 221, 449, 573, 449, 293, 395, 1019, 1408, 337, 1403, - /* 1760 */ 1396, 338, 1031, 299, 343, 1413, 1412, 481, 110, 110, - /* 1770 */ 506, 402, 225, 1296, 206, 367, 111, 1358, 449, 573, - /* 1780 */ 449, 412, 1359, 1019, 1489, 1488, 318, 563, 1019, 1019, - /* 1790 */ 1021, 1022, 28, 562, 207, 220, 80, 564, 389, 4, - /* 1800 */ 1597, 1357, 552, 1356, 1233, 181, 267, 232, 1536, 1534, - /* 1810 */ 455, 1230, 420, 567, 82, 1019, 1019, 1021, 1022, 28, - /* 1820 */ 86, 217, 85, 1494, 190, 175, 183, 465, 185, 466, - /* 1830 */ 36, 1409, 186, 187, 188, 499, 449, 244, 37, 99, - /* 1840 */ 400, 1415, 1414, 488, 1417, 194, 473, 403, 561, 1483, - /* 1850 */ 248, 92, 1505, 494, 198, 279, 112, 564, 250, 4, - /* 1860 */ 348, 497, 405, 352, 1259, 251, 252, 515, 1316, 434, - /* 1870 */ 1315, 1314, 94, 567, 1307, 886, 1306, 1031, 226, 406, - /* 1880 */ 1611, 1610, 438, 110, 110, 1580, 1286, 524, 439, 308, - /* 1890 */ 266, 111, 1285, 449, 573, 449, 449, 309, 1019, 366, - /* 1900 */ 1284, 1609, 265, 1566, 1565, 442, 372, 1381, 561, 129, - /* 1910 */ 550, 1380, 10, 1470, 383, 106, 316, 551, 100, 35, - /* 1920 */ 534, 575, 212, 1339, 381, 387, 1187, 1338, 274, 276, - /* 1930 */ 1019, 1019, 1021, 1022, 28, 277, 413, 1031, 576, 1254, - /* 1940 */ 388, 1521, 1249, 110, 110, 167, 1522, 168, 148, 1520, - /* 1950 */ 1519, 111, 306, 449, 573, 449, 222, 223, 1019, 839, - /* 1960 */ 169, 79, 450, 214, 414, 233, 320, 145, 1093, 1091, - /* 1970 */ 328, 182, 171, 1212, 918, 184, 240, 336, 243, 1107, - /* 1980 */ 189, 172, 173, 423, 425, 88, 180, 191, 89, 90, - /* 1990 */ 1019, 1019, 1021, 1022, 28, 91, 174, 1110, 245, 1106, - /* 2000 */ 246, 159, 18, 247, 347, 1099, 263, 195, 1227, 493, - /* 2010 */ 249, 196, 38, 854, 498, 368, 253, 360, 897, 197, - /* 2020 */ 502, 93, 19, 20, 507, 884, 363, 510, 95, 307, - /* 2030 */ 160, 96, 518, 97, 1175, 1060, 1146, 40, 21, 227, - /* 2040 */ 176, 1145, 282, 284, 969, 200, 963, 114, 262, 1165, - /* 2050 */ 22, 23, 24, 1161, 1169, 25, 1163, 1150, 34, 26, - /* 2060 */ 1168, 546, 27, 204, 101, 103, 104, 1074, 7, 1061, - /* 2070 */ 1059, 1063, 1116, 1064, 1115, 268, 269, 29, 41, 270, - /* 2080 */ 1024, 866, 113, 30, 568, 392, 1183, 144, 178, 1182, - /* 2090 */ 271, 928, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1602, + /* 0 */ 130, 127, 234, 282, 282, 1328, 576, 1307, 460, 289, + /* 10 */ 289, 576, 1622, 381, 576, 1328, 573, 576, 562, 413, + /* 20 */ 1300, 1542, 573, 481, 562, 524, 460, 459, 558, 82, + /* 30 */ 82, 983, 294, 375, 51, 51, 498, 61, 61, 984, + /* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063, + /* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413, + /* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130, + /* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290, + /* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063, + /* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296, + /* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132, + /* 110 */ 132, 132, 131, 128, 451, 44, 1050, 1050, 1064, 1067, + /* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174, + /* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 498, 1341, + /* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132, + /* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 1105, 1228, + /* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, + /* 170 */ 136, 1204, 320, 567, 288, 288, 283, 288, 288, 523, + /* 180 */ 523, 1250, 139, 1541, 7, 214, 503, 573, 1169, 562, + /* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 401, 547, + /* 200 */ 487, 1169, 245, 1568, 1169, 245, 133, 133, 132, 132, + /* 210 */ 132, 131, 128, 451, 261, 134, 134, 134, 134, 133, + /* 220 */ 133, 132, 132, 132, 131, 128, 451, 451, 1204, 1205, + /* 230 */ 1204, 130, 127, 234, 455, 413, 182, 455, 130, 127, + /* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132, + /* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 576, 137, + /* 260 */ 138, 91, 261, 1228, 1228, 1063, 1066, 1053, 1053, 135, + /* 270 */ 135, 136, 136, 136, 136, 44, 472, 346, 1204, 472, + /* 280 */ 346, 51, 51, 418, 93, 157, 134, 134, 134, 134, + /* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 166, 363, + /* 300 */ 298, 134, 134, 134, 134, 133, 133, 132, 132, 132, + /* 310 */ 131, 128, 451, 1293, 461, 1570, 423, 377, 275, 134, + /* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128, + /* 330 */ 451, 418, 320, 567, 1292, 1204, 1205, 1204, 257, 413, + /* 340 */ 483, 511, 508, 507, 94, 132, 132, 132, 131, 128, + /* 350 */ 451, 506, 1204, 548, 548, 388, 576, 384, 7, 413, + /* 360 */ 550, 229, 522, 137, 138, 91, 530, 1228, 1228, 1063, + /* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 51, + /* 380 */ 51, 1582, 380, 137, 138, 91, 331, 1228, 1228, 1063, + /* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 320, + /* 400 */ 567, 288, 288, 320, 567, 1602, 582, 2, 1259, 1204, + /* 410 */ 1205, 1204, 1628, 321, 573, 155, 562, 576, 1511, 264, + /* 420 */ 231, 520, 1341, 134, 134, 134, 134, 133, 133, 132, + /* 430 */ 132, 132, 131, 128, 451, 519, 1511, 1513, 1333, 1333, + /* 440 */ 82, 82, 498, 134, 134, 134, 134, 133, 133, 132, + /* 450 */ 132, 132, 131, 128, 451, 1435, 257, 288, 288, 511, + /* 460 */ 508, 507, 944, 1568, 413, 1019, 1204, 943, 360, 506, + /* 470 */ 573, 1598, 562, 44, 575, 551, 551, 557, 1107, 1582, + /* 480 */ 544, 576, 1107, 40, 417, 245, 531, 1505, 137, 138, + /* 490 */ 91, 219, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, + /* 500 */ 136, 136, 136, 136, 81, 81, 1281, 1204, 413, 553, + /* 510 */ 1511, 48, 512, 448, 447, 493, 578, 455, 578, 344, + /* 520 */ 45, 1204, 1233, 1204, 1205, 1204, 428, 1235, 158, 882, + /* 530 */ 320, 567, 137, 138, 91, 1234, 1228, 1228, 1063, 1066, + /* 540 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 134, 134, + /* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, + /* 560 */ 1236, 576, 1236, 329, 1204, 1205, 1204, 387, 492, 403, + /* 570 */ 1040, 382, 489, 123, 568, 1569, 4, 377, 1204, 1205, + /* 580 */ 1204, 570, 570, 570, 82, 82, 882, 1029, 1331, 1331, + /* 590 */ 571, 1028, 134, 134, 134, 134, 133, 133, 132, 132, + /* 600 */ 132, 131, 128, 451, 288, 288, 1281, 1204, 576, 423, + /* 610 */ 576, 1568, 413, 423, 452, 378, 886, 573, 1279, 562, + /* 620 */ 46, 557, 532, 1028, 1028, 1030, 565, 130, 127, 234, + /* 630 */ 556, 82, 82, 82, 82, 479, 137, 138, 91, 462, + /* 640 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 650 */ 136, 136, 1188, 487, 1506, 1040, 413, 6, 1204, 50, + /* 660 */ 879, 121, 121, 948, 1204, 1205, 1204, 358, 557, 122, + /* 670 */ 316, 452, 577, 452, 535, 1204, 1028, 439, 303, 212, + /* 680 */ 137, 138, 91, 213, 1228, 1228, 1063, 1066, 1053, 1053, + /* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134, + /* 700 */ 133, 133, 132, 132, 132, 131, 128, 451, 1028, 1028, + /* 710 */ 1030, 1031, 35, 288, 288, 1204, 1205, 1204, 1040, 1339, + /* 720 */ 533, 123, 568, 1569, 4, 377, 573, 1019, 562, 353, + /* 730 */ 1277, 356, 1204, 1205, 1204, 1029, 488, 1188, 571, 1028, + /* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 750 */ 128, 451, 576, 343, 288, 288, 449, 449, 449, 971, + /* 760 */ 413, 1627, 452, 911, 1187, 288, 288, 573, 464, 562, + /* 770 */ 238, 1028, 1028, 1030, 565, 82, 82, 498, 573, 411, + /* 780 */ 562, 344, 467, 332, 137, 138, 91, 197, 1228, 1228, + /* 790 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 800 */ 1188, 528, 1169, 1040, 413, 1110, 1110, 495, 1041, 121, + /* 810 */ 121, 1204, 317, 540, 862, 1169, 1244, 122, 1169, 452, + /* 820 */ 577, 452, 1340, 198, 1028, 1204, 481, 526, 137, 138, + /* 830 */ 91, 560, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, + /* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133, + /* 850 */ 132, 132, 132, 131, 128, 451, 1028, 1028, 1030, 1031, + /* 860 */ 35, 1204, 288, 288, 1204, 477, 288, 288, 1204, 1205, + /* 870 */ 1204, 539, 481, 437, 470, 573, 1451, 562, 364, 573, + /* 880 */ 1153, 562, 1204, 1205, 1204, 1188, 5, 576, 134, 134, + /* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, + /* 900 */ 221, 214, 302, 96, 1149, 1657, 232, 1657, 413, 392, + /* 910 */ 19, 19, 1024, 949, 406, 373, 1595, 1085, 1204, 1205, + /* 920 */ 1204, 1204, 1205, 1204, 1204, 426, 1149, 1658, 413, 1658, + /* 930 */ 1659, 399, 137, 138, 91, 3, 1228, 1228, 1063, 1066, + /* 940 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 304, 1311, + /* 950 */ 514, 1204, 137, 138, 91, 1498, 1228, 1228, 1063, 1066, + /* 960 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 434, 131, + /* 970 */ 128, 451, 375, 1204, 274, 291, 372, 517, 367, 516, + /* 980 */ 262, 1204, 1205, 1204, 1147, 227, 363, 448, 447, 1435, + /* 990 */ 1568, 1310, 134, 134, 134, 134, 133, 133, 132, 132, + /* 1000 */ 132, 131, 128, 451, 1568, 576, 1147, 487, 1204, 1205, + /* 1010 */ 1204, 442, 134, 134, 134, 134, 133, 133, 132, 132, + /* 1020 */ 132, 131, 128, 451, 386, 576, 485, 576, 19, 19, + /* 1030 */ 1204, 1205, 1204, 1345, 1236, 970, 1236, 574, 47, 936, + /* 1040 */ 936, 473, 413, 431, 1552, 573, 1125, 562, 19, 19, + /* 1050 */ 19, 19, 49, 336, 850, 851, 852, 111, 1368, 315, + /* 1060 */ 429, 576, 413, 433, 341, 306, 137, 138, 91, 115, + /* 1070 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 1080 */ 136, 136, 576, 1309, 82, 82, 137, 138, 91, 529, + /* 1090 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 1100 */ 136, 136, 1569, 222, 377, 19, 19, 305, 1126, 1169, + /* 1110 */ 398, 1148, 22, 22, 498, 333, 1569, 335, 377, 576, + /* 1120 */ 438, 445, 1169, 1127, 486, 1169, 134, 134, 134, 134, + /* 1130 */ 133, 133, 132, 132, 132, 131, 128, 451, 1128, 576, + /* 1140 */ 902, 576, 145, 145, 6, 576, 134, 134, 134, 134, + /* 1150 */ 133, 133, 132, 132, 132, 131, 128, 451, 214, 1336, + /* 1160 */ 922, 576, 19, 19, 19, 19, 1282, 419, 19, 19, + /* 1170 */ 923, 412, 515, 141, 576, 1169, 413, 206, 465, 207, + /* 1180 */ 903, 215, 1575, 552, 147, 147, 7, 227, 1169, 411, + /* 1190 */ 1250, 1169, 120, 307, 117, 307, 413, 66, 66, 334, + /* 1200 */ 137, 138, 91, 119, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1210 */ 135, 135, 136, 136, 136, 136, 413, 285, 209, 969, + /* 1220 */ 137, 138, 91, 471, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1230 */ 135, 135, 136, 136, 136, 136, 435, 10, 1450, 267, + /* 1240 */ 137, 126, 91, 1435, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1250 */ 135, 135, 136, 136, 136, 136, 1435, 1435, 410, 409, + /* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1270 */ 128, 451, 576, 969, 576, 1224, 498, 373, 1595, 1554, + /* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1290 */ 128, 451, 532, 457, 576, 82, 82, 82, 82, 111, + /* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1310 */ 128, 451, 109, 233, 430, 1576, 546, 67, 67, 7, + /* 1320 */ 413, 351, 550, 1550, 260, 259, 258, 494, 443, 569, + /* 1330 */ 419, 983, 446, 1224, 450, 545, 1207, 576, 969, 984, + /* 1340 */ 413, 475, 1449, 1574, 1180, 138, 91, 7, 1228, 1228, + /* 1350 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 1360 */ 21, 21, 267, 576, 300, 1126, 91, 233, 1228, 1228, + /* 1370 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 1380 */ 1127, 373, 1595, 161, 1573, 16, 53, 53, 7, 108, + /* 1390 */ 533, 38, 969, 125, 1207, 1128, 1180, 576, 1224, 123, + /* 1400 */ 568, 893, 4, 324, 134, 134, 134, 134, 133, 133, + /* 1410 */ 132, 132, 132, 131, 128, 451, 571, 564, 534, 576, + /* 1420 */ 68, 68, 576, 39, 134, 134, 134, 134, 133, 133, + /* 1430 */ 132, 132, 132, 131, 128, 451, 576, 160, 1571, 1223, + /* 1440 */ 452, 576, 54, 54, 576, 69, 69, 576, 1366, 576, + /* 1450 */ 420, 184, 565, 463, 297, 576, 1224, 463, 297, 70, + /* 1460 */ 70, 576, 44, 474, 71, 71, 576, 72, 72, 576, + /* 1470 */ 73, 73, 55, 55, 411, 874, 242, 576, 56, 56, + /* 1480 */ 576, 1040, 576, 478, 57, 57, 576, 121, 121, 59, + /* 1490 */ 59, 23, 60, 60, 411, 122, 319, 452, 577, 452, + /* 1500 */ 74, 74, 1028, 75, 75, 76, 76, 411, 290, 20, + /* 1510 */ 20, 108, 287, 231, 553, 123, 568, 325, 4, 320, + /* 1520 */ 567, 97, 218, 944, 1144, 328, 400, 576, 943, 576, + /* 1530 */ 1380, 424, 571, 874, 1028, 1028, 1030, 1031, 35, 293, + /* 1540 */ 534, 576, 1104, 576, 1104, 9, 576, 342, 576, 111, + /* 1550 */ 77, 77, 143, 143, 576, 205, 452, 222, 1379, 889, + /* 1560 */ 576, 901, 900, 1188, 144, 144, 78, 78, 565, 62, + /* 1570 */ 62, 79, 79, 323, 1021, 576, 266, 63, 63, 908, + /* 1580 */ 909, 1589, 542, 80, 80, 576, 371, 541, 123, 568, + /* 1590 */ 480, 4, 266, 482, 244, 266, 370, 1040, 64, 64, + /* 1600 */ 576, 466, 576, 121, 121, 571, 1557, 576, 170, 170, + /* 1610 */ 576, 122, 576, 452, 577, 452, 576, 889, 1028, 576, + /* 1620 */ 165, 576, 111, 171, 171, 87, 87, 337, 1616, 452, + /* 1630 */ 65, 65, 1530, 83, 83, 146, 146, 986, 987, 84, + /* 1640 */ 84, 565, 168, 168, 148, 148, 1092, 347, 1032, 111, + /* 1650 */ 1028, 1028, 1030, 1031, 35, 542, 1103, 576, 1103, 576, + /* 1660 */ 543, 123, 568, 504, 4, 263, 576, 361, 1529, 111, + /* 1670 */ 1040, 1088, 576, 263, 576, 490, 121, 121, 571, 1188, + /* 1680 */ 142, 142, 169, 169, 122, 576, 452, 577, 452, 162, + /* 1690 */ 162, 1028, 576, 563, 576, 152, 152, 151, 151, 348, + /* 1700 */ 1376, 974, 452, 266, 1092, 942, 1032, 125, 149, 149, + /* 1710 */ 939, 576, 125, 576, 565, 150, 150, 86, 86, 872, + /* 1720 */ 352, 159, 576, 1028, 1028, 1030, 1031, 35, 542, 941, + /* 1730 */ 576, 125, 355, 541, 88, 88, 85, 85, 357, 359, + /* 1740 */ 1324, 1308, 366, 1040, 376, 52, 52, 499, 1389, 121, + /* 1750 */ 121, 1434, 1188, 58, 58, 1362, 1374, 122, 1439, 452, + /* 1760 */ 577, 452, 1289, 167, 1028, 1280, 280, 1268, 1267, 1269, + /* 1770 */ 1609, 1359, 312, 313, 12, 314, 397, 1421, 224, 1416, + /* 1780 */ 295, 237, 1409, 339, 340, 1426, 301, 345, 484, 228, + /* 1790 */ 1371, 1307, 1372, 1370, 1425, 404, 1028, 1028, 1030, 1031, + /* 1800 */ 35, 1601, 1192, 454, 509, 369, 292, 1502, 210, 1501, + /* 1810 */ 1369, 396, 396, 395, 277, 393, 211, 566, 859, 1612, + /* 1820 */ 1244, 123, 568, 391, 4, 1188, 223, 270, 1549, 1547, + /* 1830 */ 1241, 239, 186, 327, 422, 96, 195, 220, 571, 235, + /* 1840 */ 180, 326, 188, 468, 190, 1507, 191, 192, 92, 193, + /* 1850 */ 469, 95, 1422, 13, 502, 247, 1430, 109, 199, 402, + /* 1860 */ 476, 405, 452, 1496, 1428, 1427, 14, 491, 251, 102, + /* 1870 */ 497, 1518, 241, 281, 565, 253, 203, 354, 500, 254, + /* 1880 */ 175, 1270, 407, 43, 350, 518, 1327, 436, 255, 1326, + /* 1890 */ 1325, 1318, 104, 893, 1626, 229, 408, 440, 1625, 441, + /* 1900 */ 240, 310, 1296, 1040, 311, 1317, 527, 1594, 1297, 121, + /* 1910 */ 121, 368, 1295, 1624, 268, 269, 1580, 122, 1579, 452, + /* 1920 */ 577, 452, 374, 444, 1028, 1394, 1393, 140, 553, 90, + /* 1930 */ 568, 11, 4, 1483, 383, 414, 385, 110, 116, 216, + /* 1940 */ 320, 567, 1350, 555, 42, 318, 571, 537, 1349, 389, + /* 1950 */ 390, 579, 1198, 276, 279, 278, 1028, 1028, 1030, 1031, + /* 1960 */ 35, 580, 415, 1265, 458, 1260, 416, 185, 1534, 172, + /* 1970 */ 452, 1535, 173, 156, 308, 846, 1533, 1532, 453, 217, + /* 1980 */ 225, 89, 565, 174, 322, 1188, 226, 236, 1102, 154, + /* 1990 */ 1100, 330, 176, 187, 1223, 189, 925, 338, 243, 1116, + /* 2000 */ 246, 194, 177, 178, 425, 427, 98, 99, 196, 100, + /* 2010 */ 101, 1040, 179, 1119, 248, 1115, 249, 121, 121, 24, + /* 2020 */ 163, 250, 349, 1108, 266, 122, 1238, 452, 577, 452, + /* 2030 */ 1192, 454, 1028, 200, 292, 496, 252, 201, 861, 396, + /* 2040 */ 396, 395, 277, 393, 15, 501, 859, 370, 292, 256, + /* 2050 */ 202, 554, 505, 396, 396, 395, 277, 393, 103, 239, + /* 2060 */ 859, 327, 25, 26, 1028, 1028, 1030, 1031, 35, 326, + /* 2070 */ 362, 510, 891, 239, 365, 327, 513, 904, 105, 309, + /* 2080 */ 164, 181, 27, 326, 106, 521, 107, 1185, 1069, 1155, + /* 2090 */ 17, 1154, 284, 1188, 286, 978, 265, 204, 125, 1171, + /* 2100 */ 241, 230, 972, 1175, 28, 1160, 29, 1179, 175, 1173, + /* 2110 */ 30, 43, 31, 1178, 241, 32, 41, 549, 8, 33, + /* 2120 */ 208, 111, 175, 1083, 1070, 43, 113, 1068, 240, 114, + /* 2130 */ 1072, 34, 1073, 561, 1124, 118, 271, 36, 18, 1194, + /* 2140 */ 1033, 873, 240, 935, 124, 37, 272, 273, 1617, 572, + /* 2150 */ 183, 153, 394, 1193, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2160 */ 1256, 1256, 1256, 414, 1256, 1256, 1256, 1256, 320, 567, + /* 2170 */ 1256, 1256, 1256, 1256, 1256, 1256, 1256, 414, 1256, 1256, + /* 2180 */ 1256, 1256, 320, 567, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2190 */ 1256, 1256, 458, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2200 */ 1256, 1256, 1256, 1256, 1256, 1256, 458, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276, - /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19, - /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216, - /* 30 */ 217, 31, 193, 216, 217, 193, 228, 213, 230, 39, - /* 40 */ 206, 216, 217, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19, - /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276, - /* 70 */ 195, 193, 197, 193, 261, 274, 275, 276, 253, 204, - /* 80 */ 238, 204, 81, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 274, 275, - /* 100 */ 276, 262, 102, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211, - /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252, - /* 130 */ 19, 314, 315, 256, 257, 113, 25, 72, 296, 138, - /* 140 */ 139, 266, 102, 103, 104, 105, 106, 107, 108, 109, - /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, - /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81, - /* 170 */ 292, 59, 292, 298, 108, 109, 110, 111, 112, 113, - /* 180 */ 69, 116, 117, 118, 72, 106, 107, 193, 111, 112, - /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105, - /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 25, - /* 210 */ 216, 217, 145, 102, 103, 104, 105, 106, 107, 108, - /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117, - /* 230 */ 118, 164, 153, 19, 155, 54, 55, 56, 57, 102, - /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 250 */ 113, 128, 129, 46, 47, 48, 49, 43, 44, 45, - /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 270 */ 56, 57, 216, 193, 25, 59, 193, 19, 165, 166, - /* 280 */ 193, 67, 24, 102, 103, 104, 105, 106, 107, 108, - /* 290 */ 109, 110, 111, 112, 113, 73, 216, 217, 59, 216, - /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, - /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 145, - /* 330 */ 59, 193, 116, 117, 118, 119, 273, 204, 122, 123, - /* 340 */ 124, 19, 20, 134, 22, 136, 137, 19, 132, 127, - /* 350 */ 128, 129, 24, 22, 23, 116, 117, 118, 36, 193, - /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 370 */ 112, 113, 239, 240, 311, 312, 215, 106, 107, 241, - /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118, - /* 390 */ 151, 120, 26, 71, 193, 308, 309, 193, 149, 128, - /* 400 */ 313, 216, 269, 81, 43, 44, 45, 46, 47, 48, - /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 253, - /* 420 */ 216, 217, 100, 95, 153, 59, 155, 261, 106, 107, - /* 430 */ 25, 193, 101, 193, 193, 231, 114, 25, 116, 117, - /* 440 */ 118, 113, 304, 121, 193, 204, 59, 119, 120, 121, - /* 450 */ 122, 123, 124, 125, 216, 217, 193, 216, 217, 131, - /* 460 */ 138, 139, 230, 102, 103, 104, 105, 106, 107, 108, - /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, - /* 480 */ 239, 240, 116, 117, 118, 76, 193, 23, 19, 25, - /* 490 */ 22, 253, 23, 252, 253, 108, 87, 204, 89, 261, - /* 500 */ 198, 92, 261, 116, 117, 118, 193, 306, 307, 216, - /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50, - /* 520 */ 51, 52, 53, 54, 55, 56, 57, 59, 193, 216, - /* 530 */ 217, 19, 239, 240, 283, 23, 106, 107, 108, 109, - /* 540 */ 110, 111, 112, 113, 73, 252, 253, 142, 308, 309, - /* 550 */ 138, 139, 81, 313, 145, 43, 44, 45, 46, 47, - /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 570 */ 307, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 580 */ 111, 112, 113, 281, 116, 117, 118, 285, 23, 193, - /* 590 */ 25, 119, 59, 193, 122, 123, 124, 59, 127, 203, - /* 600 */ 59, 205, 19, 268, 132, 25, 23, 22, 193, 138, - /* 610 */ 139, 249, 204, 251, 102, 103, 104, 105, 106, 107, - /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 640 */ 57, 19, 22, 23, 59, 23, 25, 239, 240, 116, - /* 650 */ 117, 118, 193, 11, 116, 117, 118, 116, 117, 118, - /* 660 */ 252, 269, 22, 193, 15, 43, 44, 45, 46, 47, - /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 680 */ 273, 143, 193, 118, 143, 102, 103, 104, 105, 106, - /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59, - /* 700 */ 241, 116, 117, 118, 304, 216, 217, 292, 143, 60, - /* 710 */ 89, 241, 19, 92, 193, 193, 23, 22, 311, 312, - /* 720 */ 231, 101, 22, 143, 102, 103, 104, 105, 106, 107, - /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59, - /* 760 */ 201, 21, 241, 304, 193, 206, 127, 128, 129, 193, - /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47, - /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106, - /* 800 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 193, - /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 226, - /* 820 */ 80, 193, 19, 235, 236, 304, 23, 211, 212, 231, - /* 830 */ 204, 216, 217, 205, 102, 103, 104, 105, 106, 107, - /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239, - /* 870 */ 240, 239, 240, 244, 106, 107, 193, 89, 252, 193, - /* 880 */ 92, 59, 252, 254, 252, 43, 44, 45, 46, 47, - /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106, - /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 244, - /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 254, - /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117, - /* 940 */ 24, 216, 217, 273, 102, 103, 104, 105, 106, 107, - /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190, - /* 980 */ 193, 311, 312, 16, 195, 252, 197, 193, 19, 301, - /* 990 */ 302, 135, 193, 204, 216, 217, 140, 216, 217, 266, - /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52, - /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, - /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240, - /* 1030 */ 193, 298, 238, 117, 253, 239, 240, 238, 259, 260, - /* 1040 */ 193, 252, 27, 193, 77, 193, 79, 204, 252, 262, - /* 1050 */ 193, 299, 300, 193, 100, 266, 278, 42, 204, 102, - /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193, - /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 240, - /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212, - /* 1100 */ 263, 252, 216, 217, 216, 217, 252, 153, 154, 155, - /* 1110 */ 253, 193, 19, 144, 213, 268, 43, 44, 45, 46, - /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1130 */ 57, 193, 19, 59, 216, 217, 43, 44, 45, 46, - /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1150 */ 57, 193, 19, 24, 216, 217, 43, 44, 45, 46, - /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1170 */ 57, 284, 193, 208, 209, 102, 103, 104, 105, 106, - /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 59, 193, - /* 1190 */ 232, 117, 291, 193, 193, 102, 103, 104, 105, 106, - /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 193, 204, 22, - /* 1210 */ 23, 193, 25, 66, 193, 102, 103, 104, 105, 106, - /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 193, 193, - /* 1230 */ 216, 217, 85, 193, 238, 19, 16, 216, 217, 238, - /* 1240 */ 193, 94, 193, 239, 240, 231, 117, 268, 35, 116, - /* 1250 */ 216, 217, 216, 217, 22, 23, 252, 25, 208, 209, - /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 1270 */ 54, 55, 56, 57, 193, 193, 19, 5, 59, 66, - /* 1280 */ 193, 263, 10, 11, 12, 13, 14, 74, 101, 17, - /* 1290 */ 193, 46, 193, 146, 193, 76, 213, 77, 263, 79, - /* 1300 */ 12, 260, 30, 46, 32, 264, 87, 193, 89, 29, - /* 1310 */ 263, 92, 40, 33, 232, 27, 193, 108, 102, 103, - /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 1330 */ 42, 138, 139, 101, 193, 116, 117, 118, 19, 20, - /* 1340 */ 255, 22, 70, 130, 135, 65, 256, 257, 193, 140, - /* 1350 */ 78, 63, 193, 81, 193, 36, 193, 216, 217, 193, - /* 1360 */ 115, 193, 263, 193, 145, 268, 59, 48, 193, 193, - /* 1370 */ 98, 193, 115, 193, 291, 216, 217, 193, 59, 216, - /* 1380 */ 217, 161, 216, 217, 216, 217, 216, 217, 131, 193, - /* 1390 */ 71, 193, 216, 217, 216, 217, 216, 217, 193, 260, - /* 1400 */ 216, 217, 19, 264, 85, 133, 244, 100, 193, 90, - /* 1410 */ 138, 139, 216, 217, 216, 217, 254, 244, 193, 100, - /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 254, 121, 193, - /* 1430 */ 115, 216, 217, 114, 162, 116, 117, 118, 115, 244, - /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 193, 31, 254, - /* 1450 */ 313, 309, 216, 217, 309, 313, 39, 193, 313, 309, - /* 1460 */ 153, 154, 155, 313, 193, 150, 25, 144, 216, 217, - /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2, - /* 1480 */ 216, 217, 5, 149, 150, 22, 193, 10, 11, 12, - /* 1490 */ 13, 14, 193, 158, 17, 160, 193, 19, 20, 116, - /* 1500 */ 22, 25, 193, 24, 22, 193, 24, 30, 226, 32, - /* 1510 */ 19, 20, 226, 22, 36, 193, 53, 40, 193, 216, - /* 1520 */ 217, 193, 23, 193, 25, 216, 217, 36, 216, 217, - /* 1530 */ 193, 99, 193, 193, 22, 193, 193, 59, 216, 217, - /* 1540 */ 193, 216, 217, 193, 216, 217, 193, 70, 129, 71, - /* 1550 */ 59, 129, 193, 216, 217, 78, 216, 217, 81, 216, - /* 1560 */ 217, 193, 71, 85, 193, 133, 193, 126, 90, 216, - /* 1570 */ 217, 152, 258, 61, 152, 98, 85, 193, 100, 193, - /* 1580 */ 23, 90, 25, 121, 106, 107, 23, 216, 217, 216, - /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121, - /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118, - /* 1610 */ 133, 22, 121, 193, 59, 138, 139, 193, 142, 193, - /* 1620 */ 141, 23, 23, 25, 25, 120, 121, 216, 217, 216, - /* 1630 */ 217, 153, 154, 155, 156, 157, 216, 217, 19, 162, - /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1, - /* 1650 */ 2, 193, 59, 5, 19, 20, 318, 22, 10, 11, - /* 1660 */ 12, 13, 14, 193, 59, 17, 193, 23, 23, 25, - /* 1670 */ 25, 36, 117, 193, 216, 217, 193, 23, 30, 25, - /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216, - /* 1690 */ 217, 7, 8, 23, 59, 25, 83, 84, 36, 23, - /* 1700 */ 193, 25, 23, 23, 25, 25, 71, 153, 145, 155, - /* 1710 */ 117, 153, 23, 155, 25, 23, 97, 25, 70, 193, - /* 1720 */ 193, 59, 117, 236, 193, 193, 78, 193, 193, 81, - /* 1730 */ 141, 193, 193, 71, 193, 100, 288, 287, 242, 255, - /* 1740 */ 255, 106, 107, 108, 255, 255, 98, 243, 297, 114, - /* 1750 */ 214, 116, 117, 118, 245, 191, 121, 271, 293, 267, - /* 1760 */ 267, 246, 100, 246, 245, 271, 271, 293, 106, 107, - /* 1770 */ 220, 271, 229, 225, 249, 219, 114, 259, 116, 117, - /* 1780 */ 118, 133, 259, 121, 219, 219, 138, 139, 153, 154, - /* 1790 */ 155, 156, 157, 280, 249, 243, 19, 20, 245, 22, - /* 1800 */ 196, 259, 140, 259, 60, 297, 141, 297, 200, 200, - /* 1810 */ 162, 38, 200, 36, 294, 153, 154, 155, 156, 157, - /* 1820 */ 151, 150, 294, 283, 22, 43, 234, 18, 237, 200, - /* 1830 */ 270, 272, 237, 237, 237, 18, 59, 199, 270, 149, - /* 1840 */ 246, 272, 272, 200, 234, 234, 246, 246, 71, 246, - /* 1850 */ 199, 158, 290, 62, 22, 200, 19, 20, 199, 22, - /* 1860 */ 289, 221, 221, 200, 200, 199, 199, 115, 218, 64, - /* 1870 */ 218, 218, 22, 36, 227, 126, 227, 100, 165, 221, - /* 1880 */ 224, 224, 24, 106, 107, 312, 218, 305, 113, 282, - /* 1890 */ 91, 114, 220, 116, 117, 118, 59, 282, 121, 218, - /* 1900 */ 218, 218, 200, 317, 317, 82, 221, 265, 71, 148, - /* 1910 */ 145, 265, 22, 277, 200, 158, 279, 140, 147, 25, - /* 1920 */ 146, 202, 248, 250, 249, 247, 13, 250, 194, 194, - /* 1930 */ 153, 154, 155, 156, 157, 6, 303, 100, 192, 192, - /* 1940 */ 246, 213, 192, 106, 107, 207, 213, 207, 222, 213, - /* 1950 */ 213, 114, 222, 116, 117, 118, 214, 214, 121, 4, - /* 1960 */ 207, 213, 3, 22, 303, 15, 163, 16, 23, 23, - /* 1970 */ 139, 151, 130, 25, 20, 142, 24, 16, 144, 1, - /* 1980 */ 142, 130, 130, 61, 37, 53, 300, 151, 53, 53, - /* 1990 */ 153, 154, 155, 156, 157, 53, 130, 116, 34, 1, - /* 2000 */ 141, 5, 22, 115, 161, 68, 25, 68, 75, 41, - /* 2010 */ 141, 115, 24, 20, 19, 131, 125, 23, 28, 22, - /* 2020 */ 67, 22, 22, 22, 67, 59, 24, 96, 22, 67, - /* 2030 */ 23, 149, 22, 25, 23, 23, 23, 22, 34, 141, - /* 2040 */ 37, 97, 23, 23, 116, 22, 143, 25, 34, 75, - /* 2050 */ 34, 34, 34, 88, 75, 34, 86, 23, 22, 34, - /* 2060 */ 93, 24, 34, 25, 25, 142, 142, 23, 44, 23, - /* 2070 */ 23, 23, 23, 11, 23, 25, 22, 22, 22, 141, - /* 2080 */ 23, 23, 22, 22, 25, 15, 1, 23, 25, 1, - /* 2090 */ 141, 135, 319, 319, 319, 319, 319, 319, 319, 141, - /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2150 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2160 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2170 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2180 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2280 */ 319, 319, 319, 319, 319, + /* 0 */ 276, 277, 278, 240, 241, 224, 194, 226, 194, 240, + /* 10 */ 241, 194, 216, 220, 194, 234, 253, 194, 255, 19, + /* 20 */ 224, 297, 253, 194, 255, 205, 212, 213, 205, 217, + /* 30 */ 218, 31, 205, 194, 217, 218, 194, 217, 218, 39, + /* 40 */ 217, 218, 312, 43, 44, 45, 316, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19, + /* 60 */ 240, 241, 194, 240, 241, 194, 254, 240, 241, 276, + /* 70 */ 277, 278, 233, 253, 254, 255, 253, 254, 255, 217, + /* 80 */ 253, 239, 255, 43, 44, 45, 263, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 270, + /* 100 */ 286, 22, 23, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 114, 82, 47, 48, 49, 50, + /* 120 */ 186, 187, 188, 189, 190, 191, 189, 87, 191, 89, + /* 130 */ 196, 19, 198, 196, 317, 198, 319, 25, 194, 205, + /* 140 */ 298, 270, 205, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 11, 47, + /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 170 */ 58, 60, 139, 140, 240, 241, 214, 240, 241, 311, + /* 180 */ 312, 102, 70, 239, 316, 194, 19, 253, 77, 255, + /* 190 */ 253, 122, 255, 55, 56, 57, 58, 59, 207, 88, + /* 200 */ 194, 90, 268, 194, 93, 268, 107, 108, 109, 110, + /* 210 */ 111, 112, 113, 114, 47, 103, 104, 105, 106, 107, + /* 220 */ 108, 109, 110, 111, 112, 113, 114, 114, 117, 118, + /* 230 */ 119, 276, 277, 278, 300, 19, 194, 300, 276, 277, + /* 240 */ 278, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 194, 43, + /* 260 */ 44, 45, 47, 47, 48, 49, 50, 51, 52, 53, + /* 270 */ 54, 55, 56, 57, 58, 82, 129, 130, 60, 129, + /* 280 */ 130, 217, 218, 116, 68, 25, 103, 104, 105, 106, + /* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 23, 132, + /* 300 */ 294, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 310 */ 112, 113, 114, 217, 121, 306, 194, 308, 26, 103, + /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 330 */ 114, 116, 139, 140, 217, 117, 118, 119, 120, 19, + /* 340 */ 194, 123, 124, 125, 24, 109, 110, 111, 112, 113, + /* 350 */ 114, 133, 60, 311, 312, 250, 194, 252, 316, 19, + /* 360 */ 194, 166, 167, 43, 44, 45, 205, 47, 48, 49, + /* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 217, + /* 380 */ 218, 317, 318, 43, 44, 45, 264, 47, 48, 49, + /* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 139, + /* 400 */ 140, 240, 241, 139, 140, 188, 189, 190, 191, 117, + /* 410 */ 118, 119, 231, 196, 253, 198, 255, 194, 194, 258, + /* 420 */ 259, 146, 205, 103, 104, 105, 106, 107, 108, 109, + /* 430 */ 110, 111, 112, 113, 114, 109, 212, 213, 236, 237, + /* 440 */ 217, 218, 194, 103, 104, 105, 106, 107, 108, 109, + /* 450 */ 110, 111, 112, 113, 114, 194, 120, 240, 241, 123, + /* 460 */ 124, 125, 136, 194, 19, 74, 60, 141, 23, 133, + /* 470 */ 253, 194, 255, 82, 194, 309, 310, 254, 29, 317, + /* 480 */ 318, 194, 33, 22, 199, 268, 263, 239, 43, 44, + /* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54, + /* 500 */ 55, 56, 57, 58, 217, 218, 194, 60, 19, 146, + /* 510 */ 286, 242, 23, 107, 108, 66, 204, 300, 206, 128, + /* 520 */ 73, 60, 116, 117, 118, 119, 265, 121, 165, 60, + /* 530 */ 139, 140, 43, 44, 45, 129, 47, 48, 49, 50, + /* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, + /* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 560 */ 154, 194, 156, 194, 117, 118, 119, 280, 283, 205, + /* 570 */ 101, 220, 287, 19, 20, 306, 22, 308, 117, 118, + /* 580 */ 119, 211, 212, 213, 217, 218, 117, 118, 236, 237, + /* 590 */ 36, 122, 103, 104, 105, 106, 107, 108, 109, 110, + /* 600 */ 111, 112, 113, 114, 240, 241, 194, 60, 194, 194, + /* 610 */ 194, 194, 19, 194, 60, 194, 23, 253, 206, 255, + /* 620 */ 73, 254, 19, 154, 155, 156, 72, 276, 277, 278, + /* 630 */ 263, 217, 218, 217, 218, 271, 43, 44, 45, 271, + /* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 650 */ 57, 58, 183, 194, 285, 101, 19, 214, 60, 242, + /* 660 */ 23, 107, 108, 109, 117, 118, 119, 16, 254, 115, + /* 670 */ 254, 117, 118, 119, 194, 60, 122, 263, 205, 264, + /* 680 */ 43, 44, 45, 264, 47, 48, 49, 50, 51, 52, + /* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, + /* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155, + /* 710 */ 156, 157, 158, 240, 241, 117, 118, 119, 101, 205, + /* 720 */ 117, 19, 20, 306, 22, 308, 253, 74, 255, 78, + /* 730 */ 205, 80, 117, 118, 119, 118, 293, 183, 36, 122, + /* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 750 */ 113, 114, 194, 294, 240, 241, 211, 212, 213, 144, + /* 760 */ 19, 23, 60, 25, 23, 240, 241, 253, 245, 255, + /* 770 */ 15, 154, 155, 156, 72, 217, 218, 194, 253, 256, + /* 780 */ 255, 128, 129, 130, 43, 44, 45, 22, 47, 48, + /* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 800 */ 183, 19, 77, 101, 19, 128, 129, 130, 23, 107, + /* 810 */ 108, 60, 254, 88, 21, 90, 61, 115, 93, 117, + /* 820 */ 118, 119, 239, 22, 122, 60, 194, 205, 43, 44, + /* 830 */ 45, 205, 47, 48, 49, 50, 51, 52, 53, 54, + /* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108, + /* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157, + /* 860 */ 158, 60, 240, 241, 60, 116, 240, 241, 117, 118, + /* 870 */ 119, 146, 194, 19, 81, 253, 275, 255, 24, 253, + /* 880 */ 98, 255, 117, 118, 119, 183, 22, 194, 103, 104, + /* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 900 */ 151, 194, 270, 152, 22, 23, 194, 25, 19, 202, + /* 910 */ 217, 218, 23, 109, 207, 314, 315, 124, 117, 118, + /* 920 */ 119, 117, 118, 119, 60, 232, 22, 23, 19, 25, + /* 930 */ 303, 304, 43, 44, 45, 22, 47, 48, 49, 50, + /* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 270, 227, + /* 950 */ 96, 60, 43, 44, 45, 162, 47, 48, 49, 50, + /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 112, + /* 970 */ 113, 114, 194, 60, 120, 121, 122, 123, 124, 125, + /* 980 */ 126, 117, 118, 119, 102, 25, 132, 107, 108, 194, + /* 990 */ 194, 227, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1000 */ 111, 112, 113, 114, 194, 194, 102, 194, 117, 118, + /* 1010 */ 119, 233, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1020 */ 111, 112, 113, 114, 194, 194, 19, 194, 217, 218, + /* 1030 */ 117, 118, 119, 241, 154, 144, 156, 135, 242, 137, + /* 1040 */ 138, 130, 19, 232, 194, 253, 23, 255, 217, 218, + /* 1050 */ 217, 218, 242, 16, 7, 8, 9, 25, 261, 262, + /* 1060 */ 265, 194, 19, 232, 153, 232, 43, 44, 45, 160, + /* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1080 */ 57, 58, 194, 227, 217, 218, 43, 44, 45, 194, + /* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1100 */ 57, 58, 306, 143, 308, 217, 218, 294, 12, 77, + /* 1110 */ 22, 23, 217, 218, 194, 78, 306, 80, 308, 194, + /* 1120 */ 232, 254, 90, 27, 117, 93, 103, 104, 105, 106, + /* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 194, + /* 1140 */ 35, 194, 217, 218, 214, 194, 103, 104, 105, 106, + /* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 194, 239, + /* 1160 */ 64, 194, 217, 218, 217, 218, 209, 210, 217, 218, + /* 1170 */ 74, 207, 67, 22, 194, 77, 19, 232, 245, 232, + /* 1180 */ 75, 24, 312, 232, 217, 218, 316, 25, 90, 256, + /* 1190 */ 102, 93, 159, 229, 161, 231, 19, 217, 218, 162, + /* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52, + /* 1210 */ 53, 54, 55, 56, 57, 58, 19, 23, 288, 25, + /* 1220 */ 43, 44, 45, 293, 47, 48, 49, 50, 51, 52, + /* 1230 */ 53, 54, 55, 56, 57, 58, 131, 22, 275, 24, + /* 1240 */ 43, 44, 45, 194, 47, 48, 49, 50, 51, 52, + /* 1250 */ 53, 54, 55, 56, 57, 58, 194, 194, 107, 108, + /* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1270 */ 113, 114, 194, 25, 194, 60, 194, 314, 315, 194, + /* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1290 */ 113, 114, 19, 194, 194, 217, 218, 217, 218, 25, + /* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1310 */ 113, 114, 150, 119, 265, 312, 67, 217, 218, 316, + /* 1320 */ 19, 239, 194, 194, 128, 129, 130, 265, 265, 209, + /* 1330 */ 210, 31, 254, 118, 254, 86, 60, 194, 144, 39, + /* 1340 */ 19, 130, 275, 312, 95, 44, 45, 316, 47, 48, + /* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1360 */ 217, 218, 24, 194, 153, 12, 45, 119, 47, 48, + /* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1380 */ 27, 314, 315, 22, 312, 24, 217, 218, 316, 116, + /* 1390 */ 117, 22, 144, 25, 118, 42, 147, 194, 60, 19, + /* 1400 */ 20, 127, 22, 194, 103, 104, 105, 106, 107, 108, + /* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 194, + /* 1420 */ 217, 218, 194, 54, 103, 104, 105, 106, 107, 108, + /* 1430 */ 109, 110, 111, 112, 113, 114, 194, 22, 310, 25, + /* 1440 */ 60, 194, 217, 218, 194, 217, 218, 194, 260, 194, + /* 1450 */ 301, 302, 72, 262, 262, 194, 118, 266, 266, 217, + /* 1460 */ 218, 194, 82, 245, 217, 218, 194, 217, 218, 194, + /* 1470 */ 217, 218, 217, 218, 256, 60, 24, 194, 217, 218, + /* 1480 */ 194, 101, 194, 245, 217, 218, 194, 107, 108, 217, + /* 1490 */ 218, 22, 217, 218, 256, 115, 245, 117, 118, 119, + /* 1500 */ 217, 218, 122, 217, 218, 217, 218, 256, 22, 217, + /* 1510 */ 218, 116, 258, 259, 146, 19, 20, 194, 22, 139, + /* 1520 */ 140, 150, 151, 136, 23, 194, 25, 194, 141, 194, + /* 1530 */ 194, 62, 36, 118, 154, 155, 156, 157, 158, 100, + /* 1540 */ 145, 194, 154, 194, 156, 49, 194, 23, 194, 25, + /* 1550 */ 217, 218, 217, 218, 194, 257, 60, 143, 194, 60, + /* 1560 */ 194, 121, 122, 183, 217, 218, 217, 218, 72, 217, + /* 1570 */ 218, 217, 218, 134, 23, 194, 25, 217, 218, 7, + /* 1580 */ 8, 321, 86, 217, 218, 194, 122, 91, 19, 20, + /* 1590 */ 23, 22, 25, 23, 142, 25, 132, 101, 217, 218, + /* 1600 */ 194, 194, 194, 107, 108, 36, 194, 194, 217, 218, + /* 1610 */ 194, 115, 194, 117, 118, 119, 194, 118, 122, 194, + /* 1620 */ 23, 194, 25, 217, 218, 217, 218, 194, 142, 60, + /* 1630 */ 217, 218, 194, 217, 218, 217, 218, 84, 85, 217, + /* 1640 */ 218, 72, 217, 218, 217, 218, 60, 23, 60, 25, + /* 1650 */ 154, 155, 156, 157, 158, 86, 154, 194, 156, 194, + /* 1660 */ 91, 19, 20, 23, 22, 25, 194, 23, 194, 25, + /* 1670 */ 101, 23, 194, 25, 194, 194, 107, 108, 36, 183, + /* 1680 */ 217, 218, 217, 218, 115, 194, 117, 118, 119, 217, + /* 1690 */ 218, 122, 194, 237, 194, 217, 218, 217, 218, 194, + /* 1700 */ 194, 23, 60, 25, 118, 23, 118, 25, 217, 218, + /* 1710 */ 23, 194, 25, 194, 72, 217, 218, 217, 218, 23, + /* 1720 */ 194, 25, 194, 154, 155, 156, 157, 158, 86, 23, + /* 1730 */ 194, 25, 194, 91, 217, 218, 217, 218, 194, 194, + /* 1740 */ 194, 194, 194, 101, 194, 217, 218, 290, 194, 107, + /* 1750 */ 108, 194, 183, 217, 218, 194, 194, 115, 194, 117, + /* 1760 */ 118, 119, 194, 243, 122, 194, 289, 194, 194, 194, + /* 1770 */ 194, 257, 257, 257, 244, 257, 192, 273, 215, 269, + /* 1780 */ 246, 299, 269, 295, 247, 273, 247, 246, 295, 230, + /* 1790 */ 261, 226, 261, 261, 273, 273, 154, 155, 156, 157, + /* 1800 */ 158, 0, 1, 2, 221, 220, 5, 220, 250, 220, + /* 1810 */ 261, 10, 11, 12, 13, 14, 250, 282, 17, 197, + /* 1820 */ 61, 19, 20, 246, 22, 183, 244, 142, 201, 201, + /* 1830 */ 38, 30, 299, 32, 201, 152, 22, 151, 36, 299, + /* 1840 */ 43, 40, 235, 18, 238, 285, 238, 238, 296, 238, + /* 1850 */ 201, 296, 274, 272, 18, 200, 235, 150, 235, 247, + /* 1860 */ 247, 247, 60, 247, 274, 274, 272, 201, 200, 159, + /* 1870 */ 63, 292, 71, 201, 72, 200, 22, 201, 222, 200, + /* 1880 */ 79, 201, 222, 82, 291, 116, 219, 65, 200, 219, + /* 1890 */ 219, 228, 22, 127, 225, 166, 222, 24, 225, 114, + /* 1900 */ 99, 284, 221, 101, 284, 228, 307, 315, 219, 107, + /* 1910 */ 108, 219, 219, 219, 201, 92, 320, 115, 320, 117, + /* 1920 */ 118, 119, 222, 83, 122, 267, 267, 149, 146, 19, + /* 1930 */ 20, 22, 22, 279, 250, 134, 201, 148, 159, 249, + /* 1940 */ 139, 140, 251, 141, 25, 281, 36, 147, 251, 248, + /* 1950 */ 247, 203, 13, 195, 6, 195, 154, 155, 156, 157, + /* 1960 */ 158, 193, 305, 193, 163, 193, 305, 302, 214, 208, + /* 1970 */ 60, 214, 208, 223, 223, 4, 214, 214, 3, 22, + /* 1980 */ 215, 214, 72, 208, 164, 183, 215, 15, 23, 16, + /* 1990 */ 23, 140, 131, 152, 25, 143, 20, 16, 24, 1, + /* 2000 */ 145, 143, 131, 131, 62, 37, 54, 54, 152, 54, + /* 2010 */ 54, 101, 131, 117, 34, 1, 142, 107, 108, 22, + /* 2020 */ 5, 116, 162, 69, 25, 115, 76, 117, 118, 119, + /* 2030 */ 1, 2, 122, 69, 5, 41, 142, 116, 20, 10, + /* 2040 */ 11, 12, 13, 14, 24, 19, 17, 132, 5, 126, + /* 2050 */ 22, 141, 68, 10, 11, 12, 13, 14, 22, 30, + /* 2060 */ 17, 32, 22, 22, 154, 155, 156, 157, 158, 40, + /* 2070 */ 23, 68, 60, 30, 24, 32, 97, 28, 22, 68, + /* 2080 */ 23, 37, 34, 40, 150, 22, 25, 23, 23, 23, + /* 2090 */ 22, 98, 23, 183, 23, 117, 34, 22, 25, 89, + /* 2100 */ 71, 142, 144, 76, 34, 23, 34, 76, 79, 87, + /* 2110 */ 34, 82, 34, 94, 71, 34, 22, 24, 44, 34, + /* 2120 */ 25, 25, 79, 23, 23, 82, 143, 23, 99, 143, + /* 2130 */ 23, 22, 11, 25, 23, 25, 22, 22, 22, 1, + /* 2140 */ 23, 23, 99, 136, 22, 22, 142, 142, 142, 25, + /* 2150 */ 25, 23, 15, 1, 322, 322, 322, 322, 322, 322, + /* 2160 */ 322, 322, 322, 134, 322, 322, 322, 322, 139, 140, + /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 134, 322, 322, + /* 2180 */ 322, 322, 139, 140, 322, 322, 322, 322, 322, 322, + /* 2190 */ 322, 322, 163, 322, 322, 322, 322, 322, 322, 322, + /* 2200 */ 322, 322, 322, 322, 322, 322, 163, 322, 322, 322, + /* 2210 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2220 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2230 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2240 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2250 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2260 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2270 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2280 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2290 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2300 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2310 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2330 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2340 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2350 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2360 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2370 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2380 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2390 */ 186, 186, 186, }; -#define YY_SHIFT_COUNT (578) +#define YY_SHIFT_COUNT (582) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2088) +#define YY_SHIFT_MAX (2152) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837, - /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837, - /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 30 */ 1837, 271, 271, 1219, 1219, 216, 88, 1, 1, 1, - /* 40 */ 1, 1, 40, 111, 258, 361, 469, 512, 583, 622, - /* 50 */ 693, 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, - /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - /* 70 */ 1093, 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, - /* 80 */ 1662, 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 130 */ 1837, 137, 181, 181, 181, 181, 181, 181, 181, 94, - /* 140 */ 430, 66, 65, 112, 366, 533, 533, 740, 1257, 533, - /* 150 */ 533, 79, 79, 533, 412, 412, 412, 77, 412, 123, - /* 160 */ 113, 113, 113, 22, 22, 2100, 2100, 328, 328, 328, - /* 170 */ 239, 468, 468, 468, 468, 1015, 1015, 409, 366, 1187, - /* 180 */ 1232, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 200 */ 533, 969, 621, 621, 533, 642, 788, 788, 1133, 1133, - /* 210 */ 822, 822, 67, 1193, 2100, 2100, 2100, 2100, 2100, 2100, - /* 220 */ 2100, 1307, 954, 954, 585, 472, 640, 387, 695, 538, - /* 230 */ 541, 700, 533, 533, 533, 533, 533, 533, 533, 533, - /* 240 */ 533, 533, 222, 533, 533, 533, 533, 533, 533, 533, - /* 250 */ 533, 533, 533, 533, 533, 1213, 1213, 1213, 533, 533, - /* 260 */ 533, 565, 533, 533, 533, 916, 1147, 533, 533, 1288, - /* 270 */ 533, 533, 533, 533, 533, 533, 533, 533, 639, 1280, - /* 280 */ 209, 1129, 1129, 1129, 1129, 580, 209, 209, 1209, 768, - /* 290 */ 917, 649, 1315, 1334, 405, 1334, 1383, 249, 1315, 1315, - /* 300 */ 249, 1315, 405, 1383, 1441, 464, 1245, 1417, 1417, 1417, - /* 310 */ 1323, 1323, 1323, 1323, 184, 184, 1335, 1476, 856, 1482, - /* 320 */ 1744, 1744, 1665, 1665, 1773, 1773, 1665, 1669, 1671, 1802, - /* 330 */ 1782, 1809, 1809, 1809, 1809, 1665, 1817, 1690, 1671, 1671, - /* 340 */ 1690, 1802, 1782, 1690, 1782, 1690, 1665, 1817, 1693, 1791, - /* 350 */ 1665, 1817, 1832, 1665, 1817, 1665, 1817, 1832, 1752, 1752, - /* 360 */ 1752, 1805, 1850, 1850, 1832, 1752, 1749, 1752, 1805, 1752, - /* 370 */ 1752, 1713, 1858, 1775, 1775, 1832, 1665, 1799, 1799, 1823, - /* 380 */ 1823, 1761, 1765, 1890, 1665, 1757, 1761, 1771, 1774, 1690, - /* 390 */ 1894, 1913, 1913, 1929, 1929, 1929, 2100, 2100, 2100, 2100, - /* 400 */ 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, - /* 410 */ 2100, 207, 1220, 331, 620, 967, 806, 1074, 1499, 1432, - /* 420 */ 1463, 1479, 1419, 1422, 1557, 1512, 1598, 1599, 1644, 1645, - /* 430 */ 1654, 1660, 1555, 1505, 1684, 1462, 1670, 1563, 1619, 1593, - /* 440 */ 1676, 1679, 1613, 1680, 1554, 1558, 1689, 1692, 1605, 1589, - /* 450 */ 1955, 1959, 1941, 1803, 1950, 1951, 1945, 1946, 1831, 1820, - /* 460 */ 1842, 1948, 1948, 1952, 1833, 1954, 1834, 1961, 1978, 1838, - /* 470 */ 1851, 1948, 1852, 1922, 1947, 1948, 1836, 1932, 1935, 1936, - /* 480 */ 1942, 1866, 1881, 1964, 1859, 1998, 1996, 1980, 1888, 1843, - /* 490 */ 1937, 1981, 1939, 1933, 1968, 1869, 1896, 1988, 1993, 1995, - /* 500 */ 1884, 1891, 1997, 1953, 1999, 2000, 1994, 2001, 1957, 1966, - /* 510 */ 2002, 1931, 1990, 2006, 1962, 2003, 2007, 2004, 1882, 2010, - /* 520 */ 2011, 2012, 2008, 2013, 2015, 1944, 1898, 2019, 2020, 1928, - /* 530 */ 2014, 2023, 1903, 2022, 2016, 2017, 2018, 2021, 1965, 1974, - /* 540 */ 1970, 2024, 1979, 1967, 2025, 2034, 2036, 2037, 2038, 2039, - /* 550 */ 2028, 1923, 1924, 2044, 2022, 2046, 2047, 2048, 2049, 2050, - /* 560 */ 2051, 2054, 2062, 2055, 2056, 2057, 2058, 2060, 2061, 2059, - /* 570 */ 1956, 1938, 1949, 1958, 2063, 2064, 2070, 2085, 2088, + /* 0 */ 2029, 1801, 2043, 1380, 1380, 33, 391, 1496, 1569, 1642, + /* 10 */ 702, 702, 702, 193, 33, 33, 33, 33, 33, 0, + /* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702, + /* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 406, 406, + /* 40 */ 111, 111, 218, 447, 547, 598, 598, 260, 260, 260, + /* 50 */ 260, 40, 112, 320, 340, 445, 489, 593, 637, 741, + /* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177, + /* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, + /* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554, + /* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702, + /* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198, + /* 150 */ 183, 99, 236, 292, 598, 793, 167, 598, 598, 880, + /* 160 */ 880, 598, 857, 150, 195, 195, 195, 264, 113, 113, + /* 170 */ 2207, 2207, 854, 854, 854, 751, 765, 765, 765, 765, + /* 180 */ 1096, 1096, 725, 292, 882, 904, 598, 598, 598, 598, + /* 190 */ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, + /* 200 */ 598, 598, 598, 598, 598, 1273, 1032, 1032, 598, 147, + /* 210 */ 1098, 1098, 603, 603, 1276, 1276, 363, 2207, 2207, 2207, + /* 220 */ 2207, 2207, 2207, 2207, 469, 617, 617, 801, 336, 461, + /* 230 */ 804, 864, 615, 891, 913, 598, 598, 598, 598, 598, + /* 240 */ 598, 598, 598, 598, 598, 653, 598, 598, 598, 598, + /* 250 */ 598, 598, 598, 598, 598, 598, 598, 598, 1105, 1105, + /* 260 */ 1105, 598, 598, 598, 1194, 598, 598, 598, 1215, 1249, + /* 270 */ 598, 1353, 598, 598, 598, 598, 598, 598, 598, 598, + /* 280 */ 677, 449, 902, 1338, 1338, 1338, 1338, 1248, 902, 902, + /* 290 */ 326, 1151, 1047, 755, 749, 1371, 960, 1371, 1007, 1162, + /* 300 */ 749, 749, 1162, 749, 960, 1007, 1274, 738, 215, 1300, + /* 310 */ 1300, 1300, 1395, 1395, 1395, 1395, 1368, 1368, 1033, 1414, + /* 320 */ 1387, 1361, 1759, 1759, 1685, 1685, 1792, 1792, 1685, 1683, + /* 330 */ 1686, 1814, 1797, 1825, 1825, 1825, 1825, 1685, 1836, 1707, + /* 340 */ 1686, 1686, 1707, 1814, 1797, 1707, 1797, 1707, 1685, 1836, + /* 350 */ 1710, 1807, 1685, 1836, 1854, 1685, 1836, 1685, 1836, 1854, + /* 360 */ 1769, 1769, 1769, 1822, 1870, 1870, 1854, 1769, 1766, 1769, + /* 370 */ 1822, 1769, 1769, 1729, 1873, 1785, 1785, 1854, 1685, 1823, + /* 380 */ 1823, 1840, 1840, 1778, 1782, 1909, 1685, 1779, 1778, 1789, + /* 390 */ 1800, 1707, 1919, 1939, 1939, 1948, 1948, 1948, 2207, 2207, + /* 400 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, + /* 410 */ 2207, 2207, 2207, 69, 1037, 79, 1088, 651, 1196, 1415, + /* 420 */ 1501, 1439, 1369, 1452, 911, 1211, 1524, 1469, 1551, 1567, + /* 430 */ 1570, 1624, 1640, 1644, 1499, 1440, 1572, 1464, 1597, 275, + /* 440 */ 782, 1586, 1648, 1678, 1553, 1682, 1687, 1388, 1502, 1696, + /* 450 */ 1706, 1588, 1486, 1971, 1975, 1957, 1820, 1972, 1973, 1965, + /* 460 */ 1967, 1851, 1841, 1861, 1969, 1969, 1974, 1852, 1976, 1855, + /* 470 */ 1981, 1998, 1858, 1871, 1969, 1872, 1942, 1968, 1969, 1856, + /* 480 */ 1952, 1953, 1955, 1956, 1881, 1896, 1980, 1874, 2014, 2015, + /* 490 */ 1997, 1905, 1860, 1954, 1999, 1964, 1950, 1994, 1894, 1921, + /* 500 */ 2020, 2018, 2026, 1915, 1923, 2028, 1984, 2036, 2040, 2047, + /* 510 */ 2041, 2003, 2012, 2050, 1979, 2049, 2056, 2011, 2044, 2057, + /* 520 */ 2048, 1934, 2063, 2064, 2065, 2061, 2066, 2068, 1993, 1959, + /* 530 */ 2069, 2071, 1978, 2062, 2075, 1958, 2073, 2070, 2072, 2076, + /* 540 */ 2078, 2010, 2027, 2022, 2074, 2031, 2019, 2081, 2082, 2094, + /* 550 */ 2093, 2095, 2096, 2085, 1983, 1986, 2100, 2073, 2101, 2104, + /* 560 */ 2107, 2109, 2108, 2110, 2111, 2114, 2121, 2115, 2116, 2117, + /* 570 */ 2118, 2122, 2123, 2124, 2007, 2004, 2005, 2006, 2125, 2128, + /* 580 */ 2137, 2138, 2152, }; -#define YY_REDUCE_COUNT (410) -#define YY_REDUCE_MIN (-271) -#define YY_REDUCE_MAX (1753) +#define YY_REDUCE_COUNT (412) +#define YY_REDUCE_MIN (-276) +#define YY_REDUCE_MAX (1775) static const short yy_reduce_ofst[] = { - /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187, - /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489, - /* 20 */ 576, 598, -175, 686, 860, 615, 725, 1014, 778, 781, - /* 30 */ 857, 616, 887, 87, 240, -192, 408, 626, 796, 843, - /* 40 */ 854, 1004, -271, -271, -271, -271, -271, -271, -271, -271, - /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, 80, - /* 80 */ 83, 313, 886, 888, 918, 938, 1021, 1034, 1036, 1141, - /* 90 */ 1159, 1163, 1166, 1168, 1170, 1176, 1178, 1180, 1184, 1196, - /* 100 */ 1198, 1205, 1215, 1225, 1227, 1236, 1252, 1254, 1264, 1303, - /* 110 */ 1309, 1312, 1322, 1325, 1328, 1337, 1340, 1343, 1353, 1371, - /* 120 */ 1373, 1384, 1386, 1411, 1413, 1420, 1424, 1426, 1458, 1470, - /* 130 */ 1473, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 140 */ -271, -271, 138, 459, 396, -158, 470, 302, -212, 521, - /* 150 */ 201, -195, -92, 559, 630, 632, 630, -271, 632, 901, - /* 160 */ 63, 407, 670, -271, -271, -271, -271, 161, 161, 161, - /* 170 */ 251, 335, 847, 979, 1097, 537, 588, 618, 628, 688, - /* 180 */ 688, -166, -161, 674, 787, 794, 799, 852, 996, -122, - /* 190 */ 837, -120, 1018, 1035, 415, 1047, 1001, 958, 1082, 400, - /* 200 */ 1099, 779, 1137, 1142, 263, 1083, 1145, 1150, 1041, 1139, - /* 210 */ 965, 1050, 362, 849, 752, 629, 675, 1162, 1173, 1090, - /* 220 */ 1195, -194, 56, 185, -135, 232, 522, 560, 571, 601, - /* 230 */ 617, 669, 683, 711, 850, 893, 1000, 1040, 1049, 1081, - /* 240 */ 1087, 1101, 392, 1114, 1123, 1155, 1161, 1175, 1271, 1293, - /* 250 */ 1299, 1330, 1339, 1342, 1347, 593, 1282, 1286, 1350, 1359, - /* 260 */ 1368, 1314, 1480, 1483, 1507, 1085, 1338, 1526, 1527, 1487, - /* 270 */ 1531, 560, 1532, 1534, 1535, 1538, 1539, 1541, 1448, 1450, - /* 280 */ 1496, 1484, 1485, 1489, 1490, 1314, 1496, 1496, 1504, 1536, - /* 290 */ 1564, 1451, 1486, 1492, 1509, 1493, 1465, 1515, 1494, 1495, - /* 300 */ 1517, 1500, 1519, 1474, 1550, 1543, 1548, 1556, 1565, 1566, - /* 310 */ 1518, 1523, 1542, 1544, 1525, 1545, 1513, 1553, 1552, 1604, - /* 320 */ 1508, 1510, 1608, 1609, 1520, 1528, 1612, 1540, 1559, 1560, - /* 330 */ 1592, 1591, 1595, 1596, 1597, 1629, 1638, 1594, 1569, 1570, - /* 340 */ 1600, 1568, 1610, 1601, 1611, 1603, 1643, 1651, 1562, 1571, - /* 350 */ 1655, 1659, 1640, 1663, 1666, 1664, 1667, 1641, 1650, 1652, - /* 360 */ 1653, 1647, 1656, 1657, 1658, 1668, 1672, 1681, 1649, 1682, - /* 370 */ 1683, 1573, 1582, 1607, 1615, 1685, 1702, 1586, 1587, 1642, - /* 380 */ 1646, 1673, 1675, 1636, 1714, 1637, 1677, 1674, 1678, 1694, - /* 390 */ 1719, 1734, 1735, 1746, 1747, 1750, 1633, 1661, 1686, 1738, - /* 400 */ 1728, 1733, 1736, 1737, 1740, 1726, 1730, 1742, 1743, 1748, - /* 410 */ 1753, + /* 0 */ -66, 217, -63, -177, -180, 161, 364, 64, -183, 162, + /* 10 */ 223, 367, 414, -173, 473, 514, 525, 622, 626, -207, + /* 20 */ 351, -276, -38, 693, 811, 831, 833, 888, -188, 945, + /* 30 */ 947, 416, 558, 951, 867, 287, 1078, 1080, -186, 224, + /* 40 */ -132, 42, 964, 269, 417, 796, 810, -237, -231, -237, + /* 50 */ -231, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 60 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 70 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 80 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, 895, + /* 90 */ 925, 967, 980, 1100, 1143, 1169, 1203, 1225, 1228, 1242, + /* 100 */ 1247, 1250, 1253, 1255, 1261, 1267, 1272, 1275, 1283, 1286, + /* 110 */ 1288, 1292, 1333, 1335, 1347, 1349, 1352, 1354, 1360, 1366, + /* 120 */ 1381, 1391, 1406, 1408, 1413, 1416, 1418, 1422, 1425, 1427, + /* 130 */ 1463, 1465, 1472, 1478, 1480, 1491, 1498, 1500, 1517, 1519, + /* 140 */ 1528, 1536, -45, -45, -45, -45, -45, -45, -45, -45, + /* 150 */ -45, -45, -45, 312, -158, 285, -219, 9, 166, 370, + /* 160 */ 545, 707, -45, 930, 601, 963, 1067, 792, -45, -45, + /* 170 */ -45, -45, -204, -204, -204, 369, -171, -129, 632, 678, + /* 180 */ 202, 352, -270, 412, 627, 627, -9, 122, 415, 419, + /* 190 */ -56, 248, 583, 920, 6, 261, 459, 795, 1049, 813, + /* 200 */ 1062, 1082, -161, 778, 1063, 797, 870, 1003, 1128, 443, + /* 210 */ 1031, 1072, 1191, 1192, 957, 1120, 105, 1149, 523, 933, + /* 220 */ 1218, 1238, 1254, 1251, -138, 96, 117, 146, 181, 277, + /* 230 */ 280, 421, 480, 712, 830, 850, 1085, 1099, 1129, 1209, + /* 240 */ 1323, 1331, 1336, 1364, 1407, 368, 1412, 1433, 1438, 1474, + /* 250 */ 1481, 1505, 1506, 1526, 1538, 1544, 1545, 1546, 722, 764, + /* 260 */ 856, 1547, 1548, 1550, 1188, 1554, 1557, 1561, 1298, 1260, + /* 270 */ 1562, 1456, 1564, 280, 1568, 1571, 1573, 1574, 1575, 1576, + /* 280 */ 1457, 1477, 1520, 1514, 1515, 1516, 1518, 1188, 1520, 1520, + /* 290 */ 1530, 1563, 1584, 1482, 1504, 1510, 1534, 1513, 1488, 1537, + /* 300 */ 1512, 1521, 1539, 1522, 1541, 1493, 1583, 1559, 1565, 1585, + /* 310 */ 1587, 1589, 1529, 1531, 1532, 1549, 1558, 1566, 1535, 1577, + /* 320 */ 1582, 1622, 1533, 1540, 1627, 1628, 1552, 1555, 1633, 1560, + /* 330 */ 1578, 1581, 1607, 1606, 1608, 1609, 1611, 1649, 1655, 1612, + /* 340 */ 1590, 1591, 1613, 1594, 1621, 1614, 1623, 1616, 1666, 1668, + /* 350 */ 1579, 1593, 1672, 1675, 1656, 1676, 1679, 1680, 1688, 1660, + /* 360 */ 1667, 1670, 1671, 1663, 1669, 1673, 1674, 1689, 1681, 1692, + /* 370 */ 1677, 1693, 1694, 1592, 1599, 1617, 1620, 1700, 1713, 1596, + /* 380 */ 1598, 1658, 1659, 1691, 1684, 1654, 1735, 1664, 1697, 1690, + /* 390 */ 1701, 1703, 1748, 1758, 1760, 1768, 1770, 1772, 1657, 1661, + /* 400 */ 1665, 1761, 1754, 1757, 1762, 1763, 1764, 1750, 1751, 1765, + /* 410 */ 1771, 1767, 1775, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1648, 1648, 1648, 1478, 1243, 1354, 1243, 1243, 1243, 1478, - /* 10 */ 1478, 1478, 1243, 1384, 1384, 1531, 1276, 1243, 1243, 1243, - /* 20 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1477, 1243, - /* 30 */ 1243, 1243, 1243, 1564, 1564, 1243, 1243, 1243, 1243, 1243, - /* 40 */ 1243, 1243, 1243, 1393, 1243, 1400, 1243, 1243, 1243, 1243, - /* 50 */ 1243, 1479, 1480, 1243, 1243, 1243, 1530, 1532, 1495, 1407, - /* 60 */ 1406, 1405, 1404, 1513, 1372, 1398, 1391, 1395, 1474, 1475, - /* 70 */ 1473, 1626, 1480, 1479, 1243, 1394, 1442, 1458, 1441, 1243, - /* 80 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 90 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 100 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 110 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 120 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 130 */ 1243, 1450, 1457, 1456, 1455, 1464, 1454, 1451, 1444, 1443, - /* 140 */ 1445, 1446, 1243, 1243, 1267, 1243, 1243, 1264, 1318, 1243, - /* 150 */ 1243, 1243, 1243, 1243, 1550, 1549, 1243, 1447, 1243, 1276, - /* 160 */ 1435, 1434, 1433, 1461, 1448, 1460, 1459, 1538, 1600, 1599, - /* 170 */ 1496, 1243, 1243, 1243, 1243, 1243, 1243, 1564, 1243, 1243, - /* 180 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 190 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 200 */ 1243, 1374, 1564, 1564, 1243, 1276, 1564, 1564, 1375, 1375, - /* 210 */ 1272, 1272, 1378, 1243, 1545, 1345, 1345, 1345, 1345, 1354, - /* 220 */ 1345, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 230 */ 1243, 1243, 1243, 1243, 1243, 1243, 1535, 1533, 1243, 1243, - /* 240 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 250 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 260 */ 1243, 1243, 1243, 1243, 1243, 1350, 1243, 1243, 1243, 1243, - /* 270 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1593, 1243, 1508, - /* 280 */ 1332, 1350, 1350, 1350, 1350, 1352, 1333, 1331, 1344, 1277, - /* 290 */ 1250, 1640, 1410, 1399, 1351, 1399, 1637, 1397, 1410, 1410, - /* 300 */ 1397, 1410, 1351, 1637, 1293, 1615, 1288, 1384, 1384, 1384, - /* 310 */ 1374, 1374, 1374, 1374, 1378, 1378, 1476, 1351, 1344, 1243, - /* 320 */ 1640, 1640, 1360, 1360, 1639, 1639, 1360, 1496, 1623, 1419, - /* 330 */ 1321, 1327, 1327, 1327, 1327, 1360, 1261, 1397, 1623, 1623, - /* 340 */ 1397, 1419, 1321, 1397, 1321, 1397, 1360, 1261, 1512, 1634, - /* 350 */ 1360, 1261, 1486, 1360, 1261, 1360, 1261, 1486, 1319, 1319, - /* 360 */ 1319, 1308, 1243, 1243, 1486, 1319, 1293, 1319, 1308, 1319, - /* 370 */ 1319, 1582, 1243, 1490, 1490, 1486, 1360, 1574, 1574, 1387, - /* 380 */ 1387, 1392, 1378, 1481, 1360, 1243, 1392, 1390, 1388, 1397, - /* 390 */ 1311, 1596, 1596, 1592, 1592, 1592, 1645, 1645, 1545, 1608, - /* 400 */ 1276, 1276, 1276, 1276, 1608, 1295, 1295, 1277, 1277, 1276, - /* 410 */ 1608, 1243, 1243, 1243, 1243, 1243, 1243, 1603, 1243, 1540, - /* 420 */ 1497, 1364, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 430 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1551, 1243, - /* 440 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1424, - /* 450 */ 1243, 1246, 1542, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 460 */ 1243, 1401, 1402, 1365, 1243, 1243, 1243, 1243, 1243, 1243, - /* 470 */ 1243, 1416, 1243, 1243, 1243, 1411, 1243, 1243, 1243, 1243, - /* 480 */ 1243, 1243, 1243, 1243, 1636, 1243, 1243, 1243, 1243, 1243, - /* 490 */ 1243, 1511, 1510, 1243, 1243, 1362, 1243, 1243, 1243, 1243, - /* 500 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1291, - /* 510 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 520 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, - /* 530 */ 1243, 1243, 1243, 1389, 1243, 1243, 1243, 1243, 1243, 1243, - /* 540 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1579, 1379, - /* 550 */ 1243, 1243, 1243, 1243, 1627, 1243, 1243, 1243, 1243, 1243, - /* 560 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1619, - /* 570 */ 1335, 1425, 1243, 1428, 1265, 1243, 1255, 1243, 1243, + /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254, + /* 10 */ 1491, 1491, 1491, 1254, 1254, 1254, 1254, 1254, 1254, 1397, + /* 20 */ 1397, 1544, 1287, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254, + /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254, + /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254, + /* 60 */ 1492, 1493, 1254, 1254, 1254, 1254, 1543, 1545, 1508, 1420, + /* 70 */ 1419, 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, + /* 80 */ 1486, 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, + /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 140 */ 1254, 1254, 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, + /* 150 */ 1456, 1458, 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, + /* 160 */ 1254, 1254, 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, + /* 170 */ 1473, 1472, 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, + /* 180 */ 1254, 1254, 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 200 */ 1254, 1254, 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, + /* 210 */ 1578, 1578, 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, + /* 220 */ 1358, 1358, 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, + /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, + /* 240 */ 1546, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, + /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, + /* 280 */ 1254, 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, + /* 290 */ 1357, 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, + /* 300 */ 1423, 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, + /* 310 */ 1397, 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, + /* 320 */ 1357, 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, + /* 330 */ 1638, 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, + /* 340 */ 1638, 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, + /* 350 */ 1525, 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, + /* 360 */ 1330, 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, + /* 370 */ 1319, 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, + /* 380 */ 1588, 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, + /* 390 */ 1401, 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, + /* 400 */ 1558, 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, + /* 410 */ 1288, 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, + /* 420 */ 1254, 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, + /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 440 */ 1564, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 450 */ 1254, 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, + /* 460 */ 1254, 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, + /* 470 */ 1254, 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, + /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, + /* 490 */ 1254, 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, + /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 510 */ 1254, 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 530 */ 1254, 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, + /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 550 */ 1254, 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, + /* 560 */ 1254, 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254, + /* 580 */ 1266, 1254, 1254, }; /********** End of lemon-generated parsing tables *****************************/ @@ -171634,52 +175237,53 @@ static const YYACTIONTYPE yy_default[] = { static const YYCODETYPE yyFallback[] = { 0, /* $ => nothing */ 0, /* SEMI => nothing */ - 59, /* EXPLAIN => ID */ - 59, /* QUERY => ID */ - 59, /* PLAN => ID */ - 59, /* BEGIN => ID */ + 60, /* EXPLAIN => ID */ + 60, /* QUERY => ID */ + 60, /* PLAN => ID */ + 60, /* BEGIN => ID */ 0, /* TRANSACTION => nothing */ - 59, /* DEFERRED => ID */ - 59, /* IMMEDIATE => ID */ - 59, /* EXCLUSIVE => ID */ + 60, /* DEFERRED => ID */ + 60, /* IMMEDIATE => ID */ + 60, /* EXCLUSIVE => ID */ 0, /* COMMIT => nothing */ - 59, /* END => ID */ - 59, /* ROLLBACK => ID */ - 59, /* SAVEPOINT => ID */ - 59, /* RELEASE => ID */ + 60, /* END => ID */ + 60, /* ROLLBACK => ID */ + 60, /* SAVEPOINT => ID */ + 60, /* RELEASE => ID */ 0, /* TO => nothing */ 0, /* TABLE => nothing */ 0, /* CREATE => nothing */ - 59, /* IF => ID */ + 60, /* IF => ID */ 0, /* NOT => nothing */ 0, /* EXISTS => nothing */ - 59, /* TEMP => ID */ + 60, /* TEMP => ID */ 0, /* LP => nothing */ 0, /* RP => nothing */ 0, /* AS => nothing */ 0, /* COMMA => nothing */ - 59, /* WITHOUT => ID */ - 59, /* ABORT => ID */ - 59, /* ACTION => ID */ - 59, /* AFTER => ID */ - 59, /* ANALYZE => ID */ - 59, /* ASC => ID */ - 59, /* ATTACH => ID */ - 59, /* BEFORE => ID */ - 59, /* BY => ID */ - 59, /* CASCADE => ID */ - 59, /* CAST => ID */ - 59, /* CONFLICT => ID */ - 59, /* DATABASE => ID */ - 59, /* DESC => ID */ - 59, /* DETACH => ID */ - 59, /* EACH => ID */ - 59, /* FAIL => ID */ + 60, /* WITHOUT => ID */ + 60, /* ABORT => ID */ + 60, /* ACTION => ID */ + 60, /* AFTER => ID */ + 60, /* ANALYZE => ID */ + 60, /* ASC => ID */ + 60, /* ATTACH => ID */ + 60, /* BEFORE => ID */ + 60, /* BY => ID */ + 60, /* CASCADE => ID */ + 60, /* CAST => ID */ + 60, /* CONFLICT => ID */ + 60, /* DATABASE => ID */ + 60, /* DESC => ID */ + 60, /* DETACH => ID */ + 60, /* EACH => ID */ + 60, /* FAIL => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* IS => nothing */ - 59, /* MATCH => ID */ - 59, /* LIKE_KW => ID */ + 0, /* ISNOT => nothing */ + 60, /* MATCH => ID */ + 60, /* LIKE_KW => ID */ 0, /* BETWEEN => nothing */ 0, /* IN => nothing */ 0, /* ISNULL => nothing */ @@ -171692,47 +175296,47 @@ static const YYCODETYPE yyFallback[] = { 0, /* GE => nothing */ 0, /* ESCAPE => nothing */ 0, /* ID => nothing */ - 59, /* COLUMNKW => ID */ - 59, /* DO => ID */ - 59, /* FOR => ID */ - 59, /* IGNORE => ID */ - 59, /* INITIALLY => ID */ - 59, /* INSTEAD => ID */ - 59, /* NO => ID */ - 59, /* KEY => ID */ - 59, /* OF => ID */ - 59, /* OFFSET => ID */ - 59, /* PRAGMA => ID */ - 59, /* RAISE => ID */ - 59, /* RECURSIVE => ID */ - 59, /* REPLACE => ID */ - 59, /* RESTRICT => ID */ - 59, /* ROW => ID */ - 59, /* ROWS => ID */ - 59, /* TRIGGER => ID */ - 59, /* VACUUM => ID */ - 59, /* VIEW => ID */ - 59, /* VIRTUAL => ID */ - 59, /* WITH => ID */ - 59, /* NULLS => ID */ - 59, /* FIRST => ID */ - 59, /* LAST => ID */ - 59, /* CURRENT => ID */ - 59, /* FOLLOWING => ID */ - 59, /* PARTITION => ID */ - 59, /* PRECEDING => ID */ - 59, /* RANGE => ID */ - 59, /* UNBOUNDED => ID */ - 59, /* EXCLUDE => ID */ - 59, /* GROUPS => ID */ - 59, /* OTHERS => ID */ - 59, /* TIES => ID */ - 59, /* GENERATED => ID */ - 59, /* ALWAYS => ID */ - 59, /* MATERIALIZED => ID */ - 59, /* REINDEX => ID */ - 59, /* RENAME => ID */ - 59, /* CTIME_KW => ID */ + 60, /* COLUMNKW => ID */ + 60, /* DO => ID */ + 60, /* FOR => ID */ + 60, /* IGNORE => ID */ + 60, /* INITIALLY => ID */ + 60, /* INSTEAD => ID */ + 60, /* NO => ID */ + 60, /* KEY => ID */ + 60, /* OF => ID */ + 60, /* OFFSET => ID */ + 60, /* PRAGMA => ID */ + 60, /* RAISE => ID */ + 60, /* RECURSIVE => ID */ + 60, /* REPLACE => ID */ + 60, /* RESTRICT => ID */ + 60, /* ROW => ID */ + 60, /* ROWS => ID */ + 60, /* TRIGGER => ID */ + 60, /* VACUUM => ID */ + 60, /* VIEW => ID */ + 60, /* VIRTUAL => ID */ + 60, /* WITH => ID */ + 60, /* NULLS => ID */ + 60, /* FIRST => ID */ + 60, /* LAST => ID */ + 60, /* CURRENT => ID */ + 60, /* FOLLOWING => ID */ + 60, /* PARTITION => ID */ + 60, /* PRECEDING => ID */ + 60, /* RANGE => ID */ + 60, /* UNBOUNDED => ID */ + 60, /* EXCLUDE => ID */ + 60, /* GROUPS => ID */ + 60, /* OTHERS => ID */ + 60, /* TIES => ID */ + 60, /* GENERATED => ID */ + 60, /* ALWAYS => ID */ + 60, /* MATERIALIZED => ID */ + 60, /* REINDEX => ID */ + 60, /* RENAME => ID */ + 60, /* CTIME_KW => ID */ 0, /* ANY => nothing */ 0, /* BITAND => nothing */ 0, /* BITOR => nothing */ @@ -171803,10 +175407,9 @@ static const YYCODETYPE yyFallback[] = { 0, /* AGG_FUNCTION => nothing */ 0, /* AGG_COLUMN => nothing */ 0, /* TRUEFALSE => nothing */ - 0, /* ISNOT => nothing */ 0, /* FUNCTION => nothing */ - 0, /* UMINUS => nothing */ 0, /* UPLUS => nothing */ + 0, /* UMINUS => nothing */ 0, /* TRUTH => nothing */ 0, /* REGISTER => nothing */ 0, /* VECTOR => nothing */ @@ -171815,6 +175418,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* ASTERISK => nothing */ 0, /* SPAN => nothing */ 0, /* ERROR => nothing */ + 0, /* QNUMBER => nothing */ 0, /* SPACE => nothing */ 0, /* ILLEGAL => nothing */ }; @@ -171857,14 +175461,9 @@ struct yyParser { #endif sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ sqlite3ParserCTX_SDECL /* A place to hold %extra_context */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ - yyStackEntry yystk0; /* First stack entry */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ - yyStackEntry *yystackEnd; /* Last entry in the stack */ -#endif + yyStackEntry *yystackEnd; /* Last entry in the stack */ + yyStackEntry *yystack; /* The parser stack */ + yyStackEntry yystk0[YYSTACKDEPTH]; /* Initial stack space */ }; typedef struct yyParser yyParser; @@ -171951,135 +175550,135 @@ static const char *const yyTokenName[] = { /* 43 */ "OR", /* 44 */ "AND", /* 45 */ "IS", - /* 46 */ "MATCH", - /* 47 */ "LIKE_KW", - /* 48 */ "BETWEEN", - /* 49 */ "IN", - /* 50 */ "ISNULL", - /* 51 */ "NOTNULL", - /* 52 */ "NE", - /* 53 */ "EQ", - /* 54 */ "GT", - /* 55 */ "LE", - /* 56 */ "LT", - /* 57 */ "GE", - /* 58 */ "ESCAPE", - /* 59 */ "ID", - /* 60 */ "COLUMNKW", - /* 61 */ "DO", - /* 62 */ "FOR", - /* 63 */ "IGNORE", - /* 64 */ "INITIALLY", - /* 65 */ "INSTEAD", - /* 66 */ "NO", - /* 67 */ "KEY", - /* 68 */ "OF", - /* 69 */ "OFFSET", - /* 70 */ "PRAGMA", - /* 71 */ "RAISE", - /* 72 */ "RECURSIVE", - /* 73 */ "REPLACE", - /* 74 */ "RESTRICT", - /* 75 */ "ROW", - /* 76 */ "ROWS", - /* 77 */ "TRIGGER", - /* 78 */ "VACUUM", - /* 79 */ "VIEW", - /* 80 */ "VIRTUAL", - /* 81 */ "WITH", - /* 82 */ "NULLS", - /* 83 */ "FIRST", - /* 84 */ "LAST", - /* 85 */ "CURRENT", - /* 86 */ "FOLLOWING", - /* 87 */ "PARTITION", - /* 88 */ "PRECEDING", - /* 89 */ "RANGE", - /* 90 */ "UNBOUNDED", - /* 91 */ "EXCLUDE", - /* 92 */ "GROUPS", - /* 93 */ "OTHERS", - /* 94 */ "TIES", - /* 95 */ "GENERATED", - /* 96 */ "ALWAYS", - /* 97 */ "MATERIALIZED", - /* 98 */ "REINDEX", - /* 99 */ "RENAME", - /* 100 */ "CTIME_KW", - /* 101 */ "ANY", - /* 102 */ "BITAND", - /* 103 */ "BITOR", - /* 104 */ "LSHIFT", - /* 105 */ "RSHIFT", - /* 106 */ "PLUS", - /* 107 */ "MINUS", - /* 108 */ "STAR", - /* 109 */ "SLASH", - /* 110 */ "REM", - /* 111 */ "CONCAT", - /* 112 */ "PTR", - /* 113 */ "COLLATE", - /* 114 */ "BITNOT", - /* 115 */ "ON", - /* 116 */ "INDEXED", - /* 117 */ "STRING", - /* 118 */ "JOIN_KW", - /* 119 */ "CONSTRAINT", - /* 120 */ "DEFAULT", - /* 121 */ "NULL", - /* 122 */ "PRIMARY", - /* 123 */ "UNIQUE", - /* 124 */ "CHECK", - /* 125 */ "REFERENCES", - /* 126 */ "AUTOINCR", - /* 127 */ "INSERT", - /* 128 */ "DELETE", - /* 129 */ "UPDATE", - /* 130 */ "SET", - /* 131 */ "DEFERRABLE", - /* 132 */ "FOREIGN", - /* 133 */ "DROP", - /* 134 */ "UNION", - /* 135 */ "ALL", - /* 136 */ "EXCEPT", - /* 137 */ "INTERSECT", - /* 138 */ "SELECT", - /* 139 */ "VALUES", - /* 140 */ "DISTINCT", - /* 141 */ "DOT", - /* 142 */ "FROM", - /* 143 */ "JOIN", - /* 144 */ "USING", - /* 145 */ "ORDER", - /* 146 */ "GROUP", - /* 147 */ "HAVING", - /* 148 */ "LIMIT", - /* 149 */ "WHERE", - /* 150 */ "RETURNING", - /* 151 */ "INTO", - /* 152 */ "NOTHING", - /* 153 */ "FLOAT", - /* 154 */ "BLOB", - /* 155 */ "INTEGER", - /* 156 */ "VARIABLE", - /* 157 */ "CASE", - /* 158 */ "WHEN", - /* 159 */ "THEN", - /* 160 */ "ELSE", - /* 161 */ "INDEX", - /* 162 */ "ALTER", - /* 163 */ "ADD", - /* 164 */ "WINDOW", - /* 165 */ "OVER", - /* 166 */ "FILTER", - /* 167 */ "COLUMN", - /* 168 */ "AGG_FUNCTION", - /* 169 */ "AGG_COLUMN", - /* 170 */ "TRUEFALSE", - /* 171 */ "ISNOT", + /* 46 */ "ISNOT", + /* 47 */ "MATCH", + /* 48 */ "LIKE_KW", + /* 49 */ "BETWEEN", + /* 50 */ "IN", + /* 51 */ "ISNULL", + /* 52 */ "NOTNULL", + /* 53 */ "NE", + /* 54 */ "EQ", + /* 55 */ "GT", + /* 56 */ "LE", + /* 57 */ "LT", + /* 58 */ "GE", + /* 59 */ "ESCAPE", + /* 60 */ "ID", + /* 61 */ "COLUMNKW", + /* 62 */ "DO", + /* 63 */ "FOR", + /* 64 */ "IGNORE", + /* 65 */ "INITIALLY", + /* 66 */ "INSTEAD", + /* 67 */ "NO", + /* 68 */ "KEY", + /* 69 */ "OF", + /* 70 */ "OFFSET", + /* 71 */ "PRAGMA", + /* 72 */ "RAISE", + /* 73 */ "RECURSIVE", + /* 74 */ "REPLACE", + /* 75 */ "RESTRICT", + /* 76 */ "ROW", + /* 77 */ "ROWS", + /* 78 */ "TRIGGER", + /* 79 */ "VACUUM", + /* 80 */ "VIEW", + /* 81 */ "VIRTUAL", + /* 82 */ "WITH", + /* 83 */ "NULLS", + /* 84 */ "FIRST", + /* 85 */ "LAST", + /* 86 */ "CURRENT", + /* 87 */ "FOLLOWING", + /* 88 */ "PARTITION", + /* 89 */ "PRECEDING", + /* 90 */ "RANGE", + /* 91 */ "UNBOUNDED", + /* 92 */ "EXCLUDE", + /* 93 */ "GROUPS", + /* 94 */ "OTHERS", + /* 95 */ "TIES", + /* 96 */ "GENERATED", + /* 97 */ "ALWAYS", + /* 98 */ "MATERIALIZED", + /* 99 */ "REINDEX", + /* 100 */ "RENAME", + /* 101 */ "CTIME_KW", + /* 102 */ "ANY", + /* 103 */ "BITAND", + /* 104 */ "BITOR", + /* 105 */ "LSHIFT", + /* 106 */ "RSHIFT", + /* 107 */ "PLUS", + /* 108 */ "MINUS", + /* 109 */ "STAR", + /* 110 */ "SLASH", + /* 111 */ "REM", + /* 112 */ "CONCAT", + /* 113 */ "PTR", + /* 114 */ "COLLATE", + /* 115 */ "BITNOT", + /* 116 */ "ON", + /* 117 */ "INDEXED", + /* 118 */ "STRING", + /* 119 */ "JOIN_KW", + /* 120 */ "CONSTRAINT", + /* 121 */ "DEFAULT", + /* 122 */ "NULL", + /* 123 */ "PRIMARY", + /* 124 */ "UNIQUE", + /* 125 */ "CHECK", + /* 126 */ "REFERENCES", + /* 127 */ "AUTOINCR", + /* 128 */ "INSERT", + /* 129 */ "DELETE", + /* 130 */ "UPDATE", + /* 131 */ "SET", + /* 132 */ "DEFERRABLE", + /* 133 */ "FOREIGN", + /* 134 */ "DROP", + /* 135 */ "UNION", + /* 136 */ "ALL", + /* 137 */ "EXCEPT", + /* 138 */ "INTERSECT", + /* 139 */ "SELECT", + /* 140 */ "VALUES", + /* 141 */ "DISTINCT", + /* 142 */ "DOT", + /* 143 */ "FROM", + /* 144 */ "JOIN", + /* 145 */ "USING", + /* 146 */ "ORDER", + /* 147 */ "GROUP", + /* 148 */ "HAVING", + /* 149 */ "LIMIT", + /* 150 */ "WHERE", + /* 151 */ "RETURNING", + /* 152 */ "INTO", + /* 153 */ "NOTHING", + /* 154 */ "FLOAT", + /* 155 */ "BLOB", + /* 156 */ "INTEGER", + /* 157 */ "VARIABLE", + /* 158 */ "CASE", + /* 159 */ "WHEN", + /* 160 */ "THEN", + /* 161 */ "ELSE", + /* 162 */ "INDEX", + /* 163 */ "ALTER", + /* 164 */ "ADD", + /* 165 */ "WINDOW", + /* 166 */ "OVER", + /* 167 */ "FILTER", + /* 168 */ "COLUMN", + /* 169 */ "AGG_FUNCTION", + /* 170 */ "AGG_COLUMN", + /* 171 */ "TRUEFALSE", /* 172 */ "FUNCTION", - /* 173 */ "UMINUS", - /* 174 */ "UPLUS", + /* 173 */ "UPLUS", + /* 174 */ "UMINUS", /* 175 */ "TRUTH", /* 176 */ "REGISTER", /* 177 */ "VECTOR", @@ -172088,142 +175687,145 @@ static const char *const yyTokenName[] = { /* 180 */ "ASTERISK", /* 181 */ "SPAN", /* 182 */ "ERROR", - /* 183 */ "SPACE", - /* 184 */ "ILLEGAL", - /* 185 */ "input", - /* 186 */ "cmdlist", - /* 187 */ "ecmd", - /* 188 */ "cmdx", - /* 189 */ "explain", - /* 190 */ "cmd", - /* 191 */ "transtype", - /* 192 */ "trans_opt", - /* 193 */ "nm", - /* 194 */ "savepoint_opt", - /* 195 */ "create_table", - /* 196 */ "create_table_args", - /* 197 */ "createkw", - /* 198 */ "temp", - /* 199 */ "ifnotexists", - /* 200 */ "dbnm", - /* 201 */ "columnlist", - /* 202 */ "conslist_opt", - /* 203 */ "table_option_set", - /* 204 */ "select", - /* 205 */ "table_option", - /* 206 */ "columnname", - /* 207 */ "carglist", - /* 208 */ "typetoken", - /* 209 */ "typename", - /* 210 */ "signed", - /* 211 */ "plus_num", - /* 212 */ "minus_num", - /* 213 */ "scanpt", - /* 214 */ "scantok", - /* 215 */ "ccons", - /* 216 */ "term", - /* 217 */ "expr", - /* 218 */ "onconf", - /* 219 */ "sortorder", - /* 220 */ "autoinc", - /* 221 */ "eidlist_opt", - /* 222 */ "refargs", - /* 223 */ "defer_subclause", - /* 224 */ "generated", - /* 225 */ "refarg", - /* 226 */ "refact", - /* 227 */ "init_deferred_pred_opt", - /* 228 */ "conslist", - /* 229 */ "tconscomma", - /* 230 */ "tcons", - /* 231 */ "sortlist", - /* 232 */ "eidlist", - /* 233 */ "defer_subclause_opt", - /* 234 */ "orconf", - /* 235 */ "resolvetype", - /* 236 */ "raisetype", - /* 237 */ "ifexists", - /* 238 */ "fullname", - /* 239 */ "selectnowith", - /* 240 */ "oneselect", - /* 241 */ "wqlist", - /* 242 */ "multiselect_op", - /* 243 */ "distinct", - /* 244 */ "selcollist", - /* 245 */ "from", - /* 246 */ "where_opt", - /* 247 */ "groupby_opt", - /* 248 */ "having_opt", - /* 249 */ "orderby_opt", - /* 250 */ "limit_opt", - /* 251 */ "window_clause", - /* 252 */ "values", - /* 253 */ "nexprlist", - /* 254 */ "sclp", - /* 255 */ "as", - /* 256 */ "seltablist", - /* 257 */ "stl_prefix", - /* 258 */ "joinop", - /* 259 */ "on_using", - /* 260 */ "indexed_by", - /* 261 */ "exprlist", - /* 262 */ "xfullname", - /* 263 */ "idlist", - /* 264 */ "indexed_opt", - /* 265 */ "nulls", - /* 266 */ "with", - /* 267 */ "where_opt_ret", - /* 268 */ "setlist", - /* 269 */ "insert_cmd", - /* 270 */ "idlist_opt", - /* 271 */ "upsert", - /* 272 */ "returning", - /* 273 */ "filter_over", - /* 274 */ "likeop", - /* 275 */ "between_op", - /* 276 */ "in_op", - /* 277 */ "paren_exprlist", - /* 278 */ "case_operand", - /* 279 */ "case_exprlist", - /* 280 */ "case_else", - /* 281 */ "uniqueflag", - /* 282 */ "collate", - /* 283 */ "vinto", - /* 284 */ "nmnum", - /* 285 */ "trigger_decl", - /* 286 */ "trigger_cmd_list", - /* 287 */ "trigger_time", - /* 288 */ "trigger_event", - /* 289 */ "foreach_clause", - /* 290 */ "when_clause", - /* 291 */ "trigger_cmd", - /* 292 */ "trnm", - /* 293 */ "tridxby", - /* 294 */ "database_kw_opt", - /* 295 */ "key_opt", - /* 296 */ "add_column_fullname", - /* 297 */ "kwcolumn_opt", - /* 298 */ "create_vtab", - /* 299 */ "vtabarglist", - /* 300 */ "vtabarg", - /* 301 */ "vtabargtoken", - /* 302 */ "lp", - /* 303 */ "anylist", - /* 304 */ "wqitem", - /* 305 */ "wqas", - /* 306 */ "windowdefn_list", - /* 307 */ "windowdefn", - /* 308 */ "window", - /* 309 */ "frame_opt", - /* 310 */ "part_opt", - /* 311 */ "filter_clause", - /* 312 */ "over_clause", - /* 313 */ "range_or_rows", - /* 314 */ "frame_bound", - /* 315 */ "frame_bound_s", - /* 316 */ "frame_bound_e", - /* 317 */ "frame_exclude_opt", - /* 318 */ "frame_exclude", + /* 183 */ "QNUMBER", + /* 184 */ "SPACE", + /* 185 */ "ILLEGAL", + /* 186 */ "input", + /* 187 */ "cmdlist", + /* 188 */ "ecmd", + /* 189 */ "cmdx", + /* 190 */ "explain", + /* 191 */ "cmd", + /* 192 */ "transtype", + /* 193 */ "trans_opt", + /* 194 */ "nm", + /* 195 */ "savepoint_opt", + /* 196 */ "create_table", + /* 197 */ "create_table_args", + /* 198 */ "createkw", + /* 199 */ "temp", + /* 200 */ "ifnotexists", + /* 201 */ "dbnm", + /* 202 */ "columnlist", + /* 203 */ "conslist_opt", + /* 204 */ "table_option_set", + /* 205 */ "select", + /* 206 */ "table_option", + /* 207 */ "columnname", + /* 208 */ "carglist", + /* 209 */ "typetoken", + /* 210 */ "typename", + /* 211 */ "signed", + /* 212 */ "plus_num", + /* 213 */ "minus_num", + /* 214 */ "scanpt", + /* 215 */ "scantok", + /* 216 */ "ccons", + /* 217 */ "term", + /* 218 */ "expr", + /* 219 */ "onconf", + /* 220 */ "sortorder", + /* 221 */ "autoinc", + /* 222 */ "eidlist_opt", + /* 223 */ "refargs", + /* 224 */ "defer_subclause", + /* 225 */ "generated", + /* 226 */ "refarg", + /* 227 */ "refact", + /* 228 */ "init_deferred_pred_opt", + /* 229 */ "conslist", + /* 230 */ "tconscomma", + /* 231 */ "tcons", + /* 232 */ "sortlist", + /* 233 */ "eidlist", + /* 234 */ "defer_subclause_opt", + /* 235 */ "orconf", + /* 236 */ "resolvetype", + /* 237 */ "raisetype", + /* 238 */ "ifexists", + /* 239 */ "fullname", + /* 240 */ "selectnowith", + /* 241 */ "oneselect", + /* 242 */ "wqlist", + /* 243 */ "multiselect_op", + /* 244 */ "distinct", + /* 245 */ "selcollist", + /* 246 */ "from", + /* 247 */ "where_opt", + /* 248 */ "groupby_opt", + /* 249 */ "having_opt", + /* 250 */ "orderby_opt", + /* 251 */ "limit_opt", + /* 252 */ "window_clause", + /* 253 */ "values", + /* 254 */ "nexprlist", + /* 255 */ "mvalues", + /* 256 */ "sclp", + /* 257 */ "as", + /* 258 */ "seltablist", + /* 259 */ "stl_prefix", + /* 260 */ "joinop", + /* 261 */ "on_using", + /* 262 */ "indexed_by", + /* 263 */ "exprlist", + /* 264 */ "xfullname", + /* 265 */ "idlist", + /* 266 */ "indexed_opt", + /* 267 */ "nulls", + /* 268 */ "with", + /* 269 */ "where_opt_ret", + /* 270 */ "setlist", + /* 271 */ "insert_cmd", + /* 272 */ "idlist_opt", + /* 273 */ "upsert", + /* 274 */ "returning", + /* 275 */ "filter_over", + /* 276 */ "likeop", + /* 277 */ "between_op", + /* 278 */ "in_op", + /* 279 */ "paren_exprlist", + /* 280 */ "case_operand", + /* 281 */ "case_exprlist", + /* 282 */ "case_else", + /* 283 */ "uniqueflag", + /* 284 */ "collate", + /* 285 */ "vinto", + /* 286 */ "nmnum", + /* 287 */ "trigger_decl", + /* 288 */ "trigger_cmd_list", + /* 289 */ "trigger_time", + /* 290 */ "trigger_event", + /* 291 */ "foreach_clause", + /* 292 */ "when_clause", + /* 293 */ "trigger_cmd", + /* 294 */ "trnm", + /* 295 */ "tridxby", + /* 296 */ "database_kw_opt", + /* 297 */ "key_opt", + /* 298 */ "add_column_fullname", + /* 299 */ "kwcolumn_opt", + /* 300 */ "create_vtab", + /* 301 */ "vtabarglist", + /* 302 */ "vtabarg", + /* 303 */ "vtabargtoken", + /* 304 */ "lp", + /* 305 */ "anylist", + /* 306 */ "wqitem", + /* 307 */ "wqas", + /* 308 */ "withnm", + /* 309 */ "windowdefn_list", + /* 310 */ "windowdefn", + /* 311 */ "window", + /* 312 */ "frame_opt", + /* 313 */ "part_opt", + /* 314 */ "filter_clause", + /* 315 */ "over_clause", + /* 316 */ "range_or_rows", + /* 317 */ "frame_bound", + /* 318 */ "frame_bound_s", + /* 319 */ "frame_bound_e", + /* 320 */ "frame_exclude_opt", + /* 321 */ "frame_exclude", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -172326,351 +175928,363 @@ static const char *const yyRuleName[] = { /* 92 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", /* 93 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", /* 94 */ "values ::= VALUES LP nexprlist RP", - /* 95 */ "values ::= values COMMA LP nexprlist RP", - /* 96 */ "distinct ::= DISTINCT", - /* 97 */ "distinct ::= ALL", - /* 98 */ "distinct ::=", - /* 99 */ "sclp ::=", - /* 100 */ "selcollist ::= sclp scanpt expr scanpt as", - /* 101 */ "selcollist ::= sclp scanpt STAR", - /* 102 */ "selcollist ::= sclp scanpt nm DOT STAR", - /* 103 */ "as ::= AS nm", - /* 104 */ "as ::=", - /* 105 */ "from ::=", - /* 106 */ "from ::= FROM seltablist", - /* 107 */ "stl_prefix ::= seltablist joinop", - /* 108 */ "stl_prefix ::=", - /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using", - /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", - /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", - /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using", - /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", - /* 114 */ "dbnm ::=", - /* 115 */ "dbnm ::= DOT nm", - /* 116 */ "fullname ::= nm", - /* 117 */ "fullname ::= nm DOT nm", - /* 118 */ "xfullname ::= nm", - /* 119 */ "xfullname ::= nm DOT nm", - /* 120 */ "xfullname ::= nm DOT nm AS nm", - /* 121 */ "xfullname ::= nm AS nm", - /* 122 */ "joinop ::= COMMA|JOIN", - /* 123 */ "joinop ::= JOIN_KW JOIN", - /* 124 */ "joinop ::= JOIN_KW nm JOIN", - /* 125 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 126 */ "on_using ::= ON expr", - /* 127 */ "on_using ::= USING LP idlist RP", - /* 128 */ "on_using ::=", - /* 129 */ "indexed_opt ::=", - /* 130 */ "indexed_by ::= INDEXED BY nm", - /* 131 */ "indexed_by ::= NOT INDEXED", - /* 132 */ "orderby_opt ::=", - /* 133 */ "orderby_opt ::= ORDER BY sortlist", - /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls", - /* 135 */ "sortlist ::= expr sortorder nulls", - /* 136 */ "sortorder ::= ASC", - /* 137 */ "sortorder ::= DESC", - /* 138 */ "sortorder ::=", - /* 139 */ "nulls ::= NULLS FIRST", - /* 140 */ "nulls ::= NULLS LAST", - /* 141 */ "nulls ::=", - /* 142 */ "groupby_opt ::=", - /* 143 */ "groupby_opt ::= GROUP BY nexprlist", - /* 144 */ "having_opt ::=", - /* 145 */ "having_opt ::= HAVING expr", - /* 146 */ "limit_opt ::=", - /* 147 */ "limit_opt ::= LIMIT expr", - /* 148 */ "limit_opt ::= LIMIT expr OFFSET expr", - /* 149 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 150 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", - /* 151 */ "where_opt ::=", - /* 152 */ "where_opt ::= WHERE expr", - /* 153 */ "where_opt_ret ::=", - /* 154 */ "where_opt_ret ::= WHERE expr", - /* 155 */ "where_opt_ret ::= RETURNING selcollist", - /* 156 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", - /* 157 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", - /* 158 */ "setlist ::= setlist COMMA nm EQ expr", - /* 159 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", - /* 160 */ "setlist ::= nm EQ expr", - /* 161 */ "setlist ::= LP idlist RP EQ expr", - /* 162 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", - /* 163 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", - /* 164 */ "upsert ::=", - /* 165 */ "upsert ::= RETURNING selcollist", - /* 166 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", - /* 167 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", - /* 168 */ "upsert ::= ON CONFLICT DO NOTHING returning", - /* 169 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", - /* 170 */ "returning ::= RETURNING selcollist", - /* 171 */ "insert_cmd ::= INSERT orconf", - /* 172 */ "insert_cmd ::= REPLACE", - /* 173 */ "idlist_opt ::=", - /* 174 */ "idlist_opt ::= LP idlist RP", - /* 175 */ "idlist ::= idlist COMMA nm", - /* 176 */ "idlist ::= nm", - /* 177 */ "expr ::= LP expr RP", - /* 178 */ "expr ::= ID|INDEXED|JOIN_KW", - /* 179 */ "expr ::= nm DOT nm", - /* 180 */ "expr ::= nm DOT nm DOT nm", - /* 181 */ "term ::= NULL|FLOAT|BLOB", - /* 182 */ "term ::= STRING", - /* 183 */ "term ::= INTEGER", - /* 184 */ "expr ::= VARIABLE", - /* 185 */ "expr ::= expr COLLATE ID|STRING", - /* 186 */ "expr ::= CAST LP expr AS typetoken RP", - /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", - /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP", - /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", - /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", - /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over", - /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", - /* 193 */ "term ::= CTIME_KW", - /* 194 */ "expr ::= LP nexprlist COMMA expr RP", - /* 195 */ "expr ::= expr AND expr", - /* 196 */ "expr ::= expr OR expr", - /* 197 */ "expr ::= expr LT|GT|GE|LE expr", - /* 198 */ "expr ::= expr EQ|NE expr", - /* 199 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 200 */ "expr ::= expr PLUS|MINUS expr", - /* 201 */ "expr ::= expr STAR|SLASH|REM expr", - /* 202 */ "expr ::= expr CONCAT expr", - /* 203 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 204 */ "expr ::= expr likeop expr", - /* 205 */ "expr ::= expr likeop expr ESCAPE expr", - /* 206 */ "expr ::= expr ISNULL|NOTNULL", - /* 207 */ "expr ::= expr NOT NULL", - /* 208 */ "expr ::= expr IS expr", - /* 209 */ "expr ::= expr IS NOT expr", - /* 210 */ "expr ::= expr IS NOT DISTINCT FROM expr", - /* 211 */ "expr ::= expr IS DISTINCT FROM expr", - /* 212 */ "expr ::= NOT expr", - /* 213 */ "expr ::= BITNOT expr", - /* 214 */ "expr ::= PLUS|MINUS expr", - /* 215 */ "expr ::= expr PTR expr", - /* 216 */ "between_op ::= BETWEEN", - /* 217 */ "between_op ::= NOT BETWEEN", - /* 218 */ "expr ::= expr between_op expr AND expr", - /* 219 */ "in_op ::= IN", - /* 220 */ "in_op ::= NOT IN", - /* 221 */ "expr ::= expr in_op LP exprlist RP", - /* 222 */ "expr ::= LP select RP", - /* 223 */ "expr ::= expr in_op LP select RP", - /* 224 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 225 */ "expr ::= EXISTS LP select RP", - /* 226 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 227 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 228 */ "case_exprlist ::= WHEN expr THEN expr", - /* 229 */ "case_else ::= ELSE expr", - /* 230 */ "case_else ::=", - /* 231 */ "case_operand ::=", - /* 232 */ "exprlist ::=", - /* 233 */ "nexprlist ::= nexprlist COMMA expr", - /* 234 */ "nexprlist ::= expr", - /* 235 */ "paren_exprlist ::=", - /* 236 */ "paren_exprlist ::= LP exprlist RP", - /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 238 */ "uniqueflag ::= UNIQUE", - /* 239 */ "uniqueflag ::=", - /* 240 */ "eidlist_opt ::=", - /* 241 */ "eidlist_opt ::= LP eidlist RP", - /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 243 */ "eidlist ::= nm collate sortorder", - /* 244 */ "collate ::=", - /* 245 */ "collate ::= COLLATE ID|STRING", - /* 246 */ "cmd ::= DROP INDEX ifexists fullname", - /* 247 */ "cmd ::= VACUUM vinto", - /* 248 */ "cmd ::= VACUUM nm vinto", - /* 249 */ "vinto ::= INTO expr", - /* 250 */ "vinto ::=", - /* 251 */ "cmd ::= PRAGMA nm dbnm", - /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 260 */ "trigger_time ::= BEFORE|AFTER", - /* 261 */ "trigger_time ::= INSTEAD OF", - /* 262 */ "trigger_time ::=", - /* 263 */ "trigger_event ::= DELETE|INSERT", - /* 264 */ "trigger_event ::= UPDATE", - /* 265 */ "trigger_event ::= UPDATE OF idlist", - /* 266 */ "when_clause ::=", - /* 267 */ "when_clause ::= WHEN expr", - /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 270 */ "trnm ::= nm DOT nm", - /* 271 */ "tridxby ::= INDEXED BY nm", - /* 272 */ "tridxby ::= NOT INDEXED", - /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 276 */ "trigger_cmd ::= scanpt select scanpt", - /* 277 */ "expr ::= RAISE LP IGNORE RP", - /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 279 */ "raisetype ::= ROLLBACK", - /* 280 */ "raisetype ::= ABORT", - /* 281 */ "raisetype ::= FAIL", - /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 284 */ "cmd ::= DETACH database_kw_opt expr", - /* 285 */ "key_opt ::=", - /* 286 */ "key_opt ::= KEY expr", - /* 287 */ "cmd ::= REINDEX", - /* 288 */ "cmd ::= REINDEX nm dbnm", - /* 289 */ "cmd ::= ANALYZE", - /* 290 */ "cmd ::= ANALYZE nm dbnm", - /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", - /* 294 */ "add_column_fullname ::= fullname", - /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 296 */ "cmd ::= create_vtab", - /* 297 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 299 */ "vtabarg ::=", - /* 300 */ "vtabargtoken ::= ANY", - /* 301 */ "vtabargtoken ::= lp anylist RP", - /* 302 */ "lp ::= LP", - /* 303 */ "with ::= WITH wqlist", - /* 304 */ "with ::= WITH RECURSIVE wqlist", - /* 305 */ "wqas ::= AS", - /* 306 */ "wqas ::= AS MATERIALIZED", - /* 307 */ "wqas ::= AS NOT MATERIALIZED", - /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP", - /* 309 */ "wqlist ::= wqitem", - /* 310 */ "wqlist ::= wqlist COMMA wqitem", - /* 311 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 312 */ "windowdefn ::= nm AS LP window RP", - /* 313 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 314 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 315 */ "window ::= ORDER BY sortlist frame_opt", - /* 316 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 317 */ "window ::= nm frame_opt", - /* 318 */ "frame_opt ::=", - /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 322 */ "frame_bound_s ::= frame_bound", - /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 324 */ "frame_bound_e ::= frame_bound", - /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 327 */ "frame_bound ::= CURRENT ROW", - /* 328 */ "frame_exclude_opt ::=", - /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 330 */ "frame_exclude ::= NO OTHERS", - /* 331 */ "frame_exclude ::= CURRENT ROW", - /* 332 */ "frame_exclude ::= GROUP|TIES", - /* 333 */ "window_clause ::= WINDOW windowdefn_list", - /* 334 */ "filter_over ::= filter_clause over_clause", - /* 335 */ "filter_over ::= over_clause", - /* 336 */ "filter_over ::= filter_clause", - /* 337 */ "over_clause ::= OVER LP window RP", - /* 338 */ "over_clause ::= OVER nm", - /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 340 */ "input ::= cmdlist", - /* 341 */ "cmdlist ::= cmdlist ecmd", - /* 342 */ "cmdlist ::= ecmd", - /* 343 */ "ecmd ::= SEMI", - /* 344 */ "ecmd ::= cmdx SEMI", - /* 345 */ "ecmd ::= explain cmdx SEMI", - /* 346 */ "trans_opt ::=", - /* 347 */ "trans_opt ::= TRANSACTION", - /* 348 */ "trans_opt ::= TRANSACTION nm", - /* 349 */ "savepoint_opt ::= SAVEPOINT", - /* 350 */ "savepoint_opt ::=", - /* 351 */ "cmd ::= create_table create_table_args", - /* 352 */ "table_option_set ::= table_option", - /* 353 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 354 */ "columnlist ::= columnname carglist", - /* 355 */ "nm ::= ID|INDEXED|JOIN_KW", - /* 356 */ "nm ::= STRING", - /* 357 */ "typetoken ::= typename", - /* 358 */ "typename ::= ID|STRING", - /* 359 */ "signed ::= plus_num", - /* 360 */ "signed ::= minus_num", - /* 361 */ "carglist ::= carglist ccons", - /* 362 */ "carglist ::=", - /* 363 */ "ccons ::= NULL onconf", - /* 364 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 365 */ "ccons ::= AS generated", - /* 366 */ "conslist_opt ::= COMMA conslist", - /* 367 */ "conslist ::= conslist tconscomma tcons", - /* 368 */ "conslist ::= tcons", - /* 369 */ "tconscomma ::=", - /* 370 */ "defer_subclause_opt ::= defer_subclause", - /* 371 */ "resolvetype ::= raisetype", - /* 372 */ "selectnowith ::= oneselect", - /* 373 */ "oneselect ::= values", - /* 374 */ "sclp ::= selcollist COMMA", - /* 375 */ "as ::= ID|STRING", - /* 376 */ "indexed_opt ::= indexed_by", - /* 377 */ "returning ::=", - /* 378 */ "expr ::= term", - /* 379 */ "likeop ::= LIKE_KW|MATCH", - /* 380 */ "case_operand ::= expr", - /* 381 */ "exprlist ::= nexprlist", - /* 382 */ "nmnum ::= plus_num", - /* 383 */ "nmnum ::= nm", - /* 384 */ "nmnum ::= ON", - /* 385 */ "nmnum ::= DELETE", - /* 386 */ "nmnum ::= DEFAULT", - /* 387 */ "plus_num ::= INTEGER|FLOAT", - /* 388 */ "foreach_clause ::=", - /* 389 */ "foreach_clause ::= FOR EACH ROW", - /* 390 */ "trnm ::= nm", - /* 391 */ "tridxby ::=", - /* 392 */ "database_kw_opt ::= DATABASE", - /* 393 */ "database_kw_opt ::=", - /* 394 */ "kwcolumn_opt ::=", - /* 395 */ "kwcolumn_opt ::= COLUMNKW", - /* 396 */ "vtabarglist ::= vtabarg", - /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 398 */ "vtabarg ::= vtabarg vtabargtoken", - /* 399 */ "anylist ::=", - /* 400 */ "anylist ::= anylist LP anylist RP", - /* 401 */ "anylist ::= anylist ANY", - /* 402 */ "with ::=", - /* 403 */ "windowdefn_list ::= windowdefn", - /* 404 */ "window ::= frame_opt", + /* 95 */ "oneselect ::= mvalues", + /* 96 */ "mvalues ::= values COMMA LP nexprlist RP", + /* 97 */ "mvalues ::= mvalues COMMA LP nexprlist RP", + /* 98 */ "distinct ::= DISTINCT", + /* 99 */ "distinct ::= ALL", + /* 100 */ "distinct ::=", + /* 101 */ "sclp ::=", + /* 102 */ "selcollist ::= sclp scanpt expr scanpt as", + /* 103 */ "selcollist ::= sclp scanpt STAR", + /* 104 */ "selcollist ::= sclp scanpt nm DOT STAR", + /* 105 */ "as ::= AS nm", + /* 106 */ "as ::=", + /* 107 */ "from ::=", + /* 108 */ "from ::= FROM seltablist", + /* 109 */ "stl_prefix ::= seltablist joinop", + /* 110 */ "stl_prefix ::=", + /* 111 */ "seltablist ::= stl_prefix nm dbnm as on_using", + /* 112 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", + /* 113 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", + /* 114 */ "seltablist ::= stl_prefix LP select RP as on_using", + /* 115 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", + /* 116 */ "dbnm ::=", + /* 117 */ "dbnm ::= DOT nm", + /* 118 */ "fullname ::= nm", + /* 119 */ "fullname ::= nm DOT nm", + /* 120 */ "xfullname ::= nm", + /* 121 */ "xfullname ::= nm DOT nm", + /* 122 */ "xfullname ::= nm DOT nm AS nm", + /* 123 */ "xfullname ::= nm AS nm", + /* 124 */ "joinop ::= COMMA|JOIN", + /* 125 */ "joinop ::= JOIN_KW JOIN", + /* 126 */ "joinop ::= JOIN_KW nm JOIN", + /* 127 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 128 */ "on_using ::= ON expr", + /* 129 */ "on_using ::= USING LP idlist RP", + /* 130 */ "on_using ::=", + /* 131 */ "indexed_opt ::=", + /* 132 */ "indexed_by ::= INDEXED BY nm", + /* 133 */ "indexed_by ::= NOT INDEXED", + /* 134 */ "orderby_opt ::=", + /* 135 */ "orderby_opt ::= ORDER BY sortlist", + /* 136 */ "sortlist ::= sortlist COMMA expr sortorder nulls", + /* 137 */ "sortlist ::= expr sortorder nulls", + /* 138 */ "sortorder ::= ASC", + /* 139 */ "sortorder ::= DESC", + /* 140 */ "sortorder ::=", + /* 141 */ "nulls ::= NULLS FIRST", + /* 142 */ "nulls ::= NULLS LAST", + /* 143 */ "nulls ::=", + /* 144 */ "groupby_opt ::=", + /* 145 */ "groupby_opt ::= GROUP BY nexprlist", + /* 146 */ "having_opt ::=", + /* 147 */ "having_opt ::= HAVING expr", + /* 148 */ "limit_opt ::=", + /* 149 */ "limit_opt ::= LIMIT expr", + /* 150 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 151 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 152 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", + /* 153 */ "where_opt ::=", + /* 154 */ "where_opt ::= WHERE expr", + /* 155 */ "where_opt_ret ::=", + /* 156 */ "where_opt_ret ::= WHERE expr", + /* 157 */ "where_opt_ret ::= RETURNING selcollist", + /* 158 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", + /* 159 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", + /* 160 */ "setlist ::= setlist COMMA nm EQ expr", + /* 161 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 162 */ "setlist ::= nm EQ expr", + /* 163 */ "setlist ::= LP idlist RP EQ expr", + /* 164 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 165 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", + /* 166 */ "upsert ::=", + /* 167 */ "upsert ::= RETURNING selcollist", + /* 168 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", + /* 169 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", + /* 170 */ "upsert ::= ON CONFLICT DO NOTHING returning", + /* 171 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", + /* 172 */ "returning ::= RETURNING selcollist", + /* 173 */ "insert_cmd ::= INSERT orconf", + /* 174 */ "insert_cmd ::= REPLACE", + /* 175 */ "idlist_opt ::=", + /* 176 */ "idlist_opt ::= LP idlist RP", + /* 177 */ "idlist ::= idlist COMMA nm", + /* 178 */ "idlist ::= nm", + /* 179 */ "expr ::= LP expr RP", + /* 180 */ "expr ::= ID|INDEXED|JOIN_KW", + /* 181 */ "expr ::= nm DOT nm", + /* 182 */ "expr ::= nm DOT nm DOT nm", + /* 183 */ "term ::= NULL|FLOAT|BLOB", + /* 184 */ "term ::= STRING", + /* 185 */ "term ::= INTEGER", + /* 186 */ "expr ::= VARIABLE", + /* 187 */ "expr ::= expr COLLATE ID|STRING", + /* 188 */ "expr ::= CAST LP expr AS typetoken RP", + /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", + /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP", + /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", + /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", + /* 193 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over", + /* 194 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", + /* 195 */ "term ::= CTIME_KW", + /* 196 */ "expr ::= LP nexprlist COMMA expr RP", + /* 197 */ "expr ::= expr AND expr", + /* 198 */ "expr ::= expr OR expr", + /* 199 */ "expr ::= expr LT|GT|GE|LE expr", + /* 200 */ "expr ::= expr EQ|NE expr", + /* 201 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 202 */ "expr ::= expr PLUS|MINUS expr", + /* 203 */ "expr ::= expr STAR|SLASH|REM expr", + /* 204 */ "expr ::= expr CONCAT expr", + /* 205 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 206 */ "expr ::= expr likeop expr", + /* 207 */ "expr ::= expr likeop expr ESCAPE expr", + /* 208 */ "expr ::= expr ISNULL|NOTNULL", + /* 209 */ "expr ::= expr NOT NULL", + /* 210 */ "expr ::= expr IS expr", + /* 211 */ "expr ::= expr IS NOT expr", + /* 212 */ "expr ::= expr IS NOT DISTINCT FROM expr", + /* 213 */ "expr ::= expr IS DISTINCT FROM expr", + /* 214 */ "expr ::= NOT expr", + /* 215 */ "expr ::= BITNOT expr", + /* 216 */ "expr ::= PLUS|MINUS expr", + /* 217 */ "expr ::= expr PTR expr", + /* 218 */ "between_op ::= BETWEEN", + /* 219 */ "between_op ::= NOT BETWEEN", + /* 220 */ "expr ::= expr between_op expr AND expr", + /* 221 */ "in_op ::= IN", + /* 222 */ "in_op ::= NOT IN", + /* 223 */ "expr ::= expr in_op LP exprlist RP", + /* 224 */ "expr ::= LP select RP", + /* 225 */ "expr ::= expr in_op LP select RP", + /* 226 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 227 */ "expr ::= EXISTS LP select RP", + /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 230 */ "case_exprlist ::= WHEN expr THEN expr", + /* 231 */ "case_else ::= ELSE expr", + /* 232 */ "case_else ::=", + /* 233 */ "case_operand ::=", + /* 234 */ "exprlist ::=", + /* 235 */ "nexprlist ::= nexprlist COMMA expr", + /* 236 */ "nexprlist ::= expr", + /* 237 */ "paren_exprlist ::=", + /* 238 */ "paren_exprlist ::= LP exprlist RP", + /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 240 */ "uniqueflag ::= UNIQUE", + /* 241 */ "uniqueflag ::=", + /* 242 */ "eidlist_opt ::=", + /* 243 */ "eidlist_opt ::= LP eidlist RP", + /* 244 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 245 */ "eidlist ::= nm collate sortorder", + /* 246 */ "collate ::=", + /* 247 */ "collate ::= COLLATE ID|STRING", + /* 248 */ "cmd ::= DROP INDEX ifexists fullname", + /* 249 */ "cmd ::= VACUUM vinto", + /* 250 */ "cmd ::= VACUUM nm vinto", + /* 251 */ "vinto ::= INTO expr", + /* 252 */ "vinto ::=", + /* 253 */ "cmd ::= PRAGMA nm dbnm", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 255 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 256 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 257 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 258 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 259 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 260 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 261 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 262 */ "trigger_time ::= BEFORE|AFTER", + /* 263 */ "trigger_time ::= INSTEAD OF", + /* 264 */ "trigger_time ::=", + /* 265 */ "trigger_event ::= DELETE|INSERT", + /* 266 */ "trigger_event ::= UPDATE", + /* 267 */ "trigger_event ::= UPDATE OF idlist", + /* 268 */ "when_clause ::=", + /* 269 */ "when_clause ::= WHEN expr", + /* 270 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 271 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 272 */ "trnm ::= nm DOT nm", + /* 273 */ "tridxby ::= INDEXED BY nm", + /* 274 */ "tridxby ::= NOT INDEXED", + /* 275 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 276 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 278 */ "trigger_cmd ::= scanpt select scanpt", + /* 279 */ "expr ::= RAISE LP IGNORE RP", + /* 280 */ "expr ::= RAISE LP raisetype COMMA expr RP", + /* 281 */ "raisetype ::= ROLLBACK", + /* 282 */ "raisetype ::= ABORT", + /* 283 */ "raisetype ::= FAIL", + /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 286 */ "cmd ::= DETACH database_kw_opt expr", + /* 287 */ "key_opt ::=", + /* 288 */ "key_opt ::= KEY expr", + /* 289 */ "cmd ::= REINDEX", + /* 290 */ "cmd ::= REINDEX nm dbnm", + /* 291 */ "cmd ::= ANALYZE", + /* 292 */ "cmd ::= ANALYZE nm dbnm", + /* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 294 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 295 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 296 */ "add_column_fullname ::= fullname", + /* 297 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 298 */ "cmd ::= create_vtab", + /* 299 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 300 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 301 */ "vtabarg ::=", + /* 302 */ "vtabargtoken ::= ANY", + /* 303 */ "vtabargtoken ::= lp anylist RP", + /* 304 */ "lp ::= LP", + /* 305 */ "with ::= WITH wqlist", + /* 306 */ "with ::= WITH RECURSIVE wqlist", + /* 307 */ "wqas ::= AS", + /* 308 */ "wqas ::= AS MATERIALIZED", + /* 309 */ "wqas ::= AS NOT MATERIALIZED", + /* 310 */ "wqitem ::= withnm eidlist_opt wqas LP select RP", + /* 311 */ "withnm ::= nm", + /* 312 */ "wqlist ::= wqitem", + /* 313 */ "wqlist ::= wqlist COMMA wqitem", + /* 314 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 315 */ "windowdefn ::= nm AS LP window RP", + /* 316 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 317 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 318 */ "window ::= ORDER BY sortlist frame_opt", + /* 319 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 320 */ "window ::= nm frame_opt", + /* 321 */ "frame_opt ::=", + /* 322 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 323 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 324 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 325 */ "frame_bound_s ::= frame_bound", + /* 326 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 327 */ "frame_bound_e ::= frame_bound", + /* 328 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 329 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 330 */ "frame_bound ::= CURRENT ROW", + /* 331 */ "frame_exclude_opt ::=", + /* 332 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 333 */ "frame_exclude ::= NO OTHERS", + /* 334 */ "frame_exclude ::= CURRENT ROW", + /* 335 */ "frame_exclude ::= GROUP|TIES", + /* 336 */ "window_clause ::= WINDOW windowdefn_list", + /* 337 */ "filter_over ::= filter_clause over_clause", + /* 338 */ "filter_over ::= over_clause", + /* 339 */ "filter_over ::= filter_clause", + /* 340 */ "over_clause ::= OVER LP window RP", + /* 341 */ "over_clause ::= OVER nm", + /* 342 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 343 */ "term ::= QNUMBER", + /* 344 */ "input ::= cmdlist", + /* 345 */ "cmdlist ::= cmdlist ecmd", + /* 346 */ "cmdlist ::= ecmd", + /* 347 */ "ecmd ::= SEMI", + /* 348 */ "ecmd ::= cmdx SEMI", + /* 349 */ "ecmd ::= explain cmdx SEMI", + /* 350 */ "trans_opt ::=", + /* 351 */ "trans_opt ::= TRANSACTION", + /* 352 */ "trans_opt ::= TRANSACTION nm", + /* 353 */ "savepoint_opt ::= SAVEPOINT", + /* 354 */ "savepoint_opt ::=", + /* 355 */ "cmd ::= create_table create_table_args", + /* 356 */ "table_option_set ::= table_option", + /* 357 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 358 */ "columnlist ::= columnname carglist", + /* 359 */ "nm ::= ID|INDEXED|JOIN_KW", + /* 360 */ "nm ::= STRING", + /* 361 */ "typetoken ::= typename", + /* 362 */ "typename ::= ID|STRING", + /* 363 */ "signed ::= plus_num", + /* 364 */ "signed ::= minus_num", + /* 365 */ "carglist ::= carglist ccons", + /* 366 */ "carglist ::=", + /* 367 */ "ccons ::= NULL onconf", + /* 368 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 369 */ "ccons ::= AS generated", + /* 370 */ "conslist_opt ::= COMMA conslist", + /* 371 */ "conslist ::= conslist tconscomma tcons", + /* 372 */ "conslist ::= tcons", + /* 373 */ "tconscomma ::=", + /* 374 */ "defer_subclause_opt ::= defer_subclause", + /* 375 */ "resolvetype ::= raisetype", + /* 376 */ "selectnowith ::= oneselect", + /* 377 */ "oneselect ::= values", + /* 378 */ "sclp ::= selcollist COMMA", + /* 379 */ "as ::= ID|STRING", + /* 380 */ "indexed_opt ::= indexed_by", + /* 381 */ "returning ::=", + /* 382 */ "expr ::= term", + /* 383 */ "likeop ::= LIKE_KW|MATCH", + /* 384 */ "case_operand ::= expr", + /* 385 */ "exprlist ::= nexprlist", + /* 386 */ "nmnum ::= plus_num", + /* 387 */ "nmnum ::= nm", + /* 388 */ "nmnum ::= ON", + /* 389 */ "nmnum ::= DELETE", + /* 390 */ "nmnum ::= DEFAULT", + /* 391 */ "plus_num ::= INTEGER|FLOAT", + /* 392 */ "foreach_clause ::=", + /* 393 */ "foreach_clause ::= FOR EACH ROW", + /* 394 */ "trnm ::= nm", + /* 395 */ "tridxby ::=", + /* 396 */ "database_kw_opt ::= DATABASE", + /* 397 */ "database_kw_opt ::=", + /* 398 */ "kwcolumn_opt ::=", + /* 399 */ "kwcolumn_opt ::= COLUMNKW", + /* 400 */ "vtabarglist ::= vtabarg", + /* 401 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 402 */ "vtabarg ::= vtabarg vtabargtoken", + /* 403 */ "anylist ::=", + /* 404 */ "anylist ::= anylist LP anylist RP", + /* 405 */ "anylist ::= anylist ANY", + /* 406 */ "with ::=", + /* 407 */ "windowdefn_list ::= windowdefn", + /* 408 */ "window ::= frame_opt", }; #endif /* NDEBUG */ -#if YYSTACKDEPTH<=0 +#if YYGROWABLESTACK /* ** Try to increase the size of the parser stack. Return the number ** of errors. Return 0 on success. */ static int yyGrowStack(yyParser *p){ + int oldSize = 1 + (int)(p->yystackEnd - p->yystack); int newSize; int idx; yyStackEntry *pNew; - newSize = p->yystksz*2 + 100; - idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; - if( p->yystack==&p->yystk0 ){ - pNew = malloc(newSize*sizeof(pNew[0])); - if( pNew ) pNew[0] = p->yystk0; + newSize = oldSize*2 + 100; + idx = (int)(p->yytos - p->yystack); + if( p->yystack==p->yystk0 ){ + pNew = YYREALLOC(0, newSize*sizeof(pNew[0])); + if( pNew==0 ) return 1; + memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0])); }else{ - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0])); + if( pNew==0 ) return 1; } - if( pNew ){ - p->yystack = pNew; - p->yytos = &p->yystack[idx]; + p->yystack = pNew; + p->yytos = &p->yystack[idx]; #ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", - yyTracePrompt, p->yystksz, newSize); - } -#endif - p->yystksz = newSize; + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", + yyTracePrompt, oldSize, newSize); } - return pNew==0; +#endif + p->yystackEnd = &p->yystack[newSize-1]; + return 0; } +#endif /* YYGROWABLESTACK */ + +#if !YYGROWABLESTACK +/* For builds that do no have a growable stack, yyGrowStack always +** returns an error. +*/ +# define yyGrowStack(X) 1 #endif /* Datatype of the argument to the memory allocated passed as the @@ -172690,24 +176304,14 @@ SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL) #ifdef YYTRACKMAXSTACKDEPTH yypParser->yyhwm = 0; #endif -#if YYSTACKDEPTH<=0 - yypParser->yytos = NULL; - yypParser->yystack = NULL; - yypParser->yystksz = 0; - if( yyGrowStack(yypParser) ){ - yypParser->yystack = &yypParser->yystk0; - yypParser->yystksz = 1; - } -#endif + yypParser->yystack = yypParser->yystk0; + yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt = -1; #endif yypParser->yytos = yypParser->yystack; yypParser->yystack[0].stateno = 0; yypParser->yystack[0].major = 0; -#if YYSTACKDEPTH>0 - yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; -#endif } #ifndef sqlite3Parser_ENGINEALWAYSONSTACK @@ -172761,97 +176365,98 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 204: /* select */ - case 239: /* selectnowith */ - case 240: /* oneselect */ - case 252: /* values */ + case 205: /* select */ + case 240: /* selectnowith */ + case 241: /* oneselect */ + case 253: /* values */ + case 255: /* mvalues */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy47)); -} - break; - case 216: /* term */ - case 217: /* expr */ - case 246: /* where_opt */ - case 248: /* having_opt */ - case 267: /* where_opt_ret */ - case 278: /* case_operand */ - case 280: /* case_else */ - case 283: /* vinto */ - case 290: /* when_clause */ - case 295: /* key_opt */ - case 311: /* filter_clause */ +sqlite3SelectDelete(pParse->db, (yypminor->yy555)); +} + break; + case 217: /* term */ + case 218: /* expr */ + case 247: /* where_opt */ + case 249: /* having_opt */ + case 269: /* where_opt_ret */ + case 280: /* case_operand */ + case 282: /* case_else */ + case 285: /* vinto */ + case 292: /* when_clause */ + case 297: /* key_opt */ + case 314: /* filter_clause */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy528)); -} - break; - case 221: /* eidlist_opt */ - case 231: /* sortlist */ - case 232: /* eidlist */ - case 244: /* selcollist */ - case 247: /* groupby_opt */ - case 249: /* orderby_opt */ - case 253: /* nexprlist */ - case 254: /* sclp */ - case 261: /* exprlist */ - case 268: /* setlist */ - case 277: /* paren_exprlist */ - case 279: /* case_exprlist */ - case 310: /* part_opt */ +sqlite3ExprDelete(pParse->db, (yypminor->yy454)); +} + break; + case 222: /* eidlist_opt */ + case 232: /* sortlist */ + case 233: /* eidlist */ + case 245: /* selcollist */ + case 248: /* groupby_opt */ + case 250: /* orderby_opt */ + case 254: /* nexprlist */ + case 256: /* sclp */ + case 263: /* exprlist */ + case 270: /* setlist */ + case 279: /* paren_exprlist */ + case 281: /* case_exprlist */ + case 313: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); } break; - case 238: /* fullname */ - case 245: /* from */ - case 256: /* seltablist */ - case 257: /* stl_prefix */ - case 262: /* xfullname */ + case 239: /* fullname */ + case 246: /* from */ + case 258: /* seltablist */ + case 259: /* stl_prefix */ + case 264: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy131)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy203)); } break; - case 241: /* wqlist */ + case 242: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy521)); +sqlite3WithDelete(pParse->db, (yypminor->yy59)); } break; - case 251: /* window_clause */ - case 306: /* windowdefn_list */ + case 252: /* window_clause */ + case 309: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy41)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy211)); } break; - case 263: /* idlist */ - case 270: /* idlist_opt */ + case 265: /* idlist */ + case 272: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy254)); +sqlite3IdListDelete(pParse->db, (yypminor->yy132)); } break; - case 273: /* filter_over */ - case 307: /* windowdefn */ - case 308: /* window */ - case 309: /* frame_opt */ - case 312: /* over_clause */ + case 275: /* filter_over */ + case 310: /* windowdefn */ + case 311: /* window */ + case 312: /* frame_opt */ + case 315: /* over_clause */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy41)); +sqlite3WindowDelete(pParse->db, (yypminor->yy211)); } break; - case 286: /* trigger_cmd_list */ - case 291: /* trigger_cmd */ + case 288: /* trigger_cmd_list */ + case 293: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy33)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427)); } break; - case 288: /* trigger_event */ + case 290: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy180).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy286).b); } break; - case 314: /* frame_bound */ - case 315: /* frame_bound_s */ - case 316: /* frame_bound_e */ + case 317: /* frame_bound */ + case 318: /* frame_bound_s */ + case 319: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy595).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -172885,9 +176490,26 @@ static void yy_pop_parser_stack(yyParser *pParser){ */ SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){ yyParser *pParser = (yyParser*)p; - while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); + + /* In-lined version of calling yy_pop_parser_stack() for each + ** element left in the stack */ + yyStackEntry *yytos = pParser->yytos; + while( yytos>pParser->yystack ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + if( yytos->major>=YY_MIN_DSTRCTR ){ + yy_destructor(pParser, yytos->major, &yytos->minor); + } + yytos--; + } + +#if YYGROWABLESTACK + if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack); #endif } @@ -173070,7 +176692,7 @@ static void yyStackOverflow(yyParser *yypParser){ ** stack every overflows */ /******** Begin %stack_overflow code ******************************************/ - sqlite3ErrorMsg(pParse, "parser stack overflow"); + sqlite3OomFault(pParse->db); /******** End %stack_overflow code ********************************************/ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ sqlite3ParserCTX_STORE @@ -173114,25 +176736,19 @@ static void yy_shift( assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); } #endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>yypParser->yystackEnd ){ - yypParser->yytos--; - yyStackOverflow(yypParser); - return; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ + yytos = yypParser->yytos; + if( yytos>yypParser->yystackEnd ){ if( yyGrowStack(yypParser) ){ yypParser->yytos--; yyStackOverflow(yypParser); return; } + yytos = yypParser->yytos; + assert( yytos <= yypParser->yystackEnd ); } -#endif if( yyNewState > YY_MAX_SHIFT ){ yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; } - yytos = yypParser->yytos; yytos->stateno = yyNewState; yytos->major = yyMajor; yytos->minor.yy0 = yyMinor; @@ -173142,411 +176758,415 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 189, /* (0) explain ::= EXPLAIN */ - 189, /* (1) explain ::= EXPLAIN QUERY PLAN */ - 188, /* (2) cmdx ::= cmd */ - 190, /* (3) cmd ::= BEGIN transtype trans_opt */ - 191, /* (4) transtype ::= */ - 191, /* (5) transtype ::= DEFERRED */ - 191, /* (6) transtype ::= IMMEDIATE */ - 191, /* (7) transtype ::= EXCLUSIVE */ - 190, /* (8) cmd ::= COMMIT|END trans_opt */ - 190, /* (9) cmd ::= ROLLBACK trans_opt */ - 190, /* (10) cmd ::= SAVEPOINT nm */ - 190, /* (11) cmd ::= RELEASE savepoint_opt nm */ - 190, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - 195, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - 197, /* (14) createkw ::= CREATE */ - 199, /* (15) ifnotexists ::= */ - 199, /* (16) ifnotexists ::= IF NOT EXISTS */ - 198, /* (17) temp ::= TEMP */ - 198, /* (18) temp ::= */ - 196, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ - 196, /* (20) create_table_args ::= AS select */ - 203, /* (21) table_option_set ::= */ - 203, /* (22) table_option_set ::= table_option_set COMMA table_option */ - 205, /* (23) table_option ::= WITHOUT nm */ - 205, /* (24) table_option ::= nm */ - 206, /* (25) columnname ::= nm typetoken */ - 208, /* (26) typetoken ::= */ - 208, /* (27) typetoken ::= typename LP signed RP */ - 208, /* (28) typetoken ::= typename LP signed COMMA signed RP */ - 209, /* (29) typename ::= typename ID|STRING */ - 213, /* (30) scanpt ::= */ - 214, /* (31) scantok ::= */ - 215, /* (32) ccons ::= CONSTRAINT nm */ - 215, /* (33) ccons ::= DEFAULT scantok term */ - 215, /* (34) ccons ::= DEFAULT LP expr RP */ - 215, /* (35) ccons ::= DEFAULT PLUS scantok term */ - 215, /* (36) ccons ::= DEFAULT MINUS scantok term */ - 215, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ - 215, /* (38) ccons ::= NOT NULL onconf */ - 215, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - 215, /* (40) ccons ::= UNIQUE onconf */ - 215, /* (41) ccons ::= CHECK LP expr RP */ - 215, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ - 215, /* (43) ccons ::= defer_subclause */ - 215, /* (44) ccons ::= COLLATE ID|STRING */ - 224, /* (45) generated ::= LP expr RP */ - 224, /* (46) generated ::= LP expr RP ID */ - 220, /* (47) autoinc ::= */ - 220, /* (48) autoinc ::= AUTOINCR */ - 222, /* (49) refargs ::= */ - 222, /* (50) refargs ::= refargs refarg */ - 225, /* (51) refarg ::= MATCH nm */ - 225, /* (52) refarg ::= ON INSERT refact */ - 225, /* (53) refarg ::= ON DELETE refact */ - 225, /* (54) refarg ::= ON UPDATE refact */ - 226, /* (55) refact ::= SET NULL */ - 226, /* (56) refact ::= SET DEFAULT */ - 226, /* (57) refact ::= CASCADE */ - 226, /* (58) refact ::= RESTRICT */ - 226, /* (59) refact ::= NO ACTION */ - 223, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - 223, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 227, /* (62) init_deferred_pred_opt ::= */ - 227, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - 227, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 202, /* (65) conslist_opt ::= */ - 229, /* (66) tconscomma ::= COMMA */ - 230, /* (67) tcons ::= CONSTRAINT nm */ - 230, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - 230, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ - 230, /* (70) tcons ::= CHECK LP expr RP onconf */ - 230, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 233, /* (72) defer_subclause_opt ::= */ - 218, /* (73) onconf ::= */ - 218, /* (74) onconf ::= ON CONFLICT resolvetype */ - 234, /* (75) orconf ::= */ - 234, /* (76) orconf ::= OR resolvetype */ - 235, /* (77) resolvetype ::= IGNORE */ - 235, /* (78) resolvetype ::= REPLACE */ - 190, /* (79) cmd ::= DROP TABLE ifexists fullname */ - 237, /* (80) ifexists ::= IF EXISTS */ - 237, /* (81) ifexists ::= */ - 190, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - 190, /* (83) cmd ::= DROP VIEW ifexists fullname */ - 190, /* (84) cmd ::= select */ - 204, /* (85) select ::= WITH wqlist selectnowith */ - 204, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ - 204, /* (87) select ::= selectnowith */ - 239, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ - 242, /* (89) multiselect_op ::= UNION */ - 242, /* (90) multiselect_op ::= UNION ALL */ - 242, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ - 240, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - 240, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - 252, /* (94) values ::= VALUES LP nexprlist RP */ - 252, /* (95) values ::= values COMMA LP nexprlist RP */ - 243, /* (96) distinct ::= DISTINCT */ - 243, /* (97) distinct ::= ALL */ - 243, /* (98) distinct ::= */ - 254, /* (99) sclp ::= */ - 244, /* (100) selcollist ::= sclp scanpt expr scanpt as */ - 244, /* (101) selcollist ::= sclp scanpt STAR */ - 244, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ - 255, /* (103) as ::= AS nm */ - 255, /* (104) as ::= */ - 245, /* (105) from ::= */ - 245, /* (106) from ::= FROM seltablist */ - 257, /* (107) stl_prefix ::= seltablist joinop */ - 257, /* (108) stl_prefix ::= */ - 256, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ - 256, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ - 256, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ - 256, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ - 256, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ - 200, /* (114) dbnm ::= */ - 200, /* (115) dbnm ::= DOT nm */ - 238, /* (116) fullname ::= nm */ - 238, /* (117) fullname ::= nm DOT nm */ - 262, /* (118) xfullname ::= nm */ - 262, /* (119) xfullname ::= nm DOT nm */ - 262, /* (120) xfullname ::= nm DOT nm AS nm */ - 262, /* (121) xfullname ::= nm AS nm */ - 258, /* (122) joinop ::= COMMA|JOIN */ - 258, /* (123) joinop ::= JOIN_KW JOIN */ - 258, /* (124) joinop ::= JOIN_KW nm JOIN */ - 258, /* (125) joinop ::= JOIN_KW nm nm JOIN */ - 259, /* (126) on_using ::= ON expr */ - 259, /* (127) on_using ::= USING LP idlist RP */ - 259, /* (128) on_using ::= */ - 264, /* (129) indexed_opt ::= */ - 260, /* (130) indexed_by ::= INDEXED BY nm */ - 260, /* (131) indexed_by ::= NOT INDEXED */ - 249, /* (132) orderby_opt ::= */ - 249, /* (133) orderby_opt ::= ORDER BY sortlist */ - 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ - 231, /* (135) sortlist ::= expr sortorder nulls */ - 219, /* (136) sortorder ::= ASC */ - 219, /* (137) sortorder ::= DESC */ - 219, /* (138) sortorder ::= */ - 265, /* (139) nulls ::= NULLS FIRST */ - 265, /* (140) nulls ::= NULLS LAST */ - 265, /* (141) nulls ::= */ - 247, /* (142) groupby_opt ::= */ - 247, /* (143) groupby_opt ::= GROUP BY nexprlist */ - 248, /* (144) having_opt ::= */ - 248, /* (145) having_opt ::= HAVING expr */ - 250, /* (146) limit_opt ::= */ - 250, /* (147) limit_opt ::= LIMIT expr */ - 250, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ - 250, /* (149) limit_opt ::= LIMIT expr COMMA expr */ - 190, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ - 246, /* (151) where_opt ::= */ - 246, /* (152) where_opt ::= WHERE expr */ - 267, /* (153) where_opt_ret ::= */ - 267, /* (154) where_opt_ret ::= WHERE expr */ - 267, /* (155) where_opt_ret ::= RETURNING selcollist */ - 267, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ - 190, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ - 268, /* (158) setlist ::= setlist COMMA nm EQ expr */ - 268, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ - 268, /* (160) setlist ::= nm EQ expr */ - 268, /* (161) setlist ::= LP idlist RP EQ expr */ - 190, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - 190, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ - 271, /* (164) upsert ::= */ - 271, /* (165) upsert ::= RETURNING selcollist */ - 271, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ - 271, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ - 271, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ - 271, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ - 272, /* (170) returning ::= RETURNING selcollist */ - 269, /* (171) insert_cmd ::= INSERT orconf */ - 269, /* (172) insert_cmd ::= REPLACE */ - 270, /* (173) idlist_opt ::= */ - 270, /* (174) idlist_opt ::= LP idlist RP */ - 263, /* (175) idlist ::= idlist COMMA nm */ - 263, /* (176) idlist ::= nm */ - 217, /* (177) expr ::= LP expr RP */ - 217, /* (178) expr ::= ID|INDEXED|JOIN_KW */ - 217, /* (179) expr ::= nm DOT nm */ - 217, /* (180) expr ::= nm DOT nm DOT nm */ - 216, /* (181) term ::= NULL|FLOAT|BLOB */ - 216, /* (182) term ::= STRING */ - 216, /* (183) term ::= INTEGER */ - 217, /* (184) expr ::= VARIABLE */ - 217, /* (185) expr ::= expr COLLATE ID|STRING */ - 217, /* (186) expr ::= CAST LP expr AS typetoken RP */ - 217, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ - 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - 217, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ - 217, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - 216, /* (193) term ::= CTIME_KW */ - 217, /* (194) expr ::= LP nexprlist COMMA expr RP */ - 217, /* (195) expr ::= expr AND expr */ - 217, /* (196) expr ::= expr OR expr */ - 217, /* (197) expr ::= expr LT|GT|GE|LE expr */ - 217, /* (198) expr ::= expr EQ|NE expr */ - 217, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 217, /* (200) expr ::= expr PLUS|MINUS expr */ - 217, /* (201) expr ::= expr STAR|SLASH|REM expr */ - 217, /* (202) expr ::= expr CONCAT expr */ - 274, /* (203) likeop ::= NOT LIKE_KW|MATCH */ - 217, /* (204) expr ::= expr likeop expr */ - 217, /* (205) expr ::= expr likeop expr ESCAPE expr */ - 217, /* (206) expr ::= expr ISNULL|NOTNULL */ - 217, /* (207) expr ::= expr NOT NULL */ - 217, /* (208) expr ::= expr IS expr */ - 217, /* (209) expr ::= expr IS NOT expr */ - 217, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ - 217, /* (211) expr ::= expr IS DISTINCT FROM expr */ - 217, /* (212) expr ::= NOT expr */ - 217, /* (213) expr ::= BITNOT expr */ - 217, /* (214) expr ::= PLUS|MINUS expr */ - 217, /* (215) expr ::= expr PTR expr */ - 275, /* (216) between_op ::= BETWEEN */ - 275, /* (217) between_op ::= NOT BETWEEN */ - 217, /* (218) expr ::= expr between_op expr AND expr */ - 276, /* (219) in_op ::= IN */ - 276, /* (220) in_op ::= NOT IN */ - 217, /* (221) expr ::= expr in_op LP exprlist RP */ - 217, /* (222) expr ::= LP select RP */ - 217, /* (223) expr ::= expr in_op LP select RP */ - 217, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ - 217, /* (225) expr ::= EXISTS LP select RP */ - 217, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ - 279, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 279, /* (228) case_exprlist ::= WHEN expr THEN expr */ - 280, /* (229) case_else ::= ELSE expr */ - 280, /* (230) case_else ::= */ - 278, /* (231) case_operand ::= */ - 261, /* (232) exprlist ::= */ - 253, /* (233) nexprlist ::= nexprlist COMMA expr */ - 253, /* (234) nexprlist ::= expr */ - 277, /* (235) paren_exprlist ::= */ - 277, /* (236) paren_exprlist ::= LP exprlist RP */ - 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 281, /* (238) uniqueflag ::= UNIQUE */ - 281, /* (239) uniqueflag ::= */ - 221, /* (240) eidlist_opt ::= */ - 221, /* (241) eidlist_opt ::= LP eidlist RP */ - 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ - 232, /* (243) eidlist ::= nm collate sortorder */ - 282, /* (244) collate ::= */ - 282, /* (245) collate ::= COLLATE ID|STRING */ - 190, /* (246) cmd ::= DROP INDEX ifexists fullname */ - 190, /* (247) cmd ::= VACUUM vinto */ - 190, /* (248) cmd ::= VACUUM nm vinto */ - 283, /* (249) vinto ::= INTO expr */ - 283, /* (250) vinto ::= */ - 190, /* (251) cmd ::= PRAGMA nm dbnm */ - 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ - 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ - 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 287, /* (260) trigger_time ::= BEFORE|AFTER */ - 287, /* (261) trigger_time ::= INSTEAD OF */ - 287, /* (262) trigger_time ::= */ - 288, /* (263) trigger_event ::= DELETE|INSERT */ - 288, /* (264) trigger_event ::= UPDATE */ - 288, /* (265) trigger_event ::= UPDATE OF idlist */ - 290, /* (266) when_clause ::= */ - 290, /* (267) when_clause ::= WHEN expr */ - 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ - 292, /* (270) trnm ::= nm DOT nm */ - 293, /* (271) tridxby ::= INDEXED BY nm */ - 293, /* (272) tridxby ::= NOT INDEXED */ - 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 291, /* (276) trigger_cmd ::= scanpt select scanpt */ - 217, /* (277) expr ::= RAISE LP IGNORE RP */ - 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ - 236, /* (279) raisetype ::= ROLLBACK */ - 236, /* (280) raisetype ::= ABORT */ - 236, /* (281) raisetype ::= FAIL */ - 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ - 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 190, /* (284) cmd ::= DETACH database_kw_opt expr */ - 295, /* (285) key_opt ::= */ - 295, /* (286) key_opt ::= KEY expr */ - 190, /* (287) cmd ::= REINDEX */ - 190, /* (288) cmd ::= REINDEX nm dbnm */ - 190, /* (289) cmd ::= ANALYZE */ - 190, /* (290) cmd ::= ANALYZE nm dbnm */ - 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - 296, /* (294) add_column_fullname ::= fullname */ - 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 190, /* (296) cmd ::= create_vtab */ - 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */ - 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 300, /* (299) vtabarg ::= */ - 301, /* (300) vtabargtoken ::= ANY */ - 301, /* (301) vtabargtoken ::= lp anylist RP */ - 302, /* (302) lp ::= LP */ - 266, /* (303) with ::= WITH wqlist */ - 266, /* (304) with ::= WITH RECURSIVE wqlist */ - 305, /* (305) wqas ::= AS */ - 305, /* (306) wqas ::= AS MATERIALIZED */ - 305, /* (307) wqas ::= AS NOT MATERIALIZED */ - 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ - 241, /* (309) wqlist ::= wqitem */ - 241, /* (310) wqlist ::= wqlist COMMA wqitem */ - 306, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 307, /* (312) windowdefn ::= nm AS LP window RP */ - 308, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 308, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 308, /* (315) window ::= ORDER BY sortlist frame_opt */ - 308, /* (316) window ::= nm ORDER BY sortlist frame_opt */ - 308, /* (317) window ::= nm frame_opt */ - 309, /* (318) frame_opt ::= */ - 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ - 315, /* (322) frame_bound_s ::= frame_bound */ - 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ - 316, /* (324) frame_bound_e ::= frame_bound */ - 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ - 314, /* (327) frame_bound ::= CURRENT ROW */ - 317, /* (328) frame_exclude_opt ::= */ - 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 318, /* (330) frame_exclude ::= NO OTHERS */ - 318, /* (331) frame_exclude ::= CURRENT ROW */ - 318, /* (332) frame_exclude ::= GROUP|TIES */ - 251, /* (333) window_clause ::= WINDOW windowdefn_list */ - 273, /* (334) filter_over ::= filter_clause over_clause */ - 273, /* (335) filter_over ::= over_clause */ - 273, /* (336) filter_over ::= filter_clause */ - 312, /* (337) over_clause ::= OVER LP window RP */ - 312, /* (338) over_clause ::= OVER nm */ - 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ - 185, /* (340) input ::= cmdlist */ - 186, /* (341) cmdlist ::= cmdlist ecmd */ - 186, /* (342) cmdlist ::= ecmd */ - 187, /* (343) ecmd ::= SEMI */ - 187, /* (344) ecmd ::= cmdx SEMI */ - 187, /* (345) ecmd ::= explain cmdx SEMI */ - 192, /* (346) trans_opt ::= */ - 192, /* (347) trans_opt ::= TRANSACTION */ - 192, /* (348) trans_opt ::= TRANSACTION nm */ - 194, /* (349) savepoint_opt ::= SAVEPOINT */ - 194, /* (350) savepoint_opt ::= */ - 190, /* (351) cmd ::= create_table create_table_args */ - 203, /* (352) table_option_set ::= table_option */ - 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */ - 201, /* (354) columnlist ::= columnname carglist */ - 193, /* (355) nm ::= ID|INDEXED|JOIN_KW */ - 193, /* (356) nm ::= STRING */ - 208, /* (357) typetoken ::= typename */ - 209, /* (358) typename ::= ID|STRING */ - 210, /* (359) signed ::= plus_num */ - 210, /* (360) signed ::= minus_num */ - 207, /* (361) carglist ::= carglist ccons */ - 207, /* (362) carglist ::= */ - 215, /* (363) ccons ::= NULL onconf */ - 215, /* (364) ccons ::= GENERATED ALWAYS AS generated */ - 215, /* (365) ccons ::= AS generated */ - 202, /* (366) conslist_opt ::= COMMA conslist */ - 228, /* (367) conslist ::= conslist tconscomma tcons */ - 228, /* (368) conslist ::= tcons */ - 229, /* (369) tconscomma ::= */ - 233, /* (370) defer_subclause_opt ::= defer_subclause */ - 235, /* (371) resolvetype ::= raisetype */ - 239, /* (372) selectnowith ::= oneselect */ - 240, /* (373) oneselect ::= values */ - 254, /* (374) sclp ::= selcollist COMMA */ - 255, /* (375) as ::= ID|STRING */ - 264, /* (376) indexed_opt ::= indexed_by */ - 272, /* (377) returning ::= */ - 217, /* (378) expr ::= term */ - 274, /* (379) likeop ::= LIKE_KW|MATCH */ - 278, /* (380) case_operand ::= expr */ - 261, /* (381) exprlist ::= nexprlist */ - 284, /* (382) nmnum ::= plus_num */ - 284, /* (383) nmnum ::= nm */ - 284, /* (384) nmnum ::= ON */ - 284, /* (385) nmnum ::= DELETE */ - 284, /* (386) nmnum ::= DEFAULT */ - 211, /* (387) plus_num ::= INTEGER|FLOAT */ - 289, /* (388) foreach_clause ::= */ - 289, /* (389) foreach_clause ::= FOR EACH ROW */ - 292, /* (390) trnm ::= nm */ - 293, /* (391) tridxby ::= */ - 294, /* (392) database_kw_opt ::= DATABASE */ - 294, /* (393) database_kw_opt ::= */ - 297, /* (394) kwcolumn_opt ::= */ - 297, /* (395) kwcolumn_opt ::= COLUMNKW */ - 299, /* (396) vtabarglist ::= vtabarg */ - 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ - 300, /* (398) vtabarg ::= vtabarg vtabargtoken */ - 303, /* (399) anylist ::= */ - 303, /* (400) anylist ::= anylist LP anylist RP */ - 303, /* (401) anylist ::= anylist ANY */ - 266, /* (402) with ::= */ - 306, /* (403) windowdefn_list ::= windowdefn */ - 308, /* (404) window ::= frame_opt */ + 190, /* (0) explain ::= EXPLAIN */ + 190, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 189, /* (2) cmdx ::= cmd */ + 191, /* (3) cmd ::= BEGIN transtype trans_opt */ + 192, /* (4) transtype ::= */ + 192, /* (5) transtype ::= DEFERRED */ + 192, /* (6) transtype ::= IMMEDIATE */ + 192, /* (7) transtype ::= EXCLUSIVE */ + 191, /* (8) cmd ::= COMMIT|END trans_opt */ + 191, /* (9) cmd ::= ROLLBACK trans_opt */ + 191, /* (10) cmd ::= SAVEPOINT nm */ + 191, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 191, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 196, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 198, /* (14) createkw ::= CREATE */ + 200, /* (15) ifnotexists ::= */ + 200, /* (16) ifnotexists ::= IF NOT EXISTS */ + 199, /* (17) temp ::= TEMP */ + 199, /* (18) temp ::= */ + 197, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ + 197, /* (20) create_table_args ::= AS select */ + 204, /* (21) table_option_set ::= */ + 204, /* (22) table_option_set ::= table_option_set COMMA table_option */ + 206, /* (23) table_option ::= WITHOUT nm */ + 206, /* (24) table_option ::= nm */ + 207, /* (25) columnname ::= nm typetoken */ + 209, /* (26) typetoken ::= */ + 209, /* (27) typetoken ::= typename LP signed RP */ + 209, /* (28) typetoken ::= typename LP signed COMMA signed RP */ + 210, /* (29) typename ::= typename ID|STRING */ + 214, /* (30) scanpt ::= */ + 215, /* (31) scantok ::= */ + 216, /* (32) ccons ::= CONSTRAINT nm */ + 216, /* (33) ccons ::= DEFAULT scantok term */ + 216, /* (34) ccons ::= DEFAULT LP expr RP */ + 216, /* (35) ccons ::= DEFAULT PLUS scantok term */ + 216, /* (36) ccons ::= DEFAULT MINUS scantok term */ + 216, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ + 216, /* (38) ccons ::= NOT NULL onconf */ + 216, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 216, /* (40) ccons ::= UNIQUE onconf */ + 216, /* (41) ccons ::= CHECK LP expr RP */ + 216, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ + 216, /* (43) ccons ::= defer_subclause */ + 216, /* (44) ccons ::= COLLATE ID|STRING */ + 225, /* (45) generated ::= LP expr RP */ + 225, /* (46) generated ::= LP expr RP ID */ + 221, /* (47) autoinc ::= */ + 221, /* (48) autoinc ::= AUTOINCR */ + 223, /* (49) refargs ::= */ + 223, /* (50) refargs ::= refargs refarg */ + 226, /* (51) refarg ::= MATCH nm */ + 226, /* (52) refarg ::= ON INSERT refact */ + 226, /* (53) refarg ::= ON DELETE refact */ + 226, /* (54) refarg ::= ON UPDATE refact */ + 227, /* (55) refact ::= SET NULL */ + 227, /* (56) refact ::= SET DEFAULT */ + 227, /* (57) refact ::= CASCADE */ + 227, /* (58) refact ::= RESTRICT */ + 227, /* (59) refact ::= NO ACTION */ + 224, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 224, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 228, /* (62) init_deferred_pred_opt ::= */ + 228, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 228, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 203, /* (65) conslist_opt ::= */ + 230, /* (66) tconscomma ::= COMMA */ + 231, /* (67) tcons ::= CONSTRAINT nm */ + 231, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 231, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ + 231, /* (70) tcons ::= CHECK LP expr RP onconf */ + 231, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 234, /* (72) defer_subclause_opt ::= */ + 219, /* (73) onconf ::= */ + 219, /* (74) onconf ::= ON CONFLICT resolvetype */ + 235, /* (75) orconf ::= */ + 235, /* (76) orconf ::= OR resolvetype */ + 236, /* (77) resolvetype ::= IGNORE */ + 236, /* (78) resolvetype ::= REPLACE */ + 191, /* (79) cmd ::= DROP TABLE ifexists fullname */ + 238, /* (80) ifexists ::= IF EXISTS */ + 238, /* (81) ifexists ::= */ + 191, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 191, /* (83) cmd ::= DROP VIEW ifexists fullname */ + 191, /* (84) cmd ::= select */ + 205, /* (85) select ::= WITH wqlist selectnowith */ + 205, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ + 205, /* (87) select ::= selectnowith */ + 240, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ + 243, /* (89) multiselect_op ::= UNION */ + 243, /* (90) multiselect_op ::= UNION ALL */ + 243, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ + 241, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 241, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 253, /* (94) values ::= VALUES LP nexprlist RP */ + 241, /* (95) oneselect ::= mvalues */ + 255, /* (96) mvalues ::= values COMMA LP nexprlist RP */ + 255, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */ + 244, /* (98) distinct ::= DISTINCT */ + 244, /* (99) distinct ::= ALL */ + 244, /* (100) distinct ::= */ + 256, /* (101) sclp ::= */ + 245, /* (102) selcollist ::= sclp scanpt expr scanpt as */ + 245, /* (103) selcollist ::= sclp scanpt STAR */ + 245, /* (104) selcollist ::= sclp scanpt nm DOT STAR */ + 257, /* (105) as ::= AS nm */ + 257, /* (106) as ::= */ + 246, /* (107) from ::= */ + 246, /* (108) from ::= FROM seltablist */ + 259, /* (109) stl_prefix ::= seltablist joinop */ + 259, /* (110) stl_prefix ::= */ + 258, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */ + 258, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + 258, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + 258, /* (114) seltablist ::= stl_prefix LP select RP as on_using */ + 258, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */ + 201, /* (116) dbnm ::= */ + 201, /* (117) dbnm ::= DOT nm */ + 239, /* (118) fullname ::= nm */ + 239, /* (119) fullname ::= nm DOT nm */ + 264, /* (120) xfullname ::= nm */ + 264, /* (121) xfullname ::= nm DOT nm */ + 264, /* (122) xfullname ::= nm DOT nm AS nm */ + 264, /* (123) xfullname ::= nm AS nm */ + 260, /* (124) joinop ::= COMMA|JOIN */ + 260, /* (125) joinop ::= JOIN_KW JOIN */ + 260, /* (126) joinop ::= JOIN_KW nm JOIN */ + 260, /* (127) joinop ::= JOIN_KW nm nm JOIN */ + 261, /* (128) on_using ::= ON expr */ + 261, /* (129) on_using ::= USING LP idlist RP */ + 261, /* (130) on_using ::= */ + 266, /* (131) indexed_opt ::= */ + 262, /* (132) indexed_by ::= INDEXED BY nm */ + 262, /* (133) indexed_by ::= NOT INDEXED */ + 250, /* (134) orderby_opt ::= */ + 250, /* (135) orderby_opt ::= ORDER BY sortlist */ + 232, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */ + 232, /* (137) sortlist ::= expr sortorder nulls */ + 220, /* (138) sortorder ::= ASC */ + 220, /* (139) sortorder ::= DESC */ + 220, /* (140) sortorder ::= */ + 267, /* (141) nulls ::= NULLS FIRST */ + 267, /* (142) nulls ::= NULLS LAST */ + 267, /* (143) nulls ::= */ + 248, /* (144) groupby_opt ::= */ + 248, /* (145) groupby_opt ::= GROUP BY nexprlist */ + 249, /* (146) having_opt ::= */ + 249, /* (147) having_opt ::= HAVING expr */ + 251, /* (148) limit_opt ::= */ + 251, /* (149) limit_opt ::= LIMIT expr */ + 251, /* (150) limit_opt ::= LIMIT expr OFFSET expr */ + 251, /* (151) limit_opt ::= LIMIT expr COMMA expr */ + 191, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 247, /* (153) where_opt ::= */ + 247, /* (154) where_opt ::= WHERE expr */ + 269, /* (155) where_opt_ret ::= */ + 269, /* (156) where_opt_ret ::= WHERE expr */ + 269, /* (157) where_opt_ret ::= RETURNING selcollist */ + 269, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 191, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + 270, /* (160) setlist ::= setlist COMMA nm EQ expr */ + 270, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 270, /* (162) setlist ::= nm EQ expr */ + 270, /* (163) setlist ::= LP idlist RP EQ expr */ + 191, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 191, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 273, /* (166) upsert ::= */ + 273, /* (167) upsert ::= RETURNING selcollist */ + 273, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 273, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 273, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */ + 273, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 274, /* (172) returning ::= RETURNING selcollist */ + 271, /* (173) insert_cmd ::= INSERT orconf */ + 271, /* (174) insert_cmd ::= REPLACE */ + 272, /* (175) idlist_opt ::= */ + 272, /* (176) idlist_opt ::= LP idlist RP */ + 265, /* (177) idlist ::= idlist COMMA nm */ + 265, /* (178) idlist ::= nm */ + 218, /* (179) expr ::= LP expr RP */ + 218, /* (180) expr ::= ID|INDEXED|JOIN_KW */ + 218, /* (181) expr ::= nm DOT nm */ + 218, /* (182) expr ::= nm DOT nm DOT nm */ + 217, /* (183) term ::= NULL|FLOAT|BLOB */ + 217, /* (184) term ::= STRING */ + 217, /* (185) term ::= INTEGER */ + 218, /* (186) expr ::= VARIABLE */ + 218, /* (187) expr ::= expr COLLATE ID|STRING */ + 218, /* (188) expr ::= CAST LP expr AS typetoken RP */ + 218, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + 218, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + 218, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + 218, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + 218, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + 218, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + 217, /* (195) term ::= CTIME_KW */ + 218, /* (196) expr ::= LP nexprlist COMMA expr RP */ + 218, /* (197) expr ::= expr AND expr */ + 218, /* (198) expr ::= expr OR expr */ + 218, /* (199) expr ::= expr LT|GT|GE|LE expr */ + 218, /* (200) expr ::= expr EQ|NE expr */ + 218, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 218, /* (202) expr ::= expr PLUS|MINUS expr */ + 218, /* (203) expr ::= expr STAR|SLASH|REM expr */ + 218, /* (204) expr ::= expr CONCAT expr */ + 276, /* (205) likeop ::= NOT LIKE_KW|MATCH */ + 218, /* (206) expr ::= expr likeop expr */ + 218, /* (207) expr ::= expr likeop expr ESCAPE expr */ + 218, /* (208) expr ::= expr ISNULL|NOTNULL */ + 218, /* (209) expr ::= expr NOT NULL */ + 218, /* (210) expr ::= expr IS expr */ + 218, /* (211) expr ::= expr IS NOT expr */ + 218, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */ + 218, /* (213) expr ::= expr IS DISTINCT FROM expr */ + 218, /* (214) expr ::= NOT expr */ + 218, /* (215) expr ::= BITNOT expr */ + 218, /* (216) expr ::= PLUS|MINUS expr */ + 218, /* (217) expr ::= expr PTR expr */ + 277, /* (218) between_op ::= BETWEEN */ + 277, /* (219) between_op ::= NOT BETWEEN */ + 218, /* (220) expr ::= expr between_op expr AND expr */ + 278, /* (221) in_op ::= IN */ + 278, /* (222) in_op ::= NOT IN */ + 218, /* (223) expr ::= expr in_op LP exprlist RP */ + 218, /* (224) expr ::= LP select RP */ + 218, /* (225) expr ::= expr in_op LP select RP */ + 218, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */ + 218, /* (227) expr ::= EXISTS LP select RP */ + 218, /* (228) expr ::= CASE case_operand case_exprlist case_else END */ + 281, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 281, /* (230) case_exprlist ::= WHEN expr THEN expr */ + 282, /* (231) case_else ::= ELSE expr */ + 282, /* (232) case_else ::= */ + 280, /* (233) case_operand ::= */ + 263, /* (234) exprlist ::= */ + 254, /* (235) nexprlist ::= nexprlist COMMA expr */ + 254, /* (236) nexprlist ::= expr */ + 279, /* (237) paren_exprlist ::= */ + 279, /* (238) paren_exprlist ::= LP exprlist RP */ + 191, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 283, /* (240) uniqueflag ::= UNIQUE */ + 283, /* (241) uniqueflag ::= */ + 222, /* (242) eidlist_opt ::= */ + 222, /* (243) eidlist_opt ::= LP eidlist RP */ + 233, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */ + 233, /* (245) eidlist ::= nm collate sortorder */ + 284, /* (246) collate ::= */ + 284, /* (247) collate ::= COLLATE ID|STRING */ + 191, /* (248) cmd ::= DROP INDEX ifexists fullname */ + 191, /* (249) cmd ::= VACUUM vinto */ + 191, /* (250) cmd ::= VACUUM nm vinto */ + 285, /* (251) vinto ::= INTO expr */ + 285, /* (252) vinto ::= */ + 191, /* (253) cmd ::= PRAGMA nm dbnm */ + 191, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 191, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 191, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 191, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 212, /* (258) plus_num ::= PLUS INTEGER|FLOAT */ + 213, /* (259) minus_num ::= MINUS INTEGER|FLOAT */ + 191, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 287, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 289, /* (262) trigger_time ::= BEFORE|AFTER */ + 289, /* (263) trigger_time ::= INSTEAD OF */ + 289, /* (264) trigger_time ::= */ + 290, /* (265) trigger_event ::= DELETE|INSERT */ + 290, /* (266) trigger_event ::= UPDATE */ + 290, /* (267) trigger_event ::= UPDATE OF idlist */ + 292, /* (268) when_clause ::= */ + 292, /* (269) when_clause ::= WHEN expr */ + 288, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 288, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ + 294, /* (272) trnm ::= nm DOT nm */ + 295, /* (273) tridxby ::= INDEXED BY nm */ + 295, /* (274) tridxby ::= NOT INDEXED */ + 293, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 293, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 293, /* (278) trigger_cmd ::= scanpt select scanpt */ + 218, /* (279) expr ::= RAISE LP IGNORE RP */ + 218, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ + 237, /* (281) raisetype ::= ROLLBACK */ + 237, /* (282) raisetype ::= ABORT */ + 237, /* (283) raisetype ::= FAIL */ + 191, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ + 191, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 191, /* (286) cmd ::= DETACH database_kw_opt expr */ + 297, /* (287) key_opt ::= */ + 297, /* (288) key_opt ::= KEY expr */ + 191, /* (289) cmd ::= REINDEX */ + 191, /* (290) cmd ::= REINDEX nm dbnm */ + 191, /* (291) cmd ::= ANALYZE */ + 191, /* (292) cmd ::= ANALYZE nm dbnm */ + 191, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 191, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 191, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 298, /* (296) add_column_fullname ::= fullname */ + 191, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 191, /* (298) cmd ::= create_vtab */ + 191, /* (299) cmd ::= create_vtab LP vtabarglist RP */ + 300, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 302, /* (301) vtabarg ::= */ + 303, /* (302) vtabargtoken ::= ANY */ + 303, /* (303) vtabargtoken ::= lp anylist RP */ + 304, /* (304) lp ::= LP */ + 268, /* (305) with ::= WITH wqlist */ + 268, /* (306) with ::= WITH RECURSIVE wqlist */ + 307, /* (307) wqas ::= AS */ + 307, /* (308) wqas ::= AS MATERIALIZED */ + 307, /* (309) wqas ::= AS NOT MATERIALIZED */ + 306, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */ + 308, /* (311) withnm ::= nm */ + 242, /* (312) wqlist ::= wqitem */ + 242, /* (313) wqlist ::= wqlist COMMA wqitem */ + 309, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 310, /* (315) windowdefn ::= nm AS LP window RP */ + 311, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 311, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 311, /* (318) window ::= ORDER BY sortlist frame_opt */ + 311, /* (319) window ::= nm ORDER BY sortlist frame_opt */ + 311, /* (320) window ::= nm frame_opt */ + 312, /* (321) frame_opt ::= */ + 312, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 312, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 316, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */ + 318, /* (325) frame_bound_s ::= frame_bound */ + 318, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */ + 319, /* (327) frame_bound_e ::= frame_bound */ + 319, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 317, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */ + 317, /* (330) frame_bound ::= CURRENT ROW */ + 320, /* (331) frame_exclude_opt ::= */ + 320, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 321, /* (333) frame_exclude ::= NO OTHERS */ + 321, /* (334) frame_exclude ::= CURRENT ROW */ + 321, /* (335) frame_exclude ::= GROUP|TIES */ + 252, /* (336) window_clause ::= WINDOW windowdefn_list */ + 275, /* (337) filter_over ::= filter_clause over_clause */ + 275, /* (338) filter_over ::= over_clause */ + 275, /* (339) filter_over ::= filter_clause */ + 315, /* (340) over_clause ::= OVER LP window RP */ + 315, /* (341) over_clause ::= OVER nm */ + 314, /* (342) filter_clause ::= FILTER LP WHERE expr RP */ + 217, /* (343) term ::= QNUMBER */ + 186, /* (344) input ::= cmdlist */ + 187, /* (345) cmdlist ::= cmdlist ecmd */ + 187, /* (346) cmdlist ::= ecmd */ + 188, /* (347) ecmd ::= SEMI */ + 188, /* (348) ecmd ::= cmdx SEMI */ + 188, /* (349) ecmd ::= explain cmdx SEMI */ + 193, /* (350) trans_opt ::= */ + 193, /* (351) trans_opt ::= TRANSACTION */ + 193, /* (352) trans_opt ::= TRANSACTION nm */ + 195, /* (353) savepoint_opt ::= SAVEPOINT */ + 195, /* (354) savepoint_opt ::= */ + 191, /* (355) cmd ::= create_table create_table_args */ + 204, /* (356) table_option_set ::= table_option */ + 202, /* (357) columnlist ::= columnlist COMMA columnname carglist */ + 202, /* (358) columnlist ::= columnname carglist */ + 194, /* (359) nm ::= ID|INDEXED|JOIN_KW */ + 194, /* (360) nm ::= STRING */ + 209, /* (361) typetoken ::= typename */ + 210, /* (362) typename ::= ID|STRING */ + 211, /* (363) signed ::= plus_num */ + 211, /* (364) signed ::= minus_num */ + 208, /* (365) carglist ::= carglist ccons */ + 208, /* (366) carglist ::= */ + 216, /* (367) ccons ::= NULL onconf */ + 216, /* (368) ccons ::= GENERATED ALWAYS AS generated */ + 216, /* (369) ccons ::= AS generated */ + 203, /* (370) conslist_opt ::= COMMA conslist */ + 229, /* (371) conslist ::= conslist tconscomma tcons */ + 229, /* (372) conslist ::= tcons */ + 230, /* (373) tconscomma ::= */ + 234, /* (374) defer_subclause_opt ::= defer_subclause */ + 236, /* (375) resolvetype ::= raisetype */ + 240, /* (376) selectnowith ::= oneselect */ + 241, /* (377) oneselect ::= values */ + 256, /* (378) sclp ::= selcollist COMMA */ + 257, /* (379) as ::= ID|STRING */ + 266, /* (380) indexed_opt ::= indexed_by */ + 274, /* (381) returning ::= */ + 218, /* (382) expr ::= term */ + 276, /* (383) likeop ::= LIKE_KW|MATCH */ + 280, /* (384) case_operand ::= expr */ + 263, /* (385) exprlist ::= nexprlist */ + 286, /* (386) nmnum ::= plus_num */ + 286, /* (387) nmnum ::= nm */ + 286, /* (388) nmnum ::= ON */ + 286, /* (389) nmnum ::= DELETE */ + 286, /* (390) nmnum ::= DEFAULT */ + 212, /* (391) plus_num ::= INTEGER|FLOAT */ + 291, /* (392) foreach_clause ::= */ + 291, /* (393) foreach_clause ::= FOR EACH ROW */ + 294, /* (394) trnm ::= nm */ + 295, /* (395) tridxby ::= */ + 296, /* (396) database_kw_opt ::= DATABASE */ + 296, /* (397) database_kw_opt ::= */ + 299, /* (398) kwcolumn_opt ::= */ + 299, /* (399) kwcolumn_opt ::= COLUMNKW */ + 301, /* (400) vtabarglist ::= vtabarg */ + 301, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ + 302, /* (402) vtabarg ::= vtabarg vtabargtoken */ + 305, /* (403) anylist ::= */ + 305, /* (404) anylist ::= anylist LP anylist RP */ + 305, /* (405) anylist ::= anylist ANY */ + 268, /* (406) with ::= */ + 309, /* (407) windowdefn_list ::= windowdefn */ + 311, /* (408) window ::= frame_opt */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -173647,316 +177267,320 @@ static const signed char yyRuleInfoNRhs[] = { -9, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ -10, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ -4, /* (94) values ::= VALUES LP nexprlist RP */ - -5, /* (95) values ::= values COMMA LP nexprlist RP */ - -1, /* (96) distinct ::= DISTINCT */ - -1, /* (97) distinct ::= ALL */ - 0, /* (98) distinct ::= */ - 0, /* (99) sclp ::= */ - -5, /* (100) selcollist ::= sclp scanpt expr scanpt as */ - -3, /* (101) selcollist ::= sclp scanpt STAR */ - -5, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ - -2, /* (103) as ::= AS nm */ - 0, /* (104) as ::= */ - 0, /* (105) from ::= */ - -2, /* (106) from ::= FROM seltablist */ - -2, /* (107) stl_prefix ::= seltablist joinop */ - 0, /* (108) stl_prefix ::= */ - -5, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ - -6, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ - -8, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ - -6, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ - -6, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ - 0, /* (114) dbnm ::= */ - -2, /* (115) dbnm ::= DOT nm */ - -1, /* (116) fullname ::= nm */ - -3, /* (117) fullname ::= nm DOT nm */ - -1, /* (118) xfullname ::= nm */ - -3, /* (119) xfullname ::= nm DOT nm */ - -5, /* (120) xfullname ::= nm DOT nm AS nm */ - -3, /* (121) xfullname ::= nm AS nm */ - -1, /* (122) joinop ::= COMMA|JOIN */ - -2, /* (123) joinop ::= JOIN_KW JOIN */ - -3, /* (124) joinop ::= JOIN_KW nm JOIN */ - -4, /* (125) joinop ::= JOIN_KW nm nm JOIN */ - -2, /* (126) on_using ::= ON expr */ - -4, /* (127) on_using ::= USING LP idlist RP */ - 0, /* (128) on_using ::= */ - 0, /* (129) indexed_opt ::= */ - -3, /* (130) indexed_by ::= INDEXED BY nm */ - -2, /* (131) indexed_by ::= NOT INDEXED */ - 0, /* (132) orderby_opt ::= */ - -3, /* (133) orderby_opt ::= ORDER BY sortlist */ - -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ - -3, /* (135) sortlist ::= expr sortorder nulls */ - -1, /* (136) sortorder ::= ASC */ - -1, /* (137) sortorder ::= DESC */ - 0, /* (138) sortorder ::= */ - -2, /* (139) nulls ::= NULLS FIRST */ - -2, /* (140) nulls ::= NULLS LAST */ - 0, /* (141) nulls ::= */ - 0, /* (142) groupby_opt ::= */ - -3, /* (143) groupby_opt ::= GROUP BY nexprlist */ - 0, /* (144) having_opt ::= */ - -2, /* (145) having_opt ::= HAVING expr */ - 0, /* (146) limit_opt ::= */ - -2, /* (147) limit_opt ::= LIMIT expr */ - -4, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ - -4, /* (149) limit_opt ::= LIMIT expr COMMA expr */ - -6, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ - 0, /* (151) where_opt ::= */ - -2, /* (152) where_opt ::= WHERE expr */ - 0, /* (153) where_opt_ret ::= */ - -2, /* (154) where_opt_ret ::= WHERE expr */ - -2, /* (155) where_opt_ret ::= RETURNING selcollist */ - -4, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ - -9, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ - -5, /* (158) setlist ::= setlist COMMA nm EQ expr */ - -7, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ - -3, /* (160) setlist ::= nm EQ expr */ - -5, /* (161) setlist ::= LP idlist RP EQ expr */ - -7, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - -8, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ - 0, /* (164) upsert ::= */ - -2, /* (165) upsert ::= RETURNING selcollist */ - -12, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ - -9, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ - -5, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ - -8, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ - -2, /* (170) returning ::= RETURNING selcollist */ - -2, /* (171) insert_cmd ::= INSERT orconf */ - -1, /* (172) insert_cmd ::= REPLACE */ - 0, /* (173) idlist_opt ::= */ - -3, /* (174) idlist_opt ::= LP idlist RP */ - -3, /* (175) idlist ::= idlist COMMA nm */ - -1, /* (176) idlist ::= nm */ - -3, /* (177) expr ::= LP expr RP */ - -1, /* (178) expr ::= ID|INDEXED|JOIN_KW */ - -3, /* (179) expr ::= nm DOT nm */ - -5, /* (180) expr ::= nm DOT nm DOT nm */ - -1, /* (181) term ::= NULL|FLOAT|BLOB */ - -1, /* (182) term ::= STRING */ - -1, /* (183) term ::= INTEGER */ - -1, /* (184) expr ::= VARIABLE */ - -3, /* (185) expr ::= expr COLLATE ID|STRING */ - -6, /* (186) expr ::= CAST LP expr AS typetoken RP */ - -5, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - -8, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ - -4, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - -6, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - -9, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ - -5, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - -1, /* (193) term ::= CTIME_KW */ - -5, /* (194) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (195) expr ::= expr AND expr */ - -3, /* (196) expr ::= expr OR expr */ - -3, /* (197) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (198) expr ::= expr EQ|NE expr */ - -3, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (200) expr ::= expr PLUS|MINUS expr */ - -3, /* (201) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (202) expr ::= expr CONCAT expr */ - -2, /* (203) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (204) expr ::= expr likeop expr */ - -5, /* (205) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (206) expr ::= expr ISNULL|NOTNULL */ - -3, /* (207) expr ::= expr NOT NULL */ - -3, /* (208) expr ::= expr IS expr */ - -4, /* (209) expr ::= expr IS NOT expr */ - -6, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ - -5, /* (211) expr ::= expr IS DISTINCT FROM expr */ - -2, /* (212) expr ::= NOT expr */ - -2, /* (213) expr ::= BITNOT expr */ - -2, /* (214) expr ::= PLUS|MINUS expr */ - -3, /* (215) expr ::= expr PTR expr */ - -1, /* (216) between_op ::= BETWEEN */ - -2, /* (217) between_op ::= NOT BETWEEN */ - -5, /* (218) expr ::= expr between_op expr AND expr */ - -1, /* (219) in_op ::= IN */ - -2, /* (220) in_op ::= NOT IN */ - -5, /* (221) expr ::= expr in_op LP exprlist RP */ - -3, /* (222) expr ::= LP select RP */ - -5, /* (223) expr ::= expr in_op LP select RP */ - -5, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (225) expr ::= EXISTS LP select RP */ - -5, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (228) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (229) case_else ::= ELSE expr */ - 0, /* (230) case_else ::= */ - 0, /* (231) case_operand ::= */ - 0, /* (232) exprlist ::= */ - -3, /* (233) nexprlist ::= nexprlist COMMA expr */ - -1, /* (234) nexprlist ::= expr */ - 0, /* (235) paren_exprlist ::= */ - -3, /* (236) paren_exprlist ::= LP exprlist RP */ - -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (238) uniqueflag ::= UNIQUE */ - 0, /* (239) uniqueflag ::= */ - 0, /* (240) eidlist_opt ::= */ - -3, /* (241) eidlist_opt ::= LP eidlist RP */ - -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (243) eidlist ::= nm collate sortorder */ - 0, /* (244) collate ::= */ - -2, /* (245) collate ::= COLLATE ID|STRING */ - -4, /* (246) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (247) cmd ::= VACUUM vinto */ - -3, /* (248) cmd ::= VACUUM nm vinto */ - -2, /* (249) vinto ::= INTO expr */ - 0, /* (250) vinto ::= */ - -3, /* (251) cmd ::= PRAGMA nm dbnm */ - -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (260) trigger_time ::= BEFORE|AFTER */ - -2, /* (261) trigger_time ::= INSTEAD OF */ - 0, /* (262) trigger_time ::= */ - -1, /* (263) trigger_event ::= DELETE|INSERT */ - -1, /* (264) trigger_event ::= UPDATE */ - -3, /* (265) trigger_event ::= UPDATE OF idlist */ - 0, /* (266) when_clause ::= */ - -2, /* (267) when_clause ::= WHEN expr */ - -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (270) trnm ::= nm DOT nm */ - -3, /* (271) tridxby ::= INDEXED BY nm */ - -2, /* (272) tridxby ::= NOT INDEXED */ - -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (276) trigger_cmd ::= scanpt select scanpt */ - -4, /* (277) expr ::= RAISE LP IGNORE RP */ - -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (279) raisetype ::= ROLLBACK */ - -1, /* (280) raisetype ::= ABORT */ - -1, /* (281) raisetype ::= FAIL */ - -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (284) cmd ::= DETACH database_kw_opt expr */ - 0, /* (285) key_opt ::= */ - -2, /* (286) key_opt ::= KEY expr */ - -1, /* (287) cmd ::= REINDEX */ - -3, /* (288) cmd ::= REINDEX nm dbnm */ - -1, /* (289) cmd ::= ANALYZE */ - -3, /* (290) cmd ::= ANALYZE nm dbnm */ - -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - -1, /* (294) add_column_fullname ::= fullname */ - -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (296) cmd ::= create_vtab */ - -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (299) vtabarg ::= */ - -1, /* (300) vtabargtoken ::= ANY */ - -3, /* (301) vtabargtoken ::= lp anylist RP */ - -1, /* (302) lp ::= LP */ - -2, /* (303) with ::= WITH wqlist */ - -3, /* (304) with ::= WITH RECURSIVE wqlist */ - -1, /* (305) wqas ::= AS */ - -2, /* (306) wqas ::= AS MATERIALIZED */ - -3, /* (307) wqas ::= AS NOT MATERIALIZED */ - -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ - -1, /* (309) wqlist ::= wqitem */ - -3, /* (310) wqlist ::= wqlist COMMA wqitem */ - -3, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (312) windowdefn ::= nm AS LP window RP */ - -5, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (315) window ::= ORDER BY sortlist frame_opt */ - -5, /* (316) window ::= nm ORDER BY sortlist frame_opt */ - -2, /* (317) window ::= nm frame_opt */ - 0, /* (318) frame_opt ::= */ - -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (322) frame_bound_s ::= frame_bound */ - -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (324) frame_bound_e ::= frame_bound */ - -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (327) frame_bound ::= CURRENT ROW */ - 0, /* (328) frame_exclude_opt ::= */ - -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (330) frame_exclude ::= NO OTHERS */ - -2, /* (331) frame_exclude ::= CURRENT ROW */ - -1, /* (332) frame_exclude ::= GROUP|TIES */ - -2, /* (333) window_clause ::= WINDOW windowdefn_list */ - -2, /* (334) filter_over ::= filter_clause over_clause */ - -1, /* (335) filter_over ::= over_clause */ - -1, /* (336) filter_over ::= filter_clause */ - -4, /* (337) over_clause ::= OVER LP window RP */ - -2, /* (338) over_clause ::= OVER nm */ - -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (340) input ::= cmdlist */ - -2, /* (341) cmdlist ::= cmdlist ecmd */ - -1, /* (342) cmdlist ::= ecmd */ - -1, /* (343) ecmd ::= SEMI */ - -2, /* (344) ecmd ::= cmdx SEMI */ - -3, /* (345) ecmd ::= explain cmdx SEMI */ - 0, /* (346) trans_opt ::= */ - -1, /* (347) trans_opt ::= TRANSACTION */ - -2, /* (348) trans_opt ::= TRANSACTION nm */ - -1, /* (349) savepoint_opt ::= SAVEPOINT */ - 0, /* (350) savepoint_opt ::= */ - -2, /* (351) cmd ::= create_table create_table_args */ - -1, /* (352) table_option_set ::= table_option */ - -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (354) columnlist ::= columnname carglist */ - -1, /* (355) nm ::= ID|INDEXED|JOIN_KW */ - -1, /* (356) nm ::= STRING */ - -1, /* (357) typetoken ::= typename */ - -1, /* (358) typename ::= ID|STRING */ - -1, /* (359) signed ::= plus_num */ - -1, /* (360) signed ::= minus_num */ - -2, /* (361) carglist ::= carglist ccons */ - 0, /* (362) carglist ::= */ - -2, /* (363) ccons ::= NULL onconf */ - -4, /* (364) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (365) ccons ::= AS generated */ - -2, /* (366) conslist_opt ::= COMMA conslist */ - -3, /* (367) conslist ::= conslist tconscomma tcons */ - -1, /* (368) conslist ::= tcons */ - 0, /* (369) tconscomma ::= */ - -1, /* (370) defer_subclause_opt ::= defer_subclause */ - -1, /* (371) resolvetype ::= raisetype */ - -1, /* (372) selectnowith ::= oneselect */ - -1, /* (373) oneselect ::= values */ - -2, /* (374) sclp ::= selcollist COMMA */ - -1, /* (375) as ::= ID|STRING */ - -1, /* (376) indexed_opt ::= indexed_by */ - 0, /* (377) returning ::= */ - -1, /* (378) expr ::= term */ - -1, /* (379) likeop ::= LIKE_KW|MATCH */ - -1, /* (380) case_operand ::= expr */ - -1, /* (381) exprlist ::= nexprlist */ - -1, /* (382) nmnum ::= plus_num */ - -1, /* (383) nmnum ::= nm */ - -1, /* (384) nmnum ::= ON */ - -1, /* (385) nmnum ::= DELETE */ - -1, /* (386) nmnum ::= DEFAULT */ - -1, /* (387) plus_num ::= INTEGER|FLOAT */ - 0, /* (388) foreach_clause ::= */ - -3, /* (389) foreach_clause ::= FOR EACH ROW */ - -1, /* (390) trnm ::= nm */ - 0, /* (391) tridxby ::= */ - -1, /* (392) database_kw_opt ::= DATABASE */ - 0, /* (393) database_kw_opt ::= */ - 0, /* (394) kwcolumn_opt ::= */ - -1, /* (395) kwcolumn_opt ::= COLUMNKW */ - -1, /* (396) vtabarglist ::= vtabarg */ - -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (398) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (399) anylist ::= */ - -4, /* (400) anylist ::= anylist LP anylist RP */ - -2, /* (401) anylist ::= anylist ANY */ - 0, /* (402) with ::= */ - -1, /* (403) windowdefn_list ::= windowdefn */ - -1, /* (404) window ::= frame_opt */ + -1, /* (95) oneselect ::= mvalues */ + -5, /* (96) mvalues ::= values COMMA LP nexprlist RP */ + -5, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */ + -1, /* (98) distinct ::= DISTINCT */ + -1, /* (99) distinct ::= ALL */ + 0, /* (100) distinct ::= */ + 0, /* (101) sclp ::= */ + -5, /* (102) selcollist ::= sclp scanpt expr scanpt as */ + -3, /* (103) selcollist ::= sclp scanpt STAR */ + -5, /* (104) selcollist ::= sclp scanpt nm DOT STAR */ + -2, /* (105) as ::= AS nm */ + 0, /* (106) as ::= */ + 0, /* (107) from ::= */ + -2, /* (108) from ::= FROM seltablist */ + -2, /* (109) stl_prefix ::= seltablist joinop */ + 0, /* (110) stl_prefix ::= */ + -5, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */ + -6, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + -8, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + -6, /* (114) seltablist ::= stl_prefix LP select RP as on_using */ + -6, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */ + 0, /* (116) dbnm ::= */ + -2, /* (117) dbnm ::= DOT nm */ + -1, /* (118) fullname ::= nm */ + -3, /* (119) fullname ::= nm DOT nm */ + -1, /* (120) xfullname ::= nm */ + -3, /* (121) xfullname ::= nm DOT nm */ + -5, /* (122) xfullname ::= nm DOT nm AS nm */ + -3, /* (123) xfullname ::= nm AS nm */ + -1, /* (124) joinop ::= COMMA|JOIN */ + -2, /* (125) joinop ::= JOIN_KW JOIN */ + -3, /* (126) joinop ::= JOIN_KW nm JOIN */ + -4, /* (127) joinop ::= JOIN_KW nm nm JOIN */ + -2, /* (128) on_using ::= ON expr */ + -4, /* (129) on_using ::= USING LP idlist RP */ + 0, /* (130) on_using ::= */ + 0, /* (131) indexed_opt ::= */ + -3, /* (132) indexed_by ::= INDEXED BY nm */ + -2, /* (133) indexed_by ::= NOT INDEXED */ + 0, /* (134) orderby_opt ::= */ + -3, /* (135) orderby_opt ::= ORDER BY sortlist */ + -5, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */ + -3, /* (137) sortlist ::= expr sortorder nulls */ + -1, /* (138) sortorder ::= ASC */ + -1, /* (139) sortorder ::= DESC */ + 0, /* (140) sortorder ::= */ + -2, /* (141) nulls ::= NULLS FIRST */ + -2, /* (142) nulls ::= NULLS LAST */ + 0, /* (143) nulls ::= */ + 0, /* (144) groupby_opt ::= */ + -3, /* (145) groupby_opt ::= GROUP BY nexprlist */ + 0, /* (146) having_opt ::= */ + -2, /* (147) having_opt ::= HAVING expr */ + 0, /* (148) limit_opt ::= */ + -2, /* (149) limit_opt ::= LIMIT expr */ + -4, /* (150) limit_opt ::= LIMIT expr OFFSET expr */ + -4, /* (151) limit_opt ::= LIMIT expr COMMA expr */ + -6, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 0, /* (153) where_opt ::= */ + -2, /* (154) where_opt ::= WHERE expr */ + 0, /* (155) where_opt_ret ::= */ + -2, /* (156) where_opt_ret ::= WHERE expr */ + -2, /* (157) where_opt_ret ::= RETURNING selcollist */ + -4, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */ + -9, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + -5, /* (160) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (162) setlist ::= nm EQ expr */ + -5, /* (163) setlist ::= LP idlist RP EQ expr */ + -7, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -8, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 0, /* (166) upsert ::= */ + -2, /* (167) upsert ::= RETURNING selcollist */ + -12, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + -9, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + -5, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */ + -8, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + -2, /* (172) returning ::= RETURNING selcollist */ + -2, /* (173) insert_cmd ::= INSERT orconf */ + -1, /* (174) insert_cmd ::= REPLACE */ + 0, /* (175) idlist_opt ::= */ + -3, /* (176) idlist_opt ::= LP idlist RP */ + -3, /* (177) idlist ::= idlist COMMA nm */ + -1, /* (178) idlist ::= nm */ + -3, /* (179) expr ::= LP expr RP */ + -1, /* (180) expr ::= ID|INDEXED|JOIN_KW */ + -3, /* (181) expr ::= nm DOT nm */ + -5, /* (182) expr ::= nm DOT nm DOT nm */ + -1, /* (183) term ::= NULL|FLOAT|BLOB */ + -1, /* (184) term ::= STRING */ + -1, /* (185) term ::= INTEGER */ + -1, /* (186) expr ::= VARIABLE */ + -3, /* (187) expr ::= expr COLLATE ID|STRING */ + -6, /* (188) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + -8, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + -4, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + -6, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + -9, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + -5, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + -1, /* (195) term ::= CTIME_KW */ + -5, /* (196) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (197) expr ::= expr AND expr */ + -3, /* (198) expr ::= expr OR expr */ + -3, /* (199) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (200) expr ::= expr EQ|NE expr */ + -3, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (202) expr ::= expr PLUS|MINUS expr */ + -3, /* (203) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (204) expr ::= expr CONCAT expr */ + -2, /* (205) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (206) expr ::= expr likeop expr */ + -5, /* (207) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (208) expr ::= expr ISNULL|NOTNULL */ + -3, /* (209) expr ::= expr NOT NULL */ + -3, /* (210) expr ::= expr IS expr */ + -4, /* (211) expr ::= expr IS NOT expr */ + -6, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */ + -5, /* (213) expr ::= expr IS DISTINCT FROM expr */ + -2, /* (214) expr ::= NOT expr */ + -2, /* (215) expr ::= BITNOT expr */ + -2, /* (216) expr ::= PLUS|MINUS expr */ + -3, /* (217) expr ::= expr PTR expr */ + -1, /* (218) between_op ::= BETWEEN */ + -2, /* (219) between_op ::= NOT BETWEEN */ + -5, /* (220) expr ::= expr between_op expr AND expr */ + -1, /* (221) in_op ::= IN */ + -2, /* (222) in_op ::= NOT IN */ + -5, /* (223) expr ::= expr in_op LP exprlist RP */ + -3, /* (224) expr ::= LP select RP */ + -5, /* (225) expr ::= expr in_op LP select RP */ + -5, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (227) expr ::= EXISTS LP select RP */ + -5, /* (228) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (230) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (231) case_else ::= ELSE expr */ + 0, /* (232) case_else ::= */ + 0, /* (233) case_operand ::= */ + 0, /* (234) exprlist ::= */ + -3, /* (235) nexprlist ::= nexprlist COMMA expr */ + -1, /* (236) nexprlist ::= expr */ + 0, /* (237) paren_exprlist ::= */ + -3, /* (238) paren_exprlist ::= LP exprlist RP */ + -12, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (240) uniqueflag ::= UNIQUE */ + 0, /* (241) uniqueflag ::= */ + 0, /* (242) eidlist_opt ::= */ + -3, /* (243) eidlist_opt ::= LP eidlist RP */ + -5, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (245) eidlist ::= nm collate sortorder */ + 0, /* (246) collate ::= */ + -2, /* (247) collate ::= COLLATE ID|STRING */ + -4, /* (248) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (249) cmd ::= VACUUM vinto */ + -3, /* (250) cmd ::= VACUUM nm vinto */ + -2, /* (251) vinto ::= INTO expr */ + 0, /* (252) vinto ::= */ + -3, /* (253) cmd ::= PRAGMA nm dbnm */ + -5, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (258) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (259) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (262) trigger_time ::= BEFORE|AFTER */ + -2, /* (263) trigger_time ::= INSTEAD OF */ + 0, /* (264) trigger_time ::= */ + -1, /* (265) trigger_event ::= DELETE|INSERT */ + -1, /* (266) trigger_event ::= UPDATE */ + -3, /* (267) trigger_event ::= UPDATE OF idlist */ + 0, /* (268) when_clause ::= */ + -2, /* (269) when_clause ::= WHEN expr */ + -3, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (272) trnm ::= nm DOT nm */ + -3, /* (273) tridxby ::= INDEXED BY nm */ + -2, /* (274) tridxby ::= NOT INDEXED */ + -9, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (278) trigger_cmd ::= scanpt select scanpt */ + -4, /* (279) expr ::= RAISE LP IGNORE RP */ + -6, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ + -1, /* (281) raisetype ::= ROLLBACK */ + -1, /* (282) raisetype ::= ABORT */ + -1, /* (283) raisetype ::= FAIL */ + -4, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (286) cmd ::= DETACH database_kw_opt expr */ + 0, /* (287) key_opt ::= */ + -2, /* (288) key_opt ::= KEY expr */ + -1, /* (289) cmd ::= REINDEX */ + -3, /* (290) cmd ::= REINDEX nm dbnm */ + -1, /* (291) cmd ::= ANALYZE */ + -3, /* (292) cmd ::= ANALYZE nm dbnm */ + -6, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (296) add_column_fullname ::= fullname */ + -8, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (298) cmd ::= create_vtab */ + -4, /* (299) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (301) vtabarg ::= */ + -1, /* (302) vtabargtoken ::= ANY */ + -3, /* (303) vtabargtoken ::= lp anylist RP */ + -1, /* (304) lp ::= LP */ + -2, /* (305) with ::= WITH wqlist */ + -3, /* (306) with ::= WITH RECURSIVE wqlist */ + -1, /* (307) wqas ::= AS */ + -2, /* (308) wqas ::= AS MATERIALIZED */ + -3, /* (309) wqas ::= AS NOT MATERIALIZED */ + -6, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */ + -1, /* (311) withnm ::= nm */ + -1, /* (312) wqlist ::= wqitem */ + -3, /* (313) wqlist ::= wqlist COMMA wqitem */ + -3, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (315) windowdefn ::= nm AS LP window RP */ + -5, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (318) window ::= ORDER BY sortlist frame_opt */ + -5, /* (319) window ::= nm ORDER BY sortlist frame_opt */ + -2, /* (320) window ::= nm frame_opt */ + 0, /* (321) frame_opt ::= */ + -3, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (325) frame_bound_s ::= frame_bound */ + -2, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (327) frame_bound_e ::= frame_bound */ + -2, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (330) frame_bound ::= CURRENT ROW */ + 0, /* (331) frame_exclude_opt ::= */ + -2, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (333) frame_exclude ::= NO OTHERS */ + -2, /* (334) frame_exclude ::= CURRENT ROW */ + -1, /* (335) frame_exclude ::= GROUP|TIES */ + -2, /* (336) window_clause ::= WINDOW windowdefn_list */ + -2, /* (337) filter_over ::= filter_clause over_clause */ + -1, /* (338) filter_over ::= over_clause */ + -1, /* (339) filter_over ::= filter_clause */ + -4, /* (340) over_clause ::= OVER LP window RP */ + -2, /* (341) over_clause ::= OVER nm */ + -5, /* (342) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (343) term ::= QNUMBER */ + -1, /* (344) input ::= cmdlist */ + -2, /* (345) cmdlist ::= cmdlist ecmd */ + -1, /* (346) cmdlist ::= ecmd */ + -1, /* (347) ecmd ::= SEMI */ + -2, /* (348) ecmd ::= cmdx SEMI */ + -3, /* (349) ecmd ::= explain cmdx SEMI */ + 0, /* (350) trans_opt ::= */ + -1, /* (351) trans_opt ::= TRANSACTION */ + -2, /* (352) trans_opt ::= TRANSACTION nm */ + -1, /* (353) savepoint_opt ::= SAVEPOINT */ + 0, /* (354) savepoint_opt ::= */ + -2, /* (355) cmd ::= create_table create_table_args */ + -1, /* (356) table_option_set ::= table_option */ + -4, /* (357) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (358) columnlist ::= columnname carglist */ + -1, /* (359) nm ::= ID|INDEXED|JOIN_KW */ + -1, /* (360) nm ::= STRING */ + -1, /* (361) typetoken ::= typename */ + -1, /* (362) typename ::= ID|STRING */ + -1, /* (363) signed ::= plus_num */ + -1, /* (364) signed ::= minus_num */ + -2, /* (365) carglist ::= carglist ccons */ + 0, /* (366) carglist ::= */ + -2, /* (367) ccons ::= NULL onconf */ + -4, /* (368) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (369) ccons ::= AS generated */ + -2, /* (370) conslist_opt ::= COMMA conslist */ + -3, /* (371) conslist ::= conslist tconscomma tcons */ + -1, /* (372) conslist ::= tcons */ + 0, /* (373) tconscomma ::= */ + -1, /* (374) defer_subclause_opt ::= defer_subclause */ + -1, /* (375) resolvetype ::= raisetype */ + -1, /* (376) selectnowith ::= oneselect */ + -1, /* (377) oneselect ::= values */ + -2, /* (378) sclp ::= selcollist COMMA */ + -1, /* (379) as ::= ID|STRING */ + -1, /* (380) indexed_opt ::= indexed_by */ + 0, /* (381) returning ::= */ + -1, /* (382) expr ::= term */ + -1, /* (383) likeop ::= LIKE_KW|MATCH */ + -1, /* (384) case_operand ::= expr */ + -1, /* (385) exprlist ::= nexprlist */ + -1, /* (386) nmnum ::= plus_num */ + -1, /* (387) nmnum ::= nm */ + -1, /* (388) nmnum ::= ON */ + -1, /* (389) nmnum ::= DELETE */ + -1, /* (390) nmnum ::= DEFAULT */ + -1, /* (391) plus_num ::= INTEGER|FLOAT */ + 0, /* (392) foreach_clause ::= */ + -3, /* (393) foreach_clause ::= FOR EACH ROW */ + -1, /* (394) trnm ::= nm */ + 0, /* (395) tridxby ::= */ + -1, /* (396) database_kw_opt ::= DATABASE */ + 0, /* (397) database_kw_opt ::= */ + 0, /* (398) kwcolumn_opt ::= */ + -1, /* (399) kwcolumn_opt ::= COLUMNKW */ + -1, /* (400) vtabarglist ::= vtabarg */ + -3, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (402) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (403) anylist ::= */ + -4, /* (404) anylist ::= anylist LP anylist RP */ + -2, /* (405) anylist ::= anylist ANY */ + 0, /* (406) with ::= */ + -1, /* (407) windowdefn_list ::= windowdefn */ + -1, /* (408) window ::= frame_opt */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -174008,16 +177632,16 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy394);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy394 = TK_DEFERRED;} +{yymsp[1].minor.yy144 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); - case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321); -{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} + case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324); +{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -174040,7 +177664,7 @@ static YYACTIONTYPE yy_reduce( break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy394,0,0,yymsp[-2].minor.yy394); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144); } break; case 14: /* createkw ::= CREATE */ @@ -174052,40 +177676,40 @@ static YYACTIONTYPE yy_reduce( case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62); case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); case 81: /* ifexists ::= */ yytestcase(yyruleno==81); - case 98: /* distinct ::= */ yytestcase(yyruleno==98); - case 244: /* collate ::= */ yytestcase(yyruleno==244); -{yymsp[1].minor.yy394 = 0;} + case 100: /* distinct ::= */ yytestcase(yyruleno==100); + case 246: /* collate ::= */ yytestcase(yyruleno==246); +{yymsp[1].minor.yy144 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy394 = 1;} +{yymsp[-2].minor.yy144 = 1;} break; case 17: /* temp ::= TEMP */ -{yymsp[0].minor.yy394 = pParse->db->init.busy==0;} +{yymsp[0].minor.yy144 = pParse->db->init.busy==0;} break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy285,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0); } break; case 20: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy47); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); } break; case 21: /* table_option_set ::= */ -{yymsp[1].minor.yy285 = 0;} +{yymsp[1].minor.yy391 = 0;} break; case 22: /* table_option_set ::= table_option_set COMMA table_option */ -{yylhsminor.yy285 = yymsp[-2].minor.yy285|yymsp[0].minor.yy285;} - yymsp[-2].minor.yy285 = yylhsminor.yy285; +{yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;} + yymsp[-2].minor.yy391 = yylhsminor.yy391; break; case 23: /* table_option ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy285 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy285 = 0; + yymsp[-1].minor.yy391 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } @@ -174093,20 +177717,20 @@ static YYACTIONTYPE yy_reduce( case 24: /* table_option ::= nm */ { if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ - yylhsminor.yy285 = TF_Strict; + yylhsminor.yy391 = TF_Strict; }else{ - yylhsminor.yy285 = 0; + yylhsminor.yy391 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } - yymsp[0].minor.yy285 = yylhsminor.yy285; + yymsp[0].minor.yy391 = yylhsminor.yy391; break; case 25: /* columnname ::= nm typetoken */ {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} break; case 26: /* typetoken ::= */ case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65); - case 104: /* as ::= */ yytestcase(yyruleno==104); + case 106: /* as ::= */ yytestcase(yyruleno==106); {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} break; case 27: /* typetoken ::= typename LP signed RP */ @@ -174125,7 +177749,7 @@ static YYACTIONTYPE yy_reduce( case 30: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy522 = yyLookaheadToken.z; + yymsp[1].minor.yy168 = yyLookaheadToken.z; } break; case 31: /* scantok ::= */ @@ -174139,17 +177763,17 @@ static YYACTIONTYPE yy_reduce( {pParse->constraintName = yymsp[0].minor.yy0;} break; case 33: /* ccons ::= DEFAULT scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 34: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; case 35: /* ccons ::= DEFAULT PLUS scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 36: /* ccons ::= DEFAULT MINUS scantok term */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy528, 0); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0); sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; @@ -174164,151 +177788,155 @@ static YYACTIONTYPE yy_reduce( } break; case 38: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy394);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);} break; case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy394,yymsp[0].minor.yy394,yymsp[-2].minor.yy394);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);} break; case 40: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy394,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 41: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} break; case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy394);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);} break; case 43: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy394);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);} break; case 44: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 45: /* generated ::= LP expr RP */ -{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy528,0);} +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);} break; case 46: /* generated ::= LP expr RP ID */ -{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy528,&yymsp[0].minor.yy0);} +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);} break; case 48: /* autoinc ::= AUTOINCR */ -{yymsp[0].minor.yy394 = 1;} +{yymsp[0].minor.yy144 = 1;} break; case 49: /* refargs ::= */ -{ yymsp[1].minor.yy394 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 50: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy394 = (yymsp[-1].minor.yy394 & ~yymsp[0].minor.yy231.mask) | yymsp[0].minor.yy231.value; } +{ yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; } break; case 51: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy231.value = 0; yymsp[-1].minor.yy231.mask = 0x000000; } +{ yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; } break; case 52: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy231.value = 0; yymsp[-2].minor.yy231.mask = 0x000000; } +{ yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; } break; case 53: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394; yymsp[-2].minor.yy231.mask = 0x0000ff; } +{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; } break; case 54: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394<<8; yymsp[-2].minor.yy231.mask = 0x00ff00; } +{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; } break; case 55: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy394 = OE_SetNull; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */} break; case 56: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy394 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 57: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy394 = OE_Cascade; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */} break; case 58: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy394 = OE_Restrict; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */} break; case 59: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy394 = OE_None; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */} break; case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy394 = 0;} +{yymsp[-2].minor.yy144 = 0;} break; case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); - case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171); -{yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;} + case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173); +{yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;} break; case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); - case 217: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==217); - case 220: /* in_op ::= NOT IN */ yytestcase(yyruleno==220); - case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245); -{yymsp[-1].minor.yy394 = 1;} + case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219); + case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222); + case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247); +{yymsp[-1].minor.yy144 = 1;} break; case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy394 = 0;} +{yymsp[-1].minor.yy144 = 0;} break; case 66: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy394,yymsp[-2].minor.yy394,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);} break; case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy394,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 70: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy528,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} break; case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy394); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy394); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144); } break; case 73: /* onconf ::= */ case 75: /* orconf ::= */ yytestcase(yyruleno==75); -{yymsp[1].minor.yy394 = OE_Default;} +{yymsp[1].minor.yy144 = OE_Default;} break; case 74: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy394 = yymsp[0].minor.yy394;} +{yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;} break; case 77: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy394 = OE_Ignore;} +{yymsp[0].minor.yy144 = OE_Ignore;} break; case 78: /* resolvetype ::= REPLACE */ - case 172: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==172); -{yymsp[0].minor.yy394 = OE_Replace;} + case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174); +{yymsp[0].minor.yy144 = OE_Replace;} break; case 79: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy131, 0, yymsp[-1].minor.yy394); + sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144); } break; case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy47, yymsp[-7].minor.yy394, yymsp[-5].minor.yy394); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144); } break; case 83: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy131, 1, yymsp[-1].minor.yy394); + sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144); } break; case 84: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy47, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); + if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0 + || sqlite3ReadSchema(pParse)==SQLITE_OK + ){ + sqlite3Select(pParse, yymsp[0].minor.yy555, &dest); + } + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); } break; case 85: /* select ::= WITH wqlist selectnowith */ -{yymsp[-2].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} +{yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} break; case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ -{yymsp[-3].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} +{yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} break; case 87: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy47; + Select *p = yymsp[0].minor.yy555; if( p ){ parserDoubleLinkSelect(pParse, p); } @@ -174316,8 +177944,8 @@ static YYACTIONTYPE yy_reduce( break; case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy47; - Select *pLhs = yymsp[-2].minor.yy47; + Select *pRhs = yymsp[0].minor.yy555; + Select *pLhs = yymsp[-2].minor.yy555; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -174327,153 +177955,160 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy394; + pRhs->op = (u8)yymsp[-1].minor.yy144; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy394!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy144!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy47 = pRhs; + yymsp[-2].minor.yy555 = pRhs; } break; case 89: /* multiselect_op ::= UNION */ case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); -{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-OP*/} +{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/} break; case 90: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy394 = TK_ALL;} +{yymsp[-1].minor.yy144 = TK_ALL;} break; case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy131,yymsp[-4].minor.yy528,yymsp[-3].minor.yy322,yymsp[-2].minor.yy528,yymsp[-1].minor.yy322,yymsp[-7].minor.yy394,yymsp[0].minor.yy528); + yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454); } break; case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ { - yymsp[-9].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy322,yymsp[-6].minor.yy131,yymsp[-5].minor.yy528,yymsp[-4].minor.yy322,yymsp[-3].minor.yy528,yymsp[-1].minor.yy322,yymsp[-8].minor.yy394,yymsp[0].minor.yy528); - if( yymsp[-9].minor.yy47 ){ - yymsp[-9].minor.yy47->pWinDefn = yymsp[-2].minor.yy41; + yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454); + if( yymsp[-9].minor.yy555 ){ + yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211; }else{ - sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy41); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211); } } break; case 94: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0); } break; - case 95: /* values ::= values COMMA LP nexprlist RP */ + case 95: /* oneselect ::= mvalues */ { - Select *pRight, *pLeft = yymsp[-4].minor.yy47; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0); - if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; - if( pRight ){ - pRight->op = TK_ALL; - pRight->pPrior = pLeft; - yymsp[-4].minor.yy47 = pRight; - }else{ - yymsp[-4].minor.yy47 = pLeft; - } + sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555); } break; - case 96: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy394 = SF_Distinct;} + case 96: /* mvalues ::= values COMMA LP nexprlist RP */ + case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97); +{ + yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14); +} break; - case 97: /* distinct ::= ALL */ -{yymsp[0].minor.yy394 = SF_All;} + case 98: /* distinct ::= DISTINCT */ +{yymsp[0].minor.yy144 = SF_Distinct;} break; - case 99: /* sclp ::= */ - case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); - case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); - case 232: /* exprlist ::= */ yytestcase(yyruleno==232); - case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235); - case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240); -{yymsp[1].minor.yy322 = 0;} + case 99: /* distinct ::= ALL */ +{yymsp[0].minor.yy144 = SF_All;} break; - case 100: /* selcollist ::= sclp scanpt expr scanpt as */ + case 101: /* sclp ::= */ + case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134); + case 144: /* groupby_opt ::= */ yytestcase(yyruleno==144); + case 234: /* exprlist ::= */ yytestcase(yyruleno==234); + case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237); + case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242); +{yymsp[1].minor.yy14 = 0;} + break; + case 102: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy522,yymsp[-1].minor.yy522); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168); } break; - case 101: /* selcollist ::= sclp scanpt STAR */ + case 103: /* selcollist ::= sclp scanpt STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); - yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p); + yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p); } break; - case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ + case 104: /* selcollist ::= sclp scanpt nm DOT STAR */ { Expr *pRight, *pLeft, *pDot; pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot); } break; - case 103: /* as ::= AS nm */ - case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); - case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256); - case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257); + case 105: /* as ::= AS nm */ + case 117: /* dbnm ::= DOT nm */ yytestcase(yyruleno==117); + case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258); + case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; - case 105: /* from ::= */ - case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108); -{yymsp[1].minor.yy131 = 0;} + case 107: /* from ::= */ + case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110); +{yymsp[1].minor.yy203 = 0;} break; - case 106: /* from ::= FROM seltablist */ + case 108: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy131 = yymsp[0].minor.yy131; - sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131); + yymsp[-1].minor.yy203 = yymsp[0].minor.yy203; + sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203); } break; - case 107: /* stl_prefix ::= seltablist joinop */ + case 109: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394; + if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144; } break; - case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */ + case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */ { - yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); + yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); } break; - case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ { - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561); - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0); + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0); } break; - case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ { - yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); - sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322); + yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); + sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14); } break; - case 112: /* seltablist ::= stl_prefix LP select RP as on_using */ + case 114: /* seltablist ::= stl_prefix LP select RP as on_using */ { - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561); + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269); } break; - case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ + case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ { - if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){ - yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131; - }else if( ALWAYS(yymsp[-3].minor.yy131!=0) && yymsp[-3].minor.yy131->nSrc==1 ){ - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); - if( yymsp[-5].minor.yy131 ){ - SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1]; - SrcItem *pOld = yymsp[-3].minor.yy131->a; + if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){ + yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203; + }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){ + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); + if( yymsp[-5].minor.yy203 ){ + SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; + SrcItem *pOld = yymsp[-3].minor.yy203->a; + assert( pOld->fg.fixedSchema==0 ); pNew->zName = pOld->zName; - pNew->zDatabase = pOld->zDatabase; - pNew->pSelect = pOld->pSelect; - if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){ - pNew->fg.isNestedFrom = 1; + assert( pOld->fg.fixedSchema==0 ); + if( pOld->fg.isSubquery ){ + pNew->fg.isSubquery = 1; + pNew->u4.pSubq = pOld->u4.pSubq; + pOld->u4.pSubq = 0; + pOld->fg.isSubquery = 0; + assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 ); + if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){ + pNew->fg.isNestedFrom = 1; + } + }else{ + pNew->u4.zDatabase = pOld->u4.zDatabase; + pOld->u4.zDatabase = 0; } if( pOld->fg.isTabFunc ){ pNew->u1.pFuncArg = pOld->u1.pFuncArg; @@ -174481,156 +178116,155 @@ static YYACTIONTYPE yy_reduce( pOld->fg.isTabFunc = 0; pNew->fg.isTabFunc = 1; } - pOld->zName = pOld->zDatabase = 0; - pOld->pSelect = 0; + pOld->zName = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy131); + sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0); - yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561); + sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0); + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269); } } break; - case 114: /* dbnm ::= */ - case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129); + case 116: /* dbnm ::= */ + case 131: /* indexed_opt ::= */ yytestcase(yyruleno==131); {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} break; - case 116: /* fullname ::= nm */ + case 118: /* fullname ::= nm */ { - yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy131 = yylhsminor.yy131; + yymsp[0].minor.yy203 = yylhsminor.yy203; break; - case 117: /* fullname ::= nm DOT nm */ + case 119: /* fullname ::= nm DOT nm */ { - yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy131 = yylhsminor.yy131; + yymsp[-2].minor.yy203 = yylhsminor.yy203; break; - case 118: /* xfullname ::= nm */ -{yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} + case 120: /* xfullname ::= nm */ +{yymsp[0].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; - case 119: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 121: /* xfullname ::= nm DOT nm */ +{yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 120: /* xfullname ::= nm DOT nm AS nm */ + case 122: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-4].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy203 ) yymsp[-4].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 121: /* xfullname ::= nm AS nm */ + case 123: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy203 ) yymsp[-2].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 122: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy394 = JT_INNER; } + case 124: /* joinop ::= COMMA|JOIN */ +{ yymsp[0].minor.yy144 = JT_INNER; } break; - case 123: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} + case 125: /* joinop ::= JOIN_KW JOIN */ +{yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; - case 124: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} + case 126: /* joinop ::= JOIN_KW nm JOIN */ +{yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; - case 125: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} + case 127: /* joinop ::= JOIN_KW nm nm JOIN */ +{yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; - case 126: /* on_using ::= ON expr */ -{yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;} + case 128: /* on_using ::= ON expr */ +{yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;} break; - case 127: /* on_using ::= USING LP idlist RP */ -{yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;} + case 129: /* on_using ::= USING LP idlist RP */ +{yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;} break; - case 128: /* on_using ::= */ -{yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;} + case 130: /* on_using ::= */ +{yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;} break; - case 130: /* indexed_by ::= INDEXED BY nm */ + case 132: /* indexed_by ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} break; - case 131: /* indexed_by ::= NOT INDEXED */ + case 133: /* indexed_by ::= NOT INDEXED */ {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} break; - case 133: /* orderby_opt ::= ORDER BY sortlist */ - case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143); -{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;} + case 135: /* orderby_opt ::= ORDER BY sortlist */ + case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145); +{yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;} break; - case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */ + case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322,yymsp[-2].minor.yy528); - sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); } break; - case 135: /* sortlist ::= expr sortorder nulls */ + case 137: /* sortlist ::= expr sortorder nulls */ { - yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy528); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); + yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); } break; - case 136: /* sortorder ::= ASC */ -{yymsp[0].minor.yy394 = SQLITE_SO_ASC;} + case 138: /* sortorder ::= ASC */ +{yymsp[0].minor.yy144 = SQLITE_SO_ASC;} break; - case 137: /* sortorder ::= DESC */ -{yymsp[0].minor.yy394 = SQLITE_SO_DESC;} + case 139: /* sortorder ::= DESC */ +{yymsp[0].minor.yy144 = SQLITE_SO_DESC;} break; - case 138: /* sortorder ::= */ - case 141: /* nulls ::= */ yytestcase(yyruleno==141); -{yymsp[1].minor.yy394 = SQLITE_SO_UNDEFINED;} + case 140: /* sortorder ::= */ + case 143: /* nulls ::= */ yytestcase(yyruleno==143); +{yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;} break; - case 139: /* nulls ::= NULLS FIRST */ -{yymsp[-1].minor.yy394 = SQLITE_SO_ASC;} + case 141: /* nulls ::= NULLS FIRST */ +{yymsp[-1].minor.yy144 = SQLITE_SO_ASC;} break; - case 140: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy394 = SQLITE_SO_DESC;} + case 142: /* nulls ::= NULLS LAST */ +{yymsp[-1].minor.yy144 = SQLITE_SO_DESC;} break; - case 144: /* having_opt ::= */ - case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); - case 151: /* where_opt ::= */ yytestcase(yyruleno==151); - case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); - case 230: /* case_else ::= */ yytestcase(yyruleno==230); - case 231: /* case_operand ::= */ yytestcase(yyruleno==231); - case 250: /* vinto ::= */ yytestcase(yyruleno==250); -{yymsp[1].minor.yy528 = 0;} + case 146: /* having_opt ::= */ + case 148: /* limit_opt ::= */ yytestcase(yyruleno==148); + case 153: /* where_opt ::= */ yytestcase(yyruleno==153); + case 155: /* where_opt_ret ::= */ yytestcase(yyruleno==155); + case 232: /* case_else ::= */ yytestcase(yyruleno==232); + case 233: /* case_operand ::= */ yytestcase(yyruleno==233); + case 252: /* vinto ::= */ yytestcase(yyruleno==252); +{yymsp[1].minor.yy454 = 0;} break; - case 145: /* having_opt ::= HAVING expr */ - case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); - case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); - case 229: /* case_else ::= ELSE expr */ yytestcase(yyruleno==229); - case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249); -{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} + case 147: /* having_opt ::= HAVING expr */ + case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154); + case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156); + case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231); + case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251); +{yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;} break; - case 147: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);} + case 149: /* limit_opt ::= LIMIT expr */ +{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);} break; - case 148: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + case 150: /* limit_opt ::= LIMIT expr OFFSET expr */ +{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} break; - case 149: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,yymsp[-2].minor.yy528);} + case 151: /* limit_opt ::= LIMIT expr COMMA expr */ +{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);} break; - case 150: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy131, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy131,yymsp[0].minor.yy528,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0); } break; - case 155: /* where_opt_ret ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-1].minor.yy528 = 0;} + case 157: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;} break; - case 156: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-3].minor.yy528 = yymsp[-2].minor.yy528;} + case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;} break; - case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list"); - if( yymsp[-1].minor.yy131 ){ - SrcList *pFromClause = yymsp[-1].minor.yy131; + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list"); + if( yymsp[-1].minor.yy203 ){ + SrcList *pFromClause = yymsp[-1].minor.yy203; if( pFromClause->nSrc>1 ){ Select *pSubquery; Token as; @@ -174639,92 +178273,92 @@ static YYACTIONTYPE yy_reduce( as.z = 0; pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); } - yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, pFromClause); + yymsp[-5].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause); } - sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0); + sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0); } break; - case 158: /* setlist ::= setlist COMMA nm EQ expr */ + case 160: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy528); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1); } break; - case 159: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); + yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); } break; - case 160: /* setlist ::= nm EQ expr */ + case 162: /* setlist ::= nm EQ expr */ { - yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy528); - sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454); + sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy322 = yylhsminor.yy322; + yymsp[-2].minor.yy14 = yylhsminor.yy14; break; - case 161: /* setlist ::= LP idlist RP EQ expr */ + case 163: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); + yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); } break; - case 162: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy131, yymsp[-1].minor.yy47, yymsp[-2].minor.yy254, yymsp[-5].minor.yy394, yymsp[0].minor.yy444); + sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122); } break; - case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ { - sqlite3Insert(pParse, yymsp[-4].minor.yy131, 0, yymsp[-3].minor.yy254, yymsp[-6].minor.yy394, 0); + sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0); } break; - case 164: /* upsert ::= */ -{ yymsp[1].minor.yy444 = 0; } + case 166: /* upsert ::= */ +{ yymsp[1].minor.yy122 = 0; } break; - case 165: /* upsert ::= RETURNING selcollist */ -{ yymsp[-1].minor.yy444 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy322); } + case 167: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); } break; - case 166: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ -{ yymsp[-11].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy322,yymsp[-6].minor.yy528,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,yymsp[0].minor.yy444);} + case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +{ yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);} break; - case 167: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ -{ yymsp[-8].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy322,yymsp[-3].minor.yy528,0,0,yymsp[0].minor.yy444); } + case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +{ yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); } break; - case 168: /* upsert ::= ON CONFLICT DO NOTHING returning */ -{ yymsp[-4].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } + case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } break; - case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ -{ yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);} + case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +{ yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);} break; - case 170: /* returning ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);} + case 172: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14);} break; - case 173: /* idlist_opt ::= */ -{yymsp[1].minor.yy254 = 0;} + case 175: /* idlist_opt ::= */ +{yymsp[1].minor.yy132 = 0;} break; - case 174: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} + case 176: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;} break; - case 175: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} + case 177: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);} break; - case 176: /* idlist ::= nm */ -{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + case 178: /* idlist ::= nm */ +{yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; - case 177: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} + case 179: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;} break; - case 178: /* expr ::= ID|INDEXED|JOIN_KW */ -{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 180: /* expr ::= ID|INDEXED|JOIN_KW */ +{yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 179: /* expr ::= nm DOT nm */ + case 181: /* expr ::= nm DOT nm */ { Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); - yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy528 = yylhsminor.yy528; + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 180: /* expr ::= nm DOT nm DOT nm */ + case 182: /* expr ::= nm DOT nm DOT nm */ { Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); @@ -174733,27 +178367,27 @@ static YYACTIONTYPE yy_reduce( if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, 0, temp1); } - yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy528 = yylhsminor.yy528; + yymsp[-4].minor.yy454 = yylhsminor.yy454; break; - case 181: /* term ::= NULL|FLOAT|BLOB */ - case 182: /* term ::= STRING */ yytestcase(yyruleno==182); -{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 183: /* term ::= NULL|FLOAT|BLOB */ + case 184: /* term ::= STRING */ yytestcase(yyruleno==184); +{yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 183: /* term ::= INTEGER */ + case 185: /* term ::= INTEGER */ { - yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); - if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); + yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); } - yymsp[0].minor.yy528 = yylhsminor.yy528; + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 184: /* expr ::= VARIABLE */ + case 186: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; - yymsp[0].minor.yy528 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy528, n); + yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -174761,195 +178395,204 @@ static YYACTIONTYPE yy_reduce( Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/ assert( t.n>=2 ); if( pParse->nested==0 ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy528 = 0; + parserSyntaxError(pParse, &t); + yymsp[0].minor.yy454 = 0; }else{ - yymsp[0].minor.yy528 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy528 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy528->iTable); + yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable); } } } break; - case 185: /* expr ::= expr COLLATE ID|STRING */ + case 187: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1); } break; - case 186: /* expr ::= CAST LP expr AS typetoken RP */ + case 188: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); + yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0); } break; - case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144); } - yymsp[-4].minor.yy528 = yylhsminor.yy528; + yymsp[-4].minor.yy454 = yylhsminor.yy454; break; - case 188: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy322, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy394); - sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-1].minor.yy322); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14); } - yymsp[-7].minor.yy528 = yylhsminor.yy528; + yymsp[-7].minor.yy454 = yylhsminor.yy454; break; - case 189: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy528 = yylhsminor.yy528; + yymsp[-3].minor.yy454 = yylhsminor.yy454; break; - case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); - sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); } - yymsp[-5].minor.yy528 = yylhsminor.yy528; + yymsp[-5].minor.yy454 = yylhsminor.yy454; break; - case 191: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy322, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy394); - sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); - sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-2].minor.yy322); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14); } - yymsp[-8].minor.yy528 = yylhsminor.yy528; + yymsp[-8].minor.yy454 = yylhsminor.yy454; break; - case 192: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); } - yymsp[-4].minor.yy528 = yylhsminor.yy528; + yymsp[-4].minor.yy454 = yylhsminor.yy454; break; - case 193: /* term ::= CTIME_KW */ + case 195: /* term ::= CTIME_KW */ { - yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy528 = yylhsminor.yy528; + yymsp[0].minor.yy454 = yylhsminor.yy454; break; - case 194: /* expr ::= LP nexprlist COMMA expr RP */ + case 196: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy528 ){ - yymsp[-4].minor.yy528->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy454 ){ + yymsp[-4].minor.yy454->x.pList = pList; if( ALWAYS(pList->nExpr) ){ - yymsp[-4].minor.yy528->flags |= pList->a[0].pExpr->flags & EP_Propagate; + yymsp[-4].minor.yy454->flags |= pList->a[0].pExpr->flags & EP_Propagate; } }else{ sqlite3ExprListDelete(pParse->db, pList); } } break; - case 195: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + case 197: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} break; - case 196: /* expr ::= expr OR expr */ - case 197: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==197); - case 198: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==198); - case 199: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==199); - case 200: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==200); - case 201: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==201); - case 202: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==202); -{yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} + case 198: /* expr ::= expr OR expr */ + case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202); + case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203); + case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204); +{yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} break; - case 203: /* likeop ::= NOT LIKE_KW|MATCH */ + case 205: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} break; - case 204: /* expr ::= expr likeop expr */ + case 206: /* expr ::= expr likeop expr */ { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy528); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy528); - yymsp[-2].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy528, 0); - if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454); + yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0); + if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc; } break; - case 205: /* expr ::= expr likeop expr ESCAPE expr */ + case 207: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy528); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); - if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc; } break; - case 206: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} + case 208: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy454,0);} break; - case 207: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} + case 209: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy454,0);} break; - case 208: /* expr ::= expr IS expr */ + case 210: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); + yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy454,yymsp[0].minor.yy454); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-2].minor.yy454, TK_ISNULL); } break; - case 209: /* expr ::= expr IS NOT expr */ + case 211: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); + yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy454,yymsp[0].minor.yy454); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-3].minor.yy454, TK_NOTNULL); } break; - case 210: /* expr ::= expr IS NOT DISTINCT FROM expr */ + case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */ { - yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL); + yymsp[-5].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy454,yymsp[0].minor.yy454); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-5].minor.yy454, TK_ISNULL); } break; - case 211: /* expr ::= expr IS DISTINCT FROM expr */ + case 213: /* expr ::= expr IS DISTINCT FROM expr */ { - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy454,yymsp[0].minor.yy454); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-4].minor.yy454, TK_NOTNULL); } break; - case 212: /* expr ::= NOT expr */ - case 213: /* expr ::= BITNOT expr */ yytestcase(yyruleno==213); -{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} + case 214: /* expr ::= NOT expr */ + case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215); +{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/} break; - case 214: /* expr ::= PLUS|MINUS expr */ + case 216: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); - /*A-overwrites-B*/ + Expr *p = yymsp[0].minor.yy454; + u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS); + assert( TK_UPLUS>TK_PLUS ); + assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) ); + if( p && p->op==TK_UPLUS ){ + p->op = op; + yymsp[-1].minor.yy454 = p; + }else{ + yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0); + /*A-overwrites-B*/ + } } break; - case 215: /* expr ::= expr PTR expr */ + case 217: /* expr ::= expr PTR expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); - pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); - yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); } - yymsp[-2].minor.yy528 = yylhsminor.yy528; + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; - case 216: /* between_op ::= BETWEEN */ - case 219: /* in_op ::= IN */ yytestcase(yyruleno==219); -{yymsp[0].minor.yy394 = 0;} + case 218: /* between_op ::= BETWEEN */ + case 221: /* in_op ::= IN */ yytestcase(yyruleno==221); +{yymsp[0].minor.yy144 = 0;} break; - case 218: /* expr ::= expr between_op expr AND expr */ + case 220: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0); - if( yymsp[-4].minor.yy528 ){ - yymsp[-4].minor.yy528->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ){ + yymsp[-4].minor.yy454->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); } break; - case 221: /* expr ::= expr in_op LP exprlist RP */ + case 223: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy322==0 ){ + if( yymsp[-1].minor.yy14==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -174958,208 +178601,208 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528); - yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false"); - if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528); - }else{ - Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr; - if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){ - yymsp[-1].minor.yy322->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy144 ? "true" : "false"); + if( yymsp[-4].minor.yy454 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy454); + }else{ + Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr; + if( yymsp[-1].minor.yy14->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy454->op!=TK_VECTOR ){ + yymsp[-1].minor.yy14->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); - }else if( yymsp[-1].minor.yy322->nExpr==1 && pRHS->op==TK_SELECT ){ - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pRHS->x.pSelect); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy454, pRHS); + }else if( yymsp[-1].minor.yy14->nExpr==1 && pRHS->op==TK_SELECT ){ + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pRHS->x.pSelect); pRHS->x.pSelect = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); - }else{ - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - if( yymsp[-4].minor.yy528==0 ){ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); - }else if( yymsp[-4].minor.yy528->pLeft->op==TK_VECTOR ){ - int nExpr = yymsp[-4].minor.yy528->pLeft->x.pList->nExpr; - Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy322); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + }else{ + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454==0 ){ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + }else if( yymsp[-4].minor.yy454->pLeft->op==TK_VECTOR ){ + int nExpr = yymsp[-4].minor.yy454->pLeft->x.pList->nExpr; + Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy14); if( pSelectRHS ){ parserDoubleLinkSelect(pParse, pSelectRHS); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelectRHS); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelectRHS); } }else{ - yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy322; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); + yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy14; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); } } - if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); } } break; - case 222: /* expr ::= LP select RP */ + case 224: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); + yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555); } break; - case 223: /* expr ::= expr in_op LP select RP */ + case 225: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); - if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); } break; - case 224: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322); - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect); - if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); } break; - case 225: /* expr ::= EXISTS LP select RP */ + case 227: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); + p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555); } break; - case 226: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 228: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); - if( yymsp[-4].minor.yy528 ){ - yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ){ + yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); } } break; - case 227: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); - yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454); } break; - case 228: /* case_exprlist ::= WHEN expr THEN expr */ + case 230: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); - yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); + yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454); } break; - case 233: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} + case 235: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);} break; - case 234: /* nexprlist ::= expr */ -{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} + case 236: /* nexprlist ::= expr */ +{yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/} break; - case 236: /* paren_exprlist ::= LP exprlist RP */ - case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241); -{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} + case 238: /* paren_exprlist ::= LP exprlist RP */ + case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243); +{yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;} break; - case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; - case 238: /* uniqueflag ::= UNIQUE */ - case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280); -{yymsp[0].minor.yy394 = OE_Abort;} + case 240: /* uniqueflag ::= UNIQUE */ + case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282); +{yymsp[0].minor.yy144 = OE_Abort;} break; - case 239: /* uniqueflag ::= */ -{yymsp[1].minor.yy394 = OE_None;} + case 241: /* uniqueflag ::= */ +{yymsp[1].minor.yy144 = OE_None;} break; - case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); + yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); } break; - case 243: /* eidlist ::= nm collate sortorder */ + case 245: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ + yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/ } break; - case 246: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} + case 248: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);} break; - case 247: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} + case 249: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);} break; - case 248: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} + case 250: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);} break; - case 251: /* cmd ::= PRAGMA nm dbnm */ + case 253: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 257: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all); } break; - case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 260: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } + case 262: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 261: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy394 = TK_INSTEAD;} + case 263: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy144 = TK_INSTEAD;} break; - case 262: /* trigger_time ::= */ -{ yymsp[1].minor.yy394 = TK_BEFORE; } + case 264: /* trigger_time ::= */ +{ yymsp[1].minor.yy144 = TK_BEFORE; } break; - case 263: /* trigger_event ::= DELETE|INSERT */ - case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264); -{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} + case 265: /* trigger_event ::= DELETE|INSERT */ + case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266); +{yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;} break; - case 265: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} + case 267: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;} break; - case 266: /* when_clause ::= */ - case 285: /* key_opt ::= */ yytestcase(yyruleno==285); -{ yymsp[1].minor.yy528 = 0; } + case 268: /* when_clause ::= */ + case 287: /* key_opt ::= */ yytestcase(yyruleno==287); +{ yymsp[1].minor.yy454 = 0; } break; - case 267: /* when_clause ::= WHEN expr */ - case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286); -{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } + case 269: /* when_clause ::= WHEN expr */ + case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288); +{ yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; } break; - case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy33!=0 ); - yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; - yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; + assert( yymsp[-2].minor.yy427!=0 ); + yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427; + yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427; } break; - case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy33!=0 ); - yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; + assert( yymsp[-1].minor.yy427!=0 ); + yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427; } break; - case 270: /* trnm ::= nm DOT nm */ + case 272: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -175167,367 +178810,377 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 271: /* tridxby ::= INDEXED BY nm */ + case 273: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 272: /* tridxby ::= NOT INDEXED */ + case 274: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -{yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} - yymsp[-8].minor.yy33 = yylhsminor.yy33; + case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);} + yymsp[-8].minor.yy427 = yylhsminor.yy427; break; - case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ + yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/ } - yymsp[-7].minor.yy33 = yylhsminor.yy33; + yymsp[-7].minor.yy427 = yylhsminor.yy427; break; - case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} - yymsp[-5].minor.yy33 = yylhsminor.yy33; + case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);} + yymsp[-5].minor.yy427 = yylhsminor.yy427; break; - case 276: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} - yymsp[-2].minor.yy33 = yylhsminor.yy33; + case 278: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/} + yymsp[-2].minor.yy427 = yylhsminor.yy427; break; - case 277: /* expr ::= RAISE LP IGNORE RP */ + case 279: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy528 ){ - yymsp[-3].minor.yy528->affExpr = OE_Ignore; + yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy454 ){ + yymsp[-3].minor.yy454->affExpr = OE_Ignore; } } break; - case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */ { - yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy528 ) { - yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394; + yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0); + if( yymsp[-5].minor.yy454 ) { + yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; } } break; - case 279: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy394 = OE_Rollback;} + case 281: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy144 = OE_Rollback;} break; - case 281: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy394 = OE_Fail;} + case 283: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy144 = OE_Fail;} break; - case 282: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 284: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144); } break; - case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); + sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454); } break; - case 284: /* cmd ::= DETACH database_kw_opt expr */ + case 286: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy528); + sqlite3Detach(pParse, yymsp[0].minor.yy454); } break; - case 287: /* cmd ::= REINDEX */ + case 289: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 288: /* cmd ::= REINDEX nm dbnm */ + case 290: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 289: /* cmd ::= ANALYZE */ + case 291: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 290: /* cmd ::= ANALYZE nm dbnm */ + case 292: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0); } break; - case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 294: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; - case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ { - sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0); } break; - case 294: /* add_column_fullname ::= fullname */ + case 296: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy203); } break; - case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 296: /* cmd ::= create_vtab */ + case 298: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 297: /* cmd ::= create_vtab LP vtabarglist RP */ + case 299: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 300: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144); } break; - case 299: /* vtabarg ::= */ + case 301: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 300: /* vtabargtoken ::= ANY */ - case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301); - case 302: /* lp ::= LP */ yytestcase(yyruleno==302); + case 302: /* vtabargtoken ::= ANY */ + case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303); + case 304: /* lp ::= LP */ yytestcase(yyruleno==304); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 303: /* with ::= WITH wqlist */ - case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } + case 305: /* with ::= WITH wqlist */ + case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); } break; - case 305: /* wqas ::= AS */ -{yymsp[0].minor.yy516 = M10d_Any;} + case 307: /* wqas ::= AS */ +{yymsp[0].minor.yy462 = M10d_Any;} break; - case 306: /* wqas ::= AS MATERIALIZED */ -{yymsp[-1].minor.yy516 = M10d_Yes;} + case 308: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy462 = M10d_Yes;} break; - case 307: /* wqas ::= AS NOT MATERIALIZED */ -{yymsp[-2].minor.yy516 = M10d_No;} + case 309: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy462 = M10d_No;} break; - case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */ + case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */ { - yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ + yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/ } break; - case 309: /* wqlist ::= wqitem */ + case 311: /* withnm ::= nm */ +{pParse->bHasWith = 1;} + break; + case 312: /* wqlist ::= wqitem */ { - yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ + yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/ } break; - case 310: /* wqlist ::= wqlist COMMA wqitem */ + case 313: /* wqlist ::= wqlist COMMA wqitem */ { - yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); + yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67); } break; - case 311: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { - assert( yymsp[0].minor.yy41!=0 ); - sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); - yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41; - yylhsminor.yy41 = yymsp[0].minor.yy41; + assert( yymsp[0].minor.yy211!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211); + yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211; + yylhsminor.yy211 = yymsp[0].minor.yy211; } - yymsp[-2].minor.yy41 = yylhsminor.yy41; + yymsp[-2].minor.yy211 = yylhsminor.yy211; break; - case 312: /* windowdefn ::= nm AS LP window RP */ + case 315: /* windowdefn ::= nm AS LP window RP */ { - if( ALWAYS(yymsp[-1].minor.yy41) ){ - yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + if( ALWAYS(yymsp[-1].minor.yy211) ){ + yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } - yylhsminor.yy41 = yymsp[-1].minor.yy41; + yylhsminor.yy211 = yymsp[-1].minor.yy211; } - yymsp[-4].minor.yy41 = yylhsminor.yy41; + yymsp[-4].minor.yy211 = yylhsminor.yy211; break; - case 313: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { - yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); + yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0); } break; - case 314: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { - yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy41 = yylhsminor.yy41; + yymsp[-5].minor.yy211 = yylhsminor.yy211; break; - case 315: /* window ::= ORDER BY sortlist frame_opt */ + case 318: /* window ::= ORDER BY sortlist frame_opt */ { - yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); + yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0); } break; - case 316: /* window ::= nm ORDER BY sortlist frame_opt */ + case 319: /* window ::= nm ORDER BY sortlist frame_opt */ { - yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy41 = yylhsminor.yy41; + yymsp[-4].minor.yy211 = yylhsminor.yy211; break; - case 317: /* window ::= nm frame_opt */ + case 320: /* window ::= nm frame_opt */ { - yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy41 = yylhsminor.yy41; + yymsp[-1].minor.yy211 = yylhsminor.yy211; break; - case 318: /* frame_opt ::= */ + case 321: /* frame_opt ::= */ { - yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; - case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { - yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); + yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462); } - yymsp[-2].minor.yy41 = yylhsminor.yy41; + yymsp[-2].minor.yy211 = yylhsminor.yy211; break; - case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { - yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); + yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462); } - yymsp[-5].minor.yy41 = yylhsminor.yy41; + yymsp[-5].minor.yy211 = yylhsminor.yy211; break; - case 322: /* frame_bound_s ::= frame_bound */ - case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324); -{yylhsminor.yy595 = yymsp[0].minor.yy595;} - yymsp[0].minor.yy595 = yylhsminor.yy595; + case 325: /* frame_bound_s ::= frame_bound */ + case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327); +{yylhsminor.yy509 = yymsp[0].minor.yy509;} + yymsp[0].minor.yy509 = yylhsminor.yy509; break; - case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325); - case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327); -{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} - yymsp[-1].minor.yy595 = yylhsminor.yy595; + case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328); + case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330); +{yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;} + yymsp[-1].minor.yy509 = yylhsminor.yy509; break; - case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */ -{yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} - yymsp[-1].minor.yy595 = yylhsminor.yy595; + case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;} + yymsp[-1].minor.yy509 = yylhsminor.yy509; break; - case 328: /* frame_exclude_opt ::= */ -{yymsp[1].minor.yy516 = 0;} + case 331: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy462 = 0;} break; - case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ -{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} + case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;} break; - case 330: /* frame_exclude ::= NO OTHERS */ - case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331); -{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} + case 333: /* frame_exclude ::= NO OTHERS */ + case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334); +{yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 332: /* frame_exclude ::= GROUP|TIES */ -{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} + case 335: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/} break; - case 333: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } + case 336: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; } break; - case 334: /* filter_over ::= filter_clause over_clause */ + case 337: /* filter_over ::= filter_clause over_clause */ { - if( yymsp[0].minor.yy41 ){ - yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; + if( yymsp[0].minor.yy211 ){ + yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454; }else{ - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); } - yylhsminor.yy41 = yymsp[0].minor.yy41; + yylhsminor.yy211 = yymsp[0].minor.yy211; } - yymsp[-1].minor.yy41 = yylhsminor.yy41; + yymsp[-1].minor.yy211 = yylhsminor.yy211; break; - case 335: /* filter_over ::= over_clause */ + case 338: /* filter_over ::= over_clause */ { - yylhsminor.yy41 = yymsp[0].minor.yy41; + yylhsminor.yy211 = yymsp[0].minor.yy211; } - yymsp[0].minor.yy41 = yylhsminor.yy41; + yymsp[0].minor.yy211 = yylhsminor.yy211; break; - case 336: /* filter_over ::= filter_clause */ + case 339: /* filter_over ::= filter_clause */ { - yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yylhsminor.yy41 ){ - yylhsminor.yy41->eFrmType = TK_FILTER; - yylhsminor.yy41->pFilter = yymsp[0].minor.yy528; + yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy211 ){ + yylhsminor.yy211->eFrmType = TK_FILTER; + yylhsminor.yy211->pFilter = yymsp[0].minor.yy454; }else{ - sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454); } } - yymsp[0].minor.yy41 = yylhsminor.yy41; + yymsp[0].minor.yy211 = yylhsminor.yy211; break; - case 337: /* over_clause ::= OVER LP window RP */ + case 340: /* over_clause ::= OVER LP window RP */ { - yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; - assert( yymsp[-3].minor.yy41!=0 ); + yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211; + assert( yymsp[-3].minor.yy211!=0 ); } break; - case 338: /* over_clause ::= OVER nm */ + case 341: /* over_clause ::= OVER nm */ { - yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yymsp[-1].minor.yy41 ){ - yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy211 ){ + yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); } } break; - case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ -{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } + case 342: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; } + break; + case 343: /* term ::= QNUMBER */ +{ + yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); + sqlite3DequoteNumber(pParse, yylhsminor.yy454); +} + yymsp[0].minor.yy454 = yylhsminor.yy454; break; default: - /* (340) input ::= cmdlist */ yytestcase(yyruleno==340); - /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341); - /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342); - /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343); - /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344); - /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345); - /* (346) trans_opt ::= */ yytestcase(yyruleno==346); - /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347); - /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348); - /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349); - /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350); - /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351); - /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352); - /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353); - /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354); - /* (355) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==355); - /* (356) nm ::= STRING */ yytestcase(yyruleno==356); - /* (357) typetoken ::= typename */ yytestcase(yyruleno==357); - /* (358) typename ::= ID|STRING */ yytestcase(yyruleno==358); - /* (359) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=359); - /* (360) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); - /* (361) carglist ::= carglist ccons */ yytestcase(yyruleno==361); - /* (362) carglist ::= */ yytestcase(yyruleno==362); - /* (363) ccons ::= NULL onconf */ yytestcase(yyruleno==363); - /* (364) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==364); - /* (365) ccons ::= AS generated */ yytestcase(yyruleno==365); - /* (366) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==366); - /* (367) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==367); - /* (368) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=368); - /* (369) tconscomma ::= */ yytestcase(yyruleno==369); - /* (370) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=370); - /* (371) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=371); - /* (372) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=372); - /* (373) oneselect ::= values */ yytestcase(yyruleno==373); - /* (374) sclp ::= selcollist COMMA */ yytestcase(yyruleno==374); - /* (375) as ::= ID|STRING */ yytestcase(yyruleno==375); - /* (376) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=376); - /* (377) returning ::= */ yytestcase(yyruleno==377); - /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378); - /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379); - /* (380) case_operand ::= expr */ yytestcase(yyruleno==380); - /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381); - /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382); - /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383); - /* (384) nmnum ::= ON */ yytestcase(yyruleno==384); - /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385); - /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386); - /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387); - /* (388) foreach_clause ::= */ yytestcase(yyruleno==388); - /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389); - /* (390) trnm ::= nm */ yytestcase(yyruleno==390); - /* (391) tridxby ::= */ yytestcase(yyruleno==391); - /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392); - /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393); - /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394); - /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395); - /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396); - /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397); - /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398); - /* (399) anylist ::= */ yytestcase(yyruleno==399); - /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400); - /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401); - /* (402) with ::= */ yytestcase(yyruleno==402); - /* (403) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=403); - /* (404) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=404); + /* (344) input ::= cmdlist */ yytestcase(yyruleno==344); + /* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345); + /* (346) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=346); + /* (347) ecmd ::= SEMI */ yytestcase(yyruleno==347); + /* (348) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==348); + /* (349) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=349); + /* (350) trans_opt ::= */ yytestcase(yyruleno==350); + /* (351) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==351); + /* (352) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==352); + /* (353) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==353); + /* (354) savepoint_opt ::= */ yytestcase(yyruleno==354); + /* (355) cmd ::= create_table create_table_args */ yytestcase(yyruleno==355); + /* (356) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=356); + /* (357) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==357); + /* (358) columnlist ::= columnname carglist */ yytestcase(yyruleno==358); + /* (359) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==359); + /* (360) nm ::= STRING */ yytestcase(yyruleno==360); + /* (361) typetoken ::= typename */ yytestcase(yyruleno==361); + /* (362) typename ::= ID|STRING */ yytestcase(yyruleno==362); + /* (363) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=363); + /* (364) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=364); + /* (365) carglist ::= carglist ccons */ yytestcase(yyruleno==365); + /* (366) carglist ::= */ yytestcase(yyruleno==366); + /* (367) ccons ::= NULL onconf */ yytestcase(yyruleno==367); + /* (368) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==368); + /* (369) ccons ::= AS generated */ yytestcase(yyruleno==369); + /* (370) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==370); + /* (371) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==371); + /* (372) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=372); + /* (373) tconscomma ::= */ yytestcase(yyruleno==373); + /* (374) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=374); + /* (375) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=375); + /* (376) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=376); + /* (377) oneselect ::= values */ yytestcase(yyruleno==377); + /* (378) sclp ::= selcollist COMMA */ yytestcase(yyruleno==378); + /* (379) as ::= ID|STRING */ yytestcase(yyruleno==379); + /* (380) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=380); + /* (381) returning ::= */ yytestcase(yyruleno==381); + /* (382) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=382); + /* (383) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==383); + /* (384) case_operand ::= expr */ yytestcase(yyruleno==384); + /* (385) exprlist ::= nexprlist */ yytestcase(yyruleno==385); + /* (386) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=386); + /* (387) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=387); + /* (388) nmnum ::= ON */ yytestcase(yyruleno==388); + /* (389) nmnum ::= DELETE */ yytestcase(yyruleno==389); + /* (390) nmnum ::= DEFAULT */ yytestcase(yyruleno==390); + /* (391) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==391); + /* (392) foreach_clause ::= */ yytestcase(yyruleno==392); + /* (393) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==393); + /* (394) trnm ::= nm */ yytestcase(yyruleno==394); + /* (395) tridxby ::= */ yytestcase(yyruleno==395); + /* (396) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==396); + /* (397) database_kw_opt ::= */ yytestcase(yyruleno==397); + /* (398) kwcolumn_opt ::= */ yytestcase(yyruleno==398); + /* (399) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==399); + /* (400) vtabarglist ::= vtabarg */ yytestcase(yyruleno==400); + /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==401); + /* (402) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==402); + /* (403) anylist ::= */ yytestcase(yyruleno==403); + /* (404) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==404); + /* (405) anylist ::= anylist ANY */ yytestcase(yyruleno==405); + /* (406) with ::= */ yytestcase(yyruleno==406); + /* (407) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=407); + /* (408) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=408); break; /********** End reduce actions ************************************************/ }; @@ -175590,7 +179243,7 @@ static void yy_syntax_error( UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ if( TOKEN.z[0] ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + parserSyntaxError(pParse, &TOKEN); }else{ sqlite3ErrorMsg(pParse, "incomplete input"); } @@ -175714,19 +179367,12 @@ SQLITE_PRIVATE void sqlite3Parser( (int)(yypParser->yytos - yypParser->yystack)); } #endif -#if YYSTACKDEPTH>0 if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - break; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); break; } } -#endif } yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ @@ -176797,27 +180443,58 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_INTEGER; #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ - for(i=3; sqlite3Isxdigit(z[i]); i++){} - return i; - } + for(i=3; 1; i++){ + if( sqlite3Isxdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + }else #endif - for(i=0; sqlite3Isdigit(z[i]); i++){} + { + for(i=0; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } #ifndef SQLITE_OMIT_FLOATING_POINT - if( z[i]=='.' ){ - i++; - while( sqlite3Isdigit(z[i]) ){ i++; } - *tokenType = TK_FLOAT; - } - if( (z[i]=='e' || z[i]=='E') && - ( sqlite3Isdigit(z[i+1]) - || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) - ) - ){ - i += 2; - while( sqlite3Isdigit(z[i]) ){ i++; } - *tokenType = TK_FLOAT; - } + if( z[i]=='.' ){ + if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; + for(i++; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + } + if( (z[i]=='e' || z[i]=='E') && + ( sqlite3Isdigit(z[i+1]) + || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) + ) + ){ + if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; + for(i+=2; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + } #endif + } while( IdChar(z[i]) ){ *tokenType = TK_ILLEGAL; i++; @@ -176982,10 +180659,13 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ if( tokenType>=TK_WINDOW ){ assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW + || tokenType==TK_QNUMBER ); #else if( tokenType>=TK_SPACE ){ - assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); + assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL + || tokenType==TK_QNUMBER + ); #endif /* SQLITE_OMIT_WINDOWFUNC */ if( AtomicLoad(&db->u1.isInterrupted) ){ pParse->rc = SQLITE_INTERRUPT; @@ -177018,7 +180698,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ assert( n==6 ); tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); #endif /* SQLITE_OMIT_WINDOWFUNC */ - }else{ + }else if( tokenType!=TK_QNUMBER ){ Token x; x.z = zSql; x.n = n; @@ -177054,7 +180734,9 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ if( pParse->zErrMsg==0 ){ pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); } - sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){ + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + } nErr++; } pParse->zTail = zSql; @@ -177763,32 +181445,6 @@ SQLITE_API char *sqlite3_temp_directory = 0; */ SQLITE_API char *sqlite3_data_directory = 0; -/* -** Determine whether or not high-precision (long double) floating point -** math works correctly on CPU currently running. -*/ -static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){ - if( sizeof(LONGDOUBLE_TYPE)<=8 ){ - /* If the size of "long double" is not more than 8, then - ** high-precision math is not possible. */ - return 0; - }else{ - /* Just because sizeof(long double)>8 does not mean that the underlying - ** hardware actually supports high-precision floating point. For example, - ** clearing the 0x100 bit in the floating-point control word on Intel - ** processors will make long double work like double, even though long - ** double takes up more space. The only way to determine if long double - ** actually works is to run an experiment. */ - LONGDOUBLE_TYPE a, b, c; - rc++; - a = 1.0+rc*0.1; - b = 1.0e+18+rc*25.0; - c = a+b; - return b!=c; - } -} - - /* ** Initialize SQLite. ** @@ -177983,13 +181639,6 @@ SQLITE_API int sqlite3_initialize(void){ rc = SQLITE_EXTRA_INIT(0); } #endif - - /* Experimentally determine if high-precision floating point is - ** available. */ -#ifndef SQLITE_OMIT_WSD - sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); -#endif - return rc; } @@ -178369,6 +182018,18 @@ SQLITE_API int sqlite3_config(int op, ...){ } #endif /* SQLITE_OMIT_DESERIALIZE */ + case SQLITE_CONFIG_ROWID_IN_VIEW: { + int *pVal = va_arg(ap,int*); +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( 0==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = TF_NoVisibleRowid; + if( 1==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = 0; + *pVal = (sqlite3GlobalConfig.mNoVisibleRowid==0); +#else + *pVal = 0; +#endif + break; + } + default: { rc = SQLITE_ERROR; break; @@ -179048,10 +182709,6 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ sqlite3ValueFree(db->pErr); sqlite3CloseExtensions(db); -#if SQLITE_USER_AUTHENTICATION - sqlite3_free(db->auth.zAuthUser); - sqlite3_free(db->auth.zAuthPW); -#endif db->eOpenState = SQLITE_STATE_ERROR; @@ -179518,7 +183175,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| - SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE); + SQLITE_SUBTYPE|SQLITE_INNOCUOUS| + SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But @@ -180485,8 +184143,8 @@ static const int aHardLimit[] = { #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif -#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127 -# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127 +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>32767 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 32767 #endif #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 # error SQLITE_MAX_ATTACHED must be between 0 and 125 @@ -180553,8 +184211,8 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ if( newLimit>=0 ){ /* IMP: R-52476-28732 */ if( newLimit>aHardLimit[limitId] ){ newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ - }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){ - newLimit = 1; + }else if( newLimit<SQLITE_MIN_LENGTH && limitId==SQLITE_LIMIT_LENGTH ){ + newLimit = SQLITE_MIN_LENGTH; } db->aLimit[limitId] = newLimit; } @@ -181076,6 +184734,7 @@ static int openDatabase( if( ((1<<(flags&7)) & 0x46)==0 ){ rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ }else{ + if( zFilename==0 ) zFilename = ":memory:"; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); } if( rc!=SQLITE_OK ){ @@ -181905,7 +185564,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ /* Invoke these debugging routines so that the compiler does not ** issue "defined but not used" warnings. */ if( x==9999 ){ - sqlite3ShowExpr(0); sqlite3ShowExpr(0); sqlite3ShowExprList(0); sqlite3ShowIdList(0); @@ -181993,6 +185651,18 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N) + ** + ** Write the current optimization settings into *N. A zero bit means that + ** the optimization is on, and a 1 bit means that the optimization is off. + */ + case SQLITE_TESTCTRL_GETOPT: { + sqlite3 *db = va_arg(ap, sqlite3*); + int *pN = va_arg(ap, int*); + *pN = db->dbOptFlags; + break; + } + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); ** ** If parameter onoff is 1, subsequent calls to localtime() fail. @@ -182224,24 +185894,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } -#if !defined(SQLITE_OMIT_WSD) - /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); - ** - ** X<0 Make no changes to the bUseLongDouble. Just report value. - ** X==0 Disable bUseLongDouble - ** X==1 Enable bUseLongDouble - ** X>=2 Set bUseLongDouble to its default value for this platform - */ - case SQLITE_TESTCTRL_USELONGDOUBLE: { - int b = va_arg(ap, int); - if( b>=2 ) b = hasHighPrecisionDouble(b); - if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; - rc = sqlite3Config.bUseLongDouble!=0; - break; - } -#endif - - #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) ** @@ -182271,6 +185923,28 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } #endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff); + ** + ** Activate or deactivate validation of JSONB that is generated from + ** text. Off by default, as the validation is slow. Validation is + ** only available if compiled using SQLITE_DEBUG. + ** + ** If onOff is initially 1, then turn it on. If onOff is initially + ** off, turn it off. If onOff is initially -1, then change onOff + ** to be the current setting. + */ + case SQLITE_TESTCTRL_JSON_SELFCHECK: { +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) + int *pOnOff = va_arg(ap, int*); + if( *pOnOff<0 ){ + *pOnOff = sqlite3Config.bJsonSelfcheck; + }else{ + sqlite3Config.bJsonSelfcheck = (u8)((*pOnOff)&0xff); + } +#endif + break; + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -182527,7 +186201,11 @@ SQLITE_API int sqlite3_snapshot_get( if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ + Pager *pPager = sqlite3BtreePager(pBt); + i64 dummy = 0; + sqlite3PagerSnapshotOpen(pPager, (sqlite3_snapshot*)&dummy); rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); } @@ -184255,6 +187933,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); + #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ #endif /* _FTSINT_H */ @@ -186315,10 +189995,15 @@ static int fts3PoslistPhraseMerge( if( *p1==POS_COLUMN ){ p1++; p1 += fts3GetVarint32(p1, &iCol1); + /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN + ** entry, so this is actually end-of-doclist. */ + if( iCol1==0 ) return 0; } if( *p2==POS_COLUMN ){ p2++; p2 += fts3GetVarint32(p2, &iCol2); + /* As above, iCol2==0 indicates corruption. */ + if( iCol2==0 ) return 0; } while( 1 ){ @@ -187977,7 +191662,7 @@ static int fts3ShadowName(const char *zName){ ** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual ** table. */ -static int fts3Integrity( +static int fts3IntegrityMethod( sqlite3_vtab *pVtab, /* The virtual table to be checked */ const char *zSchema, /* Name of schema in which pVtab lives */ const char *zTabname, /* Name of the pVTab table */ @@ -187985,31 +191670,24 @@ static int fts3Integrity( char **pzErr /* Write error message here */ ){ Fts3Table *p = (Fts3Table*)pVtab; - char *zSql; - int rc; - char *zErr = 0; + int rc = SQLITE_OK; + int bOk = 0; - assert( pzErr!=0 ); - assert( *pzErr==0 ); UNUSED_PARAMETER(isQuick); - zSql = sqlite3_mprintf( - "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", - zSchema, zTabname, zTabname); - if( zSql==0 ){ - return SQLITE_NOMEM; - } - rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr); - sqlite3_free(zSql); - if( (rc&0xff)==SQLITE_CORRUPT ){ - *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", - p->bFts4 ? 4 : 3, zSchema, zTabname); - }else if( rc!=SQLITE_OK ){ + rc = sqlite3Fts3IntegrityCheck(p, &bOk); + assert( rc!=SQLITE_CORRUPT_VTAB ); + if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" " FTS%d table %s.%s: %s", - p->bFts4 ? 4 : 3, zSchema, zTabname, zErr); + p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc)); + if( *pzErr ) rc = SQLITE_OK; + }else if( rc==SQLITE_OK && bOk==0 ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", + p->bFts4 ? 4 : 3, zSchema, zTabname); + if( *pzErr==0 ) rc = SQLITE_NOMEM; } - sqlite3_free(zErr); - return SQLITE_OK; + sqlite3Fts3SegmentsClose(p); + return rc; } @@ -188039,7 +191717,7 @@ static const sqlite3_module fts3Module = { /* xRelease */ fts3ReleaseMethod, /* xRollbackTo */ fts3RollbackToMethod, /* xShadowName */ fts3ShadowName, - /* xIntegrity */ fts3Integrity, + /* xIntegrity */ fts3IntegrityMethod, }; /* @@ -189496,7 +193174,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ nTmp += p->pRight->pPhrase->doclist.nList; } nTmp += p->pPhrase->doclist.nList; - aTmp = sqlite3_malloc64(nTmp*2); + aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX); if( !aTmp ){ *pRc = SQLITE_NOMEM; res = 0; @@ -190147,7 +193825,7 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ } #endif -#if !SQLITE_CORE +#if !defined(SQLITE_CORE) /* ** Initialize API pointer table, if required. */ @@ -191049,10 +194727,11 @@ static int getNextString( Fts3PhraseToken *pToken; p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); - if( !p ) goto no_mem; - zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); - if( !zTemp ) goto no_mem; + if( !zTemp || !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } assert( nToken==ii ); pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; @@ -191067,9 +194746,6 @@ static int getNextString( nToken = ii+1; } } - - pModule->xClose(pCursor); - pCursor = 0; } if( rc==SQLITE_DONE ){ @@ -191077,7 +194753,10 @@ static int getNextString( char *zBuf = 0; p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); - if( !p ) goto no_mem; + if( !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); p->eType = FTSQUERY_PHRASE; p->pPhrase = (Fts3Phrase *)&p[1]; @@ -191085,11 +194764,9 @@ static int getNextString( p->pPhrase->nToken = nToken; zBuf = (char *)&p->pPhrase->aToken[nToken]; + assert( nTemp==0 || zTemp ); if( zTemp ){ memcpy(zBuf, zTemp, nTemp); - sqlite3_free(zTemp); - }else{ - assert( nTemp==0 ); } for(jj=0; jj<p->pPhrase->nToken; jj++){ @@ -191099,17 +194776,17 @@ static int getNextString( rc = SQLITE_OK; } - *ppExpr = p; - return rc; -no_mem: - + getnextstring_out: if( pCursor ){ pModule->xClose(pCursor); } sqlite3_free(zTemp); - sqlite3_free(p); - *ppExpr = 0; - return SQLITE_NOMEM; + if( rc!=SQLITE_OK ){ + sqlite3_free(p); + p = 0; + } + *ppExpr = p; + return rc; } /* @@ -193303,11 +196980,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" /* #include <string.h> */ /* @@ -199593,7 +203266,7 @@ static u64 fts3ChecksumIndex( ** If an error occurs (e.g. an OOM or IO error), return an SQLite error ** code. The final value of *pbOk is undefined in this case. */ -static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ int rc = SQLITE_OK; /* Return code */ u64 cksum1 = 0; /* Checksum based on FTS index contents */ u64 cksum2 = 0; /* Checksum based on %_content contents */ @@ -199671,7 +203344,12 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ sqlite3_finalize(pStmt); } - *pbOk = (cksum1==cksum2); + if( rc==SQLITE_CORRUPT_VTAB ){ + rc = SQLITE_OK; + *pbOk = 0; + }else{ + *pbOk = (rc==SQLITE_OK && cksum1==cksum2); + } return rc; } @@ -199711,7 +203389,7 @@ static int fts3DoIntegrityCheck( ){ int rc; int bOk = 0; - rc = fts3IntegrityCheck(p, &bOk); + rc = sqlite3Fts3IntegrityCheck(p, &bOk); if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; return rc; } @@ -200529,6 +204207,7 @@ static int fts3SnippetNextCandidate(SnippetIter *pIter){ return 1; } + assert( pIter->nSnippet>=0 ); pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; for(i=0; i<pIter->nPhrase; i++){ SnippetPhrase *pPhrase = &pIter->aPhrase[i]; @@ -200577,7 +204256,7 @@ static void fts3SnippetDetails( } mCover |= mPhrase; - for(j=0; j<pPhrase->nToken; j++){ + for(j=0; j<pPhrase->nToken && j<pIter->nSnippet; j++){ mHighlight |= (mPos>>j); } @@ -202685,24 +206364,145 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** ****************************************************************************** ** -** This SQLite JSON functions. +** SQLite JSON functions. ** ** This file began as an extension in ext/misc/json1.c in 2015. That ** extension proved so useful that it has now been moved into the core. ** -** For the time being, all JSON is stored as pure text. (We might add -** a JSONB type in the future which stores a binary encoding of JSON in -** a BLOB, but there is no support for JSONB in the current implementation. -** This implementation parses JSON text at 250 MB/s, so it is hard to see -** how JSONB might improve on that.) +** The original design stored all JSON as pure text, canonical RFC-8259. +** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16). +** All generated JSON text still conforms strictly to RFC-8259, but text +** with JSON-5 extensions is accepted as input. +** +** Beginning with version 3.45.0 (circa 2024-01-01), these routines also +** accept BLOB values that have JSON encoded using a binary representation +** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk +** format SQLite JSONB is completely different and incompatible with +** PostgreSQL JSONB. +** +** Decoding and interpreting JSONB is still O(N) where N is the size of +** the input, the same as text JSON. However, the constant of proportionality +** for JSONB is much smaller due to faster parsing. The size of each +** element in JSONB is encoded in its header, so there is no need to search +** for delimiters using persnickety syntax rules. JSONB seems to be about +** 3x faster than text JSON as a result. JSONB is also tends to be slightly +** smaller than text JSON, by 5% or 10%, but there are corner cases where +** JSONB can be slightly larger. So you are not far mistaken to say that +** a JSONB blob is the same size as the equivalent RFC-8259 text. +** +** +** THE JSONB ENCODING: +** +** Every JSON element is encoded in JSONB as a header and a payload. +** The header is between 1 and 9 bytes in size. The payload is zero +** or more bytes. +** +** The lower 4 bits of the first byte of the header determines the +** element type: +** +** 0: NULL +** 1: TRUE +** 2: FALSE +** 3: INT -- RFC-8259 integer literal +** 4: INT5 -- JSON5 integer literal +** 5: FLOAT -- RFC-8259 floating point literal +** 6: FLOAT5 -- JSON5 floating point literal +** 7: TEXT -- Text literal acceptable to both SQL and JSON +** 8: TEXTJ -- Text containing RFC-8259 escapes +** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes +** 10: TEXTRAW -- Text containing unescaped syntax characters +** 11: ARRAY +** 12: OBJECT +** +** The other three possible values (13-15) are reserved for future +** enhancements. +** +** The upper 4 bits of the first byte determine the size of the header +** and sometimes also the size of the payload. If X is the first byte +** of the element and if X>>4 is between 0 and 11, then the payload +** will be that many bytes in size and the header is exactly one byte +** in size. Other four values for X>>4 (12-15) indicate that the header +** is more than one byte in size and that the payload size is determined +** by the remainder of the header, interpreted as a unsigned big-endian +** integer. +** +** Value of X>>4 Size integer Total header size +** ------------- -------------------- ----------------- +** 12 1 byte (0-255) 2 +** 13 2 byte (0-65535) 3 +** 14 4 byte (0-4294967295) 5 +** 15 8 byte (0-1.8e19) 9 +** +** The payload size need not be expressed in its minimal form. For example, +** if the payload size is 10, the size can be expressed in any of 5 different +** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte, +** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by +** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and +** a single byte of 0x0a. The shorter forms are preferred, of course, but +** sometimes when generating JSONB, the payload size is not known in advance +** and it is convenient to reserve sufficient header space to cover the +** largest possible payload size and then come back later and patch up +** the size when it becomes known, resulting in a non-minimal encoding. +** +** The value (X>>4)==15 is not actually used in the current implementation +** (as SQLite is currently unable handle BLOBs larger than about 2GB) +** but is included in the design to allow for future enhancements. +** +** The payload follows the header. NULL, TRUE, and FALSE have no payload and +** their payload size must always be zero. The payload for INT, INT5, +** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the +** "..." or '...' delimiters are omitted from the various text encodings. +** The payload for ARRAY and OBJECT is a list of additional elements that +** are the content for the array or object. The payload for an OBJECT +** must be an even number of elements. The first element of each pair is +** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW. +** +** A valid JSONB blob consists of a single element, as described above. +** Usually this will be an ARRAY or OBJECT element which has many more +** elements as its content. But the overall blob is just a single element. +** +** Input validation for JSONB blobs simply checks that the element type +** code is between 0 and 12 and that the total size of the element +** (header plus payload) is the same as the size of the BLOB. If those +** checks are true, the BLOB is assumed to be JSONB and processing continues. +** Errors are only raised if some other miscoding is discovered during +** processing. +** +** Additional information can be found in the doc/jsonb.md file of the +** canonical SQLite source tree. */ #ifndef SQLITE_OMIT_JSON /* #include "sqliteInt.h" */ +/* JSONB element types +*/ +#define JSONB_NULL 0 /* "null" */ +#define JSONB_TRUE 1 /* "true" */ +#define JSONB_FALSE 2 /* "false" */ +#define JSONB_INT 3 /* integer acceptable to JSON and SQL */ +#define JSONB_INT5 4 /* integer in 0x000 notation */ +#define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */ +#define JSONB_FLOAT5 6 /* float with JSON5 extensions */ +#define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */ +#define JSONB_TEXTJ 8 /* Text with JSON escapes */ +#define JSONB_TEXT5 9 /* Text with JSON-5 escape */ +#define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */ +#define JSONB_ARRAY 11 /* An array */ +#define JSONB_OBJECT 12 /* An object */ + +/* Human-readable names for the JSONB values. The index for each +** string must correspond to the JSONB_* integer above. +*/ +static const char * const jsonbType[] = { + "null", "true", "false", "integer", "integer", + "real", "real", "text", "text", "text", + "text", "array", "object", "", "", "", "" +}; + /* ** Growing our own isspace() routine this way is twice as fast as ** the library isspace() function, resulting in a 7% overall performance -** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). +** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, @@ -202723,11 +206523,19 @@ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -#define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) +#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) /* -** Characters that are special to JSON. Control charaters, -** '"' and '\\'. +** The set of all space characters recognized by jsonIsspace(). +** Useful as the second argument to strspn(). +*/ +static const char jsonSpaces[] = "\011\012\015\040"; + +/* +** Characters that are special to JSON. Control characters, +** '"' and '\\' and '\''. Actually, '\'' is not special to +** canonical JSON, but it is special in JSON-5, so we include +** it in the set of special characters. */ static const char jsonIsOk[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -202749,22 +206557,49 @@ static const char jsonIsOk[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - -#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) -# define VVA(X) -#else -# define VVA(X) X -#endif - /* Objects */ +typedef struct JsonCache JsonCache; typedef struct JsonString JsonString; -typedef struct JsonNode JsonNode; typedef struct JsonParse JsonParse; -typedef struct JsonCleanup JsonCleanup; + +/* +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +*/ +#define JSON_CACHE_ID (-429938) /* Cache entry */ +#define JSON_CACHE_SIZE 4 /* Max number of cache entries */ + +/* +** jsonUnescapeOneChar() returns this invalid code point if it encounters +** a syntax error. +*/ +#define JSON_INVALID_CHAR 0x99999 + +/* A cache mapping JSON text into JSONB blobs. +** +** Each cache entry is a JsonParse object with the following restrictions: +** +** * The bReadOnly flag must be set +** +** * The aBlob[] array must be owned by the JsonParse object. In other +** words, nBlobAlloc must be non-zero. +** +** * eEdit and delta must be zero. +** +** * zJson must be an RCStr. In other words bJsonIsRCStr must be true. +*/ +struct JsonCache { + sqlite3 *db; /* Database connection */ + int nUsed; /* Number of active entries in the cache */ + JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */ +}; /* An instance of this object represents a JSON string ** under construction. Really, this is a generic string accumulator ** that can be and is used to create strings other than JSON. +** +** If the generated string is longer than will fit into the zSpace[] buffer, +** then it will be an RCStr string. This aids with caching of large +** JSON strings. */ struct JsonString { sqlite3_context *pCtx; /* Function context - put error messages here */ @@ -202772,121 +206607,75 @@ struct JsonString { u64 nAlloc; /* Bytes of storage available in zBuf[] */ u64 nUsed; /* Bytes of zBuf[] currently used */ u8 bStatic; /* True if zBuf is static space */ - u8 bErr; /* True if an error has been encountered */ + u8 eErr; /* True if an error has been encountered */ char zSpace[100]; /* Initial static space */ }; -/* A deferred cleanup task. A list of JsonCleanup objects might be -** run when the JsonParse object is destroyed. -*/ -struct JsonCleanup { - JsonCleanup *pJCNext; /* Next in a list */ - void (*xOp)(void*); /* Routine to run */ - void *pArg; /* Argument to xOp() */ -}; +/* Allowed values for JsonString.eErr */ +#define JSTRING_OOM 0x01 /* Out of memory */ +#define JSTRING_MALFORMED 0x02 /* Malformed JSONB */ +#define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */ -/* JSON type values +/* The "subtype" set for text JSON values passed through using +** sqlite3_result_subtype() and sqlite3_value_subtype(). */ -#define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */ -#define JSON_NULL 1 -#define JSON_TRUE 2 -#define JSON_FALSE 3 -#define JSON_INT 4 -#define JSON_REAL 5 -#define JSON_STRING 6 -#define JSON_ARRAY 7 -#define JSON_OBJECT 8 - -/* The "subtype" set for JSON values */ #define JSON_SUBTYPE 74 /* Ascii for "J" */ /* -** Names of the various JSON types: -*/ -static const char * const jsonType[] = { - "subst", - "null", "true", "false", "integer", "real", "text", "array", "object" -}; - -/* Bit values for the JsonNode.jnFlag field -*/ -#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ -#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ -#define JNODE_REMOVE 0x04 /* Do not output */ -#define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */ -#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */ -#define JNODE_LABEL 0x20 /* Is a label of an object */ -#define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */ - - -/* A single node of parsed JSON. An array of these nodes describes -** a parse of JSON + edits. -** -** Use the json_parse() SQL function (available when compiled with -** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including -** a complete listing and decoding of the array of JsonNodes. +** Bit values for the flags passed into various SQL function implementations +** via the sqlite3_user_data() value. */ -struct JsonNode { - u8 eType; /* One of the JSON_ type values */ - u8 jnFlags; /* JNODE flags */ - u8 eU; /* Which union element to use */ - u32 n; /* Bytes of content for INT, REAL or STRING - ** Number of sub-nodes for ARRAY and OBJECT - ** Node that SUBST applies to */ - union { - const char *zJContent; /* 1: Content for INT, REAL, and STRING */ - u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ - u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ - u32 iPrev; /* 4: Previous SUBST node, or 0 */ - } u; -}; +#define JSON_JSON 0x01 /* Result is always JSON */ +#define JSON_SQL 0x02 /* Result is always SQL */ +#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ +#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ +#define JSON_BLOB 0x08 /* Use the BLOB output format */ -/* A parsed and possibly edited JSON string. Lifecycle: -** -** 1. JSON comes in and is parsed into an array aNode[]. The original -** JSON text is stored in zJson. -** -** 2. Zero or more changes are made (via json_remove() or json_replace() -** or similar) to the aNode[] array. +/* A parsed JSON value. Lifecycle: ** -** 3. A new, edited and mimified JSON string is generated from aNode -** and stored in zAlt. The JsonParse object always owns zAlt. +** 1. JSON comes in and is parsed into a JSONB value in aBlob. The +** original text is stored in zJson. This step is skipped if the +** input is JSONB instead of text JSON. ** -** Step 1 always happens. Step 2 and 3 may or may not happen, depending -** on the operation. +** 2. The aBlob[] array is searched using the JSON path notation, if needed. ** -** aNode[].u.zJContent entries typically point into zJson. Hence zJson -** must remain valid for the lifespan of the parse. For edits, -** aNode[].u.zJContent might point to malloced space other than zJson. -** Entries in pClup are responsible for freeing that extra malloced space. +** 3. Zero or more changes are made to aBlob[] (via json_remove() or +** json_replace() or json_patch() or similar). ** -** When walking the parse tree in aNode[], edits are ignored if useMod is -** false. +** 4. New JSON text is generated from the aBlob[] for output. This step +** is skipped if the function is one of the jsonb_* functions that +** returns JSONB instead of text JSON. */ struct JsonParse { - u32 nNode; /* Number of slots of aNode[] used */ - u32 nAlloc; /* Number of slots of aNode[] allocated */ - JsonNode *aNode; /* Array of nodes containing the parse */ - char *zJson; /* Original JSON string (before edits) */ - char *zAlt; /* Revised and/or mimified JSON */ - u32 *aUp; /* Index of parent of each node */ - JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */ + u8 *aBlob; /* JSONB representation of JSON value */ + u32 nBlob; /* Bytes of aBlob[] actually used */ + u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */ + char *zJson; /* Json text used for parsing */ + sqlite3 *db; /* The database connection to which this object belongs */ + int nJson; /* Length of the zJson string in bytes */ + u32 nJPRef; /* Number of references to this object */ + u32 iErr; /* Error location in zJson[] */ u16 iDepth; /* Nesting depth */ u8 nErr; /* Number of errors seen */ u8 oom; /* Set to true if out of memory */ u8 bJsonIsRCStr; /* True if zJson is an RCStr */ u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ - u8 useMod; /* Actually use the edits contain inside aNode */ - u8 hasMod; /* aNode contains edits from the original zJson */ - u32 nJPRef; /* Number of references to this object */ - int nJson; /* Length of the zJson string in bytes */ - int nAlt; /* Length of alternative JSON string zAlt, in bytes */ - u32 iErr; /* Error location in zJson[] */ - u32 iSubst; /* Last JSON_SUBST entry in aNode[] */ - u32 iHold; /* Age of this entry in the cache for LRU replacement */ + u8 bReadOnly; /* Do not modify. */ + /* Search and edit information. See jsonLookupStep() */ + u8 eEdit; /* Edit operation to apply */ + int delta; /* Size change due to the edit */ + u32 nIns; /* Number of bytes to insert */ + u32 iLabel; /* Location of label if search landed on an object value */ + u8 *aIns; /* Content to be inserted */ }; +/* Allowed values for JsonParse.eEdit */ +#define JEDIT_DEL 1 /* Delete if exists */ +#define JEDIT_REPL 2 /* Overwrite if exists */ +#define JEDIT_INS 3 /* Insert if not exists */ +#define JEDIT_SET 4 /* Insert or overwrite */ + /* ** Maximum nesting depth of JSON for this implementation. ** @@ -202894,15 +206683,151 @@ struct JsonParse { ** descent parser. A depth of 1000 is far deeper than any sane JSON ** should go. Historical note: This limit was 2000 prior to version 3.42.0 */ -#define JSON_MAX_DEPTH 1000 +#ifndef SQLITE_JSON_MAX_DEPTH +# define JSON_MAX_DEPTH 1000 +#else +# define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH +#endif + +/* +** Allowed values for the flgs argument to jsonParseFuncArg(); +*/ +#define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ +#define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ + +/************************************************************************** +** Forward references +**************************************************************************/ +static void jsonReturnStringAsBlob(JsonString*); +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson); +static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); +static void jsonReturnParse(sqlite3_context*,JsonParse*); +static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); +static void jsonParseFree(JsonParse*); +static u32 jsonbPayloadSize(const JsonParse*, u32, u32*); +static u32 jsonUnescapeOneChar(const char*, u32, u32*); + +/************************************************************************** +** Utility routines for dealing with JsonCache objects +**************************************************************************/ + +/* +** Free a JsonCache object. +*/ +static void jsonCacheDelete(JsonCache *p){ + int i; + for(i=0; i<p->nUsed; i++){ + jsonParseFree(p->a[i]); + } + sqlite3DbFree(p->db, p); +} +static void jsonCacheDeleteGeneric(void *p){ + jsonCacheDelete((JsonCache*)p); +} + +/* +** Insert a new entry into the cache. If the cache is full, expel +** the least recently used entry. Return SQLITE_OK on success or a +** result code otherwise. +** +** Cache entries are stored in age order, oldest first. +*/ +static int jsonCacheInsert( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + JsonParse *pParse /* The parse object to be added to the cache */ +){ + JsonCache *p; + + assert( pParse->zJson!=0 ); + assert( pParse->bJsonIsRCStr ); + assert( pParse->delta==0 ); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + sqlite3 *db = sqlite3_context_db_handle(ctx); + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM; + p->db = db; + sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ) return SQLITE_NOMEM; + } + if( p->nUsed >= JSON_CACHE_SIZE ){ + jsonParseFree(p->a[0]); + memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0])); + p->nUsed = JSON_CACHE_SIZE-1; + } + assert( pParse->nBlobAlloc>0 ); + pParse->eEdit = 0; + pParse->nJPRef++; + pParse->bReadOnly = 1; + p->a[p->nUsed] = pParse; + p->nUsed++; + return SQLITE_OK; +} + +/* +** Search for a cached translation the json text supplied by pArg. Return +** the JsonParse object if found. Return NULL if not found. +** +** When a match if found, the matching entry is moved to become the +** most-recently used entry if it isn't so already. +** +** The JsonParse object returned still belongs to the Cache and might +** be deleted at any moment. If the caller whants the JsonParse to +** linger, it needs to increment the nPJRef reference counter. +*/ +static JsonParse *jsonCacheSearch( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + sqlite3_value *pArg /* Function argument containing SQL text */ +){ + JsonCache *p; + int i; + const char *zJson; + int nJson; + + if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){ + return 0; + } + zJson = (const char*)sqlite3_value_text(pArg); + if( zJson==0 ) return 0; + nJson = sqlite3_value_bytes(pArg); + + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + return 0; + } + for(i=0; i<p->nUsed; i++){ + if( p->a[i]->zJson==zJson ) break; + } + if( i>=p->nUsed ){ + for(i=0; i<p->nUsed; i++){ + if( p->a[i]->nJson!=nJson ) continue; + if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break; + } + } + if( i<p->nUsed ){ + if( i<p->nUsed-1 ){ + /* Make the matching entry the most recently used entry */ + JsonParse *tmp = p->a[i]; + memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp)); + p->a[p->nUsed-1] = tmp; + i = p->nUsed - 1; + } + assert( p->a[i]->delta==0 ); + return p->a[i]; + }else{ + return 0; + } +} /************************************************************************** ** Utility routines for dealing with JsonString objects **************************************************************************/ -/* Set the JsonString object to an empty string +/* Turn uninitialized bulk memory into a valid JsonString object +** holding a zero-length string. */ -static void jsonZero(JsonString *p){ +static void jsonStringZero(JsonString *p){ p->zBuf = p->zSpace; p->nAlloc = sizeof(p->zSpace); p->nUsed = 0; @@ -202911,39 +206836,39 @@ static void jsonZero(JsonString *p){ /* Initialize the JsonString object */ -static void jsonInit(JsonString *p, sqlite3_context *pCtx){ +static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){ p->pCtx = pCtx; - p->bErr = 0; - jsonZero(p); + p->eErr = 0; + jsonStringZero(p); } /* Free all allocated memory and reset the JsonString object back to its ** initial state. */ -static void jsonReset(JsonString *p){ +static void jsonStringReset(JsonString *p){ if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); - jsonZero(p); + jsonStringZero(p); } /* Report an out-of-memory (OOM) condition */ -static void jsonOom(JsonString *p){ - p->bErr = 1; - sqlite3_result_error_nomem(p->pCtx); - jsonReset(p); +static void jsonStringOom(JsonString *p){ + p->eErr |= JSTRING_OOM; + if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx); + jsonStringReset(p); } /* Enlarge pJson->zBuf so that it can hold at least N more bytes. ** Return zero on success. Return non-zero on an OOM error */ -static int jsonGrow(JsonString *p, u32 N){ +static int jsonStringGrow(JsonString *p, u32 N){ u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10; char *zNew; if( p->bStatic ){ - if( p->bErr ) return 1; + if( p->eErr ) return 1; zNew = sqlite3RCStrNew(nTotal); if( zNew==0 ){ - jsonOom(p); + jsonStringOom(p); return SQLITE_NOMEM; } memcpy(zNew, p->zBuf, (size_t)p->nUsed); @@ -202952,8 +206877,8 @@ static int jsonGrow(JsonString *p, u32 N){ }else{ p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); if( p->zBuf==0 ){ - p->bErr = 1; - jsonZero(p); + p->eErr |= JSTRING_OOM; + jsonStringZero(p); return SQLITE_NOMEM; } } @@ -202963,20 +206888,20 @@ static int jsonGrow(JsonString *p, u32 N){ /* Append N bytes from zIn onto the end of the JsonString string. */ -static SQLITE_NOINLINE void jsonAppendExpand( +static SQLITE_NOINLINE void jsonStringExpandAndAppend( JsonString *p, const char *zIn, u32 N ){ assert( N>0 ); - if( jsonGrow(p,N) ) return; + if( jsonStringGrow(p,N) ) return; memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; } static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ if( N==0 ) return; if( N+p->nUsed >= p->nAlloc ){ - jsonAppendExpand(p,zIn,N); + jsonStringExpandAndAppend(p,zIn,N); }else{ memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; @@ -202985,19 +206910,18 @@ static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ assert( N>0 ); if( N+p->nUsed >= p->nAlloc ){ - jsonAppendExpand(p,zIn,N); + jsonStringExpandAndAppend(p,zIn,N); }else{ memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; } } - /* Append formatted text (not to exceed N bytes) to the JsonString. */ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ va_list ap; - if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; + if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return; va_start(ap, zFormat); sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); va_end(ap); @@ -203007,7 +206931,7 @@ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ /* Append a single character */ static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ - if( jsonGrow(p,1) ) return; + if( jsonStringGrow(p,1) ) return; p->zBuf[p->nUsed++] = c; } static void jsonAppendChar(JsonString *p, char c){ @@ -203018,24 +206942,27 @@ static void jsonAppendChar(JsonString *p, char c){ } } -/* Try to force the string to be a zero-terminated RCStr string. +/* Remove a single character from the end of the string +*/ +static void jsonStringTrimOneChar(JsonString *p){ + if( p->eErr==0 ){ + assert( p->nUsed>0 ); + p->nUsed--; + } +} + + +/* Make sure there is a zero terminator on p->zBuf[] ** ** Return true on success. Return false if an OOM prevents this ** from happening. */ -static int jsonForceRCStr(JsonString *p){ +static int jsonStringTerminate(JsonString *p){ jsonAppendChar(p, 0); - if( p->bErr ) return 0; - p->nUsed--; - if( p->bStatic==0 ) return 1; - p->nAlloc = 0; - p->nUsed++; - jsonGrow(p, p->nUsed); - p->nUsed--; - return p->bStatic==0; + jsonStringTrimOneChar(p); + return p->eErr==0; } - /* Append a comma separator to the output buffer, if the previous ** character is not '[' or '{'. */ @@ -203047,190 +206974,120 @@ static void jsonAppendSeparator(JsonString *p){ jsonAppendChar(p, ','); } -/* Append the N-byte string in zIn to the end of the JsonString string -** under construction. Enclose the string in "..." and escape -** any double-quotes or backslash characters contained within the -** string. +/* c is a control character. Append the canonical JSON representation +** of that control character to p. +** +** This routine assumes that the output buffer has already been enlarged +** sufficiently to hold the worst-case encoding plus a nul terminator. */ -static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ - u32 i; - if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return; - p->zBuf[p->nUsed++] = '"'; - for(i=0; i<N; i++){ - unsigned char c = ((unsigned const char*)zIn)[i]; - if( jsonIsOk[c] ){ - p->zBuf[p->nUsed++] = c; - }else if( c=='"' || c=='\\' ){ - json_simple_escape: - if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; - p->zBuf[p->nUsed++] = '\\'; - p->zBuf[p->nUsed++] = c; - }else if( c=='\'' ){ - p->zBuf[p->nUsed++] = c; - }else{ - static const char aSpecial[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - assert( sizeof(aSpecial)==32 ); - assert( aSpecial['\b']=='b' ); - assert( aSpecial['\f']=='f' ); - assert( aSpecial['\n']=='n' ); - assert( aSpecial['\r']=='r' ); - assert( aSpecial['\t']=='t' ); - assert( c>=0 && c<sizeof(aSpecial) ); - if( aSpecial[c] ){ - c = aSpecial[c]; - goto json_simple_escape; - } - if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; - p->zBuf[p->nUsed++] = '\\'; - p->zBuf[p->nUsed++] = 'u'; - p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; - p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; - } +static void jsonAppendControlChar(JsonString *p, u8 c){ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + assert( c>=0 && c<sizeof(aSpecial) ); + assert( p->nUsed+7 <= p->nAlloc ); + if( aSpecial[c] ){ + p->zBuf[p->nUsed] = '\\'; + p->zBuf[p->nUsed+1] = aSpecial[c]; + p->nUsed += 2; + }else{ + p->zBuf[p->nUsed] = '\\'; + p->zBuf[p->nUsed+1] = 'u'; + p->zBuf[p->nUsed+2] = '0'; + p->zBuf[p->nUsed+3] = '0'; + p->zBuf[p->nUsed+4] = "0123456789abcdef"[c>>4]; + p->zBuf[p->nUsed+5] = "0123456789abcdef"[c&0xf]; + p->nUsed += 6; } - p->zBuf[p->nUsed++] = '"'; - assert( p->nUsed<p->nAlloc ); } -/* -** The zIn[0..N] string is a JSON5 string literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. +/* Append the N-byte string in zIn to the end of the JsonString string +** under construction. Enclose the string in double-quotes ("...") and +** escape any double-quotes or backslash characters contained within the +** string. +** +** This routine is a high-runner. There is a measurable performance +** increase associated with unwinding the jsonIsOk[] loop. */ -static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ - u32 i; - jsonAppendChar(p, '"'); - zIn++; - N -= 2; - while( N>0 ){ - for(i=0; i<N && zIn[i]!='\\' && zIn[i]!='"'; i++){} - if( i>0 ){ - jsonAppendRawNZ(p, zIn, i); - zIn += i; - N -= i; - if( N==0 ) break; - } - if( zIn[0]=='"' ){ - jsonAppendRawNZ(p, "\\\"", 2); - zIn++; - N--; - continue; - } - assert( zIn[0]=='\\' ); - switch( (u8)zIn[1] ){ - case '\'': - jsonAppendChar(p, '\''); - break; - case 'v': - jsonAppendRawNZ(p, "\\u0009", 6); - break; - case 'x': - jsonAppendRawNZ(p, "\\u00", 4); - jsonAppendRawNZ(p, &zIn[2], 2); - zIn += 2; - N -= 2; - break; - case '0': - jsonAppendRawNZ(p, "\\u0000", 6); +static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ + u32 k; + u8 c; + const u8 *z = (const u8*)zIn; + if( z==0 ) return; + if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return; + p->zBuf[p->nUsed++] = '"'; + while( 1 /*exit-by-break*/ ){ + k = 0; + /* The following while() is the 4-way unwound equivalent of + ** + ** while( k<N && jsonIsOk[z[k]] ){ k++; } + */ + while( 1 /* Exit by break */ ){ + if( k+3>=N ){ + while( k<N && jsonIsOk[z[k]] ){ k++; } break; - case '\r': - if( zIn[2]=='\n' ){ - zIn++; - N--; - } + } + if( !jsonIsOk[z[k]] ){ break; - case '\n': + } + if( !jsonIsOk[z[k+1]] ){ + k += 1; break; - case 0xe2: - assert( N>=4 ); - assert( 0x80==(u8)zIn[2] ); - assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] ); - zIn += 2; - N -= 2; + } + if( !jsonIsOk[z[k+2]] ){ + k += 2; break; - default: - jsonAppendRawNZ(p, zIn, 2); + } + if( !jsonIsOk[z[k+3]] ){ + k += 3; break; + }else{ + k += 4; + } } - zIn += 2; - N -= 2; - } - jsonAppendChar(p, '"'); -} - -/* -** The zIn[0..N] string is a JSON5 integer literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){ - if( zIn[0]=='+' ){ - zIn++; - N--; - }else if( zIn[0]=='-' ){ - jsonAppendChar(p, '-'); - zIn++; - N--; - } - if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){ - sqlite3_int64 i = 0; - int rc = sqlite3DecOrHexToI64(zIn, &i); - if( rc<=1 ){ - jsonPrintf(100,p,"%lld",i); + if( k>=N ){ + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + } + break; + } + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + z += k; + N -= k; + } + c = z[0]; + if( c=='"' || c=='\\' ){ + if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = c; + }else if( c=='\'' ){ + p->zBuf[p->nUsed++] = c; }else{ - assert( rc==2 ); - jsonAppendRawNZ(p, "9.0e999", 7); + if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return; + jsonAppendControlChar(p, c); } - return; - } - assert( N>0 ); - jsonAppendRawNZ(p, zIn, N); -} - -/* -** The zIn[0..N] string is a JSON5 real literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){ - u32 i; - if( zIn[0]=='+' ){ - zIn++; - N--; - }else if( zIn[0]=='-' ){ - jsonAppendChar(p, '-'); - zIn++; + z++; N--; } - if( zIn[0]=='.' ){ - jsonAppendChar(p, '0'); - } - for(i=0; i<N; i++){ - if( zIn[i]=='.' && (i+1==N || !sqlite3Isdigit(zIn[i+1])) ){ - i++; - jsonAppendRaw(p, zIn, i); - zIn += i; - N -= i; - jsonAppendChar(p, '0'); - break; - } - } - if( N>0 ){ - jsonAppendRawNZ(p, zIn, N); - } + p->zBuf[p->nUsed++] = '"'; + assert( p->nUsed<p->nAlloc ); } - - /* -** Append a function parameter value to the JSON string under -** construction. +** Append an sqlite3_value (such as a function parameter) to the JSON +** string under construction in p. */ -static void jsonAppendValue( +static void jsonAppendSqlValue( JsonString *p, /* Append to this JSON string */ sqlite3_value *pValue /* Value to append */ ){ @@ -203260,291 +207117,127 @@ static void jsonAppendValue( break; } default: { - if( p->bErr==0 ){ + if( jsonFuncArgMightBeBinary(pValue) ){ + JsonParse px; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(pValue); + px.nBlob = sqlite3_value_bytes(pValue); + jsonTranslateBlobToText(&px, 0, p); + }else if( p->eErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); - p->bErr = 2; - jsonReset(p); + p->eErr = JSTRING_ERR; + jsonStringReset(p); } break; } } } - -/* Make the JSON in p the result of the SQL function. +/* Make the text in p (which is probably a generated JSON text string) +** the result of the SQL function. +** +** The JsonString is reset. ** -** The JSON string is reset. +** If pParse and ctx are both non-NULL, then the SQL string in p is +** loaded into the zJson field of the pParse object as a RCStr and the +** pParse is added to the cache. */ -static void jsonResult(JsonString *p){ - if( p->bErr==0 ){ - if( p->bStatic ){ +static void jsonReturnString( + JsonString *p, /* String to return */ + JsonParse *pParse, /* JSONB source or NULL */ + sqlite3_context *ctx /* Where to cache */ +){ + assert( (pParse!=0)==(ctx!=0) ); + assert( ctx==0 || ctx==p->pCtx ); + if( p->eErr==0 ){ + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx)); + if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(p); + }else if( p->bStatic ){ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, SQLITE_TRANSIENT, SQLITE_UTF8); - }else if( jsonForceRCStr(p) ){ - sqlite3RCStrRef(p->zBuf); - sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + }else if( jsonStringTerminate(p) ){ + if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){ + int rc; + pParse->zJson = sqlite3RCStrRef(p->zBuf); + pParse->nJson = p->nUsed; + pParse->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, pParse); + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(ctx); + jsonStringReset(p); + return; + } + } + sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed, sqlite3RCStrUnref, SQLITE_UTF8); + }else{ + sqlite3_result_error_nomem(p->pCtx); } - } - if( p->bErr==1 ){ + }else if( p->eErr & JSTRING_OOM ){ sqlite3_result_error_nomem(p->pCtx); + }else if( p->eErr & JSTRING_MALFORMED ){ + sqlite3_result_error(p->pCtx, "malformed JSON", -1); } - jsonReset(p); + jsonStringReset(p); } /************************************************************************** -** Utility routines for dealing with JsonNode and JsonParse objects +** Utility routines for dealing with JsonParse objects **************************************************************************/ -/* -** Return the number of consecutive JsonNode slots need to represent -** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and -** OBJECT types, the number might be larger. -** -** Appended elements are not counted. The value returned is the number -** by which the JsonNode counter should increment in order to go to the -** next peer value. -*/ -static u32 jsonNodeSize(JsonNode *pNode){ - return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; -} - /* ** Reclaim all memory allocated by a JsonParse object. But do not ** delete the JsonParse object itself. */ static void jsonParseReset(JsonParse *pParse){ - while( pParse->pClup ){ - JsonCleanup *pTask = pParse->pClup; - pParse->pClup = pTask->pJCNext; - pTask->xOp(pTask->pArg); - sqlite3_free(pTask); - } assert( pParse->nJPRef<=1 ); - if( pParse->aNode ){ - sqlite3_free(pParse->aNode); - pParse->aNode = 0; - } - pParse->nNode = 0; - pParse->nAlloc = 0; - if( pParse->aUp ){ - sqlite3_free(pParse->aUp); - pParse->aUp = 0; - } if( pParse->bJsonIsRCStr ){ sqlite3RCStrUnref(pParse->zJson); pParse->zJson = 0; + pParse->nJson = 0; pParse->bJsonIsRCStr = 0; } - if( pParse->zAlt ){ - sqlite3RCStrUnref(pParse->zAlt); - pParse->zAlt = 0; + if( pParse->nBlobAlloc ){ + sqlite3DbFree(pParse->db, pParse->aBlob); + pParse->aBlob = 0; + pParse->nBlob = 0; + pParse->nBlobAlloc = 0; } } /* -** Free a JsonParse object that was obtained from sqlite3_malloc(). -** -** Note that destroying JsonParse might call sqlite3RCStrUnref() to -** destroy the zJson value. The RCStr object might recursively invoke -** JsonParse to destroy this pParse object again. Take care to ensure -** that this recursive destructor sequence terminates harmlessly. +** Decrement the reference count on the JsonParse object. When the +** count reaches zero, free the object. */ static void jsonParseFree(JsonParse *pParse){ - if( pParse->nJPRef>1 ){ - pParse->nJPRef--; - }else{ - jsonParseReset(pParse); - sqlite3_free(pParse); - } -} - -/* -** Add a cleanup task to the JsonParse object. -** -** If an OOM occurs, the cleanup operation happens immediately -** and this function returns SQLITE_NOMEM. -*/ -static int jsonParseAddCleanup( - JsonParse *pParse, /* Add the cleanup task to this parser */ - void(*xOp)(void*), /* The cleanup task */ - void *pArg /* Argument to the cleanup */ -){ - JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) ); - if( pTask==0 ){ - pParse->oom = 1; - xOp(pArg); - return SQLITE_ERROR; - } - pTask->pJCNext = pParse->pClup; - pParse->pClup = pTask; - pTask->xOp = xOp; - pTask->pArg = pArg; - return SQLITE_OK; -} - -/* -** Convert the JsonNode pNode into a pure JSON string and -** append to pOut. Subsubstructure is also included. Return -** the number of JsonNode objects that are encoded. -*/ -static void jsonRenderNode( - JsonParse *pParse, /* the complete parse of the JSON */ - JsonNode *pNode, /* The node to render */ - JsonString *pOut /* Write JSON here */ -){ - assert( pNode!=0 ); - while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){ - u32 idx = (u32)(pNode - pParse->aNode); - u32 i = pParse->iSubst; - while( 1 /*exit-by-break*/ ){ - assert( i<pParse->nNode ); - assert( pParse->aNode[i].eType==JSON_SUBST ); - assert( pParse->aNode[i].eU==4 ); - assert( pParse->aNode[i].u.iPrev<i ); - if( pParse->aNode[i].n==idx ){ - pNode = &pParse->aNode[i+1]; - break; - } - i = pParse->aNode[i].u.iPrev; - } - } - switch( pNode->eType ){ - default: { - assert( pNode->eType==JSON_NULL ); - jsonAppendRawNZ(pOut, "null", 4); - break; - } - case JSON_TRUE: { - jsonAppendRawNZ(pOut, "true", 4); - break; - } - case JSON_FALSE: { - jsonAppendRawNZ(pOut, "false", 5); - break; - } - case JSON_STRING: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_RAW ){ - if( pNode->jnFlags & JNODE_LABEL ){ - jsonAppendChar(pOut, '"'); - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); - jsonAppendChar(pOut, '"'); - }else{ - jsonAppendString(pOut, pNode->u.zJContent, pNode->n); - } - }else if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_REAL: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_INT: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_ARRAY: { - u32 j = 1; - jsonAppendChar(pOut, '['); - for(;;){ - while( j<=pNode->n ){ - if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ - jsonAppendSeparator(pOut); - jsonRenderNode(pParse, &pNode[j], pOut); - } - j += jsonNodeSize(&pNode[j]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &pParse->aNode[pNode->u.iAppend]; - j = 1; - } - jsonAppendChar(pOut, ']'); - break; - } - case JSON_OBJECT: { - u32 j = 1; - jsonAppendChar(pOut, '{'); - for(;;){ - while( j<=pNode->n ){ - if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ - jsonAppendSeparator(pOut); - jsonRenderNode(pParse, &pNode[j], pOut); - jsonAppendChar(pOut, ':'); - jsonRenderNode(pParse, &pNode[j+1], pOut); - } - j += 1 + jsonNodeSize(&pNode[j+1]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &pParse->aNode[pNode->u.iAppend]; - j = 1; - } - jsonAppendChar(pOut, '}'); - break; + if( pParse ){ + if( pParse->nJPRef>1 ){ + pParse->nJPRef--; + }else{ + jsonParseReset(pParse); + sqlite3DbFree(pParse->db, pParse); } } } -/* -** Return a JsonNode and all its descendants as a JSON string. -*/ -static void jsonReturnJson( - JsonParse *pParse, /* The complete JSON */ - JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - int bGenerateAlt, /* Also store the rendered text in zAlt */ - int omitSubtype /* Do not call sqlite3_result_subtype() */ -){ - JsonString s; - if( pParse->oom ){ - sqlite3_result_error_nomem(pCtx); - return; - } - if( pParse->nErr==0 ){ - jsonInit(&s, pCtx); - jsonRenderNode(pParse, pNode, &s); - if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){ - pParse->zAlt = sqlite3RCStrRef(s.zBuf); - pParse->nAlt = s.nUsed; - } - jsonResult(&s); - if( !omitSubtype ) sqlite3_result_subtype(pCtx, JSON_SUBTYPE); - } -} +/************************************************************************** +** Utility routines for the JSON text parser +**************************************************************************/ /* ** Translate a single byte of Hex into an integer. -** This routine only works if h really is a valid hexadecimal -** character: 0..9a..fA..F +** This routine only gives a correct answer if h really is a valid hexadecimal +** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not +** assert() if the digit is not hex. */ static u8 jsonHexToInt(int h){ - assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif #ifdef SQLITE_EBCDIC h += 9*(1&~(h>>4)); -#else - h += 9*(1&(h>>6)); #endif return (u8)(h & 0xf); } @@ -203554,10 +207247,6 @@ static u8 jsonHexToInt(int h){ */ static u32 jsonHexToInt4(const char *z){ u32 v; - assert( sqlite3Isxdigit(z[0]) ); - assert( sqlite3Isxdigit(z[1]) ); - assert( sqlite3Isxdigit(z[2]) ); - assert( sqlite3Isxdigit(z[3]) ); v = (jsonHexToInt(z[0])<<12) + (jsonHexToInt(z[1])<<8) + (jsonHexToInt(z[2])<<4) @@ -203565,282 +207254,6 @@ static u32 jsonHexToInt4(const char *z){ return v; } -/* -** Make the JsonNode the return value of the function. -*/ -static void jsonReturn( - JsonParse *pParse, /* Complete JSON parse tree */ - JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - int omitSubtype /* Do not call sqlite3_result_subtype() */ -){ - switch( pNode->eType ){ - default: { - assert( pNode->eType==JSON_NULL ); - sqlite3_result_null(pCtx); - break; - } - case JSON_TRUE: { - sqlite3_result_int(pCtx, 1); - break; - } - case JSON_FALSE: { - sqlite3_result_int(pCtx, 0); - break; - } - case JSON_INT: { - sqlite3_int64 i = 0; - int rc; - int bNeg = 0; - const char *z; - - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - if( z[0]=='-' ){ z++; bNeg = 1; } - else if( z[0]=='+' ){ z++; } - rc = sqlite3DecOrHexToI64(z, &i); - if( rc<=1 ){ - sqlite3_result_int64(pCtx, bNeg ? -i : i); - }else if( rc==3 && bNeg ){ - sqlite3_result_int64(pCtx, SMALLEST_INT64); - }else{ - goto to_double; - } - break; - } - case JSON_REAL: { - double r; - const char *z; - assert( pNode->eU==1 ); - to_double: - z = pNode->u.zJContent; - sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); - sqlite3_result_double(pCtx, r); - break; - } - case JSON_STRING: { - if( pNode->jnFlags & JNODE_RAW ){ - assert( pNode->eU==1 ); - sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, - SQLITE_TRANSIENT); - }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ - /* JSON formatted without any backslash-escapes */ - assert( pNode->eU==1 ); - sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, - SQLITE_TRANSIENT); - }else{ - /* Translate JSON formatted string into raw text */ - u32 i; - u32 n = pNode->n; - const char *z; - char *zOut; - u32 j; - u32 nOut = n; - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - zOut = sqlite3_malloc( nOut+1 ); - if( zOut==0 ){ - sqlite3_result_error_nomem(pCtx); - break; - } - for(i=1, j=0; i<n-1; i++){ - char c = z[i]; - if( c=='\\' ){ - c = z[++i]; - if( c=='u' ){ - u32 v = jsonHexToInt4(z+i+1); - i += 4; - if( v==0 ) break; - if( v<=0x7f ){ - zOut[j++] = (char)v; - }else if( v<=0x7ff ){ - zOut[j++] = (char)(0xc0 | (v>>6)); - zOut[j++] = 0x80 | (v&0x3f); - }else{ - u32 vlo; - if( (v&0xfc00)==0xd800 - && i<n-6 - && z[i+1]=='\\' - && z[i+2]=='u' - && ((vlo = jsonHexToInt4(z+i+3))&0xfc00)==0xdc00 - ){ - /* We have a surrogate pair */ - v = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000; - i += 6; - zOut[j++] = 0xf0 | (v>>18); - zOut[j++] = 0x80 | ((v>>12)&0x3f); - zOut[j++] = 0x80 | ((v>>6)&0x3f); - zOut[j++] = 0x80 | (v&0x3f); - }else{ - zOut[j++] = 0xe0 | (v>>12); - zOut[j++] = 0x80 | ((v>>6)&0x3f); - zOut[j++] = 0x80 | (v&0x3f); - } - } - continue; - }else if( c=='b' ){ - c = '\b'; - }else if( c=='f' ){ - c = '\f'; - }else if( c=='n' ){ - c = '\n'; - }else if( c=='r' ){ - c = '\r'; - }else if( c=='t' ){ - c = '\t'; - }else if( c=='v' ){ - c = '\v'; - }else if( c=='\'' || c=='"' || c=='/' || c=='\\' ){ - /* pass through unchanged */ - }else if( c=='0' ){ - c = 0; - }else if( c=='x' ){ - c = (jsonHexToInt(z[i+1])<<4) | jsonHexToInt(z[i+2]); - i += 2; - }else if( c=='\r' && z[i+1]=='\n' ){ - i++; - continue; - }else if( 0xe2==(u8)c ){ - assert( 0x80==(u8)z[i+1] ); - assert( 0xa8==(u8)z[i+2] || 0xa9==(u8)z[i+2] ); - i += 2; - continue; - }else{ - continue; - } - } /* end if( c=='\\' ) */ - zOut[j++] = c; - } /* end for() */ - zOut[j] = 0; - sqlite3_result_text(pCtx, zOut, j, sqlite3_free); - } - break; - } - case JSON_ARRAY: - case JSON_OBJECT: { - jsonReturnJson(pParse, pNode, pCtx, 0, omitSubtype); - break; - } - } -} - -/* Forward reference */ -static int jsonParseAddNode(JsonParse*,u32,u32,const char*); - -/* -** A macro to hint to the compiler that a function should not be -** inlined. -*/ -#if defined(__GNUC__) -# define JSON_NOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) && _MSC_VER>=1310 -# define JSON_NOINLINE __declspec(noinline) -#else -# define JSON_NOINLINE -#endif - - -/* -** Add a single node to pParse->aNode after first expanding the -** size of the aNode array. Return the index of the new node. -** -** If an OOM error occurs, set pParse->oom and return -1. -*/ -static JSON_NOINLINE int jsonParseAddNodeExpand( - JsonParse *pParse, /* Append the node to this object */ - u32 eType, /* Node type */ - u32 n, /* Content size or sub-node count */ - const char *zContent /* Content */ -){ - u32 nNew; - JsonNode *pNew; - assert( pParse->nNode>=pParse->nAlloc ); - if( pParse->oom ) return -1; - nNew = pParse->nAlloc*2 + 10; - pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew); - if( pNew==0 ){ - pParse->oom = 1; - return -1; - } - pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode); - pParse->aNode = pNew; - assert( pParse->nNode<pParse->nAlloc ); - return jsonParseAddNode(pParse, eType, n, zContent); -} - -/* -** Create a new JsonNode instance based on the arguments and append that -** instance to the JsonParse. Return the index in pParse->aNode[] of the -** new node, or -1 if a memory allocation fails. -*/ -static int jsonParseAddNode( - JsonParse *pParse, /* Append the node to this object */ - u32 eType, /* Node type */ - u32 n, /* Content size or sub-node count */ - const char *zContent /* Content */ -){ - JsonNode *p; - assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc ); - if( pParse->nNode>=pParse->nAlloc ){ - return jsonParseAddNodeExpand(pParse, eType, n, zContent); - } - assert( pParse->aNode!=0 ); - p = &pParse->aNode[pParse->nNode]; - assert( p!=0 ); - p->eType = (u8)(eType & 0xff); - p->jnFlags = (u8)(eType >> 8); - VVA( p->eU = zContent ? 1 : 0 ); - p->n = n; - p->u.zJContent = zContent; - return pParse->nNode++; -} - -/* -** Add an array of new nodes to the current pParse->aNode array. -** Return the index of the first node added. -** -** If an OOM error occurs, set pParse->oom. -*/ -static void jsonParseAddNodeArray( - JsonParse *pParse, /* Append the node to this object */ - JsonNode *aNode, /* Array of nodes to add */ - u32 nNode /* Number of elements in aNew */ -){ - assert( aNode!=0 ); - assert( nNode>=1 ); - if( pParse->nNode + nNode > pParse->nAlloc ){ - u32 nNew = pParse->nNode + nNode; - JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode)); - if( aNew==0 ){ - pParse->oom = 1; - return; - } - pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode); - pParse->aNode = aNew; - } - memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode)); - pParse->nNode += nNode; -} - -/* -** Add a new JSON_SUBST node. The node immediately following -** this new node will be the substitute content for iNode. -*/ -static int jsonParseAddSubstNode( - JsonParse *pParse, /* Add the JSON_SUBST here */ - u32 iNode /* References this node */ -){ - int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0); - if( pParse->oom ) return -1; - pParse->aNode[iNode].jnFlags |= JNODE_REPLACE; - pParse->aNode[idx].eU = 4; - pParse->aNode[idx].u.iPrev = pParse->iSubst; - pParse->iSubst = idx; - pParse->hasMod = 1; - pParse->useMod = 1; - return idx; -} - /* ** Return true if z[] begins with 2 (or more) hexadecimal digits */ @@ -203994,63 +207407,503 @@ static const struct NanInfName { char *zMatch; char *zRepl; } aNanInfName[] = { - { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" }, - { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" }, - { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" }, - { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" }, - { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" }, + { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" }, + { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" }, + { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" }, + { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" }, + { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" }, }; + +/* +** Report the wrong number of arguments for json_insert(), json_replace() +** or json_set(). +*/ +static void jsonWrongNumArgs( + sqlite3_context *pCtx, + const char *zFuncName +){ + char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", + zFuncName); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); +} + +/**************************************************************************** +** Utility routines for dealing with the binary BLOB representation of JSON +****************************************************************************/ + +/* +** Expand pParse->aBlob so that it holds at least N bytes. +** +** Return the number of errors. +*/ +static int jsonBlobExpand(JsonParse *pParse, u32 N){ + u8 *aNew; + u32 t; + assert( N>pParse->nBlobAlloc ); + if( pParse->nBlobAlloc==0 ){ + t = 100; + }else{ + t = pParse->nBlobAlloc*2; + } + if( t<N ) t = N+100; + aNew = sqlite3DbRealloc(pParse->db, pParse->aBlob, t); + if( aNew==0 ){ pParse->oom = 1; return 1; } + pParse->aBlob = aNew; + pParse->nBlobAlloc = t; + return 0; +} + +/* +** If pParse->aBlob is not previously editable (because it is taken +** from sqlite3_value_blob(), as indicated by the fact that +** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable +** by making a copy into space obtained from malloc. +** +** Return true on success. Return false on OOM. +*/ +static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){ + u8 *aOld; + u32 nSize; + assert( !pParse->bReadOnly ); + if( pParse->oom ) return 0; + if( pParse->nBlobAlloc>0 ) return 1; + aOld = pParse->aBlob; + nSize = pParse->nBlob + nExtra; + pParse->aBlob = 0; + if( jsonBlobExpand(pParse, nSize) ){ + return 0; + } + assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra ); + memcpy(pParse->aBlob, aOld, pParse->nBlob); + return 1; +} + +/* Expand pParse->aBlob and append one bytes. +*/ +static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte( + JsonParse *pParse, + u8 c +){ + jsonBlobExpand(pParse, pParse->nBlob+1); + if( pParse->oom==0 ){ + assert( pParse->nBlob+1<=pParse->nBlobAlloc ); + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Append a single character. +*/ +static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){ + if( pParse->nBlob >= pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendOneByte(pParse, c); + }else{ + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Slow version of jsonBlobAppendNode() that first resizes the +** pParse->aBlob structure. +*/ +static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*); +static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( + JsonParse *pParse, + u8 eType, + u32 szPayload, + const void *aPayload +){ + if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; + jsonBlobAppendNode(pParse, eType, szPayload, aPayload); +} + + +/* Append an node type byte together with the payload size and +** possibly also the payload. +** +** If aPayload is not NULL, then it is a pointer to the payload which +** is also appended. If aPayload is NULL, the pParse->aBlob[] array +** is resized (if necessary) so that it is big enough to hold the +** payload, but the payload is not appended and pParse->nBlob is left +** pointing to where the first byte of payload will eventually be. +*/ +static void jsonBlobAppendNode( + JsonParse *pParse, /* The JsonParse object under construction */ + u8 eType, /* Node type. One of JSONB_* */ + u32 szPayload, /* Number of bytes of payload */ + const void *aPayload /* The payload. Might be NULL */ +){ + u8 *a; + if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload); + return; + } + assert( pParse->aBlob!=0 ); + a = &pParse->aBlob[pParse->nBlob]; + if( szPayload<=11 ){ + a[0] = eType | (szPayload<<4); + pParse->nBlob += 1; + }else if( szPayload<=0xff ){ + a[0] = eType | 0xc0; + a[1] = szPayload & 0xff; + pParse->nBlob += 2; + }else if( szPayload<=0xffff ){ + a[0] = eType | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + pParse->nBlob += 3; + }else{ + a[0] = eType | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + pParse->nBlob += 5; + } + if( aPayload ){ + pParse->nBlob += szPayload; + memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload); + } +} + +/* Change the payload size for the node at index i to be szPayload. +*/ +static int jsonBlobChangePayloadSize( + JsonParse *pParse, + u32 i, + u32 szPayload +){ + u8 *a; + u8 szType; + u8 nExtra; + u8 nNeeded; + int delta; + if( pParse->oom ) return 0; + a = &pParse->aBlob[i]; + szType = a[0]>>4; + if( szType<=11 ){ + nExtra = 0; + }else if( szType==12 ){ + nExtra = 1; + }else if( szType==13 ){ + nExtra = 2; + }else{ + nExtra = 4; + } + if( szPayload<=11 ){ + nNeeded = 0; + }else if( szPayload<=0xff ){ + nNeeded = 1; + }else if( szPayload<=0xffff ){ + nNeeded = 2; + }else{ + nNeeded = 4; + } + delta = nNeeded - nExtra; + if( delta ){ + u32 newSize = pParse->nBlob + delta; + if( delta>0 ){ + if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){ + return 0; /* OOM error. Error state recorded in pParse->oom. */ + } + a = &pParse->aBlob[i]; + memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1)); + }else{ + memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta)); + } + pParse->nBlob = newSize; + } + if( nNeeded==0 ){ + a[0] = (a[0] & 0x0f) | (szPayload<<4); + }else if( nNeeded==1 ){ + a[0] = (a[0] & 0x0f) | 0xc0; + a[1] = szPayload & 0xff; + }else if( nNeeded==2 ){ + a[0] = (a[0] & 0x0f) | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + }else{ + a[0] = (a[0] & 0x0f) | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + } + return delta; +} + +/* +** If z[0] is 'u' and is followed by exactly 4 hexadecimal character, +** then set *pOp to JSONB_TEXTJ and return true. If not, do not make +** any changes to *pOp and return false. +*/ +static int jsonIs4HexB(const char *z, int *pOp){ + if( z[0]!='u' ) return 0; + if( !jsonIs4Hex(&z[1]) ) return 0; + *pOp = JSONB_TEXTJ; + return 1; +} + +/* +** Check a single element of the JSONB in pParse for validity. +** +** The element to be checked starts at offset i and must end at on the +** last byte before iEnd. +** +** Return 0 if everything is correct. Return the 1-based byte offset of the +** error if a problem is detected. (In other words, if the error is at offset +** 0, return 1). +*/ +static u32 jsonbValidityCheck( + const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */ + u32 i, /* Start of element as pParse->aBlob[i] */ + u32 iEnd, /* One more than the last byte of the element */ + u32 iDepth /* Current nesting depth */ +){ + u32 n, sz, j, k; + const u8 *z; + u8 x; + if( iDepth>JSON_MAX_DEPTH ) return i+1; + sz = 0; + n = jsonbPayloadSize(pParse, i, &sz); + if( NEVER(n==0) ) return i+1; /* Checked by caller */ + if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */ + z = pParse->aBlob; + x = z[i] & 0x0f; + switch( x ){ + case JSONB_NULL: + case JSONB_TRUE: + case JSONB_FALSE: { + return n+sz==1 ? 0 : i+1; + } + case JSONB_INT: { + if( sz<1 ) return i+1; + j = i+n; + if( z[j]=='-' ){ + j++; + if( sz<2 ) return i+1; + } + k = i+n+sz; + while( j<k ){ + if( sqlite3Isdigit(z[j]) ){ + j++; + }else{ + return j+1; + } + } + return 0; + } + case JSONB_INT5: { + if( sz<3 ) return i+1; + j = i+n; + if( z[j]=='-' ){ + if( sz<4 ) return i+1; + j++; + } + if( z[j]!='0' ) return i+1; + if( z[j+1]!='x' && z[j+1]!='X' ) return j+2; + j += 2; + k = i+n+sz; + while( j<k ){ + if( sqlite3Isxdigit(z[j]) ){ + j++; + }else{ + return j+1; + } + } + return 0; + } + case JSONB_FLOAT: + case JSONB_FLOAT5: { + u8 seen = 0; /* 0: initial. 1: '.' seen 2: 'e' seen */ + if( sz<2 ) return i+1; + j = i+n; + k = j+sz; + if( z[j]=='-' ){ + j++; + if( sz<3 ) return i+1; + } + if( z[j]=='.' ){ + if( x==JSONB_FLOAT ) return j+1; + if( !sqlite3Isdigit(z[j+1]) ) return j+1; + j += 2; + seen = 1; + }else if( z[j]=='0' && x==JSONB_FLOAT ){ + if( j+3>k ) return j+1; + if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1; + j++; + } + for(; j<k; j++){ + if( sqlite3Isdigit(z[j]) ) continue; + if( z[j]=='.' ){ + if( seen>0 ) return j+1; + if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){ + return j+1; + } + seen = 1; + continue; + } + if( z[j]=='e' || z[j]=='E' ){ + if( seen==2 ) return j+1; + if( j==k-1 ) return j+1; + if( z[j+1]=='+' || z[j+1]=='-' ){ + j++; + if( j==k-1 ) return j+1; + } + seen = 2; + continue; + } + return j+1; + } + if( seen==0 ) return i+1; + return 0; + } + case JSONB_TEXT: { + j = i+n; + k = j+sz; + while( j<k ){ + if( !jsonIsOk[z[j]] && z[j]!='\'' ) return j+1; + j++; + } + return 0; + } + case JSONB_TEXTJ: + case JSONB_TEXT5: { + j = i+n; + k = j+sz; + while( j<k ){ + if( !jsonIsOk[z[j]] && z[j]!='\'' ){ + if( z[j]=='"' ){ + if( x==JSONB_TEXTJ ) return j+1; + }else if( z[j]<=0x1f ){ + /* Control characters in JSON5 string literals are ok */ + if( x==JSONB_TEXTJ ) return j+1; + }else if( NEVER(z[j]!='\\') || j+1>=k ){ + return j+1; + }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){ + j++; + }else if( z[j+1]=='u' ){ + if( j+5>=k ) return j+1; + if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1; + j++; + }else if( x!=JSONB_TEXT5 ){ + return j+1; + }else{ + u32 c = 0; + u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c); + if( c==JSON_INVALID_CHAR ) return j+1; + j += szC - 1; + } + } + j++; + } + return 0; + } + case JSONB_TEXTRAW: { + return 0; + } + case JSONB_ARRAY: { + u32 sub; + j = i+n; + k = j+sz; + while( j<k ){ + sz = 0; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return j+1; + if( j+n+sz>k ) return j+1; + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + j += n + sz; + } + assert( j==k ); + return 0; + } + case JSONB_OBJECT: { + u32 cnt = 0; + u32 sub; + j = i+n; + k = j+sz; + while( j<k ){ + sz = 0; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return j+1; + if( j+n+sz>k ) return j+1; + if( (cnt & 1)==0 ){ + x = z[j] & 0x0f; + if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return j+1; + } + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + cnt++; + j += n + sz; + } + assert( j==k ); + if( (cnt & 1)!=0 ) return j+1; + return 0; + } + default: { + return i+1; + } + } +} + /* -** Parse a single JSON value which begins at pParse->zJson[i]. Return the -** index of the first character past the end of the value parsed. +** Translate a single element of JSON text at pParse->zJson[i] into +** its equivalent binary JSONB representation. Append the translation into +** pParse->aBlob[] beginning at pParse->nBlob. The size of +** pParse->aBlob[] is increased as necessary. ** -** Special return values: +** Return the index of the first character past the end of the element parsed, +** or one of the following special result codes: ** ** 0 End of input -** -1 Syntax error -** -2 '}' seen -** -3 ']' seen -** -4 ',' seen -** -5 ':' seen +** -1 Syntax error or OOM +** -2 '}' seen \ +** -3 ']' seen \___ For these returns, pParse->iErr is set to +** -4 ',' seen / the index in zJson[] of the seen character +** -5 ':' seen / */ -static int jsonParseValue(JsonParse *pParse, u32 i){ +static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){ char c; u32 j; - int iThis; + u32 iThis, iStart; int x; - JsonNode *pNode; + u8 t; const char *z = pParse->zJson; json_parse_restart: switch( (u8)z[i] ){ case '{': { /* Parse object */ - iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - if( iThis<0 ) return -1; + iThis = pParse->nBlob; + jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0); if( ++pParse->iDepth > JSON_MAX_DEPTH ){ pParse->iErr = i; return -1; } + iStart = pParse->nBlob; for(j=i+1;;j++){ - u32 nNode = pParse->nNode; - x = jsonParseValue(pParse, j); + u32 iBlob = pParse->nBlob; + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ + int op; if( x==(-2) ){ j = pParse->iErr; - if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; + if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1; break; } j += json5Whitespace(&z[j]); + op = JSONB_TEXT; if( sqlite3JsonId1(z[j]) - || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2])) + || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op)) ){ int k = j+1; while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) - || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2])) + || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op)) ){ k++; } - jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]); + assert( iBlob==pParse->nBlob ); + jsonBlobAppendNode(pParse, op, k-j, &z[j]); pParse->hasNonstd = 1; x = k; }else{ @@ -204059,24 +207912,24 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ } } if( pParse->oom ) return -1; - pNode = &pParse->aNode[nNode]; - if( pNode->eType!=JSON_STRING ){ + t = pParse->aBlob[iBlob] & 0x0f; + if( t<JSONB_TEXT || t>JSONB_TEXTRAW ){ pParse->iErr = j; return -1; } - pNode->jnFlags |= JNODE_LABEL; j = x; if( z[j]==':' ){ j++; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + /* strspn() is not helpful here */ + do{ j++; }while( jsonIsspace(z[j]) ); if( z[j]==':' ){ j++; goto parse_object_value; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x!=(-5) ){ if( x!=(-1) ) pParse->iErr = j; return -1; @@ -204084,7 +207937,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ j = pParse->iErr+1; } parse_object_value: - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ if( x!=(-1) ) pParse->iErr = j; return -1; @@ -204095,15 +207948,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ }else if( z[j]=='}' ){ break; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); if( z[j]==',' ){ continue; }else if( z[j]=='}' ){ break; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x==(-4) ){ j = pParse->iErr; continue; @@ -204116,25 +207969,27 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ pParse->iErr = j; return -1; } - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); pParse->iDepth--; return j+1; } case '[': { /* Parse array */ - iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); - if( iThis<0 ) return -1; + iThis = pParse->nBlob; + assert( i<=(u32)pParse->nJson ); + jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0); + iStart = pParse->nBlob; + if( pParse->oom ) return -1; if( ++pParse->iDepth > JSON_MAX_DEPTH ){ pParse->iErr = i; return -1; } - memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); for(j=i+1;;j++){ - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ if( x==(-3) ){ j = pParse->iErr; - if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; + if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1; break; } if( x!=(-1) ) pParse->iErr = j; @@ -204146,15 +208001,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ }else if( z[j]==']' ){ break; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); if( z[j]==',' ){ continue; }else if( z[j]==']' ){ break; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x==(-4) ){ j = pParse->iErr; continue; @@ -204167,23 +208022,33 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ pParse->iErr = j; return -1; } - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); pParse->iDepth--; return j+1; } case '\'': { - u8 jnFlags; + u8 opcode; char cDelim; pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + opcode = JSONB_TEXT; goto parse_string; case '"': /* Parse string */ - jnFlags = 0; + opcode = JSONB_TEXT; parse_string: cDelim = z[i]; - for(j=i+1; 1; j++){ - if( jsonIsOk[(unsigned char)z[j]] ) continue; + j = i+1; + while( 1 /*exit-by-break*/ ){ + if( jsonIsOk[(u8)z[j]] ){ + if( !jsonIsOk[(u8)z[j+1]] ){ + j += 1; + }else if( !jsonIsOk[(u8)z[j+2]] ){ + j += 2; + }else{ + j += 3; + continue; + } + } c = z[j]; if( c==cDelim ){ break; @@ -204192,33 +208057,41 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' || (c=='u' && jsonIs4Hex(&z[j+1])) ){ - jnFlags |= JNODE_ESCAPE; + if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ; }else if( c=='\'' || c=='0' || c=='v' || c=='\n' || (0xe2==(u8)c && 0x80==(u8)z[j+1] && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) || (c=='x' && jsonIs2Hex(&z[j+1])) ){ - jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); + opcode = JSONB_TEXT5; pParse->hasNonstd = 1; }else if( c=='\r' ){ if( z[j+1]=='\n' ) j++; - jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); + opcode = JSONB_TEXT5; pParse->hasNonstd = 1; }else{ pParse->iErr = j; return -1; } }else if( c<=0x1f ){ - /* Control characters are not allowed in strings */ - pParse->iErr = j; - return -1; + if( c==0 ){ + pParse->iErr = j; + return -1; + } + /* Control characters are not allowed in canonical JSON string + ** literals, but are allowed in JSON5 string literals. */ + opcode = JSONB_TEXT5; + pParse->hasNonstd = 1; + }else if( c=='"' ){ + opcode = JSONB_TEXT5; } + j++; } - jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]); + jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]); return j+1; } case 't': { if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_TRUE, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_TRUE); return i+4; } pParse->iErr = i; @@ -204226,23 +208099,22 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ } case 'f': { if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ - jsonParseAddNode(pParse, JSON_FALSE, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_FALSE); return i+5; } pParse->iErr = i; return -1; } case '+': { - u8 seenDP, seenE, jnFlags; + u8 seenE; pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ goto parse_number; case '.': if( sqlite3Isdigit(z[i+1]) ){ pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ seenE = 0; - seenDP = JSON_REAL; goto parse_number_2; } pParse->iErr = i; @@ -204259,9 +208131,8 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ case '8': case '9': /* Parse number */ - jnFlags = 0; + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ parse_number: - seenDP = JSON_INT; seenE = 0; assert( '-' < '0' ); assert( '+' < '0' ); @@ -204271,9 +208142,9 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ if( c<='0' ){ if( c=='0' ){ if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ - assert( seenDP==JSON_INT ); + assert( t==0x00 ); pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t = 0x01; for(j=i+3; sqlite3Isxdigit(z[j]); j++){} goto parse_number_finish; }else if( sqlite3Isdigit(z[i+1]) ){ @@ -204290,15 +208161,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ ){ pParse->hasNonstd = 1; if( z[i]=='-' ){ - jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999"); + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); }else{ - jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999"); + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); } return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); } if( z[i+1]=='.' ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; goto parse_number_2; } pParse->iErr = i; @@ -204310,30 +208181,31 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ return -1; }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; for(j=i+4; sqlite3Isxdigit(z[j]); j++){} goto parse_number_finish; } } } } + parse_number_2: for(j=i+1;; j++){ c = z[j]; if( sqlite3Isdigit(c) ) continue; if( c=='.' ){ - if( seenDP==JSON_REAL ){ + if( (t & 0x02)!=0 ){ pParse->iErr = j; return -1; } - seenDP = JSON_REAL; + t |= 0x02; continue; } if( c=='e' || c=='E' ){ if( z[j-1]<'0' ){ if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; }else{ pParse->iErr = j; return -1; @@ -204343,7 +208215,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ pParse->iErr = j; return -1; } - seenDP = JSON_REAL; + t |= 0x02; seenE = 1; c = z[j+1]; if( c=='+' || c=='-' ){ @@ -204361,14 +208233,18 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ if( z[j-1]<'0' ){ if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; }else{ pParse->iErr = j; return -1; } } parse_number_finish: - jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]); + assert( JSONB_INT+0x01==JSONB_INT5 ); + assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 ); + assert( JSONB_INT+0x02==JSONB_FLOAT ); + if( z[i]=='+' ) i++; + jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]); return j; } case '}': { @@ -204394,9 +208270,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ case 0x0a: case 0x0d: case 0x20: { - do{ - i++; - }while( fast_isspace(z[i]) ); + i += 1 + (u32)strspn(&z[i+1], jsonSpaces); goto json_parse_restart; } case 0x0b: @@ -204418,10 +208292,11 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ } case 'n': { if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_NULL); return i+4; } /* fall-through into the default case that checks for NaN */ + /* no break */ deliberate_fall_through } default: { u32 k; @@ -204434,8 +208309,11 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ continue; } if( sqlite3Isalnum(z[i+nn]) ) continue; - jsonParseAddNode(pParse, aNanInfName[k].eType, - aNanInfName[k].nRepl, aNanInfName[k].zRepl); + if( aNanInfName[k].eType==JSONB_FLOAT ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + }else{ + jsonBlobAppendOneByte(pParse, JSONB_NULL); + } pParse->hasNonstd = 1; return i + nn; } @@ -204445,6 +208323,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ } /* End switch(z[i]) */ } + /* ** Parse a complete JSON string. Return 0 on success or non-zero if there ** are any errors. If an error occurs, free all memory held by pParse, @@ -204453,20 +208332,26 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ ** pParse must be initialized to an empty parse object prior to calling ** this routine. */ -static int jsonParse( +static int jsonConvertTextToBlob( JsonParse *pParse, /* Initialize and fill this JsonParse object */ sqlite3_context *pCtx /* Report errors here */ ){ int i; const char *zJson = pParse->zJson; - i = jsonParseValue(pParse, 0); + i = jsonTranslateTextToBlob(pParse, 0); if( pParse->oom ) i = -1; if( i>0 ){ +#ifdef SQLITE_DEBUG assert( pParse->iDepth==0 ); - while( fast_isspace(zJson[i]) ) i++; + if( sqlite3Config.bJsonSelfcheck ){ + assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 ); + } +#endif + while( jsonIsspace(zJson[i]) ) i++; if( zJson[i] ){ i += json5Whitespace(&zJson[i]); if( zJson[i] ){ + if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1); jsonParseReset(pParse); return 1; } @@ -204487,501 +208372,1541 @@ static int jsonParse( return 0; } +/* +** The input string pStr is a well-formed JSON text string. Convert +** this into the JSONB format and make it the return value of the +** SQL function. +*/ +static void jsonReturnStringAsBlob(JsonString *pStr){ + JsonParse px; + memset(&px, 0, sizeof(px)); + jsonStringTerminate(pStr); + if( pStr->eErr ){ + sqlite3_result_error_nomem(pStr->pCtx); + return; + } + px.zJson = pStr->zBuf; + px.nJson = pStr->nUsed; + px.db = sqlite3_context_db_handle(pStr->pCtx); + (void)jsonTranslateTextToBlob(&px, 0); + if( px.oom ){ + sqlite3DbFree(px.db, px.aBlob); + sqlite3_result_error_nomem(pStr->pCtx); + }else{ + assert( px.nBlobAlloc>0 ); + assert( !px.bReadOnly ); + sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, SQLITE_DYNAMIC); + } +} -/* Mark node i of pParse as being a child of iParent. Call recursively -** to fill in all the descendants of node i. +/* The byte at index i is a node type-code. This routine +** determines the payload size for that node and writes that +** payload size in to *pSz. It returns the offset from i to the +** beginning of the payload. Return 0 on error. */ -static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ - JsonNode *pNode = &pParse->aNode[i]; - u32 j; - pParse->aUp[i] = iParent; - switch( pNode->eType ){ - case JSON_ARRAY: { - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ - jsonParseFillInParentage(pParse, i+j, i); +static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ + u8 x; + u32 sz; + u32 n; + if( NEVER(i>pParse->nBlob) ){ + *pSz = 0; + return 0; + } + x = pParse->aBlob[i]>>4; + if( x<=11 ){ + sz = x; + n = 1; + }else if( x==12 ){ + if( i+1>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = pParse->aBlob[i+1]; + n = 2; + }else if( x==13 ){ + if( i+2>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2]; + n = 3; + }else if( x==14 ){ + if( i+4>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) + + (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4]; + n = 5; + }else{ + if( i+8>=pParse->nBlob + || pParse->aBlob[i+1]!=0 + || pParse->aBlob[i+2]!=0 + || pParse->aBlob[i+3]!=0 + || pParse->aBlob[i+4]!=0 + ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + + (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; + n = 9; + } + if( (i64)i+sz+n > pParse->nBlob + && (i64)i+sz+n > pParse->nBlob-pParse->delta + ){ + sz = 0; + n = 0; + } + *pSz = sz; + return n; +} + + +/* +** Translate the binary JSONB representation of JSON beginning at +** pParse->aBlob[i] into a JSON text string. Append the JSON +** text onto the end of pOut. Return the index in pParse->aBlob[] +** of the first byte past the end of the element that is translated. +** +** If an error is detected in the BLOB input, the pOut->eErr flag +** might get set to JSTRING_MALFORMED. But not all BLOB input errors +** are detected. So a malformed JSONB input might either result +** in an error, or in incorrect JSON. +** +** The pOut->eErr JSTRING_OOM flag is set on a OOM. +*/ +static u32 jsonTranslateBlobToText( + const JsonParse *pParse, /* the complete parse of the JSON */ + u32 i, /* Start rendering at this index */ + JsonString *pOut /* Write JSON here */ +){ + u32 sz, n, j, iEnd; + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + pOut->eErr |= JSTRING_MALFORMED; + return pParse->nBlob+1; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + jsonAppendRawNZ(pOut, "null", 4); + return i+1; + } + case JSONB_TRUE: { + jsonAppendRawNZ(pOut, "true", 4); + return i+1; + } + case JSONB_FALSE: { + jsonAppendRawNZ(pOut, "false", 5); + return i+1; + } + case JSONB_INT: + case JSONB_FLOAT: { + if( sz==0 ) goto malformed_jsonb; + jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_INT5: { /* Integer literal in hexadecimal notation */ + u32 k = 2; + sqlite3_uint64 u = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + int bOverflow = 0; + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + }else if( zIn[0]=='+' ){ + k++; + } + for(; k<sz; k++){ + if( !sqlite3Isxdigit(zIn[k]) ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + }else if( (u>>60)!=0 ){ + bOverflow = 1; + }else{ + u = u*16 + sqlite3HexToInt(zIn[k]); + } + } + jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u); + break; + } + case JSONB_FLOAT5: { /* Float literal missing digits beside "." */ + u32 k = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + } + if( zIn[k]=='.' ){ + jsonAppendChar(pOut, '0'); + } + for(; k<sz; k++){ + jsonAppendChar(pOut, zIn[k]); + if( zIn[k]=='.' && (k+1==sz || !sqlite3Isdigit(zIn[k+1])) ){ + jsonAppendChar(pOut, '0'); + } + } + break; + } + case JSONB_TEXT: + case JSONB_TEXTJ: { + jsonAppendChar(pOut, '"'); + jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXT5: { + const char *zIn; + u32 k; + u32 sz2 = sz; + zIn = (const char*)&pParse->aBlob[i+n]; + jsonAppendChar(pOut, '"'); + while( sz2>0 ){ + for(k=0; k<sz2 && (jsonIsOk[(u8)zIn[k]] || zIn[k]=='\''); k++){} + if( k>0 ){ + jsonAppendRawNZ(pOut, zIn, k); + if( k>=sz2 ){ + break; + } + zIn += k; + sz2 -= k; + } + if( zIn[0]=='"' ){ + jsonAppendRawNZ(pOut, "\\\"", 2); + zIn++; + sz2--; + continue; + } + if( zIn[0]<=0x1f ){ + if( pOut->nUsed+7>pOut->nAlloc && jsonStringGrow(pOut,7) ) break; + jsonAppendControlChar(pOut, zIn[0]); + zIn++; + sz2--; + continue; + } + assert( zIn[0]=='\\' ); + assert( sz2>=1 ); + if( sz2<2 ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + } + switch( (u8)zIn[1] ){ + case '\'': + jsonAppendChar(pOut, '\''); + break; + case 'v': + jsonAppendRawNZ(pOut, "\\u0009", 6); + break; + case 'x': + if( sz2<4 ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + jsonAppendRawNZ(pOut, "\\u00", 4); + jsonAppendRawNZ(pOut, &zIn[2], 2); + zIn += 2; + sz2 -= 2; + break; + case '0': + jsonAppendRawNZ(pOut, "\\u0000", 6); + break; + case '\r': + if( sz2>2 && zIn[2]=='\n' ){ + zIn++; + sz2--; + } + break; + case '\n': + break; + case 0xe2: + /* '\' followed by either U+2028 or U+2029 is ignored as + ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. + ** U+2029 is the same except for the last byte */ + if( sz2<4 + || 0x80!=(u8)zIn[2] + || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3]) + ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + zIn += 2; + sz2 -= 2; + break; + default: + jsonAppendRawNZ(pOut, zIn, 2); + break; + } + assert( sz2>=2 ); + zIn += 2; + sz2 -= 2; + } + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXTRAW: { + jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_ARRAY: { + jsonAppendChar(pOut, '['); + j = i+n; + iEnd = j+sz; + while( j<iEnd && pOut->eErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, ','); + } + if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, ']'); + break; + } + case JSONB_OBJECT: { + int x = 0; + jsonAppendChar(pOut, '{'); + j = i+n; + iEnd = j+sz; + while( j<iEnd && pOut->eErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, (x++ & 1) ? ',' : ':'); + } + if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, '}'); + break; + } + + default: { + malformed_jsonb: + pOut->eErr |= JSTRING_MALFORMED; + break; + } + } + return i+n+sz; +} + +/* Context for recursion of json_pretty() +*/ +typedef struct JsonPretty JsonPretty; +struct JsonPretty { + JsonParse *pParse; /* The BLOB being rendered */ + JsonString *pOut; /* Generate pretty output into this string */ + const char *zIndent; /* Use this text for indentation */ + u32 szIndent; /* Bytes in zIndent[] */ + u32 nIndent; /* Current level of indentation */ +}; + +/* Append indentation to the pretty JSON under construction */ +static void jsonPrettyIndent(JsonPretty *pPretty){ + u32 jj; + for(jj=0; jj<pPretty->nIndent; jj++){ + jsonAppendRaw(pPretty->pOut, pPretty->zIndent, pPretty->szIndent); + } +} + +/* +** Translate the binary JSONB representation of JSON beginning at +** pParse->aBlob[i] into a JSON text string. Append the JSON +** text onto the end of pOut. Return the index in pParse->aBlob[] +** of the first byte past the end of the element that is translated. +** +** This is a variant of jsonTranslateBlobToText() that "pretty-prints" +** the output. Extra whitespace is inserted to make the JSON easier +** for humans to read. +** +** If an error is detected in the BLOB input, the pOut->eErr flag +** might get set to JSTRING_MALFORMED. But not all BLOB input errors +** are detected. So a malformed JSONB input might either result +** in an error, or in incorrect JSON. +** +** The pOut->eErr JSTRING_OOM flag is set on a OOM. +*/ +static u32 jsonTranslateBlobToPrettyText( + JsonPretty *pPretty, /* Pretty-printing context */ + u32 i /* Start rendering at this index */ +){ + u32 sz, n, j, iEnd; + const JsonParse *pParse = pPretty->pParse; + JsonString *pOut = pPretty->pOut; + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + pOut->eErr |= JSTRING_MALFORMED; + return pParse->nBlob+1; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_ARRAY: { + j = i+n; + iEnd = j+sz; + jsonAppendChar(pOut, '['); + if( j<iEnd ){ + jsonAppendChar(pOut, '\n'); + pPretty->nIndent++; + while( pOut->eErr==0 ){ + jsonPrettyIndent(pPretty); + j = jsonTranslateBlobToPrettyText(pPretty, j); + if( j>=iEnd ) break; + jsonAppendRawNZ(pOut, ",\n", 2); + } + jsonAppendChar(pOut, '\n'); + pPretty->nIndent--; + jsonPrettyIndent(pPretty); } + jsonAppendChar(pOut, ']'); + i = iEnd; break; } - case JSON_OBJECT: { - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ - pParse->aUp[i+j] = i; - jsonParseFillInParentage(pParse, i+j+1, i); + case JSONB_OBJECT: { + j = i+n; + iEnd = j+sz; + jsonAppendChar(pOut, '{'); + if( j<iEnd ){ + jsonAppendChar(pOut, '\n'); + pPretty->nIndent++; + while( pOut->eErr==0 ){ + jsonPrettyIndent(pPretty); + j = jsonTranslateBlobToText(pParse, j, pOut); + if( j>iEnd ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + } + jsonAppendRawNZ(pOut, ": ", 2); + j = jsonTranslateBlobToPrettyText(pPretty, j); + if( j>=iEnd ) break; + jsonAppendRawNZ(pOut, ",\n", 2); + } + jsonAppendChar(pOut, '\n'); + pPretty->nIndent--; + jsonPrettyIndent(pPretty); } + jsonAppendChar(pOut, '}'); + i = iEnd; break; } default: { + i = jsonTranslateBlobToText(pParse, i, pOut); break; } } + return i; +} + + +/* Return true if the input pJson +** +** For performance reasons, this routine does not do a detailed check of the +** input BLOB to ensure that it is well-formed. Hence, false positives are +** possible. False negatives should never occur, however. +*/ +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){ + u32 sz, n; + const u8 *aBlob; + int nBlob; + JsonParse s; + if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0; + aBlob = sqlite3_value_blob(pJson); + nBlob = sqlite3_value_bytes(pJson); + if( nBlob<1 ) return 0; + if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0; + memset(&s, 0, sizeof(s)); + s.aBlob = (u8*)aBlob; + s.nBlob = nBlob; + n = jsonbPayloadSize(&s, 0, &sz); + if( n==0 ) return 0; + if( sz+n!=(u32)nBlob ) return 0; + if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0; + return sz+n==(u32)nBlob; } /* -** Compute the parentage of all nodes in a completed parse. +** Given that a JSONB_ARRAY object starts at offset i, return +** the number of entries in that array. */ -static int jsonParseFindParents(JsonParse *pParse){ - u32 *aUp; - assert( pParse->aUp==0 ); - aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode ); - if( aUp==0 ){ - pParse->oom = 1; - return SQLITE_NOMEM; +static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){ + u32 n, sz, i, iEnd; + u32 k = 0; + n = jsonbPayloadSize(pParse, iRoot, &sz); + iEnd = iRoot+n+sz; + for(i=iRoot+n; n>0 && i<iEnd; i+=sz+n, k++){ + n = jsonbPayloadSize(pParse, i, &sz); } - jsonParseFillInParentage(pParse, 0, 0); - return SQLITE_OK; + return k; } /* -** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +** Edit the payload size of the element at iRoot by the amount in +** pParse->delta. */ -#define JSON_CACHE_ID (-429938) /* First cache entry */ -#define JSON_CACHE_SZ 4 /* Max number of cache entries */ +static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){ + u32 sz = 0; + u32 nBlob; + assert( pParse->delta!=0 ); + assert( pParse->nBlobAlloc >= pParse->nBlob ); + nBlob = pParse->nBlob; + pParse->nBlob = pParse->nBlobAlloc; + (void)jsonbPayloadSize(pParse, iRoot, &sz); + pParse->nBlob = nBlob; + sz += pParse->delta; + pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); +} /* -** Obtain a complete parse of the JSON found in the pJson argument +** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of +** content beginning at iDel, and replacing them with nIns bytes of +** content given by aIns. ** -** Use the sqlite3_get_auxdata() cache to find a preexisting parse -** if it is available. If the cache is not available or if it -** is no longer valid, parse the JSON again and return the new parse. -** Also register the new parse so that it will be available for -** future sqlite3_get_auxdata() calls. +** nDel may be zero, in which case no bytes are removed. But iDel is +** still important as new bytes will be insert beginning at iDel. ** -** If an error occurs and pErrCtx!=0 then report the error on pErrCtx -** and return NULL. +** aIns may be zero, in which case space is created to hold nIns bytes +** beginning at iDel, but that space is uninitialized. ** -** The returned pointer (if it is not NULL) is owned by the cache in -** most cases, not the caller. The caller does NOT need to invoke -** jsonParseFree(), in most cases. -** -** Except, if an error occurs and pErrCtx==0 then return the JsonParse -** object with JsonParse.nErr non-zero and the caller will own the JsonParse -** object. In that case, it will be the responsibility of the caller to -** invoke jsonParseFree(). To summarize: -** -** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the -** cache. Call does not need to -** free it. -** -** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller -** and so the caller must free it. +** Set pParse->oom if an OOM occurs. */ -static JsonParse *jsonParseCached( - sqlite3_context *pCtx, /* Context to use for cache search */ - sqlite3_value *pJson, /* Function param containing JSON text */ - sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */ - int bUnedited /* No prior edits allowed */ +static void jsonBlobEdit( + JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */ + u32 iDel, /* First byte to be removed */ + u32 nDel, /* Number of bytes to remove */ + const u8 *aIns, /* Content to insert */ + u32 nIns /* Bytes of content to insert */ ){ - char *zJson = (char*)sqlite3_value_text(pJson); - int nJson = sqlite3_value_bytes(pJson); - JsonParse *p; - JsonParse *pMatch = 0; - int iKey; - int iMinKey = 0; - u32 iMinHold = 0xffffffff; - u32 iMaxHold = 0; - int bJsonRCStr; + i64 d = (i64)nIns - (i64)nDel; + if( d!=0 ){ + if( pParse->nBlob + d > pParse->nBlobAlloc ){ + jsonBlobExpand(pParse, pParse->nBlob+d); + if( pParse->oom ) return; + } + memmove(&pParse->aBlob[iDel+nIns], + &pParse->aBlob[iDel+nDel], + pParse->nBlob - (iDel+nDel)); + pParse->nBlob += d; + pParse->delta += d; + } + if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns); +} - if( zJson==0 ) return 0; - for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){ - p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey); - if( p==0 ){ - iMinKey = iKey; - break; +/* +** Return the number of escaped newlines to be ignored. +** An escaped newline is a one of the following byte sequences: +** +** 0x5c 0x0a +** 0x5c 0x0d +** 0x5c 0x0d 0x0a +** 0x5c 0xe2 0x80 0xa8 +** 0x5c 0xe2 0x80 0xa9 +*/ +static u32 jsonBytesToBypass(const char *z, u32 n){ + u32 i = 0; + while( i+1<n ){ + if( z[i]!='\\' ) return i; + if( z[i+1]=='\n' ){ + i += 2; + continue; } - if( pMatch==0 - && p->nJson==nJson - && (p->hasMod==0 || bUnedited==0) - && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0) - ){ - p->nErr = 0; - p->useMod = 0; - pMatch = p; - }else - if( pMatch==0 - && p->zAlt!=0 - && bUnedited==0 - && p->nAlt==nJson - && memcmp(p->zAlt, zJson, nJson)==0 - ){ - p->nErr = 0; - p->useMod = 1; - pMatch = p; - }else if( p->iHold<iMinHold ){ - iMinHold = p->iHold; - iMinKey = iKey; + if( z[i+1]=='\r' ){ + if( i+2<n && z[i+2]=='\n' ){ + i += 3; + }else{ + i += 2; + } + continue; } - if( p->iHold>iMaxHold ){ - iMaxHold = p->iHold; + if( 0xe2==(u8)z[i+1] + && i+3<n + && 0x80==(u8)z[i+2] + && (0xa8==(u8)z[i+3] || 0xa9==(u8)z[i+3]) + ){ + i += 4; + continue; } + break; } - if( pMatch ){ - /* The input JSON text was found in the cache. Use the preexisting - ** parse of this JSON */ - pMatch->nErr = 0; - pMatch->iHold = iMaxHold+1; - assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */ - return pMatch; - } + return i; +} - /* The input JSON was not found anywhere in the cache. We will need - ** to parse it ourselves and generate a new JsonParse object. - */ - bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref); - p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); - if( p==0 ){ - sqlite3_result_error_nomem(pCtx); - return 0; +/* +** Input z[0..n] defines JSON escape sequence including the leading '\\'. +** Decode that escape sequence into a single character. Write that +** character into *piOut. Return the number of bytes in the escape sequence. +** +** If there is a syntax error of some kind (for example too few characters +** after the '\\' to complete the encoding) then *piOut is set to +** JSON_INVALID_CHAR. +*/ +static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){ + assert( n>0 ); + assert( z[0]=='\\' ); + if( n<2 ){ + *piOut = JSON_INVALID_CHAR; + return n; } - memset(p, 0, sizeof(*p)); - if( bJsonRCStr ){ - p->zJson = sqlite3RCStrRef(zJson); - p->bJsonIsRCStr = 1; - }else{ - p->zJson = (char*)&p[1]; - memcpy(p->zJson, zJson, nJson+1); + switch( (u8)z[1] ){ + case 'u': { + u32 v, vlo; + if( n<6 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + v = jsonHexToInt4(&z[2]); + if( (v & 0xfc00)==0xd800 + && n>=12 + && z[6]=='\\' + && z[7]=='u' + && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00 + ){ + *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000; + return 12; + }else{ + *piOut = v; + return 6; + } + } + case 'b': { *piOut = '\b'; return 2; } + case 'f': { *piOut = '\f'; return 2; } + case 'n': { *piOut = '\n'; return 2; } + case 'r': { *piOut = '\r'; return 2; } + case 't': { *piOut = '\t'; return 2; } + case 'v': { *piOut = '\v'; return 2; } + case '0': { *piOut = 0; return 2; } + case '\'': + case '"': + case '/': + case '\\':{ *piOut = z[1]; return 2; } + case 'x': { + if( n<4 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]); + return 4; + } + case 0xe2: + case '\r': + case '\n': { + u32 nSkip = jsonBytesToBypass(z, n); + if( nSkip==0 ){ + *piOut = JSON_INVALID_CHAR; + return n; + }else if( nSkip==n ){ + *piOut = 0; + return n; + }else if( z[nSkip]=='\\' ){ + return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut); + }else{ + int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut); + return nSkip + sz; + } + } + default: { + *piOut = JSON_INVALID_CHAR; + return 2; + } } - p->nJPRef = 1; - if( jsonParse(p, pErrCtx) ){ - if( pErrCtx==0 ){ - p->nErr = 1; - assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */ - return p; +} + + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. +** +** In this version, we know that one or the other or both of the +** two comparands contains an escape sequence. +*/ +static SQLITE_NOINLINE int jsonLabelCompareEscaped( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + u32 cLeft, cRight; + assert( rawLeft==0 || rawRight==0 ); + while( 1 /*exit-by-return*/ ){ + if( nLeft==0 ){ + cLeft = 0; + }else if( rawLeft || zLeft[0]!='\\' ){ + cLeft = ((u8*)zLeft)[0]; + if( cLeft>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft); + zLeft += sz; + nLeft -= sz; + }else{ + zLeft++; + nLeft--; + } + }else{ + u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft); + zLeft += n; + assert( n<=nLeft ); + nLeft -= n; + } + if( nRight==0 ){ + cRight = 0; + }else if( rawRight || zRight[0]!='\\' ){ + cRight = ((u8*)zRight)[0]; + if( cRight>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight); + zRight += sz; + nRight -= sz; + }else{ + zRight++; + nRight--; + } + }else{ + u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight); + zRight += n; + assert( n<=nRight ); + nRight -= n; } - jsonParseFree(p); - return 0; + if( cLeft!=cRight ) return 0; + if( cLeft==0 ) return 1; } - p->nJson = nJson; - p->iHold = iMaxHold+1; - /* Transfer ownership of the new JsonParse to the cache */ - sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, - (void(*)(void*))jsonParseFree); - return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); } /* -** Compare the OBJECT label at pNode against zKey,nKey. Return true on -** a match. +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. Return -1 if an OOM occurs. */ -static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){ - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_RAW ){ - if( pNode->n!=nKey ) return 0; - return strncmp(pNode->u.zJContent, zKey, nKey)==0; +static int jsonLabelCompare( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + if( rawLeft && rawRight ){ + /* Simpliest case: Neither label contains escapes. A simple + ** memcmp() is sufficient. */ + if( nLeft!=nRight ) return 0; + return memcmp(zLeft, zRight, nLeft)==0; }else{ - if( pNode->n!=nKey+2 ) return 0; - return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; + return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft, + zRight, nRight, rawRight); } } -static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){ - if( p1->jnFlags & JNODE_RAW ){ - return jsonLabelCompare(p2, p1->u.zJContent, p1->n); - }else if( p2->jnFlags & JNODE_RAW ){ - return jsonLabelCompare(p1, p2->u.zJContent, p2->n); + +/* +** Error returns from jsonLookupStep() +*/ +#define JSON_LOOKUP_ERROR 0xffffffff +#define JSON_LOOKUP_NOTFOUND 0xfffffffe +#define JSON_LOOKUP_PATHERROR 0xfffffffd +#define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) + +/* Forward declaration */ +static u32 jsonLookupStep(JsonParse*,u32,const char*,u32); + + +/* This helper routine for jsonLookupStep() populates pIns with +** binary data that is to be inserted into pParse. +** +** In the common case, pIns just points to pParse->aIns and pParse->nIns. +** But if the zPath of the original edit operation includes path elements +** that go deeper, additional substructure must be created. +** +** For example: +** +** json_insert('{}', '$.a.b.c', 123); +** +** The search stops at '$.a' But additional substructure must be +** created for the ".b.c" part of the patch so that the final result +** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with +** the binary equivalent of {"b":{"c":123}} so that it can be inserted. +** +** The caller is responsible for resetting pIns when it has finished +** using the substructure. +*/ +static u32 jsonCreateEditSubstructure( + JsonParse *pParse, /* The original JSONB that is being edited */ + JsonParse *pIns, /* Populate this with the blob data to insert */ + const char *zTail /* Tail of the path that determins substructure */ +){ + static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT }; + int rc; + memset(pIns, 0, sizeof(*pIns)); + pIns->db = pParse->db; + if( zTail[0]==0 ){ + /* No substructure. Just insert what is given in pParse. */ + pIns->aBlob = pParse->aIns; + pIns->nBlob = pParse->nIns; + rc = 0; }else{ - return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0; + /* Construct the binary substructure */ + pIns->nBlob = 1; + pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.']; + pIns->eEdit = pParse->eEdit; + pIns->nIns = pParse->nIns; + pIns->aIns = pParse->aIns; + rc = jsonLookupStep(pIns, 0, zTail, 0); + pParse->oom |= pIns->oom; } + return rc; /* Error code only */ } -/* forward declaration */ -static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); - /* -** Search along zPath to find the node specified. Return a pointer -** to that node, or NULL if zPath is malformed or if there is no such -** node. +** Search along zPath to find the Json element specified. Return an +** index into pParse->aBlob[] for the start of that element's value. ** -** If pApnd!=0, then try to append new nodes to complete zPath if it is -** possible to do so and if no existing node corresponds to zPath. If -** new nodes are appended *pApnd is set to 1. +** If the value found by this routine is the value half of label/value pair +** within an object, then set pPath->iLabel to the start of the corresponding +** label, before returning. +** +** Return one of the JSON_LOOKUP error codes if problems are seen. +** +** This routine will also modify the blob. If pParse->eEdit is one of +** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be +** made to the selected value. If an edit is performed, then the return +** value does not necessarily point to the select element. If an edit +** is performed, the return value is only useful for detecting error +** conditions. */ -static JsonNode *jsonLookupStep( +static u32 jsonLookupStep( JsonParse *pParse, /* The JSON to search */ - u32 iRoot, /* Begin the search at this node */ + u32 iRoot, /* Begin the search at this element of aBlob[] */ const char *zPath, /* The path to search */ - int *pApnd, /* Append nodes to complete path if not NULL */ - const char **pzErr /* Make *pzErr point to any syntax error in zPath */ + u32 iLabel /* Label if iRoot is a value of in an object */ ){ - u32 i, j, nKey; + u32 i, j, k, nKey, sz, n, iEnd, rc; const char *zKey; - JsonNode *pRoot; - if( pParse->oom ) return 0; - pRoot = &pParse->aNode[iRoot]; - if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){ - while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){ - u32 idx = (u32)(pRoot - pParse->aNode); - i = pParse->iSubst; - while( 1 /*exit-by-break*/ ){ - assert( i<pParse->nNode ); - assert( pParse->aNode[i].eType==JSON_SUBST ); - assert( pParse->aNode[i].eU==4 ); - assert( pParse->aNode[i].u.iPrev<i ); - if( pParse->aNode[i].n==idx ){ - pRoot = &pParse->aNode[i+1]; - iRoot = i+1; - break; - } - i = pParse->aNode[i].u.iPrev; + u8 x; + + if( zPath[0]==0 ){ + if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){ + n = jsonbPayloadSize(pParse, iRoot, &sz); + sz += n; + if( pParse->eEdit==JEDIT_DEL ){ + if( iLabel>0 ){ + sz += iRoot - iLabel; + iRoot = iLabel; + } + jsonBlobEdit(pParse, iRoot, sz, 0, 0); + }else if( pParse->eEdit==JEDIT_INS ){ + /* Already exists, so json_insert() is a no-op */ + }else{ + /* json_set() or json_replace() */ + jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns); } } - if( pRoot->jnFlags & JNODE_REMOVE ){ - return 0; - } + pParse->iLabel = iLabel; + return iRoot; } - if( zPath[0]==0 ) return pRoot; if( zPath[0]=='.' ){ - if( pRoot->eType!=JSON_OBJECT ) return 0; + int rawKey = 1; + x = pParse->aBlob[iRoot]; zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; - for(i=1; zPath[i] && zPath[i]!='"'; i++){} + for(i=1; zPath[i] && zPath[i]!='"'; i++){ + if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++; + } nKey = i-1; if( zPath[i] ){ i++; }else{ - *pzErr = zPath; - return 0; + return JSON_LOOKUP_PATHERROR; } testcase( nKey==0 ); + rawKey = memchr(zKey, '\\', nKey)==0; }else{ zKey = zPath; for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} nKey = i; if( nKey==0 ){ - *pzErr = zPath; - return 0; - } - } - j = 1; - for(;;){ - while( j<=pRoot->n ){ - if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ - return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); - } - j++; - j += jsonNodeSize(&pRoot[j]); + return JSON_LOOKUP_PATHERROR; + } + } + if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + j = iRoot + n; /* j is the index of a label */ + iEnd = j+sz; + while( j<iEnd ){ + int rawLabel; + const char *zLabel; + x = pParse->aBlob[j] & 0x0f; + if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + k = j+n; /* k is the index of the label text */ + if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR; + zLabel = (const char*)&pParse->aBlob[k]; + rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW; + if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){ + u32 v = k+sz; /* v is the index of the value */ + if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, v, &sz); + if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; + assert( j>0 ); + rc = jsonLookupStep(pParse, v, &zPath[i], j); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; } - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pRoot->eU==2 ); - iRoot = pRoot->u.iAppend; - pRoot = &pParse->aNode[iRoot]; - j = 1; - } - if( pApnd ){ - u32 iStart, iLabel; - JsonNode *pNode; - assert( pParse->useMod ); - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); - iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - zPath += i; - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); - if( pParse->oom ) return 0; - if( pNode ){ - pRoot = &pParse->aNode[iRoot]; - assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart; - pRoot->jnFlags |= JNODE_APPEND; - VVA( pRoot->eU = 2 ); - pParse->aNode[iLabel].jnFlags |= JNODE_RAW; - } - return pNode; + j = k+sz; + if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( pParse->eEdit>=JEDIT_INS ){ + u32 nIns; /* Total bytes to insert (label+value) */ + JsonParse v; /* BLOB encoding of the value to be inserted */ + JsonParse ix; /* Header of the label to be inserted */ + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + memset(&ix, 0, sizeof(ix)); + ix.db = pParse->db; + jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0); + pParse->oom |= ix.oom; + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob) + ){ + assert( !pParse->oom ); + nIns = ix.nBlob + nKey + v.nBlob; + jsonBlobEdit(pParse, j, 0, 0, nIns); + if( !pParse->oom ){ + assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */ + assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */ + memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob); + k = j + ix.nBlob; + memcpy(&pParse->aBlob[k], zKey, nKey); + k += nKey; + memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob); + if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot); + } + } + jsonParseReset(&v); + jsonParseReset(&ix); + return rc; } }else if( zPath[0]=='[' ){ - i = 0; - j = 1; - while( sqlite3Isdigit(zPath[j]) ){ - i = i*10 + zPath[j] - '0'; - j++; + x = pParse->aBlob[iRoot] & 0x0f; + if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + k = 0; + i = 1; + while( sqlite3Isdigit(zPath[i]) ){ + k = k*10 + zPath[i] - '0'; + i++; } - if( j<2 || zPath[j]!=']' ){ + if( i<2 || zPath[i]!=']' ){ if( zPath[1]=='#' ){ - JsonNode *pBase = pRoot; - int iBase = iRoot; - if( pRoot->eType!=JSON_ARRAY ) return 0; - for(;;){ - while( j<=pBase->n ){ - if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++; - j += jsonNodeSize(&pBase[j]); - } - if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pBase->eU==2 ); - iBase = pBase->u.iAppend; - pBase = &pParse->aNode[iBase]; - j = 1; - } - j = 2; + k = jsonbArrayCount(pParse, iRoot); + i = 2; if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ - unsigned int x = 0; - j = 3; + unsigned int nn = 0; + i = 3; do{ - x = x*10 + zPath[j] - '0'; - j++; - }while( sqlite3Isdigit(zPath[j]) ); - if( x>i ) return 0; - i -= x; + nn = nn*10 + zPath[i] - '0'; + i++; + }while( sqlite3Isdigit(zPath[i]) ); + if( nn>k ) return JSON_LOOKUP_NOTFOUND; + k -= nn; } - if( zPath[j]!=']' ){ - *pzErr = zPath; - return 0; + if( zPath[i]!=']' ){ + return JSON_LOOKUP_PATHERROR; } }else{ - *pzErr = zPath; - return 0; + return JSON_LOOKUP_PATHERROR; } } - if( pRoot->eType!=JSON_ARRAY ) return 0; - zPath += j + 1; - j = 1; - for(;;){ - while( j<=pRoot->n - && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod)) + j = iRoot+n; + iEnd = j+sz; + while( j<iEnd ){ + if( k==0 ){ + rc = jsonLookupStep(pParse, j, &zPath[i+1], 0); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + k--; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( k>0 ) return JSON_LOOKUP_NOTFOUND; + if( pParse->eEdit>=JEDIT_INS ){ + JsonParse v; + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, v.nBlob) ){ - if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; - j += jsonNodeSize(&pRoot[j]); - } - if( i==0 && j<=pRoot->n ) break; - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pRoot->eU==2 ); - iRoot = pRoot->u.iAppend; - pRoot = &pParse->aNode[iRoot]; - j = 1; - } - if( j<=pRoot->n ){ - return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); - } - if( i==0 && pApnd ){ - u32 iStart; - JsonNode *pNode; - assert( pParse->useMod ); - iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); - if( pParse->oom ) return 0; - if( pNode ){ - pRoot = &pParse->aNode[iRoot]; - assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart; - pRoot->jnFlags |= JNODE_APPEND; - VVA( pRoot->eU = 2 ); + assert( !pParse->oom ); + jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob); } - return pNode; + jsonParseReset(&v); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; } }else{ - *pzErr = zPath; + return JSON_LOOKUP_PATHERROR; } - return 0; + return JSON_LOOKUP_NOTFOUND; } /* -** Append content to pParse that will complete zPath. Return a pointer -** to the inserted node, or return NULL if the append fails. +** Convert a JSON BLOB into text and make that text the return value +** of an SQL function. */ -static JsonNode *jsonLookupAppend( - JsonParse *pParse, /* Append content to the JSON parse */ - const char *zPath, /* Description of content to append */ - int *pApnd, /* Set this flag to 1 */ - const char **pzErr /* Make this point to any syntax error */ +static void jsonReturnTextJsonFromBlob( + sqlite3_context *ctx, + const u8 *aBlob, + u32 nBlob ){ - *pApnd = 1; - if( zPath[0]==0 ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); - return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; - } - if( zPath[0]=='.' ){ - jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - }else if( strncmp(zPath,"[0]",3)==0 ){ - jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); - }else{ - return 0; - } - if( pParse->oom ) return 0; - return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); + JsonParse x; + JsonString s; + + if( NEVER(aBlob==0) ) return; + memset(&x, 0, sizeof(x)); + x.aBlob = (u8*)aBlob; + x.nBlob = nBlob; + jsonStringInit(&s, ctx); + jsonTranslateBlobToText(&x, 0, &s); + jsonReturnString(&s, 0, 0); } + /* -** Return the text of a syntax error message on a JSON path. Space is -** obtained from sqlite3_malloc(). +** Return the value of the BLOB node at index i. +** +** If the value is a primitive, return it as an SQL value. +** If the value is an array or object, return it as either +** JSON text or the BLOB encoding, depending on the JSON_B flag +** on the userdata. */ -static char *jsonPathSyntaxError(const char *zErr){ - return sqlite3_mprintf("JSON path error near '%q'", zErr); +static void jsonReturnFromBlob( + JsonParse *pParse, /* Complete JSON parse tree */ + u32 i, /* Index of the node */ + sqlite3_context *pCtx, /* Return value for this function */ + int textOnly /* return text JSON. Disregard user-data */ +){ + u32 n, sz; + int rc; + sqlite3 *db = sqlite3_context_db_handle(pCtx); + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_null(pCtx); + break; + } + case JSONB_TRUE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 1); + break; + } + case JSONB_FALSE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 0); + break; + } + case JSONB_INT5: + case JSONB_INT: { + sqlite3_int64 iRes = 0; + char *z; + int bNeg = 0; + char x; + if( sz==0 ) goto returnfromblob_malformed; + x = (char)pParse->aBlob[i+n]; + if( x=='-' ){ + if( sz<2 ) goto returnfromblob_malformed; + n++; + sz--; + bNeg = 1; + } + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3DecOrHexToI64(z, &iRes); + sqlite3DbFree(db, z); + if( rc==0 ){ + sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes); + }else if( rc==3 && bNeg ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + }else if( rc==1 ){ + goto returnfromblob_malformed; + }else{ + if( bNeg ){ n--; sz++; } + goto to_double; + } + break; + } + case JSONB_FLOAT5: + case JSONB_FLOAT: { + double r; + char *z; + if( sz==0 ) goto returnfromblob_malformed; + to_double: + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); + sqlite3DbFree(db, z); + if( rc<=0 ) goto returnfromblob_malformed; + sqlite3_result_double(pCtx, r); + break; + } + case JSONB_TEXTRAW: + case JSONB_TEXT: { + sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz, + SQLITE_TRANSIENT); + break; + } + case JSONB_TEXT5: + case JSONB_TEXTJ: { + /* Translate JSON formatted string into raw text */ + u32 iIn, iOut; + const char *z; + char *zOut; + u32 nOut = sz; + z = (const char*)&pParse->aBlob[i+n]; + zOut = sqlite3DbMallocRaw(db, nOut+1); + if( zOut==0 ) goto returnfromblob_oom; + for(iIn=iOut=0; iIn<sz; iIn++){ + char c = z[iIn]; + if( c=='\\' ){ + u32 v; + u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v); + if( v<=0x7f ){ + zOut[iOut++] = (char)v; + }else if( v<=0x7ff ){ + assert( szEscape>=2 ); + zOut[iOut++] = (char)(0xc0 | (v>>6)); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v<0x10000 ){ + assert( szEscape>=3 ); + zOut[iOut++] = 0xe0 | (v>>12); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v==JSON_INVALID_CHAR ){ + /* Silently ignore illegal unicode */ + }else{ + assert( szEscape>=4 ); + zOut[iOut++] = 0xf0 | (v>>18); + zOut[iOut++] = 0x80 | ((v>>12)&0x3f); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + } + iIn += szEscape - 1; + }else{ + zOut[iOut++] = c; + } + } /* end for() */ + assert( iOut<=nOut ); + zOut[iOut] = 0; + sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC); + break; + } + case JSONB_ARRAY: + case JSONB_OBJECT: { + int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)); + if( flags & JSON_BLOB ){ + sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT); + }else{ + jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n); + } + break; + } + default: { + goto returnfromblob_malformed; + } + } + return; + +returnfromblob_oom: + sqlite3_result_error_nomem(pCtx); + return; + +returnfromblob_malformed: + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; } /* -** Do a node lookup using zPath. Return a pointer to the node on success. -** Return NULL if not found or if there is an error. +** pArg is a function argument that might be an SQL value or a JSON +** value. Figure out what it is and encode it as a JSONB blob. +** Return the results in pParse. ** -** On an error, write an error message into pCtx and increment the -** pParse->nErr counter. +** pParse is uninitialized upon entry. This routine will handle the +** initialization of pParse. The result will be contained in +** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically +** allocated (if pParse->nBlobAlloc is greater than zero) in which case +** the caller is responsible for freeing the space allocated to pParse->aBlob +** when it has finished with it. Or pParse->aBlob might be a static string +** or a value obtained from sqlite3_value_blob(pArg). ** -** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if -** nodes are appended. +** If the argument is a BLOB that is clearly not a JSONB, then this +** function might set an error message in ctx and return non-zero. +** It might also set an error message and return non-zero on an OOM error. */ -static JsonNode *jsonLookup( - JsonParse *pParse, /* The JSON to search */ - const char *zPath, /* The path to search */ - int *pApnd, /* Append nodes to complete path if not NULL */ - sqlite3_context *pCtx /* Report errors here, if not NULL */ -){ - const char *zErr = 0; - JsonNode *pNode = 0; - char *zMsg; - - if( zPath==0 ) return 0; - if( zPath[0]!='$' ){ - zErr = zPath; - goto lookup_err; +static int jsonFunctionArgToBlob( + sqlite3_context *ctx, + sqlite3_value *pArg, + JsonParse *pParse +){ + int eType = sqlite3_value_type(pArg); + static u8 aNull[] = { 0x00 }; + memset(pParse, 0, sizeof(pParse[0])); + pParse->db = sqlite3_context_db_handle(ctx); + switch( eType ){ + default: { + pParse->aBlob = aNull; + pParse->nBlob = 1; + return 0; + } + case SQLITE_BLOB: { + if( jsonFuncArgMightBeBinary(pArg) ){ + pParse->aBlob = (u8*)sqlite3_value_blob(pArg); + pParse->nBlob = sqlite3_value_bytes(pArg); + }else{ + sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); + return 1; + } + break; + } + case SQLITE_TEXT: { + const char *zJson = (const char*)sqlite3_value_text(pArg); + int nJson = sqlite3_value_bytes(pArg); + if( zJson==0 ) return 1; + if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){ + pParse->zJson = (char*)zJson; + pParse->nJson = nJson; + if( jsonConvertTextToBlob(pParse, ctx) ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + sqlite3DbFree(pParse->db, pParse->aBlob); + memset(pParse, 0, sizeof(pParse[0])); + return 1; + } + }else{ + jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson); + } + break; + } + case SQLITE_FLOAT: { + double r = sqlite3_value_double(pArg); + if( NEVER(sqlite3IsNaN(r)) ){ + jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0); + }else{ + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + if( z[0]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + }else if( z[0]=='-' && z[1]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); + }else{ + jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z); + } + } + break; + } + case SQLITE_INTEGER: { + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + jsonBlobAppendNode(pParse, JSONB_INT, n, z); + break; + } + } + if( pParse->oom ){ + sqlite3_result_error_nomem(ctx); + return 1; + }else{ + return 0; } - zPath++; - pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); - if( zErr==0 ) return pNode; +} -lookup_err: - pParse->nErr++; - assert( zErr!=0 && pCtx!=0 ); - zMsg = jsonPathSyntaxError(zErr); +/* +** Generate a bad path error. +** +** If ctx is not NULL then push the error message into ctx and return NULL. +** If ctx is NULL, then return the text of the error message. +*/ +static char *jsonBadPathError( + sqlite3_context *ctx, /* The function call containing the error */ + const char *zPath /* The path with the problem */ +){ + char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); + if( ctx==0 ) return zMsg; if( zMsg ){ - sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_result_error(ctx, zMsg, -1); sqlite3_free(zMsg); }else{ - sqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(ctx); } return 0; } +/* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent +** arguments come in parse where each pair contains a JSON path and +** content to insert or set at that patch. Do the updates +** and return the result. +** +** The specific operation is determined by eEdit, which can be one +** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET. +*/ +static void jsonInsertIntoBlob( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv, + int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */ +){ + int i; + u32 rc = 0; + const char *zPath = 0; + int flgs; + JsonParse *p; + JsonParse ax; + + assert( (argc&1)==1 ); + flgs = argc==1 ? 0 : JSON_EDITABLE; + p = jsonParseFuncArg(ctx, argv[0], flgs); + if( p==0 ) return; + for(i=1; i<argc-1; i+=2){ + if( sqlite3_value_type(argv[i])==SQLITE_NULL ) continue; + zPath = (const char*)sqlite3_value_text(argv[i]); + if( zPath==0 ){ + sqlite3_result_error_nomem(ctx); + jsonParseFree(p); + return; + } + if( zPath[0]!='$' ) goto jsonInsertIntoBlob_patherror; + if( jsonFunctionArgToBlob(ctx, argv[i+1], &ax) ){ + jsonParseReset(&ax); + jsonParseFree(p); + return; + } + if( zPath[1]==0 ){ + if( eEdit==JEDIT_REPL || eEdit==JEDIT_SET ){ + jsonBlobEdit(p, 0, p->nBlob, ax.aBlob, ax.nBlob); + } + rc = 0; + }else{ + p->eEdit = eEdit; + p->nIns = ax.nBlob; + p->aIns = ax.aBlob; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + } + jsonParseReset(&ax); + if( rc==JSON_LOOKUP_NOTFOUND ) continue; + if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror; + } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +jsonInsertIntoBlob_patherror: + jsonParseFree(p); + if( rc==JSON_LOOKUP_ERROR ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + }else{ + jsonBadPathError(ctx, zPath); + } + return; +} /* -** Report the wrong number of arguments for json_insert(), json_replace() -** or json_set(). +** If pArg is a blob that seems like a JSONB blob, then initialize +** p to point to that JSONB and return TRUE. If pArg does not seem like +** a JSONB blob, then return FALSE; +** +** This routine is only called if it is already known that pArg is a +** blob. The only open question is whether or not the blob appears +** to be a JSONB blob. */ -static void jsonWrongNumArgs( - sqlite3_context *pCtx, - const char *zFuncName -){ - char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", - zFuncName); - sqlite3_result_error(pCtx, zMsg, -1); - sqlite3_free(zMsg); +static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ + u32 n, sz = 0; + p->aBlob = (u8*)sqlite3_value_blob(pArg); + p->nBlob = (u32)sqlite3_value_bytes(pArg); + if( p->nBlob==0 ){ + p->aBlob = 0; + return 0; + } + if( NEVER(p->aBlob==0) ){ + return 0; + } + if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT + && (n = jsonbPayloadSize(p, 0, &sz))>0 + && sz+n==p->nBlob + && ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0) + ){ + return 1; + } + p->aBlob = 0; + p->nBlob = 0; + return 0; } /* -** Mark all NULL entries in the Object passed in as JNODE_REMOVE. +** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob, +** from the SQL function argument pArg. Return a pointer to the new +** JsonParse object. +** +** Ownership of the new JsonParse object is passed to the caller. The +** caller should invoke jsonParseFree() on the return value when it +** has finished using it. +** +** If any errors are detected, an appropriate error messages is set +** using sqlite3_result_error() or the equivalent and this routine +** returns NULL. This routine also returns NULL if the pArg argument +** is an SQL NULL value, but no error message is set in that case. This +** is so that SQL functions that are given NULL arguments will return +** a NULL value. */ -static void jsonRemoveAllNulls(JsonNode *pNode){ - int i, n; - assert( pNode->eType==JSON_OBJECT ); - n = pNode->n; - for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ - switch( pNode[i].eType ){ - case JSON_NULL: - pNode[i].jnFlags |= JNODE_REMOVE; - break; - case JSON_OBJECT: - jsonRemoveAllNulls(&pNode[i]); - break; +static JsonParse *jsonParseFuncArg( + sqlite3_context *ctx, + sqlite3_value *pArg, + u32 flgs +){ + int eType; /* Datatype of pArg */ + JsonParse *p = 0; /* Value to be returned */ + JsonParse *pFromCache = 0; /* Value taken from cache */ + sqlite3 *db; /* The database connection */ + + assert( ctx!=0 ); + eType = sqlite3_value_type(pArg); + if( eType==SQLITE_NULL ){ + return 0; + } + pFromCache = jsonCacheSearch(ctx, pArg); + if( pFromCache ){ + pFromCache->nJPRef++; + if( (flgs & JSON_EDITABLE)==0 ){ + return pFromCache; + } + } + db = sqlite3_context_db_handle(ctx); +rebuild_from_cache: + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) goto json_pfa_oom; + memset(p, 0, sizeof(*p)); + p->db = db; + p->nJPRef = 1; + if( pFromCache!=0 ){ + u32 nBlob = pFromCache->nBlob; + p->aBlob = sqlite3DbMallocRaw(db, nBlob); + if( p->aBlob==0 ) goto json_pfa_oom; + memcpy(p->aBlob, pFromCache->aBlob, nBlob); + p->nBlobAlloc = p->nBlob = nBlob; + p->hasNonstd = pFromCache->hasNonstd; + jsonParseFree(pFromCache); + return p; + } + if( eType==SQLITE_BLOB ){ + if( jsonArgIsJsonb(pArg,p) ){ + if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){ + goto json_pfa_oom; + } + return p; } + /* If the blob is not valid JSONB, fall through into trying to cast + ** the blob into text which is then interpreted as JSON. (tag-20240123-a) + ** + ** This goes against all historical documentation about how the SQLite + ** JSON functions were suppose to work. From the beginning, blob was + ** reserved for expansion and a blob value should have raised an error. + ** But it did not, due to a bug. And many applications came to depend + ** upon this buggy behavior, espeically when using the CLI and reading + ** JSON text using readfile(), which returns a blob. For this reason + ** we will continue to support the bug moving forward. + ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d + */ } + p->zJson = (char*)sqlite3_value_text(pArg); + p->nJson = sqlite3_value_bytes(pArg); + if( db->mallocFailed ) goto json_pfa_oom; + if( p->nJson==0 ) goto json_pfa_malformed; + assert( p->zJson!=0 ); + if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){ + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + return 0; + } + }else{ + int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref); + int rc; + if( !isRCStr ){ + char *zNew = sqlite3RCStrNew( p->nJson ); + if( zNew==0 ) goto json_pfa_oom; + memcpy(zNew, p->zJson, p->nJson); + p->zJson = zNew; + p->zJson[p->nJson] = 0; + }else{ + sqlite3RCStrRef(p->zJson); + } + p->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, p); + if( rc==SQLITE_NOMEM ) goto json_pfa_oom; + if( flgs & JSON_EDITABLE ){ + pFromCache = p; + p = 0; + goto rebuild_from_cache; + } + } + return p; + +json_pfa_malformed: + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + sqlite3_result_error(ctx, "malformed JSON", -1); + return 0; + } + +json_pfa_oom: + jsonParseFree(pFromCache); + jsonParseFree(p); + sqlite3_result_error_nomem(ctx); + return 0; } +/* +** Make the return value of a JSON function either the raw JSONB blob +** or make it JSON text, depending on whether the JSON_BLOB flag is +** set on the function. +*/ +static void jsonReturnParse( + sqlite3_context *ctx, + JsonParse *p +){ + int flgs; + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + return; + } + flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( flgs & JSON_BLOB ){ + if( p->nBlobAlloc>0 && !p->bReadOnly ){ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC); + p->nBlobAlloc = 0; + }else{ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT); + } + }else{ + JsonString s; + jsonStringInit(&s, ctx); + p->delta = 0; + jsonTranslateBlobToText(p, 0, &s); + jsonReturnString(&s, p, ctx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } +} /**************************************************************************** ** SQL functions used for testing and debugging @@ -204989,63 +209914,124 @@ static void jsonRemoveAllNulls(JsonNode *pNode){ #if SQLITE_DEBUG /* -** Print N node entries. -*/ -static void jsonDebugPrintNodeEntries( - JsonNode *aNode, /* First node entry to print */ - int N /* Number of node entries to print */ -){ - int i; - for(i=0; i<N; i++){ - const char *zType; - if( aNode[i].jnFlags & JNODE_LABEL ){ - zType = "label"; - }else{ - zType = jsonType[aNode[i].eType]; +** Decode JSONB bytes in aBlob[] starting at iStart through but not +** including iEnd. Indent the +** content by nIndent spaces. +*/ +static void jsonDebugPrintBlob( + JsonParse *pParse, /* JSON content */ + u32 iStart, /* Start rendering here */ + u32 iEnd, /* Do not render this byte or any byte after this one */ + int nIndent, /* Indent by this many spaces */ + sqlite3_str *pOut /* Generate output into this sqlite3_str object */ +){ + while( iStart<iEnd ){ + u32 i, n, nn, sz = 0; + int showContent = 1; + u8 x = pParse->aBlob[iStart] & 0x0f; + u32 savedNBlob = pParse->nBlob; + sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, ""); + if( pParse->nBlobAlloc>pParse->nBlob ){ + pParse->nBlob = pParse->nBlobAlloc; + } + nn = n = jsonbPayloadSize(pParse, iStart, &sz); + if( nn==0 ) nn = 1; + if( sz>0 && x<JSONB_ARRAY ){ + nn += sz; + } + for(i=0; i<nn; i++){ + sqlite3_str_appendf(pOut, " %02x", pParse->aBlob[iStart+i]); + } + if( n==0 ){ + sqlite3_str_appendf(pOut, " ERROR invalid node size\n"); + iStart = n==0 ? iStart+1 : iEnd; + continue; } - printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n); - if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){ - u8 f = aNode[i].jnFlags; - if( f & JNODE_RAW ) printf(" RAW"); - if( f & JNODE_ESCAPE ) printf(" ESCAPE"); - if( f & JNODE_REMOVE ) printf(" REMOVE"); - if( f & JNODE_REPLACE ) printf(" REPLACE"); - if( f & JNODE_APPEND ) printf(" APPEND"); - if( f & JNODE_JSON5 ) printf(" JSON5"); + pParse->nBlob = savedNBlob; + if( iStart+n+sz>iEnd ){ + iEnd = iStart+n+sz; + if( iEnd>pParse->nBlob ){ + if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){ + iEnd = pParse->nBlobAlloc; + }else{ + iEnd = pParse->nBlob; + } + } + } + sqlite3_str_appendall(pOut," <-- "); + switch( x ){ + case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break; + case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break; + case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break; + case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break; + case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break; + case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break; + case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break; + case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break; + case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break; + case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break; + case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break; + case JSONB_ARRAY: { + sqlite3_str_appendf(pOut,"array, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + case JSONB_OBJECT: { + sqlite3_str_appendf(pOut, "object, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + default: { + sqlite3_str_appendall(pOut, "ERROR: unknown node type\n"); + showContent = 0; + break; + } } - switch( aNode[i].eU ){ - case 1: printf(" zJContent=[%.*s]\n", - aNode[i].n, aNode[i].u.zJContent); break; - case 2: printf(" iAppend=%u\n", aNode[i].u.iAppend); break; - case 3: printf(" iKey=%u\n", aNode[i].u.iKey); break; - case 4: printf(" iPrev=%u\n", aNode[i].u.iPrev); break; - default: printf("\n"); + if( showContent ){ + if( sz==0 && x<=JSONB_FALSE ){ + sqlite3_str_append(pOut, "\n", 1); + }else{ + u32 j; + sqlite3_str_appendall(pOut, ": \""); + for(j=iStart+n; j<iStart+n+sz; j++){ + u8 c = pParse->aBlob[j]; + if( c<0x20 || c>=0x7f ) c = '.'; + sqlite3_str_append(pOut, (char*)&c, 1); + } + sqlite3_str_append(pOut, "\"\n", 2); + } } + iStart += n + sz; } } -#endif /* SQLITE_DEBUG */ - - -#if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */ -static void jsonDebugPrintParse(JsonParse *p){ - jsonDebugPrintNodeEntries(p->aNode, p->nNode); -} -static void jsonDebugPrintNode(JsonNode *pNode){ - jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode)); +static void jsonShowParse(JsonParse *pParse){ + sqlite3_str out; + char zBuf[1000]; + if( pParse==0 ){ + printf("NULL pointer\n"); + return; + }else{ + printf("nBlobAlloc = %u\n", pParse->nBlobAlloc); + printf("nBlob = %u\n", pParse->nBlob); + printf("delta = %d\n", pParse->delta); + if( pParse->nBlob==0 ) return; + printf("content (bytes 0..%u):\n", pParse->nBlob-1); + } + sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000); + jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out); + printf("%s", sqlite3_str_value(&out)); + sqlite3_str_reset(&out); } -#else - /* The usual case */ -# define jsonDebugPrintNode(X) -# define jsonDebugPrintParse(X) -#endif +#endif /* SQLITE_DEBUG */ #ifdef SQLITE_DEBUG /* ** SQL function: json_parse(JSON) ** -** Parse JSON using jsonParseCached(). Then print a dump of that -** parse on standard output. Return the mimified JSON result, just -** like the json() function. +** Parse JSON using jsonParseFuncArg(). Return text that is a +** human-readable dump of the binary JSONB for the input parameter. */ static void jsonParseFunc( sqlite3_context *ctx, @@ -205053,38 +210039,20 @@ static void jsonParseFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ + sqlite3_str out; - assert( argc==1 ); - p = jsonParseCached(ctx, argv[0], ctx, 0); + assert( argc>=1 ); + sqlite3StrAccumInit(&out, 0, 0, 0, 1000000); + p = jsonParseFuncArg(ctx, argv[0], 0); if( p==0 ) return; - printf("nNode = %u\n", p->nNode); - printf("nAlloc = %u\n", p->nAlloc); - printf("nJson = %d\n", p->nJson); - printf("nAlt = %d\n", p->nAlt); - printf("nErr = %u\n", p->nErr); - printf("oom = %u\n", p->oom); - printf("hasNonstd = %u\n", p->hasNonstd); - printf("useMod = %u\n", p->useMod); - printf("hasMod = %u\n", p->hasMod); - printf("nJPRef = %u\n", p->nJPRef); - printf("iSubst = %u\n", p->iSubst); - printf("iHold = %u\n", p->iHold); - jsonDebugPrintNodeEntries(p->aNode, p->nNode); - jsonReturnJson(p, p->aNode, ctx, 1, 0); -} - -/* -** The json_test1(JSON) function return true (1) if the input is JSON -** text generated by another json function. It returns (0) if the input -** is not known to be JSON. -*/ -static void jsonTest1Func( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - UNUSED_PARAMETER(argc); - sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); + if( argc==1 ){ + jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out); + sqlite3_result_text64(ctx,out.zText,out.nChar,SQLITE_TRANSIENT,SQLITE_UTF8); + }else{ + jsonShowParse(p); + } + jsonParseFree(p); + sqlite3_str_reset(&out); } #endif /* SQLITE_DEBUG */ @@ -205093,7 +210061,7 @@ static void jsonTest1Func( ****************************************************************************/ /* -** Implementation of the json_QUOTE(VALUE) function. Return a JSON value +** Implementation of the json_quote(VALUE) function. Return a JSON value ** corresponding to the SQL value input. Mostly this means putting ** double-quotes around strings and returning the unquoted string "null" ** when given a NULL input. @@ -205106,9 +210074,9 @@ static void jsonQuoteFunc( JsonString jx; UNUSED_PARAMETER(argc); - jsonInit(&jx, ctx); - jsonAppendValue(&jx, argv[0]); - jsonResult(&jx); + jsonStringInit(&jx, ctx); + jsonAppendSqlValue(&jx, argv[0]); + jsonReturnString(&jx, 0, 0); sqlite3_result_subtype(ctx, JSON_SUBTYPE); } @@ -205125,18 +210093,17 @@ static void jsonArrayFunc( int i; JsonString jx; - jsonInit(&jx, ctx); + jsonStringInit(&jx, ctx); jsonAppendChar(&jx, '['); for(i=0; i<argc; i++){ jsonAppendSeparator(&jx); - jsonAppendValue(&jx, argv[i]); + jsonAppendSqlValue(&jx, argv[i]); } jsonAppendChar(&jx, ']'); - jsonResult(&jx); + jsonReturnString(&jx, 0, 0); sqlite3_result_subtype(ctx, JSON_SUBTYPE); } - /* ** json_array_length(JSON) ** json_array_length(JSON, PATH) @@ -205150,46 +210117,46 @@ static void jsonArrayLengthFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - sqlite3_int64 n = 0; + sqlite3_int64 cnt = 0; u32 i; - JsonNode *pNode; + u8 eErr = 0; - p = jsonParseCached(ctx, argv[0], ctx, 0); + p = jsonParseFuncArg(ctx, argv[0], 0); if( p==0 ) return; - assert( p->nNode ); if( argc==2 ){ const char *zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(p, zPath, 0, ctx); - }else{ - pNode = p->aNode; - } - if( pNode==0 ){ - return; - } - if( pNode->eType==JSON_ARRAY ){ - while( 1 /*exit-by-break*/ ){ - i = 1; - while( i<=pNode->n ){ - if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) n++; - i += jsonNodeSize(&pNode[i]); + if( zPath==0 ){ + jsonParseFree(p); + return; + } + i = jsonLookupStep(p, 0, zPath[0]=='$' ? zPath+1 : "@", 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + /* no-op */ + }else if( i==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( p->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &p->aNode[pNode->u.iAppend]; + eErr = 1; + i = 0; } + }else{ + i = 0; } - sqlite3_result_int64(ctx, n); + if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){ + cnt = jsonbArrayCount(p, i); + } + if( !eErr ) sqlite3_result_int64(ctx, cnt); + jsonParseFree(p); } -/* -** Bit values for the flags passed into jsonExtractFunc() or -** jsonSetFunc() via the user-data value. -*/ -#define JSON_JSON 0x01 /* Result is always JSON */ -#define JSON_SQL 0x02 /* Result is always SQL */ -#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ -#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ +/* True if the string is all alphanumerics and underscores */ +static int jsonAllAlphanum(const char *z, int n){ + int i; + for(i=0; i<n && (sqlite3Isalnum(z[i]) || z[i]=='_'); i++){} + return i==n; +} /* ** json_extract(JSON, PATH, ...) @@ -205216,151 +210183,313 @@ static void jsonExtractFunc( int argc, sqlite3_value **argv ){ - JsonParse *p; /* The parse */ - JsonNode *pNode; - const char *zPath; - int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); - JsonString jx; + JsonParse *p = 0; /* The parse */ + int flags; /* Flags associated with the function */ + int i; /* Loop counter */ + JsonString jx; /* String for array result */ if( argc<2 ) return; - p = jsonParseCached(ctx, argv[0], ctx, 0); + p = jsonParseFuncArg(ctx, argv[0], 0); if( p==0 ) return; - if( argc==2 ){ + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + jsonStringInit(&jx, ctx); + if( argc>2 ){ + jsonAppendChar(&jx, '['); + } + for(i=1; i<argc; i++){ /* With a single PATH argument */ - zPath = (const char*)sqlite3_value_text(argv[1]); - if( zPath==0 ) return; - if( flags & JSON_ABPATH ){ - if( zPath[0]!='$' || (zPath[1]!='.' && zPath[1]!='[' && zPath[1]!=0) ){ - /* The -> and ->> operators accept abbreviated PATH arguments. This - ** is mostly for compatibility with PostgreSQL, but also for - ** convenience. - ** - ** NUMBER ==> $[NUMBER] // PG compatible - ** LABEL ==> $.LABEL // PG compatible - ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience - */ - jsonInit(&jx, ctx); - if( sqlite3Isdigit(zPath[0]) ){ - jsonAppendRawNZ(&jx, "$[", 2); - jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); - jsonAppendRawNZ(&jx, "]", 2); - }else{ - jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='[')); - jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); - jsonAppendChar(&jx, 0); - } - pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx); - jsonReset(&jx); + const char *zPath = (const char*)sqlite3_value_text(argv[i]); + int nPath; + u32 j; + if( zPath==0 ) goto json_extract_error; + nPath = sqlite3Strlen30(zPath); + if( zPath[0]=='$' ){ + j = jsonLookupStep(p, 0, zPath+1, 0); + }else if( (flags & JSON_ABPATH) ){ + /* The -> and ->> operators accept abbreviated PATH arguments. This + ** is mostly for compatibility with PostgreSQL, but also for + ** convenience. + ** + ** NUMBER ==> $[NUMBER] // PG compatible + ** LABEL ==> $.LABEL // PG compatible + ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + ** + ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from + ** the right of the array. Hence for negative NUMBER: + ** + ** NUMBER ==> $[#NUMBER] // PG compatible + */ + jsonStringInit(&jx, ctx); + if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ + jsonAppendRawNZ(&jx, "[", 1); + if( zPath[0]=='-' ) jsonAppendRawNZ(&jx,"#",1); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "]", 2); + }else if( jsonAllAlphanum(zPath, nPath) ){ + jsonAppendRawNZ(&jx, ".", 1); + jsonAppendRaw(&jx, zPath, nPath); + }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){ + jsonAppendRaw(&jx, zPath, nPath); }else{ - pNode = jsonLookup(p, zPath, 0, ctx); + jsonAppendRawNZ(&jx, ".\"", 2); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "\"", 1); } - if( pNode ){ + jsonStringTerminate(&jx); + j = jsonLookupStep(p, 0, jx.zBuf, 0); + jsonStringReset(&jx); + }else{ + jsonBadPathError(ctx, zPath); + goto json_extract_error; + } + if( j<p->nBlob ){ + if( argc==2 ){ if( flags & JSON_JSON ){ - jsonReturnJson(p, pNode, ctx, 0, 0); + jsonStringInit(&jx, ctx); + jsonTranslateBlobToText(p, j, &jx); + jsonReturnString(&jx, 0, 0); + jsonStringReset(&jx); + assert( (flags & JSON_BLOB)==0 ); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); }else{ - jsonReturn(p, pNode, ctx, 1); + jsonReturnFromBlob(p, j, ctx, 0); + if( (flags & (JSON_SQL|JSON_BLOB))==0 + && (p->aBlob[j]&0x0f)>=JSONB_ARRAY + ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } } + }else{ + jsonAppendSeparator(&jx); + jsonTranslateBlobToText(p, j, &jx); } - }else{ - pNode = jsonLookup(p, zPath, 0, ctx); - if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx, 0); - } - }else{ - /* Two or more PATH arguments results in a JSON array with each - ** element of the array being the value selected by one of the PATHs */ - int i; - jsonInit(&jx, ctx); - jsonAppendChar(&jx, '['); - for(i=1; i<argc; i++){ - zPath = (const char*)sqlite3_value_text(argv[i]); - pNode = jsonLookup(p, zPath, 0, ctx); - if( p->nErr ) break; - jsonAppendSeparator(&jx); - if( pNode ){ - jsonRenderNode(p, pNode, &jx); + }else if( j==JSON_LOOKUP_NOTFOUND ){ + if( argc==2 ){ + goto json_extract_error; /* Return NULL if not found */ }else{ + jsonAppendSeparator(&jx); jsonAppendRawNZ(&jx, "null", 4); } + }else if( j==JSON_LOOKUP_ERROR ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + goto json_extract_error; + }else{ + jsonBadPathError(ctx, zPath); + goto json_extract_error; } - if( i==argc ){ - jsonAppendChar(&jx, ']'); - jsonResult(&jx); + } + if( argc>2 ){ + jsonAppendChar(&jx, ']'); + jsonReturnString(&jx, 0, 0); + if( (flags & JSON_BLOB)==0 ){ sqlite3_result_subtype(ctx, JSON_SUBTYPE); } - jsonReset(&jx); } +json_extract_error: + jsonStringReset(&jx); + jsonParseFree(p); + return; } -/* This is the RFC 7396 MergePatch algorithm. -*/ -static JsonNode *jsonMergePatch( - JsonParse *pParse, /* The JSON parser that contains the TARGET */ - u32 iTarget, /* Node of the TARGET in pParse */ - JsonNode *pPatch /* The PATCH */ -){ - u32 i, j; - u32 iRoot; - JsonNode *pTarget; - if( pPatch->eType!=JSON_OBJECT ){ - return pPatch; - } - assert( iTarget<pParse->nNode ); - pTarget = &pParse->aNode[iTarget]; - assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); - if( pTarget->eType!=JSON_OBJECT ){ - jsonRemoveAllNulls(pPatch); - return pPatch; - } - iRoot = iTarget; - for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){ - u32 nKey; - const char *zKey; - assert( pPatch[i].eType==JSON_STRING ); - assert( pPatch[i].jnFlags & JNODE_LABEL ); - assert( pPatch[i].eU==1 ); - nKey = pPatch[i].n; - zKey = pPatch[i].u.zJContent; - for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){ - assert( pTarget[j].eType==JSON_STRING ); - assert( pTarget[j].jnFlags & JNODE_LABEL ); - if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){ - if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break; - if( pPatch[i+1].eType==JSON_NULL ){ - pTarget[j+1].jnFlags |= JNODE_REMOVE; - }else{ - JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); - if( pNew==0 ) return 0; - if( pNew!=&pParse->aNode[iTarget+j+1] ){ - jsonParseAddSubstNode(pParse, iTarget+j+1); - jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew)); - } - pTarget = &pParse->aNode[iTarget]; - } - break; +/* +** Return codes for jsonMergePatch() +*/ +#define JSON_MERGE_OK 0 /* Success */ +#define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */ +#define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */ +#define JSON_MERGE_OOM 3 /* Out-of-memory condition */ + +/* +** RFC-7396 MergePatch for two JSONB blobs. +** +** pTarget is the target. pPatch is the patch. The target is updated +** in place. The patch is read-only. +** +** The original RFC-7396 algorithm is this: +** +** define MergePatch(Target, Patch): +** if Patch is an Object: +** if Target is not an Object: +** Target = {} # Ignore the contents and set it to an empty Object +** for each Name/Value pair in Patch: +** if Value is null: +** if Name exists in Target: +** remove the Name/Value pair from Target +** else: +** Target[Name] = MergePatch(Target[Name], Value) +** return Target +** else: +** return Patch +** +** Here is an equivalent algorithm restructured to show the actual +** implementation: +** +** 01 define MergePatch(Target, Patch): +** 02 if Patch is not an Object: +** 03 return Patch +** 04 else: // if Patch is an Object +** 05 if Target is not an Object: +** 06 Target = {} +** 07 for each Name/Value pair in Patch: +** 08 if Name exists in Target: +** 09 if Value is null: +** 10 remove the Name/Value pair from Target +** 11 else +** 12 Target[name] = MergePatch(Target[Name], Value) +** 13 else if Value is not NULL: +** 14 if Value is not an Object: +** 15 Target[name] = Value +** 16 else: +** 17 Target[name] = MergePatch('{}',value) +** 18 return Target +** | +** ^---- Line numbers referenced in comments in the implementation +*/ +static int jsonMergePatch( + JsonParse *pTarget, /* The JSON parser that contains the TARGET */ + u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */ + const JsonParse *pPatch, /* The PATCH */ + u32 iPatch /* Index of PATCH in pPatch->aBlob[] */ +){ + u8 x; /* Type of a single node */ + u32 n, sz=0; /* Return values from jsonbPayloadSize() */ + u32 iTCursor; /* Cursor position while scanning the target object */ + u32 iTStart; /* First label in the target object */ + u32 iTEndBE; /* Original first byte past end of target, before edit */ + u32 iTEnd; /* Current first byte past end of target */ + u8 eTLabel; /* Node type of the target label */ + u32 iTLabel = 0; /* Index of the label */ + u32 nTLabel = 0; /* Header size in bytes for the target label */ + u32 szTLabel = 0; /* Size of the target label payload */ + u32 iTValue = 0; /* Index of the target value */ + u32 nTValue = 0; /* Header size of the target value */ + u32 szTValue = 0; /* Payload size for the target value */ + + u32 iPCursor; /* Cursor position while scanning the patch */ + u32 iPEnd; /* First byte past the end of the patch */ + u8 ePLabel; /* Node type of the patch label */ + u32 iPLabel; /* Start of patch label */ + u32 nPLabel; /* Size of header on the patch label */ + u32 szPLabel; /* Payload size of the patch label */ + u32 iPValue; /* Start of patch value */ + u32 nPValue; /* Header size for the patch value */ + u32 szPValue; /* Payload size of the patch value */ + + assert( iTarget>=0 && iTarget<pTarget->nBlob ); + assert( iPatch>=0 && iPatch<pPatch->nBlob ); + x = pPatch->aBlob[iPatch] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */ + u32 szPatch; /* Total size of the patch, header+payload */ + u32 szTarget; /* Total size of the target, header+payload */ + n = jsonbPayloadSize(pPatch, iPatch, &sz); + szPatch = n+sz; + sz = 0; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + szTarget = n+sz; + jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */ + } + x = pTarget->aBlob[iTarget] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */ + n = jsonbPayloadSize(pTarget, iTarget, &sz); + jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0); + x = pTarget->aBlob[iTarget]; + pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT; + } + n = jsonbPayloadSize(pPatch, iPatch, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADPATCH; + iPCursor = iPatch+n; + iPEnd = iPCursor+sz; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADTARGET; + iTStart = iTarget+n; + iTEndBE = iTStart+sz; + + while( iPCursor<iPEnd ){ /* Algorithm line 07 */ + iPLabel = iPCursor; + ePLabel = pPatch->aBlob[iPCursor] & 0x0f; + if( ePLabel<JSONB_TEXT || ePLabel>JSONB_TEXTRAW ){ + return JSON_MERGE_BADPATCH; + } + nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel); + if( nPLabel==0 ) return JSON_MERGE_BADPATCH; + iPValue = iPCursor + nPLabel + szPLabel; + if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH; + nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue); + if( nPValue==0 ) return JSON_MERGE_BADPATCH; + iPCursor = iPValue + nPValue + szPValue; + if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH; + + iTCursor = iTStart; + iTEnd = iTEndBE + pTarget->delta; + while( iTCursor<iTEnd ){ + int isEqual; /* true if the patch and target labels match */ + iTLabel = iTCursor; + eTLabel = pTarget->aBlob[iTCursor] & 0x0f; + if( eTLabel<JSONB_TEXT || eTLabel>JSONB_TEXTRAW ){ + return JSON_MERGE_BADTARGET; + } + nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel); + if( nTLabel==0 ) return JSON_MERGE_BADTARGET; + iTValue = iTLabel + nTLabel + szTLabel; + if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET; + nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue); + if( nTValue==0 ) return JSON_MERGE_BADTARGET; + if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET; + isEqual = jsonLabelCompare( + (const char*)&pPatch->aBlob[iPLabel+nPLabel], + szPLabel, + (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW), + (const char*)&pTarget->aBlob[iTLabel+nTLabel], + szTLabel, + (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW)); + if( isEqual ) break; + iTCursor = iTValue + nTValue + szTValue; + } + x = pPatch->aBlob[iPValue] & 0x0f; + if( iTCursor<iTEnd ){ + /* A match was found. Algorithm line 08 */ + if( x==0 ){ + /* Patch value is NULL. Algorithm line 09 */ + jsonBlobEdit(pTarget, iTLabel, nTLabel+szTLabel+nTValue+szTValue, 0,0); + /* vvvvvv----- No OOM on a delete-only edit */ + if( NEVER(pTarget->oom) ) return JSON_MERGE_OOM; + }else{ + /* Algorithm line 12 */ + int rc, savedDelta = pTarget->delta; + pTarget->delta = 0; + rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue); + if( rc ) return rc; + pTarget->delta += savedDelta; + } + }else if( x>0 ){ /* Algorithm line 13 */ + /* No match and patch value is not NULL */ + u32 szNew = szPLabel+nPLabel; + if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */ + jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + memcpy(&pTarget->aBlob[iTEnd+szNew], + &pPatch->aBlob[iPValue], szPValue+nPValue); + }else{ + int rc, savedDelta; + jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + pTarget->aBlob[iTEnd+szNew] = 0x00; + savedDelta = pTarget->delta; + pTarget->delta = 0; + rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue); + if( rc ) return rc; + pTarget->delta += savedDelta; } } - if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ - int iStart; - JsonNode *pApnd; - u32 nApnd; - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - pApnd = &pPatch[i+1]; - if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd); - nApnd = jsonNodeSize(pApnd); - jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd)); - if( pParse->oom ) return 0; - pParse->aNode[iStart].n = 1+nApnd; - pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; - pParse->aNode[iRoot].u.iAppend = iStart; - VVA( pParse->aNode[iRoot].eU = 2 ); - iRoot = iStart; - pTarget = &pParse->aNode[iTarget]; - } } - return pTarget; + if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; } + /* ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON ** object that is the result of running the RFC 7396 MergePatch() algorithm @@ -205371,28 +210500,27 @@ static void jsonPatchFunc( int argc, sqlite3_value **argv ){ - JsonParse *pX; /* The JSON that is being patched */ - JsonParse *pY; /* The patch */ - JsonNode *pResult; /* The result of the merge */ + JsonParse *pTarget; /* The TARGET */ + JsonParse *pPatch; /* The PATCH */ + int rc; /* Result code */ UNUSED_PARAMETER(argc); - pX = jsonParseCached(ctx, argv[0], ctx, 1); - if( pX==0 ) return; - assert( pX->hasMod==0 ); - pX->hasMod = 1; - pY = jsonParseCached(ctx, argv[1], ctx, 1); - if( pY==0 ) return; - pX->useMod = 1; - pY->useMod = 1; - pResult = jsonMergePatch(pX, 0, pY->aNode); - assert( pResult!=0 || pX->oom ); - if( pResult && pX->oom==0 ){ - jsonDebugPrintParse(pX); - jsonDebugPrintNode(pResult); - jsonReturnJson(pX, pResult, ctx, 0, 0); - }else{ - sqlite3_result_error_nomem(ctx); + assert( argc==2 ); + pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE); + if( pTarget==0 ) return; + pPatch = jsonParseFuncArg(ctx, argv[1], 0); + if( pPatch ){ + rc = jsonMergePatch(pTarget, 0, pPatch, 0); + if( rc==JSON_MERGE_OK ){ + jsonReturnParse(ctx, pTarget); + }else if( rc==JSON_MERGE_OOM ){ + sqlite3_result_error_nomem(ctx); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + jsonParseFree(pPatch); } + jsonParseFree(pTarget); } @@ -205416,23 +210544,23 @@ static void jsonObjectFunc( "of arguments", -1); return; } - jsonInit(&jx, ctx); + jsonStringInit(&jx, ctx); jsonAppendChar(&jx, '{'); for(i=0; i<argc; i+=2){ if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){ sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1); - jsonReset(&jx); + jsonStringReset(&jx); return; } jsonAppendSeparator(&jx); z = (const char*)sqlite3_value_text(argv[i]); - n = (u32)sqlite3_value_bytes(argv[i]); + n = sqlite3_value_bytes(argv[i]); jsonAppendString(&jx, z, n); jsonAppendChar(&jx, ':'); - jsonAppendValue(&jx, argv[i+1]); + jsonAppendSqlValue(&jx, argv[i+1]); } jsonAppendChar(&jx, '}'); - jsonResult(&jx); + jsonReturnString(&jx, 0, 0); sqlite3_result_subtype(ctx, JSON_SUBTYPE); } @@ -205448,120 +210576,50 @@ static void jsonRemoveFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; + JsonParse *p; /* The parse */ + const char *zPath = 0; /* Path of element to be removed */ + int i; /* Loop counter */ + u32 rc; /* Subroutine return code */ if( argc<1 ) return; - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - for(i=1; i<(u32)argc; i++){ + p = jsonParseFuncArg(ctx, argv[0], argc>1 ? JSON_EDITABLE : 0); + if( p==0 ) return; + for(i=1; i<argc; i++){ zPath = (const char*)sqlite3_value_text(argv[i]); - if( zPath==0 ) goto remove_done; - pNode = jsonLookup(pParse, zPath, 0, ctx); - if( pParse->nErr ) goto remove_done; - if( pNode ){ - pNode->jnFlags |= JNODE_REMOVE; - pParse->hasMod = 1; - pParse->useMod = 1; - } - } - if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){ - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); - } -remove_done: - jsonDebugPrintParse(p); -} - -/* -** Substitute the value at iNode with the pValue parameter. -*/ -static void jsonReplaceNode( - sqlite3_context *pCtx, - JsonParse *p, - int iNode, - sqlite3_value *pValue -){ - int idx = jsonParseAddSubstNode(p, iNode); - if( idx<=0 ){ - assert( p->oom ); - return; - } - switch( sqlite3_value_type(pValue) ){ - case SQLITE_NULL: { - jsonParseAddNode(p, JSON_NULL, 0, 0); - break; - } - case SQLITE_FLOAT: { - char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue)); - int n; - if( z==0 ){ - p->oom = 1; - break; - } - n = sqlite3Strlen30(z); - jsonParseAddNode(p, JSON_REAL, n, z); - jsonParseAddCleanup(p, sqlite3_free, z); - break; - } - case SQLITE_INTEGER: { - char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue)); - int n; - if( z==0 ){ - p->oom = 1; - break; - } - n = sqlite3Strlen30(z); - jsonParseAddNode(p, JSON_INT, n, z); - jsonParseAddCleanup(p, sqlite3_free, z); - - break; - } - case SQLITE_TEXT: { - const char *z = (const char*)sqlite3_value_text(pValue); - u32 n = (u32)sqlite3_value_bytes(pValue); - if( z==0 ){ - p->oom = 1; - break; - } - if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ - char *zCopy = sqlite3_malloc64( n+1 ); - int k; - if( zCopy ){ - memcpy(zCopy, z, n); - zCopy[n] = 0; - jsonParseAddCleanup(p, sqlite3_free, zCopy); - }else{ - p->oom = 1; - sqlite3_result_error_nomem(pCtx); - } - k = jsonParseAddNode(p, JSON_STRING, n, zCopy); - assert( k>0 || p->oom ); - if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW; + if( zPath==0 ){ + goto json_remove_done; + } + if( zPath[0]!='$' ){ + goto json_remove_patherror; + } + if( zPath[1]==0 ){ + /* json_remove(j,'$') returns NULL */ + goto json_remove_done; + } + p->eEdit = JEDIT_DEL; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(rc) ){ + if( rc==JSON_LOOKUP_NOTFOUND ){ + continue; /* No-op */ + }else if( rc==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); }else{ - JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1); - if( pPatch==0 ){ - p->oom = 1; - break; - } - jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode); - /* The nodes copied out of pPatch and into p likely contain - ** u.zJContent pointers into pPatch->zJson. So preserve the - ** content of pPatch until p is destroyed. */ - assert( pPatch->nJPRef>=1 ); - pPatch->nJPRef++; - jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch); + sqlite3_result_error(ctx, "malformed JSON", -1); } - break; - } - default: { - jsonParseAddNode(p, JSON_NULL, 0, 0); - sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1); - p->nErr++; - break; + goto json_remove_done; } } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +json_remove_patherror: + jsonBadPathError(ctx, zPath); + +json_remove_done: + jsonParseFree(p); + return; } /* @@ -205575,32 +210633,12 @@ static void jsonReplaceFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; - if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, "replace"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - pParse->nJPRef++; - for(i=1; i<(u32)argc; i+=2){ - zPath = (const char*)sqlite3_value_text(argv[i]); - pParse->useMod = 1; - pNode = jsonLookup(pParse, zPath, 0, ctx); - if( pParse->nErr ) goto replace_err; - if( pNode ){ - jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); - } - } - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); -replace_err: - jsonDebugPrintParse(pParse); - jsonParseFree(pParse); + jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL); } @@ -205621,39 +210659,16 @@ static void jsonSetFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; - int bApnd; - int bIsSet = sqlite3_user_data(ctx)!=0; + + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + int bIsSet = (flags&JSON_ISSET)!=0; if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - pParse->nJPRef++; - for(i=1; i<(u32)argc; i+=2){ - zPath = (const char*)sqlite3_value_text(argv[i]); - bApnd = 0; - pParse->useMod = 1; - pNode = jsonLookup(pParse, zPath, &bApnd, ctx); - if( pParse->oom ){ - sqlite3_result_error_nomem(ctx); - goto jsonSetDone; - }else if( pParse->nErr ){ - goto jsonSetDone; - }else if( pNode && (bApnd || bIsSet) ){ - jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); - } - } - jsonDebugPrintParse(pParse); - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); -jsonSetDone: - jsonParseFree(pParse); + jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS); } /* @@ -205669,27 +210684,127 @@ static void jsonTypeFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - const char *zPath; - JsonNode *pNode; + const char *zPath = 0; + u32 i; - p = jsonParseCached(ctx, argv[0], ctx, 0); + p = jsonParseFuncArg(ctx, argv[0], 0); if( p==0 ) return; if( argc==2 ){ zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(p, zPath, 0, ctx); + if( zPath==0 ) goto json_type_done; + if( zPath[0]!='$' ){ + jsonBadPathError(ctx, zPath); + goto json_type_done; + } + i = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + /* no-op */ + }else if( i==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + goto json_type_done; + } }else{ - pNode = p->aNode; + i = 0; } - if( pNode ){ - sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); + sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC); +json_type_done: + jsonParseFree(p); +} + +/* +** json_pretty(JSON) +** json_pretty(JSON, INDENT) +** +** Return text that is a pretty-printed rendering of the input JSON. +** If the argument is not valid JSON, return NULL. +** +** The INDENT argument is text that is used for indentation. If omitted, +** it defaults to four spaces (the same as PostgreSQL). +*/ +static void jsonPrettyFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString s; /* The output string */ + JsonPretty x; /* Pretty printing context */ + + memset(&x, 0, sizeof(x)); + x.pParse = jsonParseFuncArg(ctx, argv[0], 0); + if( x.pParse==0 ) return; + x.pOut = &s; + jsonStringInit(&s, ctx); + if( argc==1 || (x.zIndent = (const char*)sqlite3_value_text(argv[1]))==0 ){ + x.zIndent = " "; + x.szIndent = 4; + }else{ + x.szIndent = (u32)strlen(x.zIndent); } + jsonTranslateBlobToPrettyText(&x, 0); + jsonReturnString(&s, 0, 0); + jsonParseFree(x.pParse); } /* ** json_valid(JSON) -** -** Return 1 if JSON is a well-formed canonical JSON string according -** to RFC-7159. Return 0 otherwise. +** json_valid(JSON, FLAGS) +** +** Check the JSON argument to see if it is well-formed. The FLAGS argument +** encodes the various constraints on what is meant by "well-formed": +** +** 0x01 Canonical RFC-8259 JSON text +** 0x02 JSON text with optional JSON-5 extensions +** 0x04 Superficially appears to be JSONB +** 0x08 Strictly well-formed JSONB +** +** If the FLAGS argument is omitted, it defaults to 1. Useful values for +** FLAGS include: +** +** 1 Strict canonical JSON text +** 2 JSON text perhaps with JSON-5 extensions +** 4 Superficially appears to be JSONB +** 5 Canonical JSON text or superficial JSONB +** 6 JSON-5 text or superficial JSONB +** 8 Strict JSONB +** 9 Canonical JSON text or strict JSONB +** 10 JSON-5 text or strict JSONB +** +** Other flag combinations are redundant. For example, every canonical +** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3 +** are the same. Similarly, any input that passes a strict JSONB validation +** will also pass the superficial validation so 12 through 15 are the same +** as 8 through 11 respectively. +** +** This routine runs in linear time to validate text and when doing strict +** JSONB validation. Superficial JSONB validation is constant time, +** assuming the BLOB is already in memory. The performance advantage +** of superficial JSONB validation is why that option is provided. +** Application developers can choose to do fast superficial validation or +** slower strict validation, according to their specific needs. +** +** Only the lower four bits of the FLAGS argument are currently used. +** Higher bits are reserved for future expansion. To facilitate +** compatibility, the current implementation raises an error if any bit +** in FLAGS is set other than the lower four bits. +** +** The original circa 2015 implementation of the JSON routines in +** SQLite only supported canonical RFC-8259 JSON text and the json_valid() +** function only accepted one argument. That is why the default value +** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only +** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS +** argument was added when the JSON routines were extended to support +** JSON5-like extensions and binary JSONB stored in BLOBs. +** +** Return Values: +** +** * Raise an error if FLAGS is outside the range of 1 to 15. +** * Return NULL if the input is NULL +** * Return 1 if the input is well-formed. +** * Return 0 if the input is not well-formed. */ static void jsonValidFunc( sqlite3_context *ctx, @@ -205697,79 +210812,128 @@ static void jsonValidFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + u8 flags = 1; + u8 res = 0; + if( argc==2 ){ + i64 f = sqlite3_value_int64(argv[1]); + if( f<1 || f>15 ){ + sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be" + " between 1 and 15", -1); + return; + } + flags = f & 0x0f; + } + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_NULL: { #ifdef SQLITE_LEGACY_JSON_VALID - /* Incorrect legacy behavior was to return FALSE for a NULL input */ - sqlite3_result_int(ctx, 0); + /* Incorrect legacy behavior was to return FALSE for a NULL input */ + sqlite3_result_int(ctx, 0); #endif - return; - } - p = jsonParseCached(ctx, argv[0], 0, 0); - if( p==0 || p->oom ){ - sqlite3_result_error_nomem(ctx); - sqlite3_free(p); - }else{ - sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod)); - if( p->nErr ) jsonParseFree(p); + return; + } + case SQLITE_BLOB: { + if( jsonFuncArgMightBeBinary(argv[0]) ){ + if( flags & 0x04 ){ + /* Superficial checking only - accomplished by the + ** jsonFuncArgMightBeBinary() call above. */ + res = 1; + }else if( flags & 0x08 ){ + /* Strict checking. Check by translating BLOB->TEXT->BLOB. If + ** no errors occur, call that a "strict check". */ + JsonParse px; + u32 iErr; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(argv[0]); + px.nBlob = sqlite3_value_bytes(argv[0]); + iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1); + res = iErr==0; + } + break; + } + /* Fall through into interpreting the input as text. See note + ** above at tag-20240123-a. */ + /* no break */ deliberate_fall_through + } + default: { + JsonParse px; + if( (flags & 0x3)==0 ) break; + memset(&px, 0, sizeof(px)); + + p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR); + if( p ){ + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + }else if( p->nErr ){ + /* no-op */ + }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){ + res = 1; + } + jsonParseFree(p); + }else{ + sqlite3_result_error_nomem(ctx); + } + break; + } } + sqlite3_result_int(ctx, res); } /* ** json_error_position(JSON) ** -** If the argument is not an interpretable JSON string, then return the 1-based -** character position at which the parser first recognized that the input -** was in error. The left-most character is 1. If the string is valid -** JSON, then return 0. -** -** Note that json_valid() is only true for strictly conforming canonical JSON. -** But this routine returns zero if the input contains extension. Thus: -** -** (1) If the input X is strictly conforming canonical JSON: -** -** json_valid(X) returns true -** json_error_position(X) returns 0 -** -** (2) If the input X is JSON but it includes extension (such as JSON5) that -** are not part of RFC-8259: +** If the argument is NULL, return NULL ** -** json_valid(X) returns false -** json_error_position(X) return 0 +** If the argument is BLOB, do a full validity check and return non-zero +** if the check fails. The return value is the approximate 1-based offset +** to the byte of the element that contains the first error. ** -** (3) If the input X cannot be interpreted as JSON even taking extensions -** into account: -** -** json_valid(X) return false -** json_error_position(X) returns 1 or more +** Otherwise interpret the argument is TEXT (even if it is numeric) and +** return the 1-based character position for where the parser first recognized +** that the input was not valid JSON, or return 0 if the input text looks +** ok. JSON-5 extensions are accepted. */ static void jsonErrorFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonParse *p; /* The parse */ + i64 iErrPos = 0; /* Error position to be returned */ + JsonParse s; + + assert( argc==1 ); UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - p = jsonParseCached(ctx, argv[0], 0, 0); - if( p==0 || p->oom ){ + memset(&s, 0, sizeof(s)); + s.db = sqlite3_context_db_handle(ctx); + if( jsonFuncArgMightBeBinary(argv[0]) ){ + s.aBlob = (u8*)sqlite3_value_blob(argv[0]); + s.nBlob = sqlite3_value_bytes(argv[0]); + iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); + }else{ + s.zJson = (char*)sqlite3_value_text(argv[0]); + if( s.zJson==0 ) return; /* NULL input or OOM */ + s.nJson = sqlite3_value_bytes(argv[0]); + if( jsonConvertTextToBlob(&s,0) ){ + if( s.oom ){ + iErrPos = -1; + }else{ + /* Convert byte-offset s.iErr into a character offset */ + u32 k; + assert( s.zJson!=0 ); /* Because s.oom is false */ + for(k=0; k<s.iErr && ALWAYS(s.zJson[k]); k++){ + if( (s.zJson[k] & 0xc0)!=0x80 ) iErrPos++; + } + iErrPos++; + } + } + } + jsonParseReset(&s); + if( iErrPos<0 ){ sqlite3_result_error_nomem(ctx); - sqlite3_free(p); - }else if( p->nErr==0 ){ - sqlite3_result_int(ctx, 0); }else{ - int n = 1; - u32 i; - const char *z = (const char*)sqlite3_value_text(argv[0]); - for(i=0; i<p->iErr && ALWAYS(z[i]); i++){ - if( (z[i]&0xc0)!=0x80 ) n++; - } - sqlite3_result_int(ctx, n); - jsonParseFree(p); + sqlite3_result_int64(ctx, iErrPos); } } - /**************************************************************************** ** Aggregate SQL function implementations ****************************************************************************/ @@ -205788,24 +210952,34 @@ static void jsonArrayStep( pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ - jsonInit(pStr, ctx); + jsonStringInit(pStr, ctx); jsonAppendChar(pStr, '['); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); } pStr->pCtx = ctx; - jsonAppendValue(pStr, argv[0]); + jsonAppendSqlValue(pStr, argv[0]); } } static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ + int flags; pStr->pCtx = ctx; jsonAppendChar(pStr, ']'); - if( pStr->bErr ){ - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); - assert( pStr->bStatic ); + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + jsonStringTrimOneChar(pStr); + } + return; }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : @@ -205813,7 +210987,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); - pStr->nUsed--; + jsonStringTrimOneChar(pStr); } }else{ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); @@ -205894,27 +211068,38 @@ static void jsonObjectStep( pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ - jsonInit(pStr, ctx); + jsonStringInit(pStr, ctx); jsonAppendChar(pStr, '{'); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); } pStr->pCtx = ctx; z = (const char*)sqlite3_value_text(argv[0]); - n = (u32)sqlite3_value_bytes(argv[0]); + n = sqlite3Strlen30(z); jsonAppendString(pStr, z, n); jsonAppendChar(pStr, ':'); - jsonAppendValue(pStr, argv[1]); + jsonAppendSqlValue(pStr, argv[1]); } } static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ + int flags; jsonAppendChar(pStr, '}'); - if( pStr->bErr ){ - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); - assert( pStr->bStatic ); + pStr->pCtx = ctx; + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + jsonStringTrimOneChar(pStr); + } + return; }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : @@ -205922,7 +211107,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); - pStr->nUsed--; + jsonStringTrimOneChar(pStr); } }else{ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); @@ -205942,19 +211127,37 @@ static void jsonObjectFinal(sqlite3_context *ctx){ /**************************************************************************** ** The json_each virtual table ****************************************************************************/ +typedef struct JsonParent JsonParent; +struct JsonParent { + u32 iHead; /* Start of object or array */ + u32 iValue; /* Start of the value */ + u32 iEnd; /* First byte past the end */ + u32 nPath; /* Length of path */ + i64 iKey; /* Key for JSONB_ARRAY */ +}; + typedef struct JsonEachCursor JsonEachCursor; struct JsonEachCursor { sqlite3_vtab_cursor base; /* Base class - must be first */ u32 iRowid; /* The rowid */ - u32 iBegin; /* The first node of the scan */ - u32 i; /* Index in sParse.aNode[] of current row */ + u32 i; /* Index in sParse.aBlob[] of current row */ u32 iEnd; /* EOF when i equals or exceeds this value */ - u8 eType; /* Type of top-level element */ + u32 nRoot; /* Size of the root path in bytes */ + u8 eType; /* Type of the container for element i */ u8 bRecursive; /* True for json_tree(). False for json_each() */ - char *zJson; /* Input JSON */ - char *zRoot; /* Path by which to filter zJson */ + u32 nParent; /* Current nesting depth */ + u32 nParentAlloc; /* Space allocated for aParent[] */ + JsonParent *aParent; /* Parent elements of i */ + sqlite3 *db; /* Database connection */ + JsonString path; /* Current path */ JsonParse sParse; /* Parse of the input JSON */ }; +typedef struct JsonEachConnection JsonEachConnection; +struct JsonEachConnection { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection */ +}; + /* Constructor for the json_each virtual table */ static int jsonEachConnect( @@ -205964,7 +211167,7 @@ static int jsonEachConnect( sqlite3_vtab **ppVtab, char **pzErr ){ - sqlite3_vtab *pNew; + JsonEachConnection *pNew; int rc; /* Column numbers */ @@ -205990,28 +211193,32 @@ static int jsonEachConnect( "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," "json HIDDEN,root HIDDEN)"); if( rc==SQLITE_OK ){ - pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew)); + *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(*pNew)); sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + pNew->db = db; } return rc; } /* destructor for json_each virtual table */ static int jsonEachDisconnect(sqlite3_vtab *pVtab){ - sqlite3_free(pVtab); + JsonEachConnection *p = (JsonEachConnection*)pVtab; + sqlite3DbFree(p->db, pVtab); return SQLITE_OK; } /* constructor for a JsonEachCursor object for json_each(). */ static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + JsonEachConnection *pVtab = (JsonEachConnection*)p; JsonEachCursor *pCur; UNUSED_PARAMETER(p); - pCur = sqlite3_malloc( sizeof(*pCur) ); + pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur)); if( pCur==0 ) return SQLITE_NOMEM; - memset(pCur, 0, sizeof(*pCur)); + pCur->db = pVtab->db; + jsonStringZero(&pCur->path); *ppCursor = &pCur->base; return SQLITE_OK; } @@ -206029,21 +211236,24 @@ static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ /* Reset a JsonEachCursor back to its original state. Free any memory ** held. */ static void jsonEachCursorReset(JsonEachCursor *p){ - sqlite3_free(p->zRoot); jsonParseReset(&p->sParse); + jsonStringReset(&p->path); + sqlite3DbFree(p->db, p->aParent); p->iRowid = 0; p->i = 0; + p->aParent = 0; + p->nParent = 0; + p->nParentAlloc = 0; p->iEnd = 0; p->eType = 0; - p->zJson = 0; - p->zRoot = 0; } /* Destructor for a jsonEachCursor object */ static int jsonEachClose(sqlite3_vtab_cursor *cur){ JsonEachCursor *p = (JsonEachCursor*)cur; jsonEachCursorReset(p); - sqlite3_free(cur); + + sqlite3DbFree(p->db, cur); return SQLITE_OK; } @@ -206054,200 +211264,233 @@ static int jsonEachEof(sqlite3_vtab_cursor *cur){ return p->i >= p->iEnd; } -/* Advance the cursor to the next element for json_tree() */ -static int jsonEachNext(sqlite3_vtab_cursor *cur){ - JsonEachCursor *p = (JsonEachCursor*)cur; - if( p->bRecursive ){ - if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; - p->i++; - p->iRowid++; - if( p->i<p->iEnd ){ - u32 iUp = p->sParse.aUp[p->i]; - JsonNode *pUp = &p->sParse.aNode[iUp]; - p->eType = pUp->eType; - if( pUp->eType==JSON_ARRAY ){ - assert( pUp->eU==0 || pUp->eU==3 ); - testcase( pUp->eU==3 ); - VVA( pUp->eU = 3 ); - if( iUp==p->i-1 ){ - pUp->u.iKey = 0; - }else{ - pUp->u.iKey++; +/* +** If the cursor is currently pointing at the label of a object entry, +** then return the index of the value. For all other cases, return the +** current pointer position, which is the value. +*/ +static int jsonSkipLabel(JsonEachCursor *p){ + if( p->eType==JSONB_OBJECT ){ + u32 sz = 0; + u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz); + return p->i + n + sz; + }else{ + return p->i; + } +} + +/* +** Append the path name for the current element. +*/ +static void jsonAppendPathName(JsonEachCursor *p){ + assert( p->nParent>0 ); + assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT ); + if( p->eType==JSONB_ARRAY ){ + jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey); + }else{ + u32 n, sz = 0, k, i; + const char *z; + int needQuote = 0; + n = jsonbPayloadSize(&p->sParse, p->i, &sz); + k = p->i + n; + z = (const char*)&p->sParse.aBlob[k]; + if( sz==0 || !sqlite3Isalpha(z[0]) ){ + needQuote = 1; + }else{ + for(i=0; i<sz; i++){ + if( !sqlite3Isalnum(z[i]) ){ + needQuote = 1; + break; } } } - }else{ - switch( p->eType ){ - case JSON_ARRAY: { - p->i += jsonNodeSize(&p->sParse.aNode[p->i]); - p->iRowid++; - break; - } - case JSON_OBJECT: { - p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); - p->iRowid++; - break; - } - default: { - p->i = p->iEnd; - break; - } + if( needQuote ){ + jsonPrintf(sz+4,&p->path,".\"%.*s\"", sz, z); + }else{ + jsonPrintf(sz+2,&p->path,".%.*s", sz, z); } } - return SQLITE_OK; } -/* Append an object label to the JSON Path being constructed -** in pStr. -*/ -static void jsonAppendObjectPathElement( - JsonString *pStr, - JsonNode *pNode -){ - int jj, nn; - const char *z; - assert( pNode->eType==JSON_STRING ); - assert( pNode->jnFlags & JNODE_LABEL ); - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - nn = pNode->n; - if( (pNode->jnFlags & JNODE_RAW)==0 ){ - assert( nn>=2 ); - assert( z[0]=='"' || z[0]=='\'' ); - assert( z[nn-1]=='"' || z[0]=='\'' ); - if( nn>2 && sqlite3Isalpha(z[1]) ){ - for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){} - if( jj==nn-1 ){ - z++; - nn -= 2; +/* Advance the cursor to the next element for json_tree() */ +static int jsonEachNext(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + int rc = SQLITE_OK; + if( p->bRecursive ){ + u8 x; + u8 levelChange = 0; + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + x = p->sParse.aBlob[i] & 0x0f; + n = jsonbPayloadSize(&p->sParse, i, &sz); + if( x==JSONB_OBJECT || x==JSONB_ARRAY ){ + JsonParent *pParent; + if( p->nParent>=p->nParentAlloc ){ + JsonParent *pNew; + u64 nNew; + nNew = p->nParentAlloc*2 + 3; + pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew); + if( pNew==0 ) return SQLITE_NOMEM; + p->nParentAlloc = (u32)nNew; + p->aParent = pNew; + } + levelChange = 1; + pParent = &p->aParent[p->nParent]; + pParent->iHead = p->i; + pParent->iValue = i; + pParent->iEnd = i + n + sz; + pParent->iKey = -1; + pParent->nPath = (u32)p->path.nUsed; + if( p->eType && p->nParent ){ + jsonAppendPathName(p); + if( p->path.eErr ) rc = SQLITE_NOMEM; + } + p->nParent++; + p->i = i + n; + }else{ + p->i = i + n + sz; + } + while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){ + p->nParent--; + p->path.nUsed = p->aParent[p->nParent].nPath; + levelChange = 1; + } + if( levelChange ){ + if( p->nParent>0 ){ + JsonParent *pParent = &p->aParent[p->nParent-1]; + u32 iVal = pParent->iValue; + p->eType = p->sParse.aBlob[iVal] & 0x0f; + }else{ + p->eType = 0; } } + }else{ + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->i = i + n + sz; + } + if( p->eType==JSONB_ARRAY && p->nParent ){ + p->aParent[p->nParent-1].iKey++; } - jsonPrintf(nn+2, pStr, ".%.*s", nn, z); + p->iRowid++; + return rc; } -/* Append the name of the path for element i to pStr +/* Length of the path for rowid==0 in bRecursive mode. */ -static void jsonEachComputePath( - JsonEachCursor *p, /* The cursor */ - JsonString *pStr, /* Write the path here */ - u32 i /* Path to this element */ -){ - JsonNode *pNode, *pUp; - u32 iUp; - if( i==0 ){ - jsonAppendChar(pStr, '$'); - return; - } - iUp = p->sParse.aUp[i]; - jsonEachComputePath(p, pStr, iUp); - pNode = &p->sParse.aNode[i]; - pUp = &p->sParse.aNode[iUp]; - if( pUp->eType==JSON_ARRAY ){ - assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) ); - testcase( pUp->eU==0 ); - jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); - }else{ - assert( pUp->eType==JSON_OBJECT ); - if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; - jsonAppendObjectPathElement(pStr, pNode); +static int jsonEachPathLength(JsonEachCursor *p){ + u32 n = p->path.nUsed; + char *z = p->path.zBuf; + if( p->iRowid==0 && p->bRecursive && n>=2 ){ + while( n>1 ){ + n--; + if( z[n]=='[' || z[n]=='.' ){ + u32 x, sz = 0; + char cSaved = z[n]; + z[n] = 0; + assert( p->sParse.eEdit==0 ); + x = jsonLookupStep(&p->sParse, 0, z+1, 0); + z[n] = cSaved; + if( JSON_LOOKUP_ISERROR(x) ) continue; + if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break; + } + } } + return n; } /* Return the value of a column */ static int jsonEachColumn( sqlite3_vtab_cursor *cur, /* The cursor */ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ - int i /* Which column to return */ + int iColumn /* Which column to return */ ){ JsonEachCursor *p = (JsonEachCursor*)cur; - JsonNode *pThis = &p->sParse.aNode[p->i]; - switch( i ){ + switch( iColumn ){ case JEACH_KEY: { - if( p->i==0 ) break; - if( p->eType==JSON_OBJECT ){ - jsonReturn(&p->sParse, pThis, ctx, 0); - }else if( p->eType==JSON_ARRAY ){ - u32 iKey; - if( p->bRecursive ){ - if( p->iRowid==0 ) break; - assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 ); - iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; + if( p->nParent==0 ){ + u32 n, j; + if( p->nRoot==1 ) break; + j = jsonEachPathLength(p); + n = p->nRoot - j; + if( n==0 ){ + break; + }else if( p->path.zBuf[j]=='[' ){ + i64 x; + sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8); + sqlite3_result_int64(ctx, x); + }else if( p->path.zBuf[j+1]=='"' ){ + sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT); }else{ - iKey = p->iRowid; + sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT); } - sqlite3_result_int64(ctx, (sqlite3_int64)iKey); + break; + } + if( p->eType==JSONB_OBJECT ){ + jsonReturnFromBlob(&p->sParse, p->i, ctx, 1); + }else{ + assert( p->eType==JSONB_ARRAY ); + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey); } break; } case JEACH_VALUE: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(&p->sParse, pThis, ctx, 0); + u32 i = jsonSkipLabel(p); + jsonReturnFromBlob(&p->sParse, i, ctx, 1); + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } break; } case JEACH_TYPE: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); + u32 i = jsonSkipLabel(p); + u8 eType = p->sParse.aBlob[i] & 0x0f; + sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC); break; } case JEACH_ATOM: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(&p->sParse, pThis, ctx, 0); + u32 i = jsonSkipLabel(p); + if( (p->sParse.aBlob[i] & 0x0f)<JSONB_ARRAY ){ + jsonReturnFromBlob(&p->sParse, i, ctx, 1); + } break; } case JEACH_ID: { - sqlite3_result_int64(ctx, - (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); + sqlite3_result_int64(ctx, (sqlite3_int64)p->i); break; } case JEACH_PARENT: { - if( p->i>p->iBegin && p->bRecursive ){ - sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); + if( p->nParent>0 && p->bRecursive ){ + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead); } break; } case JEACH_FULLKEY: { - JsonString x; - jsonInit(&x, ctx); - if( p->bRecursive ){ - jsonEachComputePath(p, &x, p->i); - }else{ - if( p->zRoot ){ - jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); - }else{ - jsonAppendChar(&x, '$'); - } - if( p->eType==JSON_ARRAY ){ - jsonPrintf(30, &x, "[%d]", p->iRowid); - }else if( p->eType==JSON_OBJECT ){ - jsonAppendObjectPathElement(&x, pThis); - } - } - jsonResult(&x); + u64 nBase = p->path.nUsed; + if( p->nParent ) jsonAppendPathName(p); + sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); + p->path.nUsed = nBase; break; } case JEACH_PATH: { - if( p->bRecursive ){ - JsonString x; - jsonInit(&x, ctx); - jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); - jsonResult(&x); - break; - } - /* For json_each() path and root are the same so fall through - ** into the root case */ - /* no break */ deliberate_fall_through + u32 n = jsonEachPathLength(p); + sqlite3_result_text64(ctx, p->path.zBuf, n, + SQLITE_TRANSIENT, SQLITE_UTF8); + break; } default: { - const char *zRoot = p->zRoot; - if( zRoot==0 ) zRoot = "$"; - sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC); break; } case JEACH_JSON: { - assert( i==JEACH_JSON ); - sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); + if( p->sParse.zJson==0 ){ + sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob, + SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT); + } break; } } @@ -206338,86 +211581,97 @@ static int jsonEachFilter( int argc, sqlite3_value **argv ){ JsonEachCursor *p = (JsonEachCursor*)cur; - const char *z; const char *zRoot = 0; - sqlite3_int64 n; + u32 i, n, sz; UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; - z = (const char*)sqlite3_value_text(argv[0]); - if( z==0 ) return SQLITE_OK; memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; - if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){ - p->sParse.zJson = sqlite3RCStrRef((char*)z); - }else{ - n = sqlite3_value_bytes(argv[0]); - p->sParse.zJson = sqlite3RCStrNew( n+1 ); - if( p->sParse.zJson==0 ) return SQLITE_NOMEM; - memcpy(p->sParse.zJson, z, (size_t)n+1); - } - p->sParse.bJsonIsRCStr = 1; - p->zJson = p->sParse.zJson; - if( jsonParse(&p->sParse, 0) ){ - int rc = SQLITE_NOMEM; - if( p->sParse.oom==0 ){ - sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); - if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; + p->sParse.db = p->db; + if( jsonFuncArgMightBeBinary(argv[0]) ){ + p->sParse.nBlob = sqlite3_value_bytes(argv[0]); + p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); + }else{ + p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); + p->sParse.nJson = sqlite3_value_bytes(argv[0]); + if( p->sParse.zJson==0 ){ + p->i = p->iEnd = 0; + return SQLITE_OK; } - jsonEachCursorReset(p); - return rc; - }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ - jsonEachCursorReset(p); - return SQLITE_NOMEM; - }else{ - JsonNode *pNode = 0; - if( idxNum==3 ){ - const char *zErr = 0; - zRoot = (const char*)sqlite3_value_text(argv[1]); - if( zRoot==0 ) return SQLITE_OK; - n = sqlite3_value_bytes(argv[1]); - p->zRoot = sqlite3_malloc64( n+1 ); - if( p->zRoot==0 ) return SQLITE_NOMEM; - memcpy(p->zRoot, zRoot, (size_t)n+1); - if( zRoot[0]!='$' ){ - zErr = zRoot; - }else{ - pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); + if( jsonConvertTextToBlob(&p->sParse, 0) ){ + if( p->sParse.oom ){ + return SQLITE_NOMEM; } - if( zErr ){ + goto json_each_malformed_input; + } + } + if( idxNum==3 ){ + zRoot = (const char*)sqlite3_value_text(argv[1]); + if( zRoot==0 ) return SQLITE_OK; + if( zRoot[0]!='$' ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } + p->nRoot = sqlite3Strlen30(zRoot); + if( zRoot[1]==0 ){ + i = p->i = 0; + p->eType = 0; + }else{ + i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + p->i = 0; + p->eType = 0; + p->iEnd = 0; + return SQLITE_OK; + } sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); jsonEachCursorReset(p); return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; - }else if( pNode==0 ){ - return SQLITE_OK; } - }else{ - pNode = p->sParse.aNode; - } - p->iBegin = p->i = (int)(pNode - p->sParse.aNode); - p->eType = pNode->eType; - if( p->eType>=JSON_ARRAY ){ - assert( pNode->eU==0 ); - VVA( pNode->eU = 3 ); - pNode->u.iKey = 0; - p->iEnd = p->i + pNode->n + 1; - if( p->bRecursive ){ - p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; - if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ - p->i--; - } + if( p->sParse.iLabel ){ + p->i = p->sParse.iLabel; + p->eType = JSONB_OBJECT; }else{ - p->i++; - } - }else{ - p->iEnd = p->i+1; - } + p->i = i; + p->eType = JSONB_ARRAY; + } + } + jsonAppendRaw(&p->path, zRoot, p->nRoot); + }else{ + i = p->i = 0; + p->eType = 0; + p->nRoot = 1; + jsonAppendRaw(&p->path, "$", 1); + } + p->nParent = 0; + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->iEnd = i+n+sz; + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){ + p->i = i + n; + p->eType = p->sParse.aBlob[i] & 0x0f; + p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent)); + if( p->aParent==0 ) return SQLITE_NOMEM; + p->nParent = 1; + p->nParentAlloc = 1; + p->aParent[0].iKey = 0; + p->aParent[0].iEnd = p->iEnd; + p->aParent[0].iHead = p->i; + p->aParent[0].iValue = i; } return SQLITE_OK; + +json_each_malformed_input: + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; } /* The methods of the json_each virtual table */ @@ -206486,40 +211740,56 @@ static sqlite3_module jsonTreeModule = { SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ #ifndef SQLITE_OMIT_JSON static FuncDef aJsonFunc[] = { - /* calls sqlite3_result_subtype() */ - /* | */ - /* Uses cache ______ | __ calls sqlite3_value_subtype() */ - /* | | | */ - /* Num args _________ | | | ___ Flags */ - /* | | | | | */ - /* | | | | | */ - JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc), - JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc), - JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc), - JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc), - JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc), - JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc), - JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc), - JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc), - JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc), - JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc), - JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc), - JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc), - JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc), - JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc), - JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc), - JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc), - JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc), - JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc), -#ifdef SQLITE_DEBUG - JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc), - JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func), + /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */ + /* | | */ + /* Uses cache ------, | | ,---- Returns JSONB */ + /* | | | | */ + /* Number of arguments ---, | | | | ,--- Flags */ + /* | | | | | | */ + JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc), + JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc), + JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc), + JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc), + JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc), + JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc), + JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc), + JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc), + JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc), + JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc), + JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc), + JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc), + JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc), + JFUNCTION(json_pretty, 1,1,0, 0,0,0, jsonPrettyFunc), + JFUNCTION(json_pretty, 2,1,0, 0,0,0, jsonPrettyFunc), + JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc), + JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc), + JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc), + JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc), + JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc), + JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc), +#if SQLITE_DEBUG + JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc), #endif WAGGREGATE(json_group_array, 1, 0, 0, jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), WAGGREGATE(json_group_object, 2, 0, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| SQLITE_DETERMINISTIC) @@ -207247,11 +212517,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ ** Clear the Rtree.pNodeBlob object */ static void nodeBlobReset(Rtree *pRtree){ - if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){ - sqlite3_blob *pBlob = pRtree->pNodeBlob; - pRtree->pNodeBlob = 0; - sqlite3_blob_close(pBlob); - } + sqlite3_blob *pBlob = pRtree->pNodeBlob; + pRtree->pNodeBlob = 0; + sqlite3_blob_close(pBlob); } /* @@ -207270,7 +212538,7 @@ static int nodeAcquire( ** increase its reference count and return it. */ if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ - if( pParent && pParent!=pNode->pParent ){ + if( pParent && ALWAYS(pParent!=pNode->pParent) ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } @@ -207295,7 +212563,6 @@ static int nodeAcquire( &pRtree->pNodeBlob); } if( rc ){ - nodeBlobReset(pRtree); *ppNode = 0; /* If unable to open an sqlite3_blob on the desired row, that can only ** be because the shadow tables hold erroneous data. */ @@ -207355,6 +212622,7 @@ static int nodeAcquire( } *ppNode = pNode; }else{ + nodeBlobReset(pRtree); if( pNode ){ pRtree->nNodeRef--; sqlite3_free(pNode); @@ -207499,6 +212767,7 @@ static void nodeGetCoord( int iCoord, /* Which coordinate to extract */ RtreeCoord *pCoord /* OUT: Space to write result to */ ){ + assert( iCell<NCELL(pNode) ); readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); } @@ -207688,7 +212957,9 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){ sqlite3_finalize(pCsr->pReadAux); sqlite3_free(pCsr); pRtree->nCursor--; - nodeBlobReset(pRtree); + if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){ + nodeBlobReset(pRtree); + } return SQLITE_OK; } @@ -208273,7 +213544,11 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ int rc = SQLITE_OK; RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); if( rc==SQLITE_OK && ALWAYS(p) ){ - *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); + if( p->iCell>=NCELL(pNode) ){ + rc = SQLITE_ABORT; + }else{ + *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); + } } return rc; } @@ -208291,6 +213566,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ if( rc ) return rc; if( NEVER(p==0) ) return SQLITE_OK; + if( p->iCell>=NCELL(pNode) ) return SQLITE_ABORT; if( i==0 ){ sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); }else if( i<=pRtree->nDim2 ){ @@ -208388,6 +213664,8 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ return SQLITE_OK; } +SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); + /* ** Rtree virtual table module xFilter method. */ @@ -208417,7 +213695,8 @@ static int rtreeFilter( i64 iNode = 0; int eType = sqlite3_value_numeric_type(argv[0]); if( eType==SQLITE_INTEGER - || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid) + || (eType==SQLITE_FLOAT + && 0==sqlite3IntFloatCompare(iRowid,sqlite3_value_double(argv[0]))) ){ rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); }else{ @@ -209773,7 +215052,7 @@ static int rtreeUpdate( static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ Rtree *pRtree = (Rtree *)pVtab; assert( pRtree->inWrTrans==0 ); - pRtree->inWrTrans++; + pRtree->inWrTrans = 1; return SQLITE_OK; } @@ -209787,6 +215066,9 @@ static int rtreeEndTransaction(sqlite3_vtab *pVtab){ nodeBlobReset(pRtree); return SQLITE_OK; } +static int rtreeRollback(sqlite3_vtab *pVtab){ + return rtreeEndTransaction(pVtab); +} /* ** The xRename method for rtree module virtual tables. @@ -209905,7 +215187,7 @@ static sqlite3_module rtreeModule = { rtreeBeginTransaction, /* xBegin - begin transaction */ rtreeEndTransaction, /* xSync - sync transaction */ rtreeEndTransaction, /* xCommit - commit transaction */ - rtreeEndTransaction, /* xRollback - rollback transaction */ + rtreeRollback, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ rtreeRename, /* xRename - rename the table */ rtreeSavepoint, /* xSavepoint */ @@ -210005,7 +215287,7 @@ static int rtreeSqlInit( } sqlite3_free(zSql); } - if( pRtree->nAux ){ + if( pRtree->nAux && rc!=SQLITE_NOMEM ){ pRtree->zReadAuxSql = sqlite3_mprintf( "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", zDb, zPrefix); @@ -210316,8 +215598,8 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ sqlite3_str_append(pOut, "}", 1); } errCode = sqlite3_str_errcode(pOut); - sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free); sqlite3_result_error_code(ctx, errCode); + sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free); } /* This routine implements an SQL function that returns the "depth" parameter @@ -210694,15 +215976,13 @@ static int rtreeCheckTable( check.zTab = zTab; /* Find the number of auxiliary columns */ - if( check.rc==SQLITE_OK ){ - pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); - if( pStmt ){ - nAux = sqlite3_column_count(pStmt) - 2; - sqlite3_finalize(pStmt); - }else - if( check.rc!=SQLITE_NOMEM ){ - check.rc = SQLITE_OK; - } + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); + if( pStmt ){ + nAux = sqlite3_column_count(pStmt) - 2; + sqlite3_finalize(pStmt); + }else + if( check.rc!=SQLITE_NOMEM ){ + check.rc = SQLITE_OK; } /* Find number of dimensions in the rtree table. */ @@ -210757,6 +216037,7 @@ static int rtreeIntegrity( if( rc==SQLITE_OK && *pzErr ){ *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", pRtree->zDb, pRtree->zName, *pzErr); + if( (*pzErr)==0 ) rc = SQLITE_NOMEM; } return rc; } @@ -212834,7 +218115,7 @@ SQLITE_API int sqlite3_rtree_query_callback( ); } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif @@ -213325,7 +218606,7 @@ static void icuLoadCollation( UCollator *pUCollator; /* ICU library collation object */ int rc; /* Return code from sqlite3_create_collation_x() */ - assert(nArg==2); + assert(nArg==2 || nArg==3); (void)nArg; /* Unused parameter */ zLocale = (const char *)sqlite3_value_text(apArg[0]); zName = (const char *)sqlite3_value_text(apArg[1]); @@ -213340,7 +218621,39 @@ static void icuLoadCollation( return; } assert(p); - + if(nArg==3){ + const char *zOption = (const char*)sqlite3_value_text(apArg[2]); + static const struct { + const char *zName; + UColAttributeValue val; + } aStrength[] = { + { "PRIMARY", UCOL_PRIMARY }, + { "SECONDARY", UCOL_SECONDARY }, + { "TERTIARY", UCOL_TERTIARY }, + { "DEFAULT", UCOL_DEFAULT_STRENGTH }, + { "QUARTERNARY", UCOL_QUATERNARY }, + { "IDENTICAL", UCOL_IDENTICAL }, + }; + unsigned int i; + for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){ + if( sqlite3_stricmp(zOption,aStrength[i].zName)==0 ){ + ucol_setStrength(pUCollator, aStrength[i].val); + break; + } + } + if( i>=sizeof(aStrength)/sizeof(aStrength[0]) ){ + sqlite3_str *pStr = sqlite3_str_new(sqlite3_context_db_handle(p)); + sqlite3_str_appendf(pStr, + "unknown collation strength \"%s\" - should be one of:", + zOption); + for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){ + sqlite3_str_appendf(pStr, " %s", aStrength[i].zName); + } + sqlite3_result_error(p, sqlite3_str_value(pStr), -1); + sqlite3_free(sqlite3_str_finish(pStr)); + return; + } + } rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, icuCollationColl, icuCollationDel ); @@ -213363,6 +218676,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, + {"icu_load_collation",3,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc}, {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, @@ -213392,7 +218706,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ return rc; } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif @@ -214513,6 +219827,7 @@ typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8; typedef sqlite3_int64 i64; +typedef sqlite3_uint64 u64; #endif /* @@ -214649,6 +219964,27 @@ struct RbuFrame { u32 iWalFrame; }; +#ifndef UNUSED_PARAMETER +/* +** The following macros are used to suppress compiler warnings and to +** make it clear to human readers when a function parameter is deliberately +** left unused within the body of a function. This usually happens when +** a function is called via a function pointer. For example the +** implementation of an SQL aggregate step callback may not use the +** parameter indicating the number of arguments passed to the aggregate, +** if it knows that this is enforced elsewhere. +** +** When a function parameter is not used at all within the body of a function, +** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. +** However, these macros may also be used to suppress warnings related to +** parameters that may or may not be used depending on compilation options. +** For example those parameters only used in assert() statements. In these +** cases the parameters are named as per the usual conventions. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) +#endif + /* ** RBU handle. ** @@ -214700,7 +220036,7 @@ struct sqlite3rbu { int rc; /* Value returned by last rbu_step() call */ char *zErrmsg; /* Error message if rc!=SQLITE_OK */ int nStep; /* Rows processed for current object */ - int nProgress; /* Rows processed for all objects */ + sqlite3_int64 nProgress; /* Rows processed for all objects */ RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ @@ -214817,7 +220153,7 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ v = (v<<6) + c; } z--; - *pLen -= z - zStart; + *pLen -= (int)(z - zStart); *pz = (char*)z; return v; } @@ -215002,6 +220338,7 @@ static void rbuFossilDeltaFunc( char *aOut; assert( argc==2 ); + UNUSED_PARAMETER(argc); nOrig = sqlite3_value_bytes(argv[0]); aOrig = (const char*)sqlite3_value_blob(argv[0]); @@ -215199,6 +220536,7 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ if( rc!=SQLITE_ROW ){ rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); pIter->zTbl = 0; + pIter->zDataTbl = 0; }else{ pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1); @@ -216580,13 +221918,13 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ else if( c==')' ){ nParen--; if( nParen==0 ){ - int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; + int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); pIter->aIdxCol[iIdxCol++].nSpan = nSpan; i++; break; } }else if( c==',' && nParen==1 ){ - int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; + int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); pIter->aIdxCol[iIdxCol++].nSpan = nSpan; pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; }else if( c=='"' || c=='\'' || c=='`' ){ @@ -217276,6 +222614,8 @@ static void rbuFileSuffix3(const char *zBase, char *z){ for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); } +#else + UNUSED_PARAMETER2(zBase,z); #endif } @@ -217293,7 +222633,7 @@ static i64 rbuShmChecksum(sqlite3rbu *p){ u32 volatile *ptr; p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); if( p->rc==SQLITE_OK ){ - iRet = ((i64)ptr[10] << 32) + ptr[11]; + iRet = (i64)(((u64)ptr[10] << 32) + ptr[11]); } } return iRet; @@ -217860,7 +223200,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ "(%d, %Q), " "(%d, %Q), " "(%d, %d), " - "(%d, %d), " + "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " @@ -218218,6 +223558,7 @@ static void rbuIndexCntFunc( sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); assert( nVal==1 ); + UNUSED_PARAMETER(nVal); rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, sqlite3_mprintf("SELECT count(*) FROM sqlite_schema " @@ -218493,7 +223834,7 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( ){ if( zTarget==0 ){ return rbuMisuseError(); } if( zState ){ - int n = strlen(zState); + size_t n = strlen(zState); if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){ return rbuMisuseError(); } @@ -218710,6 +224051,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){ */ static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ int rc = SQLITE_OK; + UNUSED_PARAMETER(pArg); #if defined(_WIN32_WCE) { LPWSTR zWideOld; @@ -219614,6 +224956,9 @@ static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ ** No-op. */ static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(a); + UNUSED_PARAMETER(b); return 0; } @@ -220012,6 +225357,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ pIdxInfo->orderByConsumed = 1; pIdxInfo->idxNum |= 0x08; } + pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX; return SQLITE_OK; } @@ -220669,7 +226015,13 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; } ** ** The data field of sqlite_dbpage table can be updated. The new ** value must be a BLOB which is the correct page size, otherwise the -** update fails. Rows may not be deleted or inserted. +** update fails. INSERT operations also work, and operate as if they +** where REPLACE. The size of the database can be extended by INSERT-ing +** new pages on the end. +** +** Rows may not be deleted. However, doing an INSERT to page number N +** with NULL page data causes the N-th page and all subsequent pages to be +** deleted and the database to be truncated. */ /* #include "sqliteInt.h" ** Requires access to internal data structures ** */ @@ -220692,6 +226044,8 @@ struct DbpageCursor { struct DbpageTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database */ + int iDbTrunc; /* Database to truncate */ + Pgno pgnoTrunc; /* Size to truncate to */ }; /* Columns */ @@ -220700,7 +226054,6 @@ struct DbpageTable { #define DBPAGE_COLUMN_SCHEMA 2 - /* ** Connect to or create a dbpagevfs virtual table. */ @@ -220951,6 +226304,24 @@ static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ return SQLITE_OK; } +/* +** Open write transactions. Since we do not know in advance which database +** files will be written by the sqlite_dbpage virtual table, start a write +** transaction on them all. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int dbpageBeginTrans(DbpageTable *pTab){ + sqlite3 *db = pTab->db; + int rc = SQLITE_OK; + int i; + for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ) rc = sqlite3BtreeBeginTrans(pBt, 1, 0); + } + return rc; +} + static int dbpageUpdate( sqlite3_vtab *pVtab, int argc, @@ -220962,11 +226333,11 @@ static int dbpageUpdate( DbPage *pDbPage = 0; int rc = SQLITE_OK; char *zErr = 0; - const char *zSchema; int iDb; Btree *pBt; Pager *pPager; int szPage; + int isInsert; (void)pRowid; if( pTab->db->flags & SQLITE_Defensive ){ @@ -220977,21 +226348,29 @@ static int dbpageUpdate( zErr = "cannot delete"; goto update_fail; } - pgno = sqlite3_value_int(argv[0]); - if( sqlite3_value_type(argv[0])==SQLITE_NULL - || (Pgno)sqlite3_value_int(argv[1])!=pgno - ){ - zErr = "cannot insert"; - goto update_fail; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + pgno = (Pgno)sqlite3_value_int(argv[2]); + isInsert = 1; + }else{ + pgno = sqlite3_value_int(argv[0]); + if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ + zErr = "cannot insert"; + goto update_fail; + } + isInsert = 0; } - zSchema = (const char*)sqlite3_value_text(argv[4]); - iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1; - if( NEVER(iDb<0) ){ - zErr = "no such schema"; - goto update_fail; + if( sqlite3_value_type(argv[4])==SQLITE_NULL ){ + iDb = 0; + }else{ + const char *zSchema = (const char*)sqlite3_value_text(argv[4]); + iDb = sqlite3FindDbName(pTab->db, zSchema); + if( iDb<0 ){ + zErr = "no such schema"; + goto update_fail; + } } pBt = pTab->db->aDb[iDb].pBt; - if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){ + if( pgno<1 || NEVER(pBt==0) ){ zErr = "bad page number"; goto update_fail; } @@ -220999,19 +226378,34 @@ static int dbpageUpdate( if( sqlite3_value_type(argv[3])!=SQLITE_BLOB || sqlite3_value_bytes(argv[3])!=szPage ){ - zErr = "bad page value"; + if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){ + /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and + ** all subsequent pages to be deleted. */ + pTab->iDbTrunc = iDb; + pgno--; + pTab->pgnoTrunc = pgno; + }else{ + zErr = "bad page value"; + goto update_fail; + } + } + + if( dbpageBeginTrans(pTab)!=SQLITE_OK ){ + zErr = "failed to open transaction"; goto update_fail; } + pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ const void *pData = sqlite3_value_blob(argv[3]); - assert( pData!=0 || pTab->db->mallocFailed ); - if( pData - && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK - ){ - memcpy(sqlite3PagerGetData(pDbPage), pData, szPage); + if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){ + unsigned char *aPage = sqlite3PagerGetData(pDbPage); + memcpy(aPage, pData, szPage); + pTab->pgnoTrunc = 0; } + }else{ + pTab->pgnoTrunc = 0; } sqlite3PagerUnref(pDbPage); return rc; @@ -221022,28 +226416,44 @@ static int dbpageUpdate( return SQLITE_ERROR; } -/* Since we do not know in advance which database files will be -** written by the sqlite_dbpage virtual table, start a write transaction -** on them all. -*/ static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; - sqlite3 *db = pTab->db; - int i; - for(i=0; i<db->nDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); + pTab->pgnoTrunc = 0; + return SQLITE_OK; +} + +/* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT +*/ +static int dbpageSync(sqlite3_vtab *pVtab){ + DbpageTable *pTab = (DbpageTable *)pVtab; + if( pTab->pgnoTrunc>0 ){ + Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt; + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3BtreeEnter(pBt); + if( pTab->pgnoTrunc<sqlite3BtreeLastPage(pBt) ){ + sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); + } + sqlite3BtreeLeave(pBt); } + pTab->pgnoTrunc = 0; return SQLITE_OK; } +/* Cancel any pending truncate. +*/ +static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){ + DbpageTable *pTab = (DbpageTable *)pVtab; + pTab->pgnoTrunc = 0; + (void)notUsed1; + return SQLITE_OK; +} /* ** Invoke this routine to register the "dbpage" virtual table module */ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ static sqlite3_module dbpage_module = { - 0, /* iVersion */ + 2, /* iVersion */ dbpageConnect, /* xCreate */ dbpageConnect, /* xConnect */ dbpageBestIndex, /* xBestIndex */ @@ -221058,14 +226468,14 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ dbpageRowid, /* xRowid - read data */ dbpageUpdate, /* xUpdate */ dbpageBegin, /* xBegin */ - 0, /* xSync */ + dbpageSync, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ - 0, /* xRollbackTo */ + dbpageRollbackTo, /* xRollbackTo */ 0, /* xShadowName */ 0 /* xIntegrity */ }; @@ -221153,6 +226563,10 @@ struct SessionBuffer { ** input data. Input data may be supplied either as a single large buffer ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. ** sqlite3changeset_start_strm()). +** +** bNoDiscard: +** If true, then the only time data is discarded is as a result of explicit +** sessionDiscardData() calls. Not within every sessionInputBuffer() call. */ struct SessionInput { int bNoDiscard; /* If true, do not discard in InputBuffer() */ @@ -222836,16 +228250,19 @@ static void sessionPreupdateOneChange( for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ - TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); - assert( trc==SQLITE_OK ); + /* This may fail if the column has a non-NULL default and was added + ** using ALTER TABLE ADD COLUMN after this record was created. */ + rc = pSession->hook.xOld(pSession->hook.pCtx, i, &p); }else if( pTab->abPK[i] ){ TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p); assert( trc==SQLITE_OK ); } - /* This may fail if SQLite value p contains a utf-16 string that must - ** be converted to utf-8 and an OOM error occurs while doing so. */ - rc = sessionSerializeValue(0, p, &nByte); + if( rc==SQLITE_OK ){ + /* This may fail if SQLite value p contains a utf-16 string that must + ** be converted to utf-8 and an OOM error occurs while doing so. */ + rc = sessionSerializeValue(0, p, &nByte); + } if( rc!=SQLITE_OK ) goto error_out; } if( pTab->bRowid ){ @@ -223427,9 +228844,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ ** associated hash-tables. */ sessionDeleteTable(pSession, pSession->pTable); - /* Assert that all allocations have been freed and then free the - ** session object itself. */ - // assert( pSession->nMalloc==0 ); + /* Free the session object. */ sqlite3_free(pSession); } @@ -224766,14 +230181,14 @@ static int sessionChangesetNextOne( p->rc = sessionInputBuffer(&p->in, 2); if( p->rc!=SQLITE_OK ) return p->rc; + sessionDiscardData(&p->in); + p->in.iCurrent = p->in.iNext; + /* If the iterator is already at the end of the changeset, return DONE. */ if( p->in.iNext>=p->in.nData ){ return SQLITE_DONE; } - sessionDiscardData(&p->in); - p->in.iCurrent = p->in.iNext; - op = p->in.aData[p->in.iNext++]; while( op=='T' || op=='P' ){ if( pbNew ) *pbNew = 1; @@ -226205,15 +231620,21 @@ static int sessionChangesetApply( int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ int bPatchset; + u64 savedFlag = db->flags & SQLITE_FkNoAction; assert( xConflict!=0 ); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ + db->flags |= ((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } + pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); - sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); } @@ -226351,12 +231772,12 @@ static int sessionChangesetApply( } } } - sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); - }else{ + } + if( rc!=SQLITE_OK ){ sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); } @@ -226375,6 +231796,12 @@ static int sessionChangesetApply( sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); sqlite3_free((char*)sApply.rebase.aBuf); + + if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ + assert( db->flags & SQLITE_FkNoAction ); + db->flags &= ~((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } @@ -226403,12 +231830,6 @@ SQLITE_API int sqlite3changeset_apply_v2( sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); - u64 savedFlag = db->flags & SQLITE_FkNoAction; - - if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ - db->flags |= ((u64)SQLITE_FkNoAction); - db->aDb[0].pSchema->schema_cookie -= 32; - } if( rc==SQLITE_OK ){ rc = sessionChangesetApply( @@ -226416,11 +231837,6 @@ SQLITE_API int sqlite3changeset_apply_v2( ); } - if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ - assert( db->flags & SQLITE_FkNoAction ); - db->flags &= ~((u64)SQLITE_FkNoAction); - db->aDb[0].pSchema->schema_cookie -= 32; - } return rc; } @@ -226508,6 +231924,7 @@ struct sqlite3_changegroup { int rc; /* Error code */ int bPatch; /* True to accumulate patchsets */ SessionTable *pList; /* List of tables in current patch */ + SessionBuffer rec; sqlite3 *db; /* Configured by changegroup_schema() */ char *zDb; /* Configured by changegroup_schema() */ @@ -226740,6 +232157,9 @@ static int sessionChangesetExtendRecord( sessionAppendBlob(pOut, aRec, nRec, &rc); if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); + if( rc==SQLITE_OK && SQLITE_ROW!=sqlite3_step(pTab->pDfltStmt) ){ + rc = sqlite3_errcode(pGrp->db); + } } for(ii=nCol; rc==SQLITE_OK && ii<pTab->nCol; ii++){ int eType = sqlite3_column_type(pTab->pDfltStmt, ii); @@ -226756,6 +232176,7 @@ static int sessionChangesetExtendRecord( } if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); + pOut->nBuf += 8; } break; } @@ -226806,108 +232227,130 @@ static int sessionChangesetExtendRecord( } /* -** Add all changes in the changeset traversed by the iterator passed as -** the first argument to the changegroup hash tables. +** Locate or create a SessionTable object that may be used to add the +** change currently pointed to by iterator pIter to changegroup pGrp. +** If successful, set output variable (*ppTab) to point to the table +** object and return SQLITE_OK. Otherwise, if some error occurs, return +** an SQLite error code and leave (*ppTab) set to NULL. */ -static int sessionChangesetToHash( - sqlite3_changeset_iter *pIter, /* Iterator to read from */ - sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ - int bRebase /* True if hash table is for rebasing */ +static int sessionChangesetFindTable( + sqlite3_changegroup *pGrp, + const char *zTab, + sqlite3_changeset_iter *pIter, + SessionTable **ppTab ){ - u8 *aRec; - int nRec; int rc = SQLITE_OK; SessionTable *pTab = 0; - SessionBuffer rec = {0, 0, 0}; - - while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ - const char *zNew; - int nCol; - int op; - int iHash; - int bIndirect; - SessionChange *pChange; - SessionChange *pExist = 0; - SessionChange **pp; - - /* Ensure that only changesets, or only patchsets, but not a mixture - ** of both, are being combined. It is an error to try to combine a - ** changeset and a patchset. */ - if( pGrp->pList==0 ){ - pGrp->bPatch = pIter->bPatchset; - }else if( pIter->bPatchset!=pGrp->bPatch ){ - rc = SQLITE_ERROR; - break; - } + int nTab = (int)strlen(zTab); + u8 *abPK = 0; + int nCol = 0; - sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); - if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){ - /* Search the list for a matching table */ - int nNew = (int)strlen(zNew); - u8 *abPK; + *ppTab = 0; + sqlite3changeset_pk(pIter, &abPK, &nCol); - sqlite3changeset_pk(pIter, &abPK, 0); - for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ - if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; - } - if( !pTab ){ - SessionTable **ppTab; + /* Search the list for an existing table */ + for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_strnicmp(pTab->zName, zTab, nTab+1) ) break; + } - pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1); - if( !pTab ){ - rc = SQLITE_NOMEM; - break; - } - memset(pTab, 0, sizeof(SessionTable)); - pTab->nCol = nCol; - pTab->abPK = (u8*)&pTab[1]; - memcpy(pTab->abPK, abPK, nCol); - pTab->zName = (char*)&pTab->abPK[nCol]; - memcpy(pTab->zName, zNew, nNew+1); - - if( pGrp->db ){ - pTab->nCol = 0; - rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); - if( rc ){ - assert( pTab->azCol==0 ); - sqlite3_free(pTab); - break; - } - } + /* If one was not found above, create a new table now */ + if( !pTab ){ + SessionTable **ppNew; - /* The new object must be linked on to the end of the list, not - ** simply added to the start of it. This is to ensure that the - ** tables within the output of sqlite3changegroup_output() are in - ** the right order. */ - for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); - *ppTab = pTab; - } + pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nTab+1); + if( !pTab ){ + return SQLITE_NOMEM; + } + memset(pTab, 0, sizeof(SessionTable)); + pTab->nCol = nCol; + pTab->abPK = (u8*)&pTab[1]; + memcpy(pTab->abPK, abPK, nCol); + pTab->zName = (char*)&pTab->abPK[nCol]; + memcpy(pTab->zName, zTab, nTab+1); - if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ - rc = SQLITE_SCHEMA; - break; + if( pGrp->db ){ + pTab->nCol = 0; + rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); + if( rc ){ + assert( pTab->azCol==0 ); + sqlite3_free(pTab); + return rc; } } - if( nCol<pTab->nCol ){ - assert( pGrp->db ); - rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec); - if( rc ) break; - aRec = rec.aBuf; - nRec = rec.nBuf; - } + /* The new object must be linked on to the end of the list, not + ** simply added to the start of it. This is to ensure that the + ** tables within the output of sqlite3changegroup_output() are in + ** the right order. */ + for(ppNew=&pGrp->pList; *ppNew; ppNew=&(*ppNew)->pNext); + *ppNew = pTab; + } - if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ - rc = SQLITE_NOMEM; - break; - } + /* Check that the table is compatible. */ + if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ + rc = SQLITE_SCHEMA; + } + + *ppTab = pTab; + return rc; +} + +/* +** Add the change currently indicated by iterator pIter to the hash table +** belonging to changegroup pGrp. +*/ +static int sessionOneChangeToHash( + sqlite3_changegroup *pGrp, + sqlite3_changeset_iter *pIter, + int bRebase +){ + int rc = SQLITE_OK; + int nCol = 0; + int op = 0; + int iHash = 0; + int bIndirect = 0; + SessionChange *pChange = 0; + SessionChange *pExist = 0; + SessionChange **pp = 0; + SessionTable *pTab = 0; + u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; + int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; + + assert( nRec>0 ); + + /* Ensure that only changesets, or only patchsets, but not a mixture + ** of both, are being combined. It is an error to try to combine a + ** changeset and a patchset. */ + if( pGrp->pList==0 ){ + pGrp->bPatch = pIter->bPatchset; + }else if( pIter->bPatchset!=pGrp->bPatch ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_OK ){ + const char *zTab = 0; + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); + rc = sessionChangesetFindTable(pGrp, zTab, pIter, &pTab); + } + + if( rc==SQLITE_OK && nCol<pTab->nCol ){ + SessionBuffer *pBuf = &pGrp->rec; + rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, pBuf); + aRec = pBuf->aBuf; + nRec = pBuf->nBuf; + assert( pGrp->db ); + } + + if( rc==SQLITE_OK && sessionGrowHash(0, pIter->bPatchset, pTab) ){ + rc = SQLITE_NOMEM; + } + + if( rc==SQLITE_OK ){ + /* Search for existing entry. If found, remove it from the hash table. + ** Code below may link it back in. */ iHash = sessionChangeHash( pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange ); - - /* Search for existing entry. If found, remove it from the hash table. - ** Code below may link it back in. - */ for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ int bPkOnly1 = 0; int bPkOnly2 = 0; @@ -226922,19 +232365,42 @@ static int sessionChangesetToHash( break; } } + } + if( rc==SQLITE_OK ){ rc = sessionChangeMerge(pTab, bRebase, pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange ); - if( rc ) break; - if( pChange ){ - pChange->pNext = pTab->apChange[iHash]; - pTab->apChange[iHash] = pChange; - pTab->nEntry++; - } + } + if( rc==SQLITE_OK && pChange ){ + pChange->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pChange; + pTab->nEntry++; + } + + if( rc==SQLITE_OK ) rc = pIter->rc; + return rc; +} + +/* +** Add all changes in the changeset traversed by the iterator passed as +** the first argument to the changegroup hash tables. +*/ +static int sessionChangesetToHash( + sqlite3_changeset_iter *pIter, /* Iterator to read from */ + sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ + int bRebase /* True if hash table is for rebasing */ +){ + u8 *aRec; + int nRec; + int rc = SQLITE_OK; + + pIter->in.bNoDiscard = 1; + while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ + rc = sessionOneChangeToHash(pGrp, pIter, bRebase); + if( rc!=SQLITE_OK ) break; } - sqlite3_free(rec.aBuf); if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } @@ -227062,6 +232528,23 @@ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void return rc; } +/* +** Add a single change to a changeset-group. +*/ +SQLITE_API int sqlite3changegroup_add_change( + sqlite3_changegroup *pGrp, + sqlite3_changeset_iter *pIter +){ + if( pIter->in.iCurrent==pIter->in.iNext + || pIter->rc!=SQLITE_OK + || pIter->bInvert + ){ + /* Iterator does not point to any valid entry or is an INVERT iterator. */ + return SQLITE_ERROR; + } + return sessionOneChangeToHash(pGrp, pIter, 0); +} + /* ** Obtain a buffer containing a changeset representing the concatenation ** of all changesets added to the group so far. @@ -227111,6 +232594,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ sqlite3_free(pGrp->zDb); sessionDeleteTable(0, pGrp->pList); + sqlite3_free(pGrp->rec.aBuf); sqlite3_free(pGrp); } } @@ -227512,6 +232996,7 @@ SQLITE_API int sqlite3rebaser_rebase_strm( SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ if( p ){ sessionDeleteTable(0, p->grp.pList); + sqlite3_free(p->grp.rec.aBuf); sqlite3_free(p); } } @@ -227542,7 +233027,27 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ /************** End of sqlite3session.c **************************************/ /************** Begin file fts5.c ********************************************/ - +/* +** This, the "fts5.c" source file, is a composite file that is itself +** assembled from the following files: +** +** fts5.h +** fts5Int.h +** fts5parse.h <--- Generated from fts5parse.y by Lemon +** fts5parse.c <--- Generated from fts5parse.y by Lemon +** fts5_aux.c +** fts5_buffer.c +** fts5_config.c +** fts5_expr.c +** fts5_hash.c +** fts5_index.c +** fts5_main.c +** fts5_storage.c +** fts5_tokenize.c +** fts5_unicode2.c +** fts5_varint.c +** fts5_vocab.c +*/ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) @@ -227552,6 +233057,12 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ # undef NDEBUG #endif +#ifdef HAVE_STDINT_H +/* #include <stdint.h> */ +#endif +#ifdef HAVE_INTTYPES_H +/* #include <inttypes.h> */ +#endif /* ** 2014 May 31 ** @@ -227609,8 +233120,8 @@ struct Fts5PhraseIter { ** EXTENSION API FUNCTIONS ** ** xUserData(pFts): -** Return a copy of the context pointer the extension function was -** registered with. +** Return a copy of the pUserData pointer passed to the xCreateFunction() +** API when the extension function was registered. ** ** xColumnTotalSize(pFts, iCol, pnToken): ** If parameter iCol is less than zero, set output variable *pnToken @@ -227642,8 +233153,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -227653,8 +233167,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -227670,12 +233186,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -227701,6 +233218,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -227782,6 +233303,10 @@ struct Fts5PhraseIter { ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** +** In all cases, matches are visited in (column ASC, offset ASC) order. +** i.e. all those in column 0, sorted by offset, followed by those in +** column 1, etc. +** ** xPhraseNext() ** See xPhraseFirst above. ** @@ -227815,9 +233340,80 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. +** +** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the locale associated +** with column iCol of the current row. Usually, there is no associated +** locale, and output parameters (*pzLocale) and (*pnLocale) are set +** to NULL and 0, respectively. However, if the fts5_locale() function +** was used to associate a locale with the value when it was inserted +** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated +** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) +** is set to the size in bytes of the buffer, not including the +** nul-terminator. +** +** If successful, SQLITE_OK is returned. Or, if an error occurs, an +** SQLite error code is returned. The final value of the output parameters +** is undefined in this case. +** +** xTokenize_v2: +** Tokenize text using the tokenizer belonging to the FTS5 table. This +** API is the same as the xTokenize() API, except that it allows a tokenizer +** locale to be specified. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 4 */ void *(*xUserData)(Fts5Context*); @@ -227852,6 +233448,22 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); + + /* Below this point are iVersion>=4 only */ + int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xTokenize_v2)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); }; /* @@ -227872,7 +233484,7 @@ struct Fts5ExtensionApi { ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) -** pointer provided by the application when the fts5_tokenizer object +** pointer provided by the application when the fts5_tokenizer_v2 object ** was registered with FTS5 (the third argument to xCreateTokenizer()). ** The second and third arguments are an array of nul-terminated strings ** containing the tokenizer arguments, if any, specified following the @@ -227896,7 +233508,7 @@ struct Fts5ExtensionApi { ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** -** The second argument indicates the reason that FTS5 is requesting +** The third argument indicates the reason that FTS5 is requesting ** tokenization of the supplied text. This is always one of the following ** four values: ** @@ -227920,6 +233532,13 @@ struct Fts5ExtensionApi { ** on a columnsize=0 database. ** </ul> ** +** The sixth and seventh arguments passed to xTokenize() - pLocale and +** nLocale - are a pointer to a buffer containing the locale to use for +** tokenization (e.g. "en_US") and its size in bytes, respectively. The +** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in +** which case nLocale is always 0) to indicate that the tokenizer should +** use its default locale. +** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth @@ -227943,6 +233562,30 @@ struct Fts5ExtensionApi { ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** +** If the tokenizer is registered using an fts5_tokenizer_v2 object, +** then the xTokenize() method has two additional arguments - pLocale +** and nLocale. These specify the locale that the tokenizer should use +** for the current request. If pLocale and nLocale are both 0, then the +** tokenizer should use its default locale. Otherwise, pLocale points to +** an nLocale byte buffer containing the name of the locale to use as utf-8 +** text. pLocale is not nul-terminated. +** +** FTS5_TOKENIZER +** +** There is also an fts5_tokenizer object. This is an older, deprecated, +** version of fts5_tokenizer_v2. It is similar except that: +** +** <ul> +** <li> There is no "iVersion" field, and +** <li> The xTokenize() method does not take a locale argument. +** </ul> +** +** Legacy fts5_tokenizer tokenizers must be registered using the +** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). +** +** Tokenizer implementations registered using either API may be retrieved +** using both xFindTokenizer() and xFindTokenizer_v2(). +** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a @@ -228051,6 +233694,33 @@ struct Fts5ExtensionApi { ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; +struct fts5_tokenizer_v2 { + int iVersion; /* Currently always 2 */ + + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* +** New code should use the fts5_tokenizer_v2 type to define tokenizer +** implementations. The following type is included for legacy applications +** that still use it. +*/ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); @@ -228070,6 +233740,7 @@ struct fts5_tokenizer { ); }; + /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 @@ -228089,7 +233760,7 @@ struct fts5_tokenizer { */ typedef struct fts5_api fts5_api; struct fts5_api { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( @@ -228116,6 +233787,25 @@ struct fts5_api { fts5_extension_function xFunction, void (*xDestroy)(void*) ); + + /* APIs below this point are only available if iVersion>=3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer_v2 *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer + ); }; /* @@ -228189,6 +233879,22 @@ typedef sqlite3_uint64 u64; # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) +/* The uptr type is an unsigned integer large enough to hold a pointer +*/ +#if defined(HAVE_STDINT_H) + typedef uintptr_t uptr; +#elif SQLITE_PTRSIZE==4 + typedef u32 uptr; +#else + typedef u64 uptr; +#endif + +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) +#else +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) +#endif + #endif /* Truncate very long tokens to this many bytes. Hard limit is @@ -228272,6 +233978,18 @@ struct Fts5Colset { */ typedef struct Fts5Config Fts5Config; +typedef struct Fts5TokenizerConfig Fts5TokenizerConfig; + +struct Fts5TokenizerConfig { + Fts5Tokenizer *pTok; + fts5_tokenizer_v2 *pApi2; + fts5_tokenizer *pApi1; + const char **azArg; + int nArg; + int ePattern; /* FTS_PATTERN_XXX constant */ + const char *pLocale; /* Current locale to use */ + int nLocale; /* Size of pLocale in bytes */ +}; /* ** An instance of the following structure encodes all information that can @@ -228311,9 +234029,12 @@ typedef struct Fts5Config Fts5Config; ** ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex); ** +** bLocale: +** Set to true if locale=1 was specified when the table was created. */ struct Fts5Config { sqlite3 *db; /* Database handle */ + Fts5Global *pGlobal; /* Global fts5 object for handle db */ char *zDb; /* Database holding FTS index (e.g. "main") */ char *zName; /* Name of FTS index */ int nCol; /* Number of columns */ @@ -228323,15 +234044,17 @@ struct Fts5Config { int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ int eContent; /* An FTS5_CONTENT value */ int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ + int bContentlessUnindexed; /* "contentless_unindexed=" option (dflt=0) */ char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ + int bTokendata; /* "tokendata=" option value (dflt==0) */ + int bLocale; /* "locale=" option value (dflt==0) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; - Fts5Tokenizer *pTok; - fts5_tokenizer *pTokApi; + Fts5TokenizerConfig t; int bLock; /* True when table is preparing statement */ - int ePattern; /* FTS_PATTERN_XXX constant */ + /* Values loaded from the %_config table */ int iVersion; /* fts5 file format 'version' */ @@ -228344,7 +234067,8 @@ struct Fts5Config { char *zRank; /* Name of rank function */ char *zRankArgs; /* Arguments to rank function */ int bSecureDelete; /* 'secure-delete' */ - int nDeleteMerge; /* 'deletemerge' */ + int nDeleteMerge; /* 'deletemerge' */ + int bPrefixInsttoken; /* 'prefix-insttoken' */ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ char **pzErrmsg; @@ -228360,9 +234084,10 @@ struct Fts5Config { #define FTS5_CURRENT_VERSION 4 #define FTS5_CURRENT_VERSION_SECUREDELETE 5 -#define FTS5_CONTENT_NORMAL 0 -#define FTS5_CONTENT_NONE 1 -#define FTS5_CONTENT_EXTERNAL 2 +#define FTS5_CONTENT_NORMAL 0 +#define FTS5_CONTENT_NONE 1 +#define FTS5_CONTENT_EXTERNAL 2 +#define FTS5_CONTENT_UNINDEXED 3 #define FTS5_DETAIL_FULL 0 #define FTS5_DETAIL_NONE 1 @@ -228397,6 +234122,8 @@ static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, i static int sqlite3Fts5ConfigParseRank(const char*, char**, char**); +static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...); + /* ** End of interface to code in fts5_config.c. **************************************************************************/ @@ -228441,7 +234168,7 @@ static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); static void sqlite3Fts5Put32(u8*, int); static int sqlite3Fts5Get32(const u8*); -#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32) +#define FTS5_POS2COLUMN(iPos) (int)((iPos >> 32) & 0x7FFFFFFF) #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF) typedef struct Fts5PoslistReader Fts5PoslistReader; @@ -228514,17 +234241,19 @@ struct Fts5IndexIter { /* ** Values used as part of the flags argument passed to IndexQuery(). */ -#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ -#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ -#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ -#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ +#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ +#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ +#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ +#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ /* The following are used internally by the fts5_index.c module. They are ** defined here only to make it easier to avoid clashes with the flags ** above. */ -#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 -#define FTS5INDEX_QUERY_NOOUTPUT 0x0020 -#define FTS5INDEX_QUERY_SKIPHASH 0x0040 +#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 +#define FTS5INDEX_QUERY_NOOUTPUT 0x0020 +#define FTS5INDEX_QUERY_SKIPHASH 0x0040 +#define FTS5INDEX_QUERY_NOTOKENDATA 0x0080 +#define FTS5INDEX_QUERY_SCANONETERM 0x0100 /* ** Create/destroy an Fts5Index object. @@ -228593,6 +234322,17 @@ static void *sqlite3Fts5StructureRef(Fts5Index*); static void sqlite3Fts5StructureRelease(void*); static int sqlite3Fts5StructureTest(Fts5Index*, void*); +/* +** Used by xInstToken(): +*/ +static int sqlite3Fts5IterToken( + Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, + i64 iRowid, + int iCol, + int iOff, + const char **ppOut, int *pnOut +); /* ** Insert or remove data to or from the index. Each time a document is @@ -228670,6 +234410,13 @@ static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin); static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid); +static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter*); + +/* Used to populate hash tables for xInstToken in detail=none/column mode. */ +static int sqlite3Fts5IndexIterWriteTokendata( + Fts5IndexIter*, const char*, int, i64 iRowid, int iCol, int iOff +); + /* ** End of interface to code in fts5_index.c. **************************************************************************/ @@ -228713,18 +234460,20 @@ struct Fts5Table { Fts5Index *pIndex; /* Full-text index */ }; -static int sqlite3Fts5GetTokenizer( - Fts5Global*, - const char **azArg, - int nArg, - Fts5Config*, - char **pzErr -); +static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig); static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); static int sqlite3Fts5FlushToDisk(Fts5Table*); +static void sqlite3Fts5ClearLocale(Fts5Config *pConfig); +static void sqlite3Fts5SetLocale(Fts5Config *pConfig, const char *pLoc, int nLoc); + +static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal); +static int sqlite3Fts5DecodeLocaleValue(sqlite3_value *pVal, + const char **ppText, int *pnText, const char **ppLoc, int *pnLoc +); + /* ** End of interface to code in fts5.c. **************************************************************************/ @@ -228775,6 +234524,7 @@ static void sqlite3Fts5HashScanNext(Fts5Hash*); static int sqlite3Fts5HashScanEof(Fts5Hash*); static void sqlite3Fts5HashScanEntry(Fts5Hash *, const char **pzTerm, /* OUT: term (nul-terminated) */ + int *pnTerm, /* OUT: Size of term in bytes */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ); @@ -228803,8 +234553,8 @@ static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName); static int sqlite3Fts5DropAll(Fts5Config*); static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); -static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**); -static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); +static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**, int); +static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, int, sqlite3_value**, i64*); static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg); @@ -228829,6 +234579,9 @@ static int sqlite3Fts5StorageOptimize(Fts5Storage *p); static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); static int sqlite3Fts5StorageReset(Fts5Storage *p); +static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage*); +static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel); + /* ** End of interface to code in fts5_storage.c. **************************************************************************/ @@ -228901,6 +234654,10 @@ static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**); static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *); +static int sqlite3Fts5ExprQueryToken(Fts5Expr*, int, int, const char**, int*); +static int sqlite3Fts5ExprInstToken(Fts5Expr*, i64, int, int, int, int, const char**, int*); +static void sqlite3Fts5ExprClearTokens(Fts5Expr*); + /******************************************* ** The fts5_expr.c API above this point is used by the other hand-written ** C code in this module. The interfaces below this point are called by @@ -228977,6 +234734,7 @@ static int sqlite3Fts5TokenizerPattern( int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), Fts5Tokenizer *pTok ); +static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig*); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ @@ -229137,6 +234895,9 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); ** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser ** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser ** sqlite3Fts5ParserCTX_* As sqlite3Fts5ParserARG_ except for %extra_context +** fts5YYREALLOC Name of the realloc() function to use +** fts5YYFREE Name of the free() function to use +** fts5YYDYNSTACK True if stack space should be extended on heap ** fts5YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. ** fts5YYNSTATE the combined number of states. @@ -229150,6 +234911,8 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); ** fts5YY_NO_ACTION The fts5yy_action[] code for no-op ** fts5YY_MIN_REDUCE Minimum value for reduce actions ** fts5YY_MAX_REDUCE Maximum value for reduce actions +** fts5YY_MIN_DSTRCTR Minimum symbol value that has a destructor +** fts5YY_MAX_DSTRCTR Maximum symbol value that has a destructor */ #ifndef INTERFACE # define INTERFACE 1 @@ -229176,6 +234939,9 @@ typedef union { #define sqlite3Fts5ParserARG_PARAM ,pParse #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; +#define fts5YYREALLOC realloc +#define fts5YYFREE free +#define fts5YYDYNSTACK 0 #define sqlite3Fts5ParserCTX_SDECL #define sqlite3Fts5ParserCTX_PDECL #define sqlite3Fts5ParserCTX_PARAM @@ -229193,6 +234959,8 @@ typedef union { #define fts5YY_NO_ACTION 82 #define fts5YY_MIN_REDUCE 83 #define fts5YY_MAX_REDUCE 110 +#define fts5YY_MIN_DSTRCTR 16 +#define fts5YY_MAX_DSTRCTR 24 /************* End control #defines *******************************************/ #define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0]))) @@ -229208,6 +234976,22 @@ typedef union { # define fts5yytestcase(X) #endif +/* Macro to determine if stack space has the ability to grow using +** heap memory. +*/ +#if fts5YYSTACKDEPTH<=0 || fts5YYDYNSTACK +# define fts5YYGROWABLESTACK 1 +#else +# define fts5YYGROWABLESTACK 0 +#endif + +/* Guarantee a minimum number of initial stack slots. +*/ +#if fts5YYSTACKDEPTH<=0 +# undef fts5YYSTACKDEPTH +# define fts5YYSTACKDEPTH 2 /* Need a minimum stack size */ +#endif + /* Next are the tables used to determine what action to take based on the ** current state and lookahead token. These tables are used to implement @@ -229368,14 +235152,9 @@ struct fts5yyParser { #endif sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */ sqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */ -#if fts5YYSTACKDEPTH<=0 - int fts5yystksz; /* Current side of the stack */ - fts5yyStackEntry *fts5yystack; /* The parser's stack */ - fts5yyStackEntry fts5yystk0; /* First stack entry */ -#else - fts5yyStackEntry fts5yystack[fts5YYSTACKDEPTH]; /* The parser's stack */ - fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */ -#endif + fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */ + fts5yyStackEntry *fts5yystack; /* The parser stack */ + fts5yyStackEntry fts5yystk0[fts5YYSTACKDEPTH]; /* Initial stack space */ }; typedef struct fts5yyParser fts5yyParser; @@ -229482,37 +235261,45 @@ static const char *const fts5yyRuleName[] = { #endif /* NDEBUG */ -#if fts5YYSTACKDEPTH<=0 +#if fts5YYGROWABLESTACK /* ** Try to increase the size of the parser stack. Return the number ** of errors. Return 0 on success. */ static int fts5yyGrowStack(fts5yyParser *p){ + int oldSize = 1 + (int)(p->fts5yystackEnd - p->fts5yystack); int newSize; int idx; fts5yyStackEntry *pNew; - newSize = p->fts5yystksz*2 + 100; - idx = p->fts5yytos ? (int)(p->fts5yytos - p->fts5yystack) : 0; - if( p->fts5yystack==&p->fts5yystk0 ){ - pNew = malloc(newSize*sizeof(pNew[0])); - if( pNew ) pNew[0] = p->fts5yystk0; + newSize = oldSize*2 + 100; + idx = (int)(p->fts5yytos - p->fts5yystack); + if( p->fts5yystack==p->fts5yystk0 ){ + pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0])); + if( pNew==0 ) return 1; + memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0])); }else{ - pNew = realloc(p->fts5yystack, newSize*sizeof(pNew[0])); + pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0])); + if( pNew==0 ) return 1; } - if( pNew ){ - p->fts5yystack = pNew; - p->fts5yytos = &p->fts5yystack[idx]; + p->fts5yystack = pNew; + p->fts5yytos = &p->fts5yystack[idx]; #ifndef NDEBUG - if( fts5yyTraceFILE ){ - fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n", - fts5yyTracePrompt, p->fts5yystksz, newSize); - } -#endif - p->fts5yystksz = newSize; + if( fts5yyTraceFILE ){ + fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n", + fts5yyTracePrompt, oldSize, newSize); } - return pNew==0; +#endif + p->fts5yystackEnd = &p->fts5yystack[newSize-1]; + return 0; } +#endif /* fts5YYGROWABLESTACK */ + +#if !fts5YYGROWABLESTACK +/* For builds that do no have a growable stack, fts5yyGrowStack always +** returns an error. +*/ +# define fts5yyGrowStack(X) 1 #endif /* Datatype of the argument to the memory allocated passed as the @@ -229532,24 +235319,14 @@ static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PD #ifdef fts5YYTRACKMAXSTACKDEPTH fts5yypParser->fts5yyhwm = 0; #endif -#if fts5YYSTACKDEPTH<=0 - fts5yypParser->fts5yytos = NULL; - fts5yypParser->fts5yystack = NULL; - fts5yypParser->fts5yystksz = 0; - if( fts5yyGrowStack(fts5yypParser) ){ - fts5yypParser->fts5yystack = &fts5yypParser->fts5yystk0; - fts5yypParser->fts5yystksz = 1; - } -#endif + fts5yypParser->fts5yystack = fts5yypParser->fts5yystk0; + fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1]; #ifndef fts5YYNOERRORRECOVERY fts5yypParser->fts5yyerrcnt = -1; #endif fts5yypParser->fts5yytos = fts5yypParser->fts5yystack; fts5yypParser->fts5yystack[0].stateno = 0; fts5yypParser->fts5yystack[0].major = 0; -#if fts5YYSTACKDEPTH>0 - fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1]; -#endif } #ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK @@ -229663,9 +235440,26 @@ static void fts5yy_pop_parser_stack(fts5yyParser *pParser){ */ static void sqlite3Fts5ParserFinalize(void *p){ fts5yyParser *pParser = (fts5yyParser*)p; - while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser); -#if fts5YYSTACKDEPTH<=0 - if( pParser->fts5yystack!=&pParser->fts5yystk0 ) free(pParser->fts5yystack); + + /* In-lined version of calling fts5yy_pop_parser_stack() for each + ** element left in the stack */ + fts5yyStackEntry *fts5yytos = pParser->fts5yytos; + while( fts5yytos>pParser->fts5yystack ){ +#ifndef NDEBUG + if( fts5yyTraceFILE ){ + fprintf(fts5yyTraceFILE,"%sPopping %s\n", + fts5yyTracePrompt, + fts5yyTokenName[fts5yytos->major]); + } +#endif + if( fts5yytos->major>=fts5YY_MIN_DSTRCTR ){ + fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor); + } + fts5yytos--; + } + +#if fts5YYGROWABLESTACK + if( pParser->fts5yystack!=pParser->fts5yystk0 ) fts5YYFREE(pParser->fts5yystack); #endif } @@ -229892,25 +235686,19 @@ static void fts5yy_shift( assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack) ); } #endif -#if fts5YYSTACKDEPTH>0 - if( fts5yypParser->fts5yytos>fts5yypParser->fts5yystackEnd ){ - fts5yypParser->fts5yytos--; - fts5yyStackOverflow(fts5yypParser); - return; - } -#else - if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz] ){ + fts5yytos = fts5yypParser->fts5yytos; + if( fts5yytos>fts5yypParser->fts5yystackEnd ){ if( fts5yyGrowStack(fts5yypParser) ){ fts5yypParser->fts5yytos--; fts5yyStackOverflow(fts5yypParser); return; } + fts5yytos = fts5yypParser->fts5yytos; + assert( fts5yytos <= fts5yypParser->fts5yystackEnd ); } -#endif if( fts5yyNewState > fts5YY_MAX_SHIFT ){ fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE; } - fts5yytos = fts5yypParser->fts5yytos; fts5yytos->stateno = fts5yyNewState; fts5yytos->major = fts5yyMajor; fts5yytos->minor.fts5yy0 = fts5yyMinor; @@ -230347,19 +236135,12 @@ static void sqlite3Fts5Parser( (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)); } #endif -#if fts5YYSTACKDEPTH>0 if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){ - fts5yyStackOverflow(fts5yypParser); - break; - } -#else - if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){ if( fts5yyGrowStack(fts5yypParser) ){ fts5yyStackOverflow(fts5yypParser); break; } } -#endif } fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyruleno,fts5yymajor,fts5yyminor sqlite3Fts5ParserCTX_PARAM); }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ @@ -230716,6 +236497,14 @@ static int fts5HighlightCb( } if( iPos==p->iRangeEnd ){ + if( p->bOpen ){ + if( p->iter.iStart>=0 && iPos>=p->iter.iStart ){ + fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); + p->iOff = iEndOff; + } + fts5HighlightAppend(&rc, p, p->zClose, -1); + p->bOpen = 0; + } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; } @@ -230723,6 +236512,7 @@ static int fts5HighlightCb( return rc; } + /* ** Implementation of highlight() function. */ @@ -230749,14 +236539,23 @@ static void fts5HighlightFunction( ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); ctx.iRangeEnd = -1; rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); - - if( ctx.zIn ){ + if( rc==SQLITE_RANGE ){ + sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); + rc = SQLITE_OK; + }else if( ctx.zIn ){ + const char *pLoc = 0; /* Locale of column iCol */ + int nLoc = 0; /* Size of pLoc in bytes */ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); } if( rc==SQLITE_OK ){ - rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); + rc = pApi->xColumnLocale(pFts, iCol, &pLoc, &nLoc); + } + if( rc==SQLITE_OK ){ + rc = pApi->xTokenize_v2( + pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx, fts5HighlightCb + ); } if( ctx.bOpen ){ fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); @@ -230953,6 +236752,8 @@ static void fts5SnippetFunction( memset(&sFinder, 0, sizeof(Fts5SFinder)); for(i=0; i<nCol; i++){ if( iCol<0 || iCol==i ){ + const char *pLoc = 0; /* Locale of column iCol */ + int nLoc = 0; /* Size of pLoc in bytes */ int nDoc; int nDocsize; int ii; @@ -230960,8 +236761,10 @@ static void fts5SnippetFunction( sFinder.nFirst = 0; rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc); if( rc!=SQLITE_OK ) break; - rc = pApi->xTokenize(pFts, - sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb + rc = pApi->xColumnLocale(pFts, i, &pLoc, &nLoc); + if( rc!=SQLITE_OK ) break; + rc = pApi->xTokenize_v2(pFts, + sFinder.zDoc, nDoc, pLoc, nLoc, (void*)&sFinder, fts5SentenceFinderCb ); if( rc!=SQLITE_OK ) break; rc = pApi->xColumnSize(pFts, i, &nDocsize); @@ -231019,6 +236822,9 @@ static void fts5SnippetFunction( rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); } if( ctx.zIn ){ + const char *pLoc = 0; /* Locale of column iBestCol */ + int nLoc = 0; /* Bytes in pLoc */ + if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); } @@ -231037,7 +236843,12 @@ static void fts5SnippetFunction( } if( rc==SQLITE_OK ){ - rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); + rc = pApi->xColumnLocale(pFts, iBestCol, &pLoc, &nLoc); + } + if( rc==SQLITE_OK ){ + rc = pApi->xTokenize_v2( + pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx,fts5HighlightCb + ); } if( ctx.bOpen ){ fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); @@ -231221,6 +237032,53 @@ static void fts5Bm25Function( } } +/* +** Implementation of fts5_get_locale() function. +*/ +static void fts5GetLocaleFunction( + const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ + Fts5Context *pFts, /* First arg to pass to pApi functions */ + sqlite3_context *pCtx, /* Context for returning result/error */ + int nVal, /* Number of values in apVal[] array */ + sqlite3_value **apVal /* Array of trailing arguments */ +){ + int iCol = 0; + int eType = 0; + int rc = SQLITE_OK; + const char *zLocale = 0; + int nLocale = 0; + + /* xColumnLocale() must be available */ + assert( pApi->iVersion>=4 ); + + if( nVal!=1 ){ + const char *z = "wrong number of arguments to function fts5_get_locale()"; + sqlite3_result_error(pCtx, z, -1); + return; + } + + eType = sqlite3_value_numeric_type(apVal[0]); + if( eType!=SQLITE_INTEGER ){ + const char *z = "non-integer argument passed to function fts5_get_locale()"; + sqlite3_result_error(pCtx, z, -1); + return; + } + + iCol = sqlite3_value_int(apVal[0]); + if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){ + sqlite3_result_error_code(pCtx, SQLITE_RANGE); + return; + } + + rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale); + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + return; + } + + sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT); +} + static int sqlite3Fts5AuxInit(fts5_api *pApi){ struct Builtin { const char *zFunc; /* Function name (nul-terminated) */ @@ -231228,9 +237086,10 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){ fts5_extension_function xFunc;/* Callback function */ void (*xDestroy)(void*); /* Destructor function */ } aBuiltin [] = { - { "snippet", 0, fts5SnippetFunction, 0 }, - { "highlight", 0, fts5HighlightFunction, 0 }, - { "bm25", 0, fts5Bm25Function, 0 }, + { "snippet", 0, fts5SnippetFunction, 0 }, + { "highlight", 0, fts5HighlightFunction, 0 }, + { "bm25", 0, fts5Bm25Function, 0 }, + { "fts5_get_locale", 0, fts5GetLocaleFunction, 0 }, }; int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ @@ -231317,6 +237176,7 @@ static void sqlite3Fts5BufferAppendBlob( ){ if( nData ){ if( fts5BufferGrow(pRc, pBuf, nData) ) return; + assert( pBuf->p!=0 ); memcpy(&pBuf->p[pBuf->n], pData, nData); pBuf->n += nData; } @@ -231418,6 +237278,7 @@ static int sqlite3Fts5PoslistNext64( i64 *piOff /* IN/OUT: Current offset */ ){ int i = *pi; + assert( a!=0 || i==0 ); if( i>=n ){ /* EOF */ *piOff = -1; @@ -231425,6 +237286,7 @@ static int sqlite3Fts5PoslistNext64( }else{ i64 iOff = *piOff; u32 iVal; + assert( a!=0 ); fts5FastGetVarint32(a, i, iVal); if( iVal<=1 ){ if( iVal==0 ){ @@ -231892,7 +237754,6 @@ static int fts5ConfigSetEnum( ** eventually free any such error message using sqlite3_free(). */ static int fts5ConfigParseSpecial( - Fts5Global *pGlobal, Fts5Config *pConfig, /* Configuration object to update */ const char *zCmd, /* Special command to parse */ const char *zArg, /* Argument to parse */ @@ -231900,6 +237761,7 @@ static int fts5ConfigParseSpecial( ){ int rc = SQLITE_OK; int nCmd = (int)strlen(zCmd); + if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; const char *p; @@ -231956,12 +237818,11 @@ static int fts5ConfigParseSpecial( if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; sqlite3_int64 nArg = strlen(zArg) + 1; - char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); - char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2); - char *pSpace = pDel; + char **azArg = sqlite3Fts5MallocZero(&rc, (sizeof(char*) + 2) * nArg); - if( azArg && pSpace ){ - if( pConfig->pTok ){ + if( azArg ){ + char *pSpace = (char*)&azArg[nArg]; + if( pConfig->t.azArg ){ *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); rc = SQLITE_ERROR; }else{ @@ -231984,16 +237845,14 @@ static int fts5ConfigParseSpecial( *pzErr = sqlite3_mprintf("parse error in tokenize directive"); rc = SQLITE_ERROR; }else{ - rc = sqlite3Fts5GetTokenizer(pGlobal, - (const char**)azArg, (int)nArg, pConfig, - pzErr - ); + pConfig->t.azArg = (const char**)azArg; + pConfig->t.nArg = nArg; + azArg = 0; } } } - sqlite3_free(azArg); - sqlite3_free(pDel); + return rc; } @@ -232022,6 +237881,16 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("contentless_unindexed", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bContentlessUnindexed = (zArg[0]=='1'); + } + return rc; + } + if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ if( pConfig->zContentRowid ){ *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); @@ -232042,6 +237911,16 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("locale", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed locale=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bLocale = (zArg[0]=='1'); + } + return rc; + } + if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ const Fts5Enum aDetail[] = { { "none", FTS5_DETAIL_NONE }, @@ -232056,20 +237935,20 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("tokendata", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed tokendata=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bTokendata = (zArg[0]=='1'); + } + return rc; + } + *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); return SQLITE_ERROR; } -/* -** Allocate an instance of the default tokenizer ("simple") at -** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error -** code if an error occurs. -*/ -static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){ - assert( pConfig->pTok==0 && pConfig->pTokApi==0 ); - return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0); -} - /* ** Gobble up the first bareword or quoted word from the input buffer zIn. ** Return a pointer to the character immediately following the last in @@ -232129,7 +238008,8 @@ static int fts5ConfigParseColumn( Fts5Config *p, char *zCol, char *zArg, - char **pzErr + char **pzErr, + int *pbUnindexed ){ int rc = SQLITE_OK; if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME) @@ -232140,6 +238020,7 @@ static int fts5ConfigParseColumn( }else if( zArg ){ if( 0==sqlite3_stricmp(zArg, "unindexed") ){ p->abUnindexed[p->nCol] = 1; + *pbUnindexed = 1; }else{ *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg); rc = SQLITE_ERROR; @@ -232160,11 +238041,26 @@ static int fts5ConfigMakeExprlist(Fts5Config *p){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid); if( p->eContent!=FTS5_CONTENT_NONE ){ + assert( p->eContent==FTS5_CONTENT_EXTERNAL + || p->eContent==FTS5_CONTENT_NORMAL + || p->eContent==FTS5_CONTENT_UNINDEXED + ); for(i=0; i<p->nCol; i++){ if( p->eContent==FTS5_CONTENT_EXTERNAL ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); - }else{ + }else if( p->eContent==FTS5_CONTENT_NORMAL || p->abUnindexed[i] ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); + }else{ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); + } + } + } + if( p->eContent==FTS5_CONTENT_NORMAL && p->bLocale ){ + for(i=0; i<p->nCol; i++){ + if( p->abUnindexed[i]==0 ){ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.l%d", i); + }else{ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); } } } @@ -232198,10 +238094,12 @@ static int sqlite3Fts5ConfigParse( Fts5Config *pRet; /* New object to return */ int i; sqlite3_int64 nByte; + int bUnindexed = 0; /* True if there are one or more UNINDEXED */ *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(Fts5Config)); + pRet->pGlobal = pGlobal; pRet->db = db; pRet->iCookie = -1; @@ -232250,13 +238148,13 @@ static int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; }else{ if( bOption ){ - rc = fts5ConfigParseSpecial(pGlobal, pRet, + rc = fts5ConfigParseSpecial(pRet, ALWAYS(zOne)?zOne:"", zTwo?zTwo:"", pzErr ); }else{ - rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr); + rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr, &bUnindexed); zOne = 0; } } @@ -232288,11 +238186,17 @@ static int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; } - /* If a tokenizer= option was successfully parsed, the tokenizer has - ** already been allocated. Otherwise, allocate an instance of the default - ** tokenizer (unicode61) now. */ - if( rc==SQLITE_OK && pRet->pTok==0 ){ - rc = fts5ConfigDefaultTokenizer(pGlobal, pRet); + /* We only allow contentless_unindexed=1 if the table is actually a + ** contentless one. + */ + if( rc==SQLITE_OK + && pRet->bContentlessUnindexed + && pRet->eContent!=FTS5_CONTENT_NONE + ){ + *pzErr = sqlite3_mprintf( + "contentless_unindexed=1 requires a contentless table" + ); + rc = SQLITE_ERROR; } /* If no zContent option was specified, fill in the default values. */ @@ -232303,6 +238207,9 @@ static int sqlite3Fts5ConfigParse( ); if( pRet->eContent==FTS5_CONTENT_NORMAL ){ zTail = "content"; + }else if( bUnindexed && pRet->bContentlessUnindexed ){ + pRet->eContent = FTS5_CONTENT_UNINDEXED; + zTail = "content"; }else if( pRet->bColumnsize ){ zTail = "docsize"; } @@ -232336,9 +238243,14 @@ static int sqlite3Fts5ConfigParse( static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ if( pConfig ){ int i; - if( pConfig->pTok ){ - pConfig->pTokApi->xDelete(pConfig->pTok); + if( pConfig->t.pTok ){ + if( pConfig->t.pApi1 ){ + pConfig->t.pApi1->xDelete(pConfig->t.pTok); + }else{ + pConfig->t.pApi2->xDelete(pConfig->t.pTok); + } } + sqlite3_free((char*)pConfig->t.azArg); sqlite3_free(pConfig->zDb); sqlite3_free(pConfig->zName); for(i=0; i<pConfig->nCol; i++){ @@ -232413,10 +238325,24 @@ static int sqlite3Fts5Tokenize( void *pCtx, /* Context passed to xToken() */ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ){ - if( pText==0 ) return SQLITE_OK; - return pConfig->pTokApi->xTokenize( - pConfig->pTok, pCtx, flags, pText, nText, xToken - ); + int rc = SQLITE_OK; + if( pText ){ + if( pConfig->t.pTok==0 ){ + rc = sqlite3Fts5LoadTokenizer(pConfig); + } + if( rc==SQLITE_OK ){ + if( pConfig->t.pApi1 ){ + rc = pConfig->t.pApi1->xTokenize( + pConfig->t.pTok, pCtx, flags, pText, nText, xToken + ); + }else{ + rc = pConfig->t.pApi2->xTokenize(pConfig->t.pTok, pCtx, flags, + pText, nText, pConfig->t.pLocale, pConfig->t.nLocale, xToken + ); + } + } + } + return rc; } /* @@ -232620,6 +238546,19 @@ static int sqlite3Fts5ConfigSetValue( }else{ pConfig->bSecureDelete = (bVal ? 1 : 0); } + } + + else if( 0==sqlite3_stricmp(zKey, "insttoken") ){ + int bVal = -1; + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + bVal = sqlite3_value_int(pVal); + } + if( bVal<0 ){ + *pbBadkey = 1; + }else{ + pConfig->bPrefixInsttoken = (bVal ? 1 : 0); + } + }else{ *pbBadkey = 1; } @@ -232670,13 +238609,10 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ rc = SQLITE_ERROR; - if( pConfig->pzErrmsg ){ - assert( 0==*pConfig->pzErrmsg ); - *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format " - "(found %d, expected %d or %d) - run 'rebuild'", - iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE - ); - } + sqlite3Fts5ConfigErrmsg(pConfig, "invalid fts5 file format " + "(found %d, expected %d or %d) - run 'rebuild'", + iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE + ); }else{ pConfig->iVersion = iVersion; } @@ -232687,6 +238623,29 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ return rc; } +/* +** Set (*pConfig->pzErrmsg) to point to an sqlite3_malloc()ed buffer +** containing the error message created using printf() style formatting +** string zFmt and its trailing arguments. +*/ +static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){ + va_list ap; /* ... printf arguments */ + char *zMsg = 0; + + va_start(ap, zFmt); + zMsg = sqlite3_vmprintf(zFmt, ap); + if( pConfig->pzErrmsg ){ + assert( *pConfig->pzErrmsg==0 ); + *pConfig->pzErrmsg = zMsg; + }else{ + sqlite3_free(zMsg); + } + + va_end(ap); +} + + + /* ** 2014 May 31 ** @@ -232743,7 +238702,7 @@ struct Fts5Expr { /* ** eType: -** Expression node type. Always one of: +** Expression node type. Usually one of: ** ** FTS5_AND (nChild, apChild valid) ** FTS5_OR (nChild, apChild valid) @@ -232751,6 +238710,10 @@ struct Fts5Expr { ** FTS5_STRING (pNear valid) ** FTS5_TERM (pNear valid) ** +** An expression node with eType==0 may also exist. It always matches zero +** rows. This is created when a phrase containing no tokens is parsed. +** e.g. "". +** ** iHeight: ** Distance from this node to furthest leaf. This is always 0 for nodes ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one @@ -232789,7 +238752,9 @@ struct Fts5ExprNode { struct Fts5ExprTerm { u8 bPrefix; /* True for a prefix term */ u8 bFirst; /* True if token must be first in column */ - char *zTerm; /* nul-terminated term */ + char *pTerm; /* Term data */ + int nQueryTerm; /* Effective size of term in bytes */ + int nFullTerm; /* Size of term in bytes incl. tokendata */ Fts5IndexIter *pIter; /* Iterator for this term */ Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */ }; @@ -232969,11 +238934,12 @@ static int sqlite3Fts5ExprNew( }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); sqlite3Fts5ParserFree(pEngine, fts5ParseFree); + assert( sParse.pExpr || sParse.rc!=SQLITE_OK ); assert_expr_depth_ok(sParse.rc, sParse.pExpr); /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ - if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ + if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){ int n = sizeof(Fts5Colset); Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); if( pColset ){ @@ -232990,15 +238956,7 @@ static int sqlite3Fts5ExprNew( sParse.rc = SQLITE_NOMEM; sqlite3Fts5ParseNodeFree(sParse.pExpr); }else{ - if( !sParse.pExpr ){ - const int nByte = sizeof(Fts5ExprNode); - pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte); - if( pNew->pRoot ){ - pNew->pRoot->bEof = 1; - } - }else{ - pNew->pRoot = sParse.pExpr; - } + pNew->pRoot = sParse.pExpr; pNew->pIndex = 0; pNew->pConfig = pConfig; pNew->apExprPhrase = sParse.apPhrase; @@ -233011,7 +238969,11 @@ static int sqlite3Fts5ExprNew( } sqlite3_free(sParse.apPhrase); - *pzErr = sParse.zErr; + if( 0==*pzErr ){ + *pzErr = sParse.zErr; + }else{ + sqlite3_free(sParse.zErr); + } return sParse.rc; } @@ -233656,7 +239618,7 @@ static int fts5ExprNearInitAll( p->pIter = 0; } rc = sqlite3Fts5IndexQuery( - pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm), + pExpr->pIndex, p->pTerm, p->nQueryTerm, (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), pNear->pColset, @@ -233812,7 +239774,7 @@ static int fts5ExprNodeTest_STRING( } }else{ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; - if( pIter->iRowid==iLast || pIter->bEof ) continue; + if( pIter->iRowid==iLast ) continue; bMatch = 0; if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ return rc; @@ -234293,7 +240255,7 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){ Fts5ExprTerm *pSyn; Fts5ExprTerm *pNext; Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; - sqlite3_free(pTerm->zTerm); + sqlite3_free(pTerm->pTerm); sqlite3Fts5IterClose(pTerm->pIter); for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){ pNext = pSyn->pSynonym; @@ -234334,9 +240296,6 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( Fts5ExprNearset *pRet = 0; if( pParse->rc==SQLITE_OK ){ - if( pPhrase==0 ){ - return pNear; - } if( pNear==0 ){ sqlite3_int64 nByte; nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); @@ -234391,6 +240350,7 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( typedef struct TokenCtx TokenCtx; struct TokenCtx { Fts5ExprPhrase *pPhrase; + Fts5Config *pConfig; int rc; }; @@ -234424,8 +240384,12 @@ static int fts5ParseTokenize( rc = SQLITE_NOMEM; }else{ memset(pSyn, 0, (size_t)nByte); - pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); - memcpy(pSyn->zTerm, pToken, nToken); + pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); + pSyn->nFullTerm = pSyn->nQueryTerm = nToken; + if( pCtx->pConfig->bTokendata ){ + pSyn->nQueryTerm = (int)strlen(pSyn->pTerm); + } + memcpy(pSyn->pTerm, pToken, nToken); pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; } @@ -234450,7 +240414,11 @@ static int fts5ParseTokenize( if( rc==SQLITE_OK ){ pTerm = &pPhrase->aTerm[pPhrase->nTerm++]; memset(pTerm, 0, sizeof(Fts5ExprTerm)); - pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); + pTerm->pTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); + pTerm->nFullTerm = pTerm->nQueryTerm = nToken; + if( pCtx->pConfig->bTokendata && rc==SQLITE_OK ){ + pTerm->nQueryTerm = (int)strlen(pTerm->pTerm); + } } } @@ -234517,6 +240485,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( memset(&sCtx, 0, sizeof(TokenCtx)); sCtx.pPhrase = pAppend; + sCtx.pConfig = pConfig; rc = fts5ParseStringFromToken(pToken, &z); if( rc==SQLITE_OK ){ @@ -234548,6 +240517,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } + assert( pParse->apPhrase!=0 ); pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; } @@ -234564,12 +240534,15 @@ static int sqlite3Fts5ExprClonePhrase( Fts5Expr **ppNew ){ int rc = SQLITE_OK; /* Return code */ - Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */ + Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ - TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */ - - pOrig = pExpr->apExprPhrase[iPhrase]; - pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); + TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ + if( !pExpr || iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + rc = SQLITE_RANGE; + }else{ + pOrig = pExpr->apExprPhrase[iPhrase]; + pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); + } if( rc==SQLITE_OK ){ pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase*)); @@ -234582,7 +240555,7 @@ static int sqlite3Fts5ExprClonePhrase( pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; if( pColsetOrig ){ sqlite3_int64 nByte; @@ -234596,26 +240569,27 @@ static int sqlite3Fts5ExprClonePhrase( } } - if( pOrig->nTerm ){ - int i; /* Used to iterate through phrase terms */ - for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){ - int tflags = 0; - Fts5ExprTerm *p; - for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ - const char *zTerm = p->zTerm; - rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm), - 0, 0); - tflags = FTS5_TOKEN_COLOCATED; - } - if( rc==SQLITE_OK ){ - sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; - sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; + if( rc==SQLITE_OK ){ + if( pOrig->nTerm ){ + int i; /* Used to iterate through phrase terms */ + sCtx.pConfig = pExpr->pConfig; + for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){ + int tflags = 0; + Fts5ExprTerm *p; + for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ + rc = fts5ParseTokenize((void*)&sCtx,tflags,p->pTerm,p->nFullTerm,0,0); + tflags = FTS5_TOKEN_COLOCATED; + } + if( rc==SQLITE_OK ){ + sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; + sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; + } } + }else{ + /* This happens when parsing a token or quoted phrase that contains + ** no token characters at all. (e.g ... MATCH '""'). */ + sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } - }else{ - /* This happens when parsing a token or quoted phrase that contains - ** no token characters at all. (e.g ... MATCH '""'). */ - sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ @@ -234931,6 +240905,9 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ } } +/* +** Add pSub as a child of p. +*/ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ int ii = p->nChild; if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ @@ -234985,11 +240962,13 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( if( parseGrowPhraseArray(pParse) ){ fts5ExprPhraseFree(pPhrase); }else{ + Fts5ExprTerm *p = &pNear->apPhrase[0]->aTerm[ii]; + Fts5ExprTerm *pTo = &pPhrase->aTerm[0]; pParse->apPhrase[pParse->nPhrase++] = pPhrase; pPhrase->nTerm = 1; - pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup( - &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1 - ); + pTo->pTerm = sqlite3Fts5Strndup(&pParse->rc, p->pTerm, p->nFullTerm); + pTo->nQueryTerm = p->nQueryTerm; + pTo->nFullTerm = p->nFullTerm; pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase) ); @@ -235073,19 +241052,23 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); - sqlite3_free(pRet); + sqlite3Fts5ParseNodeFree(pRet); pRet = 0; + pNear = 0; + assert( pLeft==0 && pRight==0 ); } } }else{ + assert( pNear==0 ); fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pRight); + pLeft = pRight = 0; if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ sqlite3Fts5ParseError(pParse, "fts5 expression tree is too large (maximum depth %d)", SQLITE_FTS5_MAX_EXPR_DEPTH ); - sqlite3_free(pRet); + sqlite3Fts5ParseNodeFree(pRet); pRet = 0; } } @@ -235123,6 +241106,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( assert( pRight->eType==FTS5_STRING || pRight->eType==FTS5_TERM || pRight->eType==FTS5_EOF + || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd) ); if( pLeft->eType==FTS5_AND ){ @@ -235136,6 +241120,8 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( ); if( pRight->eType==FTS5_EOF ){ + assert( pParse->apPhrase!=0 ); + assert( pParse->nPhrase>0 ); assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); sqlite3Fts5ParseNodeFree(pRight); pRet = pLeft; @@ -235174,16 +241160,17 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ /* Determine the maximum amount of space required. */ for(p=pTerm; p; p=p->pSynonym){ - nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2; + nByte += pTerm->nQueryTerm * 2 + 3 + 2; } zQuoted = sqlite3_malloc64(nByte); if( zQuoted ){ int i = 0; for(p=pTerm; p; p=p->pSynonym){ - char *zIn = p->zTerm; + char *zIn = p->pTerm; + char *zEnd = &zIn[p->nQueryTerm]; zQuoted[i++] = '"'; - while( *zIn ){ + while( zIn<zEnd ){ if( *zIn=='"' ) zQuoted[i++] = '"'; zQuoted[i++] = *zIn++; } @@ -235261,8 +241248,10 @@ static char *fts5ExprPrintTcl( zRet = fts5PrintfAppend(zRet, " {"); for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){ - char *zTerm = pPhrase->aTerm[iTerm].zTerm; - zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm); + Fts5ExprTerm *p = &pPhrase->aTerm[iTerm]; + zRet = fts5PrintfAppend(zRet, "%s%.*s", iTerm==0?"":" ", + p->nQueryTerm, p->pTerm + ); if( pPhrase->aTerm[iTerm].bPrefix ){ zRet = fts5PrintfAppend(zRet, "*"); } @@ -235663,6 +241652,17 @@ static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){ return 0; } +/* +** pToken is a buffer nToken bytes in size that may or may not contain +** an embedded 0x00 byte. If it does, return the number of bytes in +** the buffer before the 0x00. If it does not, return nToken. +*/ +static int fts5QueryTerm(const char *pToken, int nToken){ + int ii; + for(ii=0; ii<nToken && pToken[ii]; ii++){} + return ii; +} + static int fts5ExprPopulatePoslistsCb( void *pCtx, /* Copy of 2nd argument to xTokenize() */ int tflags, /* Mask of FTS5_TOKEN_* flags */ @@ -235674,22 +241674,33 @@ static int fts5ExprPopulatePoslistsCb( Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx; Fts5Expr *pExpr = p->pExpr; int i; + int nQuery = nToken; + i64 iRowid = pExpr->pRoot->iRowid; UNUSED_PARAM2(iUnused1, iUnused2); - if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; + if( nQuery>FTS5_MAX_TOKEN_SIZE ) nQuery = FTS5_MAX_TOKEN_SIZE; + if( pExpr->pConfig->bTokendata ){ + nQuery = fts5QueryTerm(pToken, nQuery); + } if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++; for(i=0; i<pExpr->nPhrase; i++){ - Fts5ExprTerm *pTerm; + Fts5ExprTerm *pT; if( p->aPopulator[i].bOk==0 ) continue; - for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ - int nTerm = (int)strlen(pTerm->zTerm); - if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix)) - && memcmp(pTerm->zTerm, pToken, nTerm)==0 + for(pT=&pExpr->apExprPhrase[i]->aTerm[0]; pT; pT=pT->pSynonym){ + if( (pT->nQueryTerm==nQuery || (pT->nQueryTerm<nQuery && pT->bPrefix)) + && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0 ){ int rc = sqlite3Fts5PoslistWriterAppend( &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff ); + if( rc==SQLITE_OK && (pExpr->pConfig->bTokendata || pT->bPrefix) ){ + int iCol = p->iOff>>32; + int iTokOff = p->iOff & 0x7FFFFFFF; + rc = sqlite3Fts5IndexIterWriteTokendata( + pT->pIter, pToken, nToken, iRowid, iCol, iTokOff + ); + } if( rc ) return rc; break; } @@ -235743,6 +241754,7 @@ static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ pNode->iRowid = iRowid; pNode->bEof = 0; switch( pNode->eType ){ + case 0: case FTS5_TERM: case FTS5_STRING: return (pNode->pNear->apPhrase[0]->poslist.n>0); @@ -235825,6 +241837,82 @@ static int sqlite3Fts5ExprPhraseCollist( return rc; } +/* +** Does the work of the fts5_api.xQueryToken() API method. +*/ +static int sqlite3Fts5ExprQueryToken( + Fts5Expr *pExpr, + int iPhrase, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5ExprPhrase *pPhrase = 0; + + if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + return SQLITE_RANGE; + } + pPhrase = pExpr->apExprPhrase[iPhrase]; + if( iToken<0 || iToken>=pPhrase->nTerm ){ + return SQLITE_RANGE; + } + + *ppOut = pPhrase->aTerm[iToken].pTerm; + *pnOut = pPhrase->aTerm[iToken].nFullTerm; + return SQLITE_OK; +} + +/* +** Does the work of the fts5_api.xInstToken() API method. +*/ +static int sqlite3Fts5ExprInstToken( + Fts5Expr *pExpr, + i64 iRowid, + int iPhrase, + int iCol, + int iOff, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5ExprPhrase *pPhrase = 0; + Fts5ExprTerm *pTerm = 0; + int rc = SQLITE_OK; + + if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + return SQLITE_RANGE; + } + pPhrase = pExpr->apExprPhrase[iPhrase]; + if( iToken<0 || iToken>=pPhrase->nTerm ){ + return SQLITE_RANGE; + } + pTerm = &pPhrase->aTerm[iToken]; + if( pExpr->pConfig->bTokendata || pTerm->bPrefix ){ + rc = sqlite3Fts5IterToken( + pTerm->pIter, pTerm->pTerm, pTerm->nQueryTerm, + iRowid, iCol, iOff+iToken, ppOut, pnOut + ); + }else{ + *ppOut = pTerm->pTerm; + *pnOut = pTerm->nFullTerm; + } + return rc; +} + +/* +** Clear the token mappings for all Fts5IndexIter objects mannaged by +** the expression passed as the only argument. +*/ +static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){ + int ii; + for(ii=0; ii<pExpr->nPhrase; ii++){ + Fts5ExprTerm *pT; + for(pT=&pExpr->apExprPhrase[ii]->aTerm[0]; pT; pT=pT->pSynonym){ + sqlite3Fts5IndexIterClearTokendata(pT->pIter); + } + } +} + /* ** 2014 August 11 ** @@ -235863,10 +241951,15 @@ struct Fts5Hash { /* ** Each entry in the hash table is represented by an object of the -** following type. Each object, its key (a nul-terminated string) and -** its current data are stored in a single memory allocation. The -** key immediately follows the object in memory. The position list -** data immediately follows the key data in memory. +** following type. Each object, its key, and its current data are stored +** in a single memory allocation. The key immediately follows the object +** in memory. The position list data immediately follows the key data +** in memory. +** +** The key is Fts5HashEntry.nKey bytes in size. It consists of a single +** byte identifying the index (either the main term index or a prefix-index), +** followed by the term data. For example: "0token". There is no +** nul-terminator - in this case nKey=6. ** ** The data that follows the key is in a similar, but not identical format ** to the doclist data stored in the database. It is: @@ -236001,8 +242094,7 @@ static int fts5HashResize(Fts5Hash *pHash){ unsigned int iHash; Fts5HashEntry *p = apOld[i]; apOld[i] = p->pHashNext; - iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), - (int)strlen(fts5EntryKey(p))); + iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), p->nKey); p->pHashNext = apNew[iHash]; apNew[iHash] = p; } @@ -236086,7 +242178,7 @@ static int sqlite3Fts5HashWrite( for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ char *zKey = fts5EntryKey(p); if( zKey[0]==bByte - && p->nKey==nToken + && p->nKey==nToken+1 && memcmp(&zKey[1], pToken, nToken)==0 ){ break; @@ -236116,9 +242208,9 @@ static int sqlite3Fts5HashWrite( zKey[0] = bByte; memcpy(&zKey[1], pToken, nToken); assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) ); - p->nKey = nToken; + p->nKey = nToken+1; zKey[nToken+1] = '\0'; - p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry); + p->nData = nToken+1 + sizeof(Fts5HashEntry); p->pHashNext = pHash->aSlot[iHash]; pHash->aSlot[iHash] = p; pHash->nEntry++; @@ -236235,12 +242327,17 @@ static Fts5HashEntry *fts5HashEntryMerge( *ppOut = p1; p1 = 0; }else{ - int i = 0; char *zKey1 = fts5EntryKey(p1); char *zKey2 = fts5EntryKey(p2); - while( zKey1[i]==zKey2[i] ) i++; + int nMin = MIN(p1->nKey, p2->nKey); + + int cmp = memcmp(zKey1, zKey2, nMin); + if( cmp==0 ){ + cmp = p1->nKey - p2->nKey; + } + assert( cmp!=0 ); - if( ((u8)zKey1[i])>((u8)zKey2[i]) ){ + if( cmp>0 ){ /* p2 is smaller */ *ppOut = p2; ppOut = &p2->pScanNext; @@ -236282,7 +242379,7 @@ static int fts5HashEntrySort( Fts5HashEntry *pIter; for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){ if( pTerm==0 - || (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm)) + || (pIter->nKey>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm)) ){ Fts5HashEntry *pEntry = pIter; pEntry->pScanNext = 0; @@ -236321,12 +242418,11 @@ static int sqlite3Fts5HashQuery( for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ zKey = fts5EntryKey(p); - assert( p->nKey+1==(int)strlen(zKey) ); - if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break; + if( nTerm==p->nKey && memcmp(zKey, pTerm, nTerm)==0 ) break; } if( p ){ - int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1; + int nHashPre = sizeof(Fts5HashEntry) + nTerm; int nList = p->nData - nHashPre; u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10)); if( pRet ){ @@ -236387,19 +242483,22 @@ static int sqlite3Fts5HashScanEof(Fts5Hash *p){ static void sqlite3Fts5HashScanEntry( Fts5Hash *pHash, const char **pzTerm, /* OUT: term (nul-terminated) */ + int *pnTerm, /* OUT: Size of term in bytes */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ){ Fts5HashEntry *p; if( (p = pHash->pScan) ){ char *zKey = fts5EntryKey(p); - int nTerm = (int)strlen(zKey); + int nTerm = p->nKey; fts5HashAddPoslistSize(pHash, p, 0); *pzTerm = zKey; - *ppDoclist = (const u8*)&zKey[nTerm+1]; - *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1); + *pnTerm = nTerm; + *ppDoclist = (const u8*)&zKey[nTerm]; + *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm); }else{ *pzTerm = 0; + *pnTerm = 0; *ppDoclist = 0; *pnDoclist = 0; } @@ -236730,6 +242829,9 @@ typedef struct Fts5SegWriter Fts5SegWriter; typedef struct Fts5Structure Fts5Structure; typedef struct Fts5StructureLevel Fts5StructureLevel; typedef struct Fts5StructureSegment Fts5StructureSegment; +typedef struct Fts5TokenDataIter Fts5TokenDataIter; +typedef struct Fts5TokenDataMap Fts5TokenDataMap; +typedef struct Fts5TombstoneArray Fts5TombstoneArray; struct Fts5Data { u8 *p; /* Pointer to buffer containing record */ @@ -236764,6 +242866,7 @@ struct Fts5Index { /* Error state. */ int rc; /* Current error code */ + int flushRc; /* State used by the fts5DataXXX() functions. */ sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ @@ -236772,6 +242875,7 @@ struct Fts5Index { sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ sqlite3_stmt *pIdxSelect; + sqlite3_stmt *pIdxNextSelect; int nRead; /* Total number of blocks read */ sqlite3_stmt *pDeleteFromIdx; @@ -236925,8 +243029,7 @@ struct Fts5SegIter { Fts5Data *pLeaf; /* Current leaf data */ Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ i64 iLeafOffset; /* Byte offset within current leaf */ - Fts5Data **apTombstone; /* Array of tombstone pages */ - int nTombstone; + Fts5TombstoneArray *pTombArray; /* Array of tombstone pages */ /* Next method */ void (*xNext)(Fts5Index*, Fts5SegIter*, int*); @@ -236953,6 +243056,15 @@ struct Fts5SegIter { u8 bDel; /* True if the delete flag is set */ }; +/* +** Array of tombstone pages. Reference counted. +*/ +struct Fts5TombstoneArray { + int nRef; /* Number of pointers to this object */ + int nTombstone; + Fts5Data *apTombstone[1]; /* Array of tombstone pages */ +}; + /* ** Argument is a pointer to an Fts5Data structure that contains a ** leaf page. @@ -236997,9 +243109,16 @@ struct Fts5SegIter { ** poslist: ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. +** +** pColset: +** If not NULL, points to an object containing a set of column indices. +** Only matches that occur in one of these columns will be returned. +** The Fts5Iter does not own the Fts5Colset object, and so it is not +** freed when the iterator is closed - it is owned by the upper layer. */ struct Fts5Iter { Fts5IndexIter base; /* Base class containing output vars */ + Fts5TokenDataIter *pTokenDataIter; Fts5Index *pIndex; /* Index that owns this iterator */ Fts5Buffer poslist; /* Buffer containing current poslist */ @@ -237017,7 +243136,6 @@ struct Fts5Iter { Fts5SegIter aSeg[1]; /* Array of segment iterators */ }; - /* ** An instance of the following type is used to iterate through the contents ** of a doclist-index record. @@ -237219,11 +243337,12 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ if( rc==SQLITE_OK ){ u8 *aOut = 0; /* Read blob data into this buffer */ int nByte = sqlite3_blob_bytes(p->pReader); - sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; + int szData = (sizeof(Fts5Data) + 7) & ~7; + sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING; pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); if( pRet ){ pRet->nn = nByte; - aOut = pRet->p = (u8*)&pRet[1]; + aOut = pRet->p = (u8*)pRet + szData; }else{ rc = SQLITE_NOMEM; } @@ -237246,6 +243365,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ } assert( (pRet==0)==(p->rc!=SQLITE_OK) ); + assert( pRet==0 || EIGHT_BYTE_ALIGNMENT( pRet->p ) ); return pRet; } @@ -237277,9 +243397,13 @@ static int fts5IndexPrepareStmt( ){ if( p->rc==SQLITE_OK ){ if( zSql ){ - p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, + int rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB, ppStmt, 0); + /* If this prepare() call fails with SQLITE_ERROR, then one of the + ** %_idx or %_data tables has been removed or modified. Call this + ** corruption. */ + p->rc = (rc==SQLITE_ERROR ? SQLITE_CORRUPT : rc); }else{ p->rc = SQLITE_NOMEM; } @@ -237935,9 +244059,9 @@ static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){ } if( iOff<pData->nn ){ - i64 iVal; + u64 iVal; pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1; - iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal); + iOff += fts5GetVarint(&pData->p[iOff], &iVal); pLvl->iRowid += iVal; pLvl->iOff = iOff; }else{ @@ -238316,18 +244440,20 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ } /* -** Allocate a tombstone hash page array (pIter->apTombstone) for the -** iterator passed as the second argument. If an OOM error occurs, leave -** an error in the Fts5Index object. +** Allocate a tombstone hash page array object (pIter->pTombArray) for +** the iterator passed as the second argument. If an OOM error occurs, +** leave an error in the Fts5Index object. */ static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ const int nTomb = pIter->pSeg->nPgTombstone; if( nTomb>0 ){ - Fts5Data **apTomb = 0; - apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb); - if( apTomb ){ - pIter->apTombstone = apTomb; - pIter->nTombstone = nTomb; + int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray); + Fts5TombstoneArray *pNew; + pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( pNew ){ + pNew->nTombstone = nTomb; + pNew->nRef = 1; + pIter->pTombArray = pNew; } } } @@ -238569,7 +244695,7 @@ static void fts5SegIterNext_None( if( iOff<pIter->iEndofDoclist ){ /* Next entry is on the current page */ - i64 iDelta; + u64 iDelta; iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta); pIter->iLeafOffset = iOff; pIter->iRowid += iDelta; @@ -238584,15 +244710,16 @@ static void fts5SegIterNext_None( }else{ const u8 *pList = 0; const char *zTerm = 0; + int nTerm = 0; int nList; sqlite3Fts5HashScanNext(p->pHash); - sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); + sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList); if( pList==0 ) goto next_none_eof; pIter->pLeaf->p = (u8*)pList; pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList; - sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm); + sqlite3Fts5BufferSet(&p->rc,&pIter->term, nTerm, (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); } @@ -238658,11 +244785,12 @@ static void fts5SegIterNext( }else if( pIter->pSeg==0 ){ const u8 *pList = 0; const char *zTerm = 0; + int nTerm = 0; int nList = 0; assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm ); if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ sqlite3Fts5HashScanNext(p->pHash); - sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); + sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList); } if( pList==0 ){ fts5DataRelease(pIter->pLeaf); @@ -238672,8 +244800,7 @@ static void fts5SegIterNext( pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList+1; - sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), - (u8*)zTerm); + sqlite3Fts5BufferSet(&p->rc, &pIter->term, nTerm, (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); *pbNewTerm = 1; } @@ -239059,7 +245186,7 @@ static void fts5SegIterSeekInit( fts5LeafSeek(p, bGe, pIter, pTerm, nTerm); } - if( p->rc==SQLITE_OK && bGe==0 ){ + if( p->rc==SQLITE_OK && (bGe==0 || (flags & FTS5INDEX_QUERY_SCANONETERM)) ){ pIter->flags |= FTS5_SEGITER_ONETERM; if( pIter->pLeaf ){ if( flags & FTS5INDEX_QUERY_DESC ){ @@ -239075,7 +245202,9 @@ static void fts5SegIterSeekInit( } fts5SegIterSetNext(p, pIter); - fts5SegIterAllocTombstone(p, pIter); + if( 0==(flags & FTS5INDEX_QUERY_SCANONETERM) ){ + fts5SegIterAllocTombstone(p, pIter); + } /* Either: ** @@ -239092,6 +245221,79 @@ static void fts5SegIterSeekInit( ); } + +/* +** SQL used by fts5SegIterNextInit() to find the page to open. +*/ +static sqlite3_stmt *fts5IdxNextStmt(Fts5Index *p){ + if( p->pIdxNextSelect==0 ){ + Fts5Config *pConfig = p->pConfig; + fts5IndexPrepareStmt(p, &p->pIdxNextSelect, sqlite3_mprintf( + "SELECT pgno FROM '%q'.'%q_idx' WHERE " + "segid=? AND term>? ORDER BY term ASC LIMIT 1", + pConfig->zDb, pConfig->zName + )); + + } + return p->pIdxNextSelect; +} + +/* +** This is similar to fts5SegIterSeekInit(), except that it initializes +** the segment iterator to point to the first term following the page +** with pToken/nToken on it. +*/ +static void fts5SegIterNextInit( + Fts5Index *p, + const char *pTerm, int nTerm, + Fts5StructureSegment *pSeg, /* Description of segment */ + Fts5SegIter *pIter /* Object to populate */ +){ + int iPg = -1; /* Page of segment to open */ + int bDlidx = 0; + sqlite3_stmt *pSel = 0; /* SELECT to find iPg */ + + pSel = fts5IdxNextStmt(p); + if( pSel ){ + assert( p->rc==SQLITE_OK ); + sqlite3_bind_int(pSel, 1, pSeg->iSegid); + sqlite3_bind_blob(pSel, 2, pTerm, nTerm, SQLITE_STATIC); + + if( sqlite3_step(pSel)==SQLITE_ROW ){ + i64 val = sqlite3_column_int64(pSel, 0); + iPg = (int)(val>>1); + bDlidx = (val & 0x0001); + } + p->rc = sqlite3_reset(pSel); + sqlite3_bind_null(pSel, 2); + if( p->rc ) return; + } + + memset(pIter, 0, sizeof(*pIter)); + pIter->pSeg = pSeg; + pIter->flags |= FTS5_SEGITER_ONETERM; + if( iPg>=0 ){ + pIter->iLeafPgno = iPg - 1; + fts5SegIterNextPage(p, pIter); + fts5SegIterSetNext(p, pIter); + } + if( pIter->pLeaf ){ + const u8 *a = pIter->pLeaf->p; + int iTermOff = 0; + + pIter->iPgidxOff = pIter->pLeaf->szLeaf; + pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff); + pIter->iLeafOffset = iTermOff; + fts5SegIterLoadTerm(p, pIter, 0); + fts5SegIterLoadNPos(p, pIter); + if( bDlidx ) fts5SegIterLoadDlidx(p, pIter); + + assert( p->rc!=SQLITE_OK || + fts5BufferCompareBlob(&pIter->term, (const u8*)pTerm, nTerm)>0 + ); + } +} + /* ** Initialize the object pIter to point to term pTerm/nTerm within the ** in-memory hash table. If there is no such term in the hash-table, the @@ -239118,8 +245320,7 @@ static void fts5SegIterHashInit( const u8 *pList = 0; p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); - sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList); - n = (z ? (int)strlen((const char*)z) : 0); + sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &n, &pList, &nList); if( pList ){ pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data)); if( pLeaf ){ @@ -239178,6 +245379,23 @@ static void fts5IndexFreeArray(Fts5Data **ap, int n){ } } +/* +** Decrement the ref-count of the object passed as the only argument. If it +** reaches 0, free it and its contents. +*/ +static void fts5TombstoneArrayDelete(Fts5TombstoneArray *p){ + if( p ){ + p->nRef--; + if( p->nRef<=0 ){ + int ii; + for(ii=0; ii<p->nTombstone; ii++){ + fts5DataRelease(p->apTombstone[ii]); + } + sqlite3_free(p); + } + } +} + /* ** Zero the iterator passed as the only argument. */ @@ -239185,7 +245403,7 @@ static void fts5SegIterClear(Fts5SegIter *pIter){ fts5BufferFree(&pIter->term); fts5DataRelease(pIter->pLeaf); fts5DataRelease(pIter->pNextLeaf); - fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone); + fts5TombstoneArrayDelete(pIter->pTombArray); fts5DlidxIterFree(pIter->pDlidx); sqlite3_free(pIter->aRowidOffset); memset(pIter, 0, sizeof(Fts5SegIter)); @@ -239430,7 +245648,6 @@ static void fts5SegIterNextFrom( }while( p->rc==SQLITE_OK ); } - /* ** Free the iterator object passed as the second argument. */ @@ -239575,24 +245792,25 @@ static int fts5IndexTombstoneQuery( static int fts5MultiIterIsDeleted(Fts5Iter *pIter){ int iFirst = pIter->aFirst[1].iFirst; Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; + Fts5TombstoneArray *pArray = pSeg->pTombArray; - if( pSeg->pLeaf && pSeg->nTombstone ){ + if( pSeg->pLeaf && pArray ){ /* Figure out which page the rowid might be present on. */ - int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone; + int iPg = ((u64)pSeg->iRowid) % pArray->nTombstone; assert( iPg>=0 ); /* If tombstone hash page iPg has not yet been loaded from the ** database, load it now. */ - if( pSeg->apTombstone[iPg]==0 ){ - pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex, + if( pArray->apTombstone[iPg]==0 ){ + pArray->apTombstone[iPg] = fts5DataRead(pIter->pIndex, FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) ); - if( pSeg->apTombstone[iPg]==0 ) return 0; + if( pArray->apTombstone[iPg]==0 ) return 0; } return fts5IndexTombstoneQuery( - pSeg->apTombstone[iPg], - pSeg->nTombstone, + pArray->apTombstone[iPg], + pArray->nTombstone, pSeg->iRowid ); } @@ -240131,6 +246349,32 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ } } +/* +** All the component segment-iterators of pIter have been set up. This +** functions finishes setup for iterator pIter itself. +*/ +static void fts5MultiIterFinishSetup(Fts5Index *p, Fts5Iter *pIter){ + int iIter; + for(iIter=pIter->nSeg-1; iIter>0; iIter--){ + int iEq; + if( (iEq = fts5MultiIterDoCompare(pIter, iIter)) ){ + Fts5SegIter *pSeg = &pIter->aSeg[iEq]; + if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); + fts5MultiIterAdvanced(p, pIter, iEq, iIter); + } + } + fts5MultiIterSetEof(pIter); + fts5AssertMultiIterSetup(p, pIter); + + if( (pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter)) + || fts5MultiIterIsDeleted(pIter) + ){ + fts5MultiIterNext(p, pIter, 0, 0); + }else if( pIter->base.bEof==0 ){ + Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; + pIter->xSetOutputs(pIter, pSeg); + } +} /* ** Allocate a new Fts5Iter object. @@ -240212,31 +246456,12 @@ static void fts5MultiIterNew( assert( iIter==nSeg ); } - /* If the above was successful, each component iterators now points + /* If the above was successful, each component iterator now points ** to the first entry in its segment. In this case initialize the ** aFirst[] array. Or, if an error has occurred, free the iterator ** object and set the output variable to NULL. */ if( p->rc==SQLITE_OK ){ - for(iIter=pNew->nSeg-1; iIter>0; iIter--){ - int iEq; - if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){ - Fts5SegIter *pSeg = &pNew->aSeg[iEq]; - if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); - fts5MultiIterAdvanced(p, pNew, iEq, iIter); - } - } - fts5MultiIterSetEof(pNew); - fts5AssertMultiIterSetup(p, pNew); - - if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew)) - || fts5MultiIterIsDeleted(pNew) - ){ - fts5MultiIterNext(p, pNew, 0, 0); - }else if( pNew->base.bEof==0 ){ - Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; - pNew->xSetOutputs(pNew, pSeg); - } - + fts5MultiIterFinishSetup(p, pNew); }else{ fts5MultiIterFree(pNew); *ppOut = 0; @@ -240261,7 +246486,6 @@ static void fts5MultiIterNew2( pNew = fts5MultiIterAlloc(p, 2); if( pNew ){ Fts5SegIter *pIter = &pNew->aSeg[1]; - pIter->flags = FTS5_SEGITER_ONETERM; if( pData->szLeaf>0 ){ pIter->pLeaf = pData; @@ -240409,6 +246633,7 @@ static void fts5IndexDiscardData(Fts5Index *p){ sqlite3Fts5HashClear(p->pHash); p->nPendingData = 0; p->nPendingRow = 0; + p->flushRc = SQLITE_OK; } p->nContentlessDelete = 0; } @@ -240624,7 +246849,7 @@ static void fts5WriteDlidxAppend( } if( pDlidx->bPrevValid ){ - iVal = iRowid - pDlidx->iPrev; + iVal = (u64)iRowid - (u64)pDlidx->iPrev; }else{ i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno); assert( pDlidx->buf.n==0 ); @@ -241174,6 +247399,11 @@ static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){ nBest = nPercent; } } + + /* If pLvl is already the input level to an ongoing merge, look no + ** further for a merge candidate. The caller should be allowed to + ** continue merging from pLvl first. */ + if( pLvl->nMerge ) break; } } return iRet; @@ -241747,12 +247977,30 @@ static void fts5FlushSecureDelete( Fts5Index *p, Fts5Structure *pStruct, const char *zTerm, + int nTerm, i64 iRowid ){ const int f = FTS5INDEX_QUERY_SKIPHASH; - int nTerm = (int)strlen(zTerm); Fts5Iter *pIter = 0; /* Used to find term instance */ + /* If the version number has not been set to SECUREDELETE, do so now. */ + if( p->pConfig->iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ + Fts5Config *pConfig = p->pConfig; + sqlite3_stmt *pStmt = 0; + fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf( + "REPLACE INTO %Q.'%q_config' VALUES ('version', %d)", + pConfig->zDb, pConfig->zName, FTS5_CURRENT_VERSION_SECUREDELETE + )); + if( p->rc==SQLITE_OK ){ + int rc; + sqlite3_step(pStmt); + rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK ) p->rc = rc; + pConfig->iCookie++; + pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; + } + } + fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); if( fts5MultiIterEof(p, pIter)==0 ){ i64 iThis = fts5MultiIterRowid(pIter); @@ -241824,8 +248072,7 @@ static void fts5FlushOneHash(Fts5Index *p){ int nDoclist; /* Size of doclist in bytes */ /* Get the term and doclist for this entry. */ - sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); - nTerm = (int)strlen(zTerm); + sqlite3Fts5HashScanEntry(pHash, &zTerm, &nTerm, &pDoclist, &nDoclist); if( bSecureDelete==0 ){ fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); if( p->rc!=SQLITE_OK ) break; @@ -241855,7 +248102,7 @@ static void fts5FlushOneHash(Fts5Index *p){ if( bSecureDelete ){ if( eDetail==FTS5_DETAIL_NONE ){ if( iOff<nDoclist && pDoclist[iOff]==0x00 ){ - fts5FlushSecureDelete(p, pStruct, zTerm, iRowid); + fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid); iOff++; if( iOff<nDoclist && pDoclist[iOff]==0x00 ){ iOff++; @@ -241865,7 +248112,7 @@ static void fts5FlushOneHash(Fts5Index *p){ } } }else if( (pDoclist[iOff] & 0x01) ){ - fts5FlushSecureDelete(p, pStruct, zTerm, iRowid); + fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid); if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ iOff++; continue; @@ -241991,6 +248238,10 @@ static void fts5FlushOneHash(Fts5Index *p){ */ static void fts5IndexFlush(Fts5Index *p){ /* Unless it is empty, flush the hash table to disk */ + if( p->flushRc ){ + p->rc = p->flushRc; + return; + } if( p->nPendingData || p->nContentlessDelete ){ assert( p->pHash ); fts5FlushOneHash(p); @@ -241999,6 +248250,8 @@ static void fts5IndexFlush(Fts5Index *p){ p->nPendingData = 0; p->nPendingRow = 0; p->nContentlessDelete = 0; + }else if( p->nPendingData || p->nContentlessDelete ){ + p->flushRc = p->rc; } } } @@ -242478,6 +248731,383 @@ static void fts5MergePrefixLists( *p1 = out; } + +/* +** Iterate through a range of entries in the FTS index, invoking the xVisit +** callback for each of them. +** +** Parameter pToken points to an nToken buffer containing an FTS index term +** (i.e. a document term with the preceding 1 byte index identifier - +** FTS5_MAIN_PREFIX or similar). If bPrefix is true, then the call visits +** all entries for terms that have pToken/nToken as a prefix. If bPrefix +** is false, then only entries with pToken/nToken as the entire key are +** visited. +** +** If the current table is a tokendata=1 table, then if bPrefix is true then +** each index term is treated separately. However, if bPrefix is false, then +** all index terms corresponding to pToken/nToken are collapsed into a single +** term before the callback is invoked. +** +** The callback invoked for each entry visited is specified by paramter xVisit. +** Each time it is invoked, it is passed a pointer to the Fts5Index object, +** a copy of the 7th paramter to this function (pCtx) and a pointer to the +** iterator that indicates the current entry. If the current entry is the +** first with a new term (i.e. different from that of the previous entry, +** including the very first term), then the final two parameters are passed +** a pointer to the term and its size in bytes, respectively. If the current +** entry is not the first associated with its term, these two parameters +** are passed 0. +** +** If parameter pColset is not NULL, then it is used to filter entries before +** the callback is invoked. +*/ +static int fts5VisitEntries( + Fts5Index *p, /* Fts5 index object */ + Fts5Colset *pColset, /* Columns filter to apply, or NULL */ + u8 *pToken, /* Buffer containing token */ + int nToken, /* Size of buffer pToken in bytes */ + int bPrefix, /* True for a prefix scan */ + void (*xVisit)(Fts5Index*, void *pCtx, Fts5Iter *pIter, const u8*, int), + void *pCtx /* Passed as second argument to xVisit() */ +){ + const int flags = (bPrefix ? FTS5INDEX_QUERY_SCAN : 0) + | FTS5INDEX_QUERY_SKIPEMPTY + | FTS5INDEX_QUERY_NOOUTPUT; + Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ + int bNewTerm = 1; + Fts5Structure *pStruct = fts5StructureRead(p); + + fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for( /* no-op */ ; + fts5MultiIterEof(p, p1)==0; + fts5MultiIterNext2(p, p1, &bNewTerm) + ){ + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + int nNew = 0; + const u8 *pNew = 0; + + p1->xSetOutputs(p1, pSeg); + if( p->rc ) break; + + if( bNewTerm ){ + nNew = pSeg->term.n; + pNew = pSeg->term.p; + if( nNew<nToken || memcmp(pToken, pNew, nToken) ) break; + } + + xVisit(p, pCtx, p1, pNew, nNew); + } + fts5MultiIterFree(p1); + + fts5StructureRelease(pStruct); + return p->rc; +} + + +/* +** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an +** array of these for each row it visits (so all iRowid fields are the same). +** Or, for an iterator used by an "ORDER BY rank" query, it accumulates an +** array of these for the entire query (in which case iRowid fields may take +** a variety of values). +** +** Each instance in the array indicates the iterator (and therefore term) +** associated with position iPos of rowid iRowid. This is used by the +** xInstToken() API. +** +** iRowid: +** Rowid for the current entry. +** +** iPos: +** Position of current entry within row. In the usual ((iCol<<32)+iOff) +** format (e.g. see macros FTS5_POS2COLUMN() and FTS5_POS2OFFSET()). +** +** iIter: +** If the Fts5TokenDataIter iterator that the entry is part of is +** actually an iterator (i.e. with nIter>0, not just a container for +** Fts5TokenDataMap structures), then this variable is an index into +** the apIter[] array. The corresponding term is that which the iterator +** at apIter[iIter] currently points to. +** +** Or, if the Fts5TokenDataIter iterator is just a container object +** (nIter==0), then iIter is an index into the term.p[] buffer where +** the term is stored. +** +** nByte: +** In the case where iIter is an index into term.p[], this variable +** is the size of the term in bytes. If iIter is an index into apIter[], +** this variable is unused. +*/ +struct Fts5TokenDataMap { + i64 iRowid; /* Row this token is located in */ + i64 iPos; /* Position of token */ + int iIter; /* Iterator token was read from */ + int nByte; /* Length of token in bytes (or 0) */ +}; + +/* +** An object used to supplement Fts5Iter for tokendata=1 iterators. +** +** This object serves two purposes. The first is as a container for an array +** of Fts5TokenDataMap structures, which are used to find the token required +** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and +** aMap[] variables. +*/ +struct Fts5TokenDataIter { + int nMapAlloc; /* Allocated size of aMap[] in entries */ + int nMap; /* Number of valid entries in aMap[] */ + Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */ + + /* The following are used for prefix-queries only. */ + Fts5Buffer terms; + + /* The following are used for other full-token tokendata queries only. */ + int nIter; + int nIterAlloc; + Fts5PoslistReader *aPoslistReader; + int *aPoslistToIter; + Fts5Iter *apIter[1]; +}; + +/* +** The two input arrays - a1[] and a2[] - are in sorted order. This function +** merges the two arrays together and writes the result to output array +** aOut[]. aOut[] is guaranteed to be large enough to hold the result. +** +** Duplicate entries are copied into the output. So the size of the output +** array is always (n1+n2) entries. +*/ +static void fts5TokendataMerge( + Fts5TokenDataMap *a1, int n1, /* Input array 1 */ + Fts5TokenDataMap *a2, int n2, /* Input array 2 */ + Fts5TokenDataMap *aOut /* Output array */ +){ + int i1 = 0; + int i2 = 0; + + assert( n1>=0 && n2>=0 ); + while( i1<n1 || i2<n2 ){ + Fts5TokenDataMap *pOut = &aOut[i1+i2]; + if( i2>=n2 || (i1<n1 && ( + a1[i1].iRowid<a2[i2].iRowid + || (a1[i1].iRowid==a2[i2].iRowid && a1[i1].iPos<=a2[i2].iPos) + ))){ + memcpy(pOut, &a1[i1], sizeof(Fts5TokenDataMap)); + i1++; + }else{ + memcpy(pOut, &a2[i2], sizeof(Fts5TokenDataMap)); + i2++; + } + } +} + + +/* +** Append a mapping to the token-map belonging to object pT. +*/ +static void fts5TokendataIterAppendMap( + Fts5Index *p, + Fts5TokenDataIter *pT, + int iIter, + int nByte, + i64 iRowid, + i64 iPos +){ + if( p->rc==SQLITE_OK ){ + if( pT->nMap==pT->nMapAlloc ){ + int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; + int nAlloc = nNew * sizeof(Fts5TokenDataMap); + Fts5TokenDataMap *aNew; + + aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc); + if( aNew==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pT->aMap[pT->nMap].iRowid = iRowid; + pT->aMap[pT->nMap].iPos = iPos; + pT->aMap[pT->nMap].iIter = iIter; + pT->aMap[pT->nMap].nByte = nByte; + pT->nMap++; + } +} + +/* +** Sort the contents of the pT->aMap[] array. +** +** The sorting algorithm requries a malloc(). If this fails, an error code +** is left in Fts5Index.rc before returning. +*/ +static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ + Fts5TokenDataMap *aTmp = 0; + int nByte = pT->nMap * sizeof(Fts5TokenDataMap); + + aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( aTmp ){ + Fts5TokenDataMap *a1 = pT->aMap; + Fts5TokenDataMap *a2 = aTmp; + i64 nHalf; + + for(nHalf=1; nHalf<pT->nMap; nHalf=nHalf*2){ + int i1; + for(i1=0; i1<pT->nMap; i1+=(nHalf*2)){ + int n1 = MIN(nHalf, pT->nMap-i1); + int n2 = MIN(nHalf, pT->nMap-i1-n1); + fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]); + } + SWAPVAL(Fts5TokenDataMap*, a1, a2); + } + + if( a1!=pT->aMap ){ + memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap)); + } + sqlite3_free(aTmp); + +#ifdef SQLITE_DEBUG + { + int ii; + for(ii=1; ii<pT->nMap; ii++){ + Fts5TokenDataMap *p1 = &pT->aMap[ii-1]; + Fts5TokenDataMap *p2 = &pT->aMap[ii]; + assert( p1->iRowid<p2->iRowid + || (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos) + ); + } + } +#endif + } +} + +/* +** Delete an Fts5TokenDataIter structure and its contents. +*/ +static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ + if( pSet ){ + int ii; + for(ii=0; ii<pSet->nIter; ii++){ + fts5MultiIterFree(pSet->apIter[ii]); + } + fts5BufferFree(&pSet->terms); + sqlite3_free(pSet->aPoslistReader); + sqlite3_free(pSet->aMap); + sqlite3_free(pSet); + } +} + + +/* +** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata() +** to pass data to prefixIterSetupTokendataCb(). +*/ +typedef struct TokendataSetupCtx TokendataSetupCtx; +struct TokendataSetupCtx { + Fts5TokenDataIter *pT; /* Object being populated with mappings */ + int iTermOff; /* Offset of current term in terms.p[] */ + int nTermByte; /* Size of current term in bytes */ +}; + +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This +** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each +** position in the current position-list. It doesn't matter that some of +** these may be out of order - they will be sorted later. +*/ +static void prefixIterSetupTokendataCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx; + int iPosOff = 0; + i64 iPos = 0; + + if( pNew ){ + pSetup->nTermByte = nNew-1; + pSetup->iTermOff = pSetup->pT->terms.n; + fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1); + } + + while( 0==sqlite3Fts5PoslistNext64( + p1->base.pData, p1->base.nData, &iPosOff, &iPos + ) ){ + fts5TokendataIterAppendMap(p, + pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos + ); + } +} + + +/* +** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries(). +*/ +typedef struct PrefixSetupCtx PrefixSetupCtx; +struct PrefixSetupCtx { + void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); + void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); + i64 iLastRowid; + int nMerge; + Fts5Buffer *aBuf; + int nBuf; + Fts5Buffer doclist; + TokendataSetupCtx *pTokendata; +}; + +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIter() +*/ +static void prefixIterSetupCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + PrefixSetupCtx *pSetup = (PrefixSetupCtx*)pCtx; + const int nMerge = pSetup->nMerge; + + if( p1->base.nData>0 ){ + if( p1->base.iRowid<=pSetup->iLastRowid && pSetup->doclist.n>0 ){ + int i; + for(i=0; p->rc==SQLITE_OK && pSetup->doclist.n; i++){ + int i1 = i*nMerge; + int iStore; + assert( i1+nMerge<=pSetup->nBuf ); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + if( pSetup->aBuf[iStore].n==0 ){ + fts5BufferSwap(&pSetup->doclist, &pSetup->aBuf[iStore]); + fts5BufferZero(&pSetup->doclist); + break; + } + } + if( iStore==i1+nMerge ){ + pSetup->xMerge(p, &pSetup->doclist, nMerge, &pSetup->aBuf[i1]); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + fts5BufferZero(&pSetup->aBuf[iStore]); + } + } + } + pSetup->iLastRowid = 0; + } + + pSetup->xAppend( + p, (u64)p1->base.iRowid-(u64)pSetup->iLastRowid, p1, &pSetup->doclist + ); + pSetup->iLastRowid = p1->base.iRowid; + } + + if( pSetup->pTokendata ){ + prefixIterSetupTokendataCb(p, (void*)pSetup->pTokendata, p1, pNew, nNew); + } +} + static void fts5SetupPrefixIter( Fts5Index *p, /* Index to read from */ int bDesc, /* True for "ORDER BY rowid DESC" */ @@ -242485,129 +249115,90 @@ static void fts5SetupPrefixIter( u8 *pToken, /* Buffer containing prefix to match */ int nToken, /* Size of buffer pToken in bytes */ Fts5Colset *pColset, /* Restrict matches to these columns */ - Fts5Iter **ppIter /* OUT: New iterator */ + Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; - Fts5Buffer *aBuf; - int nBuf = 32; - int nMerge = 1; + PrefixSetupCtx s; + TokendataSetupCtx s2; + + memset(&s, 0, sizeof(s)); + memset(&s2, 0, sizeof(s2)); + + s.nMerge = 1; + s.iLastRowid = 0; + s.nBuf = 32; + if( iIdx==0 + && p->pConfig->eDetail==FTS5_DETAIL_FULL + && p->pConfig->bPrefixInsttoken + ){ + s.pTokendata = &s2; + s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT)); + } - void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); - void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ - xMerge = fts5MergeRowidLists; - xAppend = fts5AppendRowid; + s.xMerge = fts5MergeRowidLists; + s.xAppend = fts5AppendRowid; }else{ - nMerge = FTS5_MERGE_NLIST-1; - nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ - xMerge = fts5MergePrefixLists; - xAppend = fts5AppendPoslist; + s.nMerge = FTS5_MERGE_NLIST-1; + s.nBuf = s.nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ + s.xMerge = fts5MergePrefixLists; + s.xAppend = fts5AppendPoslist; } - aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); + s.aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*s.nBuf); pStruct = fts5StructureRead(p); + assert( p->rc!=SQLITE_OK || (s.aBuf && pStruct) ); - if( aBuf && pStruct ){ - const int flags = FTS5INDEX_QUERY_SCAN - | FTS5INDEX_QUERY_SKIPEMPTY - | FTS5INDEX_QUERY_NOOUTPUT; + if( p->rc==SQLITE_OK ){ + void *pCtx = (void*)&s; int i; - i64 iLastRowid = 0; - Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; - Fts5Buffer doclist; - int bNewTerm = 1; - memset(&doclist, 0, sizeof(doclist)); + /* If iIdx is non-zero, then it is the number of a prefix-index for + ** prefixes 1 character longer than the prefix being queried for. That + ** index contains all the doclists required, except for the one + ** corresponding to the prefix itself. That one is extracted from the + ** main term index here. */ if( iIdx!=0 ){ - int dummy = 0; - const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; pToken[0] = FTS5_MAIN_PREFIX; - fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); - for(; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &dummy) - ){ - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - p1->xSetOutputs(p1, pSeg); - if( p1->base.nData ){ - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); - iLastRowid = p1->base.iRowid; - } - } - fts5MultiIterFree(p1); + fts5VisitEntries(p, pColset, pToken, nToken, 0, prefixIterSetupCb, pCtx); } pToken[0] = FTS5_MAIN_PREFIX + iIdx; - fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); - for( /* no-op */ ; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &bNewTerm) - ){ - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - int nTerm = pSeg->term.n; - const u8 *pTerm = pSeg->term.p; - p1->xSetOutputs(p1, pSeg); + fts5VisitEntries(p, pColset, pToken, nToken, 1, prefixIterSetupCb, pCtx); - assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 ); - if( bNewTerm ){ - if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break; - } - - if( p1->base.nData==0 ) continue; - - if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ - for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - int i1 = i*nMerge; - int iStore; - assert( i1+nMerge<=nBuf ); - for(iStore=i1; iStore<i1+nMerge; iStore++){ - if( aBuf[iStore].n==0 ){ - fts5BufferSwap(&doclist, &aBuf[iStore]); - fts5BufferZero(&doclist); - break; - } - } - if( iStore==i1+nMerge ){ - xMerge(p, &doclist, nMerge, &aBuf[i1]); - for(iStore=i1; iStore<i1+nMerge; iStore++){ - fts5BufferZero(&aBuf[iStore]); - } - } - } - iLastRowid = 0; - } - - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); - iLastRowid = p1->base.iRowid; - } - - assert( (nBuf%nMerge)==0 ); - for(i=0; i<nBuf; i+=nMerge){ + assert( (s.nBuf%s.nMerge)==0 ); + for(i=0; i<s.nBuf; i+=s.nMerge){ int iFree; if( p->rc==SQLITE_OK ){ - xMerge(p, &doclist, nMerge, &aBuf[i]); + s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]); } - for(iFree=i; iFree<i+nMerge; iFree++){ - fts5BufferFree(&aBuf[iFree]); + for(iFree=i; iFree<i+s.nMerge; iFree++){ + fts5BufferFree(&s.aBuf[iFree]); } } - fts5MultiIterFree(p1); - pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING); + pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING); + assert( pData!=0 || p->rc!=SQLITE_OK ); if( pData ){ pData->p = (u8*)&pData[1]; - pData->nn = pData->szLeaf = doclist.n; - if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n); + pData->nn = pData->szLeaf = s.doclist.n; + if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n); fts5MultiIterNew2(p, pData, bDesc, ppIter); } - fts5BufferFree(&doclist); + + assert( (*ppIter)!=0 || p->rc!=SQLITE_OK ); + if( p->rc==SQLITE_OK && s.pTokendata ){ + fts5TokendataIterSortMap(p, s2.pT); + (*ppIter)->pTokenDataIter = s2.pT; + s2.pT = 0; + } } + fts5TokendataIterDelete(s2.pT); + fts5BufferFree(&s.doclist); fts5StructureRelease(pStruct); - sqlite3_free(aBuf); + sqlite3_free(s.aBuf); } @@ -242739,6 +249330,7 @@ static int sqlite3Fts5IndexClose(Fts5Index *p){ sqlite3_finalize(p->pIdxWriter); sqlite3_finalize(p->pIdxDeleter); sqlite3_finalize(p->pIdxSelect); + sqlite3_finalize(p->pIdxNextSelect); sqlite3_finalize(p->pDataVersion); sqlite3_finalize(p->pDeleteFromIdx); sqlite3Fts5HashFree(p->pHash); @@ -242834,6 +249426,377 @@ static int sqlite3Fts5IndexWrite( return rc; } +/* +** pToken points to a buffer of size nToken bytes containing a search +** term, including the index number at the start, used on a tokendata=1 +** table. This function returns true if the term in buffer pBuf matches +** token pToken/nToken. +*/ +static int fts5IsTokendataPrefix( + Fts5Buffer *pBuf, + const u8 *pToken, + int nToken +){ + return ( + pBuf->n>=nToken + && 0==memcmp(pBuf->p, pToken, nToken) + && (pBuf->n==nToken || pBuf->p[nToken]==0x00) + ); +} + +/* +** Ensure the segment-iterator passed as the only argument points to EOF. +*/ +static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ + fts5DataRelease(pSeg->pLeaf); + pSeg->pLeaf = 0; +} + +/* +** This function appends iterator pAppend to Fts5TokenDataIter pIn and +** returns the result. +*/ +static Fts5TokenDataIter *fts5AppendTokendataIter( + Fts5Index *p, /* Index object (for error code) */ + Fts5TokenDataIter *pIn, /* Current Fts5TokenDataIter struct */ + Fts5Iter *pAppend /* Append this iterator */ +){ + Fts5TokenDataIter *pRet = pIn; + + if( p->rc==SQLITE_OK ){ + if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ + int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; + int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter); + Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); + + if( pNew==0 ){ + p->rc = SQLITE_NOMEM; + }else{ + if( pIn==0 ) memset(pNew, 0, nByte); + pRet = pNew; + pNew->nIterAlloc = nAlloc; + } + } + } + if( p->rc ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pAppend); + }else{ + pRet->apIter[pRet->nIter++] = pAppend; + } + assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc ); + + return pRet; +} + +/* +** The iterator passed as the only argument must be a tokendata=1 iterator +** (pIter->pTokenDataIter!=0). This function sets the iterator output +** variables (pIter->base.*) according to the contents of the current +** row. +*/ +static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ + int ii; + int nHit = 0; + i64 iRowid = SMALLEST_INT64; + int iMin = 0; + + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + + pIter->base.nData = 0; + pIter->base.pData = 0; + + for(ii=0; ii<pT->nIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( p->base.bEof==0 ){ + if( nHit==0 || p->base.iRowid<iRowid ){ + iRowid = p->base.iRowid; + nHit = 1; + pIter->base.pData = p->base.pData; + pIter->base.nData = p->base.nData; + iMin = ii; + }else if( p->base.iRowid==iRowid ){ + nHit++; + } + } + } + + if( nHit==0 ){ + pIter->base.bEof = 1; + }else{ + int eDetail = pIter->pIndex->pConfig->eDetail; + pIter->base.bEof = 0; + pIter->base.iRowid = iRowid; + + if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){ + fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, 0, iRowid, -1); + }else + if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){ + int nReader = 0; + int nByte = 0; + i64 iPrev = 0; + + /* Allocate array of iterators if they are not already allocated. */ + if( pT->aPoslistReader==0 ){ + pT->aPoslistReader = (Fts5PoslistReader*)sqlite3Fts5MallocZero( + &pIter->pIndex->rc, + pT->nIter * (sizeof(Fts5PoslistReader) + sizeof(int)) + ); + if( pT->aPoslistReader==0 ) return; + pT->aPoslistToIter = (int*)&pT->aPoslistReader[pT->nIter]; + } + + /* Populate an iterator for each poslist that will be merged */ + for(ii=0; ii<pT->nIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( iRowid==p->base.iRowid ){ + pT->aPoslistToIter[nReader] = ii; + sqlite3Fts5PoslistReaderInit( + p->base.pData, p->base.nData, &pT->aPoslistReader[nReader++] + ); + nByte += p->base.nData; + } + } + + /* Ensure the output buffer is large enough */ + if( fts5BufferGrow(&pIter->pIndex->rc, &pIter->poslist, nByte+nHit*10) ){ + return; + } + + /* Ensure the token-mapping is large enough */ + if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){ + int nNew = (pT->nMapAlloc + nByte) * 2; + Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc( + pT->aMap, nNew*sizeof(Fts5TokenDataMap) + ); + if( aNew==0 ){ + pIter->pIndex->rc = SQLITE_NOMEM; + return; + } + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pIter->poslist.n = 0; + + while( 1 ){ + i64 iMinPos = LARGEST_INT64; + + /* Find smallest position */ + iMin = 0; + for(ii=0; ii<nReader; ii++){ + Fts5PoslistReader *pReader = &pT->aPoslistReader[ii]; + if( pReader->bEof==0 ){ + if( pReader->iPos<iMinPos ){ + iMinPos = pReader->iPos; + iMin = ii; + } + } + } + + /* If all readers were at EOF, break out of the loop. */ + if( iMinPos==LARGEST_INT64 ) break; + + sqlite3Fts5PoslistSafeAppend(&pIter->poslist, &iPrev, iMinPos); + sqlite3Fts5PoslistReaderNext(&pT->aPoslistReader[iMin]); + + if( eDetail==FTS5_DETAIL_FULL ){ + pT->aMap[pT->nMap].iPos = iMinPos; + pT->aMap[pT->nMap].iIter = pT->aPoslistToIter[iMin]; + pT->aMap[pT->nMap].iRowid = iRowid; + pT->nMap++; + } + } + + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + } + } +} + +/* +** The iterator passed as the only argument must be a tokendata=1 iterator +** (pIter->pTokenDataIter!=0). This function advances the iterator. If +** argument bFrom is false, then the iterator is advanced to the next +** entry. Or, if bFrom is true, it is advanced to the first entry with +** a rowid of iFrom or greater. +*/ +static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){ + int ii; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + Fts5Index *pIndex = pIter->pIndex; + + for(ii=0; ii<pT->nIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( p->base.bEof==0 + && (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowid<iFrom)) + ){ + fts5MultiIterNext(pIndex, p, bFrom, iFrom); + while( bFrom && p->base.bEof==0 + && p->base.iRowid<iFrom + && pIndex->rc==SQLITE_OK + ){ + fts5MultiIterNext(pIndex, p, 0, 0); + } + } + } + + if( pIndex->rc==SQLITE_OK ){ + fts5IterSetOutputsTokendata(pIter); + } +} + +/* +** If the segment-iterator passed as the first argument is at EOF, then +** set pIter->term to a copy of buffer pTerm. +*/ +static void fts5TokendataSetTermIfEof(Fts5Iter *pIter, Fts5Buffer *pTerm){ + if( pIter && pIter->aSeg[0].pLeaf==0 ){ + fts5BufferSet(&pIter->pIndex->rc, &pIter->aSeg[0].term, pTerm->n, pTerm->p); + } +} + +/* +** This function sets up an iterator to use for a non-prefix query on a +** tokendata=1 table. +*/ +static Fts5Iter *fts5SetupTokendataIter( + Fts5Index *p, /* FTS index to query */ + const u8 *pToken, /* Buffer containing query term */ + int nToken, /* Size of buffer pToken in bytes */ + Fts5Colset *pColset /* Colset to filter on */ +){ + Fts5Iter *pRet = 0; + Fts5TokenDataIter *pSet = 0; + Fts5Structure *pStruct = 0; + const int flags = FTS5INDEX_QUERY_SCANONETERM | FTS5INDEX_QUERY_SCAN; + + Fts5Buffer bSeek = {0, 0, 0}; + Fts5Buffer *pSmall = 0; + + fts5IndexFlush(p); + pStruct = fts5StructureRead(p); + + while( p->rc==SQLITE_OK ){ + Fts5Iter *pPrev = pSet ? pSet->apIter[pSet->nIter-1] : 0; + Fts5Iter *pNew = 0; + Fts5SegIter *pNewIter = 0; + Fts5SegIter *pPrevIter = 0; + + int iLvl, iSeg, ii; + + pNew = fts5MultiIterAlloc(p, pStruct->nSegment); + if( pSmall ){ + fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p); + fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0"); + }else{ + fts5BufferSet(&p->rc, &bSeek, nToken, pToken); + } + if( p->rc ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pNew); + break; + } + + pNewIter = &pNew->aSeg[0]; + pPrevIter = (pPrev ? &pPrev->aSeg[0] : 0); + for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ + for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){ + Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; + int bDone = 0; + + if( pPrevIter ){ + if( fts5BufferCompare(pSmall, &pPrevIter->term) ){ + memcpy(pNewIter, pPrevIter, sizeof(Fts5SegIter)); + memset(pPrevIter, 0, sizeof(Fts5SegIter)); + bDone = 1; + }else if( pPrevIter->iEndofDoclist>pPrevIter->pLeaf->szLeaf ){ + fts5SegIterNextInit(p,(const char*)bSeek.p,bSeek.n-1,pSeg,pNewIter); + bDone = 1; + } + } + + if( bDone==0 ){ + fts5SegIterSeekInit(p, bSeek.p, bSeek.n, flags, pSeg, pNewIter); + } + + if( pPrevIter ){ + if( pPrevIter->pTombArray ){ + pNewIter->pTombArray = pPrevIter->pTombArray; + pNewIter->pTombArray->nRef++; + } + }else{ + fts5SegIterAllocTombstone(p, pNewIter); + } + + pNewIter++; + if( pPrevIter ) pPrevIter++; + if( p->rc ) break; + } + } + fts5TokendataSetTermIfEof(pPrev, pSmall); + + pNew->bSkipEmpty = 1; + pNew->pColset = pColset; + fts5IterSetOutputCb(&p->rc, pNew); + + /* Loop through all segments in the new iterator. Find the smallest + ** term that any segment-iterator points to. Iterator pNew will be + ** used for this term. Also, set any iterator that points to a term that + ** does not match pToken/nToken to point to EOF */ + pSmall = 0; + for(ii=0; ii<pNew->nSeg; ii++){ + Fts5SegIter *pII = &pNew->aSeg[ii]; + if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken) ){ + fts5SegIterSetEOF(pII); + } + if( pII->pLeaf && (!pSmall || fts5BufferCompare(pSmall, &pII->term)>0) ){ + pSmall = &pII->term; + } + } + + /* If pSmall is still NULL at this point, then the new iterator does + ** not point to any terms that match the query. So delete it and break + ** out of the loop - all required iterators have been collected. */ + if( pSmall==0 ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pNew); + break; + } + + /* Append this iterator to the set and continue. */ + pSet = fts5AppendTokendataIter(p, pSet, pNew); + } + + if( p->rc==SQLITE_OK && pSet ){ + int ii; + for(ii=0; ii<pSet->nIter; ii++){ + Fts5Iter *pIter = pSet->apIter[ii]; + int iSeg; + for(iSeg=0; iSeg<pIter->nSeg; iSeg++){ + pIter->aSeg[iSeg].flags |= FTS5_SEGITER_ONETERM; + } + fts5MultiIterFinishSetup(p, pIter); + } + } + + if( p->rc==SQLITE_OK ){ + pRet = fts5MultiIterAlloc(p, 0); + } + if( pRet ){ + pRet->nSeg = 0; + pRet->pTokenDataIter = pSet; + if( pSet ){ + fts5IterSetOutputsTokendata(pRet); + }else{ + pRet->base.bEof = 1; + } + }else{ + fts5TokendataIterDelete(pSet); + } + + fts5StructureRelease(pStruct); + fts5BufferFree(&bSeek); + return pRet; +} + /* ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. @@ -242855,8 +249818,19 @@ static int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ int iPrefixIdx = 0; /* +1 prefix index */ + int bTokendata = pConfig->bTokendata; + assert( buf.p!=0 ); if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); + /* The NOTOKENDATA flag is set when each token in a tokendata=1 table + ** should be treated individually, instead of merging all those with + ** a common prefix into a single entry. This is used, for example, by + ** queries performed as part of an integrity-check, or by the fts5vocab + ** module. */ + if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){ + bTokendata = 0; + } + /* Figure out which index to search and set iIdx accordingly. If this ** is a prefix query for which there is no prefix index, set iIdx to ** greater than pConfig->nPrefix to indicate that the query will be @@ -242882,7 +249856,10 @@ static int sqlite3Fts5IndexQuery( } } - if( iIdx<=pConfig->nPrefix ){ + if( bTokendata && iIdx==0 ){ + buf.p[0] = FTS5_MAIN_PREFIX; + pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset); + }else if( iIdx<=pConfig->nPrefix ){ /* Straight index lookup */ Fts5Structure *pStruct = fts5StructureRead(p); buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx); @@ -242893,7 +249870,7 @@ static int sqlite3Fts5IndexQuery( fts5StructureRelease(pStruct); } }else{ - /* Scan multiple terms in the main index */ + /* Scan multiple terms in the main index for a prefix query. */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); if( pRet==0 ){ @@ -242929,7 +249906,12 @@ static int sqlite3Fts5IndexQuery( static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); - fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); + if( pIter->nSeg==0 ){ + assert( pIter->pTokenDataIter ); + fts5TokendataIterNext(pIter, 0, 0); + }else{ + fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); + } return fts5IndexReturn(pIter->pIndex); } @@ -242962,7 +249944,12 @@ static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ */ static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); + if( pIter->nSeg==0 ){ + assert( pIter->pTokenDataIter ); + fts5TokendataIterNext(pIter, 1, iMatch); + }else{ + fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); + } return fts5IndexReturn(pIter->pIndex); } @@ -242977,6 +249964,175 @@ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return (z ? &z[1] : 0); } +/* +** pIter is a prefix query. This function populates pIter->pTokenDataIter +** with an Fts5TokenDataIter object containing mappings for all rows +** matched by the query. +*/ +static int fts5SetupPrefixIterTokendata( + Fts5Iter *pIter, + const char *pToken, /* Token prefix to search for */ + int nToken /* Size of pToken in bytes */ +){ + Fts5Index *p = pIter->pIndex; + Fts5Buffer token = {0, 0, 0}; + TokendataSetupCtx ctx; + + memset(&ctx, 0, sizeof(ctx)); + + fts5BufferGrow(&p->rc, &token, nToken+1); + assert( token.p!=0 || p->rc!=SQLITE_OK ); + ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT)); + + if( p->rc==SQLITE_OK ){ + + /* Fill in the token prefix to search for */ + token.p[0] = FTS5_MAIN_PREFIX; + memcpy(&token.p[1], pToken, nToken); + token.n = nToken+1; + + fts5VisitEntries( + p, 0, token.p, token.n, 1, prefixIterSetupTokendataCb, (void*)&ctx + ); + + fts5TokendataIterSortMap(p, ctx.pT); + } + + if( p->rc==SQLITE_OK ){ + pIter->pTokenDataIter = ctx.pT; + }else{ + fts5TokendataIterDelete(ctx.pT); + } + fts5BufferFree(&token); + + return fts5IndexReturn(p); +} + +/* +** This is used by xInstToken() to access the token at offset iOff, column +** iCol of row iRowid. The token is returned via output variables *ppOut +** and *pnOut. The iterator passed as the first argument must be a tokendata=1 +** iterator (pIter->pTokenDataIter!=0). +** +** pToken/nToken: +*/ +static int sqlite3Fts5IterToken( + Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, + i64 iRowid, + int iCol, + int iOff, + const char **ppOut, int *pnOut +){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + i64 iPos = (((i64)iCol)<<32) + iOff; + Fts5TokenDataMap *aMap = 0; + int i1 = 0; + int i2 = 0; + int iTest = 0; + + assert( pT || (pToken && pIter->nSeg>0) ); + if( pT==0 ){ + int rc = fts5SetupPrefixIterTokendata(pIter, pToken, nToken); + if( rc!=SQLITE_OK ) return rc; + pT = pIter->pTokenDataIter; + } + + i2 = pT->nMap; + aMap = pT->aMap; + + while( i2>i1 ){ + iTest = (i1 + i2) / 2; + + if( aMap[iTest].iRowid<iRowid ){ + i1 = iTest+1; + }else if( aMap[iTest].iRowid>iRowid ){ + i2 = iTest; + }else{ + if( aMap[iTest].iPos<iPos ){ + if( aMap[iTest].iPos<0 ){ + break; + } + i1 = iTest+1; + }else if( aMap[iTest].iPos>iPos ){ + i2 = iTest; + }else{ + break; + } + } + } + + if( i2>i1 ){ + if( pIter->nSeg==0 ){ + Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; + *ppOut = (const char*)pMap->aSeg[0].term.p+1; + *pnOut = pMap->aSeg[0].term.n-1; + }else{ + Fts5TokenDataMap *p = &aMap[iTest]; + *ppOut = (const char*)&pT->terms.p[p->iIter]; + *pnOut = aMap[iTest].nByte; + } + } + + return SQLITE_OK; +} + +/* +** Clear any existing entries from the token-map associated with the +** iterator passed as the only argument. +*/ +static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + if( pIter && pIter->pTokenDataIter + && (pIter->nSeg==0 || pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_FULL) + ){ + pIter->pTokenDataIter->nMap = 0; + } +} + +/* +** Set a token-mapping for the iterator passed as the first argument. This +** is used in detail=column or detail=none mode when a token is requested +** using the xInstToken() API. In this case the caller tokenizers the +** current row and configures the token-mapping via multiple calls to this +** function. +*/ +static int sqlite3Fts5IndexIterWriteTokendata( + Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, + i64 iRowid, int iCol, int iOff +){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + Fts5Index *p = pIter->pIndex; + i64 iPos = (((i64)iCol)<<32) + iOff; + + assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); + assert( pIter->pTokenDataIter || pIter->nSeg>0 ); + if( pIter->nSeg>0 ){ + /* This is a prefix term iterator. */ + if( pT==0 ){ + pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); + pIter->pTokenDataIter = pT; + } + if( pT ){ + fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos); + fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken); + } + }else{ + int ii; + for(ii=0; ii<pT->nIter; ii++){ + Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; + if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; + } + if( ii<pT->nIter ){ + fts5TokendataIterAppendMap(p, pT, ii, 0, iRowid, iPos); + } + } + return fts5IndexReturn(p); +} + /* ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ @@ -242984,6 +250140,7 @@ static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ if( pIndexIter ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; + fts5TokendataIterDelete(pIter->pTokenDataIter); fts5MultiIterFree(pIter); sqlite3Fts5IndexCloseReader(pIndex); } @@ -243491,7 +250648,9 @@ static int fts5QueryCksum( int eDetail = p->pConfig->eDetail; u64 cksum = *pCksum; Fts5IndexIter *pIter = 0; - int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); + int rc = sqlite3Fts5IndexQuery( + p, z, n, (flags | FTS5INDEX_QUERY_NOTOKENDATA), 0, &pIter + ); while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){ i64 rowid = pIter->iRowid; @@ -243658,7 +250817,7 @@ static void fts5IndexIntegrityCheckEmpty( } static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ - int iTermOff = 0; + i64 iTermOff = 0; int ii; Fts5Buffer buf1 = {0,0,0}; @@ -243667,7 +250826,7 @@ static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ ii = pLeaf->szLeaf; while( ii<pLeaf->nn && p->rc==SQLITE_OK ){ int res; - int iOff; + i64 iOff; int nIncr; ii += fts5GetVarint32(&pLeaf->p[ii], nIncr); @@ -244189,6 +251348,24 @@ static void fts5DecodeRowidList( } #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +static void fts5BufferAppendTerm(int *pRc, Fts5Buffer *pBuf, Fts5Buffer *pTerm){ + int ii; + fts5BufferGrow(pRc, pBuf, pTerm->n*2 + 1); + if( *pRc==SQLITE_OK ){ + for(ii=0; ii<pTerm->n; ii++){ + if( pTerm->p[ii]==0x00 ){ + pBuf->p[pBuf->n++] = '\\'; + pBuf->p[pBuf->n++] = '0'; + }else{ + pBuf->p[pBuf->n++] = pTerm->p[ii]; + } + } + pBuf->p[pBuf->n] = 0x00; + } +} +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ + #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** The implementation of user-defined scalar function fts5_decode(). @@ -244296,9 +251473,8 @@ static void fts5DecodeFunction( iOff += fts5GetVarint32(&a[iOff], nAppend); term.n = nKeep; fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]); - sqlite3Fts5BufferAppendPrintf( - &rc, &s, " term=%.*s", term.n, (const char*)term.p - ); + sqlite3Fts5BufferAppendPrintf(&rc, &s, " term="); + fts5BufferAppendTerm(&rc, &s, &term); iOff += nAppend; /* Figure out where the doclist for this term ends */ @@ -244406,9 +251582,8 @@ static void fts5DecodeFunction( fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]); iOff += nByte; - sqlite3Fts5BufferAppendPrintf( - &rc, &s, " term=%.*s", term.n, (const char*)term.p - ); + sqlite3Fts5BufferAppendPrintf(&rc, &s, " term="); + fts5BufferAppendTerm(&rc, &s, &term); iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff); } @@ -244506,7 +251681,7 @@ static int fts5structConnectMethod( /* ** We must have a single struct=? constraint that will be passed through -** into the xFilter method. If there is no valid stmt=? constraint, +** into the xFilter method. If there is no valid struct=? constraint, ** then return an SQLITE_CONSTRAINT error. */ static int fts5structBestIndexMethod( @@ -244848,8 +252023,18 @@ struct Fts5Global { Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */ Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */ Fts5Cursor *pCsr; /* First in list of all open cursors */ + u32 aLocaleHdr[4]; }; +/* +** Size of header on fts5_locale() values. And macro to access a buffer +** containing a copy of the header from an Fts5Config pointer. +*/ +#define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr )) +#define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr)) + +#define FTS5_INSTTOKEN_SUBTYPE 73 + /* ** Each auxiliary function registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part @@ -244868,11 +252053,28 @@ struct Fts5Auxiliary { ** Each tokenizer module registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part ** of the Fts5Global.pTok list. +** +** bV2Native: +** True if the tokenizer was registered using xCreateTokenizer_v2(), false +** for xCreateTokenizer(). If this variable is true, then x2 is populated +** with the routines as supplied by the caller and x1 contains synthesized +** wrapper routines. In this case the user-data pointer passed to +** x1.xCreate should be a pointer to the Fts5TokenizerModule structure, +** not a copy of pUserData. +** +** Of course, if bV2Native is false, then x1 contains the real routines and +** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule +** object should be passed to x2.xCreate. +** +** The synthesized wrapper routines are necessary for xFindTokenizer(_v2) +** calls. */ struct Fts5TokenizerModule { char *zName; /* Name of tokenizer */ void *pUserData; /* User pointer passed to xCreate() */ - fts5_tokenizer x; /* Tokenizer functions */ + int bV2Native; /* True if v2 native tokenizer */ + fts5_tokenizer x1; /* Tokenizer functions */ + fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ void (*xDestroy)(void*); /* Destructor function */ Fts5TokenizerModule *pNext; /* Next registered tokenizer module */ }; @@ -244883,7 +252085,7 @@ struct Fts5FullTable { Fts5Global *pGlobal; /* Global (connection wide) data */ Fts5Cursor *pSortCsr; /* Sort data from this cursor */ int iSavepoint; /* Successful xSavepoint()+1 */ - int bInSavepoint; + #ifdef SQLITE_DEBUG struct Fts5TransactionState ts; #endif @@ -244960,7 +252162,7 @@ struct Fts5Cursor { Fts5Auxiliary *pAux; /* Currently executing extension function */ Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */ - /* Cache used by auxiliary functions xInst() and xInstCount() */ + /* Cache used by auxiliary API functions xInst() and xInstCount() */ Fts5PoslistReader *aInstIter; /* One for each phrase */ int nInstAlloc; /* Size of aInst[] array (entries / 3) */ int nInstCount; /* Number of phrase instances */ @@ -245071,10 +252273,16 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ #endif /* -** Return true if pTab is a contentless table. +** Return true if pTab is a contentless table. If parameter bIncludeUnindexed +** is true, this includes contentless tables that store UNINDEXED columns +** only. */ -static int fts5IsContentless(Fts5FullTable *pTab){ - return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE; +static int fts5IsContentless(Fts5FullTable *pTab, int bIncludeUnindexed){ + int eContent = pTab->p.pConfig->eContent; + return ( + eContent==FTS5_CONTENT_NONE + || (bIncludeUnindexed && eContent==FTS5_CONTENT_UNINDEXED) + ); } /* @@ -245142,8 +252350,12 @@ static int fts5InitVtab( assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); } if( rc==SQLITE_OK ){ + pConfig->pzErrmsg = pzErr; pTab->p.pConfig = pConfig; pTab->pGlobal = pGlobal; + if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){ + rc = sqlite3Fts5LoadTokenizer(pConfig); + } } /* Open the index sub-system */ @@ -245165,11 +252377,7 @@ static int fts5InitVtab( /* Load the initial configuration */ if( rc==SQLITE_OK ){ - assert( pConfig->pzErrmsg==0 ); - pConfig->pzErrmsg = pzErr; - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); - sqlite3Fts5IndexRollback(pTab->p.pIndex); - pConfig->pzErrmsg = 0; + rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1); } if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ @@ -245179,6 +252387,7 @@ static int fts5InitVtab( rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } + if( pConfig ) pConfig->pzErrmsg = 0; if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); pTab = 0; @@ -245246,10 +252455,10 @@ static int fts5UsePatternMatch( ){ assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); - if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ + if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ return 1; } - if( pConfig->ePattern==FTS5_PATTERN_LIKE + if( pConfig->t.ePattern==FTS5_PATTERN_LIKE && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) ){ return 1; @@ -245296,10 +252505,10 @@ static int fts5UsePatternMatch( ** This function ensures that there is at most one "r" or "=". And that if ** there exists an "=" then there is no "<" or ">". ** -** Costs are assigned as follows: +** If an unusable MATCH operator is present in the WHERE clause, then +** SQLITE_CONSTRAINT is returned. ** -** a) If an unusable MATCH operator is present in the WHERE clause, the -** cost is unconditionally set to 1e50 (a really big number). +** Costs are assigned as follows: ** ** a) If a MATCH operator is present, the cost depends on the other ** constraints also present. As follows: @@ -245332,7 +252541,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ int bSeenEq = 0; int bSeenGt = 0; int bSeenLt = 0; - int bSeenMatch = 0; + int nSeenMatch = 0; int bSeenRank = 0; @@ -245363,18 +252572,16 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* A MATCH operator or equivalent */ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an - ** unusable plan. Set a prohibitively high cost. */ - pInfo->estimatedCost = 1e50; - assert( iIdxStr < pInfo->nConstraint*6 + 1 ); + ** unusable plan. Return SQLITE_CONSTRAINT. */ idxStr[iIdxStr] = 0; - return SQLITE_OK; + return SQLITE_CONSTRAINT; }else{ if( iCol==nCol+1 ){ if( bSeenRank ) continue; idxStr[iIdxStr++] = 'r'; bSeenRank = 1; - }else if( iCol>=0 ){ - bSeenMatch = 1; + }else{ + nSeenMatch++; idxStr[iIdxStr++] = 'M'; sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); idxStr += strlen(&idxStr[iIdxStr]); @@ -245391,6 +252598,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ idxStr += strlen(&idxStr[iIdxStr]); pInfo->aConstraintUsage[i].argvIndex = ++iCons; assert( idxStr[iIdxStr]=='\0' ); + nSeenMatch++; }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ idxStr[iIdxStr++] = '='; bSeenEq = 1; @@ -245421,12 +252629,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ } idxStr[iIdxStr] = '\0'; - /* Set idxFlags flags for the ORDER BY clause */ + /* Set idxFlags flags for the ORDER BY clause + ** + ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC". + */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; - if( iSort==(pConfig->nCol+1) && bSeenMatch ){ + if( iSort==(pConfig->nCol+1) && nSeenMatch>0 ){ idxFlags |= FTS5_BI_ORDER_RANK; - }else if( iSort==-1 ){ + }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ idxFlags |= FTS5_BI_ORDER_ROWID; } if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){ @@ -245439,14 +252650,17 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* Calculate the estimated cost based on the flags set in idxFlags. */ if( bSeenEq ){ - pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0; - if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo); + pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0; + if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo); }else if( bSeenLt && bSeenGt ){ - pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0; + pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0; }else if( bSeenLt || bSeenGt ){ - pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0; + pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0; }else{ - pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0; + pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0; + } + for(i=1; i<nSeenMatch; i++){ + pInfo->estimatedCost *= 0.4; } pInfo->idxNum = idxFlags; @@ -245678,6 +252892,16 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ ); assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) ); + /* If this cursor uses FTS5_PLAN_MATCH and this is a tokendata=1 table, + ** clear any token mappings accumulated at the fts5_index.c level. In + ** other cases, specifically FTS5_PLAN_SOURCE and FTS5_PLAN_SORTED_MATCH, + ** we need to retain the mappings for the entire query. */ + if( pCsr->ePlan==FTS5_PLAN_MATCH + && ((Fts5Table*)pCursor->pVtab)->pConfig->bTokendata + ){ + sqlite3Fts5ExprClearTokens(pCsr->pExpr); + } + if( pCsr->ePlan<3 ){ int bSkip = 0; if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc; @@ -245712,6 +252936,7 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ } }else{ rc = SQLITE_OK; + CsrFlagSet(pCsr, FTS5CSR_REQUIRE_DOCSIZE); } break; } @@ -245741,7 +252966,7 @@ static int fts5PrepareStatement( rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT, &pRet, 0); if( rc!=SQLITE_OK ){ - *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db)); + sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db)); } sqlite3_free(zSql); } @@ -245965,6 +253190,145 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){ return iDefault; } +/* +** Set the error message on the virtual table passed as the first argument. +*/ +static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ + va_list ap; /* ... printf arguments */ + va_start(ap, zFormat); + sqlite3_free(p->p.base.zErrMsg); + p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); + va_end(ap); +} + +/* +** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale +** specified by pLocale/nLocale. The buffer indicated by pLocale must remain +** valid until after the final call to sqlite3Fts5Tokenize() that will use +** the locale. +*/ +static void sqlite3Fts5SetLocale( + Fts5Config *pConfig, + const char *zLocale, + int nLocale +){ + Fts5TokenizerConfig *pT = &pConfig->t; + pT->pLocale = zLocale; + pT->nLocale = nLocale; +} + +/* +** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale(). +*/ +static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){ + sqlite3Fts5SetLocale(pConfig, 0, 0); +} + +/* +** Return true if the value passed as the only argument is an +** fts5_locale() value. +*/ +static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){ + int ret = 0; + if( sqlite3_value_type(pVal)==SQLITE_BLOB ){ + /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case. + ** If the blob was created using zeroblob(), then sqlite3_value_blob() + ** may call malloc(). If this malloc() fails, then the values returned + ** by both value_blob() and value_bytes() will be 0. If value_bytes() were + ** called first, then the NULL pointer returned by value_blob() might + ** be dereferenced. */ + const u8 *pBlob = sqlite3_value_blob(pVal); + int nBlob = sqlite3_value_bytes(pVal); + if( nBlob>FTS5_LOCALE_HDR_SIZE + && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE) + ){ + ret = 1; + } + } + return ret; +} + +/* +** Value pVal is guaranteed to be an fts5_locale() value, according to +** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale +** from the value and returns them separately. +** +** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set +** to point to buffers containing the text and locale, as utf-8, +** respectively. In this case output parameters (*pnText) and (*pnLoc) are +** set to the sizes in bytes of these two buffers. +** +** Or, if an error occurs, then an SQLite error code is returned. The final +** value of the four output parameters is undefined in this case. +*/ +static int sqlite3Fts5DecodeLocaleValue( + sqlite3_value *pVal, + const char **ppText, + int *pnText, + const char **ppLoc, + int *pnLoc +){ + const char *p = sqlite3_value_blob(pVal); + int n = sqlite3_value_bytes(pVal); + int nLoc = 0; + + assert( sqlite3_value_type(pVal)==SQLITE_BLOB ); + assert( n>FTS5_LOCALE_HDR_SIZE ); + + for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){ + if( nLoc==(n-1) ){ + return SQLITE_MISMATCH; + } + } + *ppLoc = &p[FTS5_LOCALE_HDR_SIZE]; + *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE; + + *ppText = &p[nLoc+1]; + *pnText = n - nLoc - 1; + return SQLITE_OK; +} + +/* +** Argument pVal is the text of a full-text search expression. It may or +** may not have been wrapped by fts5_locale(). This function extracts +** the text of the expression, and sets output variable (*pzText) to +** point to a nul-terminated buffer containing the expression. +** +** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called +** to set the tokenizer to use the specified locale. +** +** If output variable (*pbFreeAndReset) is set to true, then the caller +** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer +** locale, and (b) call sqlite3_free() to free (*pzText). +*/ +static int fts5ExtractExprText( + Fts5Config *pConfig, /* Fts5 configuration */ + sqlite3_value *pVal, /* Value to extract expression text from */ + char **pzText, /* OUT: nul-terminated buffer of text */ + int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */ +){ + int rc = SQLITE_OK; + + if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText); + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + } + *pbFreeAndReset = 1; + }else{ + *pzText = (char*)sqlite3_value_text(pVal); + *pbFreeAndReset = 0; + } + + return rc; +} + + /* ** This is the xFilter interface for the virtual table. See ** the virtual table xFilter method documentation for additional @@ -245995,17 +253359,12 @@ static int fts5FilterMethod( sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; + int bPrefixInsttoken = pConfig->bPrefixInsttoken; int i; int iIdxStr = 0; Fts5Expr *pExpr = 0; - if( pConfig->bLock ){ - pTab->p.base.zErrMsg = sqlite3_mprintf( - "recursively defined fts5 content table" - ); - return SQLITE_ERROR; - } - + assert( pConfig->bLock==0 ); if( pCsr->ePlan ){ fts5FreeCursorComponents(pCsr); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); @@ -246029,8 +253388,17 @@ static int fts5FilterMethod( pRank = apVal[i]; break; case 'M': { - const char *zText = (const char*)sqlite3_value_text(apVal[i]); + char *zText = 0; + int bFreeAndReset = 0; + int bInternal = 0; + + rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset); + if( rc!=SQLITE_OK ) goto filter_out; if( zText==0 ) zText = ""; + if( sqlite3_value_subtype(apVal[i])==FTS5_INSTTOKEN_SUBTYPE ){ + pConfig->bPrefixInsttoken = 1; + } + iCol = 0; do{ iCol = iCol*10 + (idxStr[iIdxStr]-'0'); @@ -246042,7 +253410,7 @@ static int fts5FilterMethod( ** indicates that the MATCH expression is not a full text query, ** but a request for an internal parameter. */ rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); - goto filter_out; + bInternal = 1; }else{ char **pzErr = &pTab->p.base.zErrMsg; rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr); @@ -246050,9 +253418,15 @@ static int fts5FilterMethod( rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); pExpr = 0; } - if( rc!=SQLITE_OK ) goto filter_out; } + if( bFreeAndReset ){ + sqlite3_free(zText); + sqlite3Fts5ClearLocale(pConfig); + } + + if( bInternal || rc!=SQLITE_OK ) goto filter_out; + break; } case 'L': @@ -246140,9 +253514,7 @@ static int fts5FilterMethod( } } }else if( pConfig->zContent==0 ){ - *pConfig->pzErrmsg = sqlite3_mprintf( - "%s: table does not support scanning", pConfig->zName - ); + fts5SetVtabError(pTab,"%s: table does not support scanning",pConfig->zName); rc = SQLITE_ERROR; }else{ /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup @@ -246166,6 +253538,7 @@ static int fts5FilterMethod( filter_out: sqlite3Fts5ExprFree(pExpr); pConfig->pzErrmsg = pzErrmsg; + pConfig->bPrefixInsttoken = bPrefixInsttoken; return rc; } @@ -246185,9 +253558,13 @@ static i64 fts5CursorRowid(Fts5Cursor *pCsr){ assert( pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE + || pCsr->ePlan==FTS5_PLAN_SCAN + || pCsr->ePlan==FTS5_PLAN_ROWID ); if( pCsr->pSorter ){ return pCsr->pSorter->iRowid; + }else if( pCsr->ePlan>=FTS5_PLAN_SCAN ){ + return sqlite3_column_int64(pCsr->pStmt, 0); }else{ return sqlite3Fts5ExprRowid(pCsr->pExpr); } @@ -246204,25 +253581,16 @@ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ int ePlan = pCsr->ePlan; assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 ); - switch( ePlan ){ - case FTS5_PLAN_SPECIAL: - *pRowid = 0; - break; - - case FTS5_PLAN_SOURCE: - case FTS5_PLAN_MATCH: - case FTS5_PLAN_SORTED_MATCH: - *pRowid = fts5CursorRowid(pCsr); - break; - - default: - *pRowid = sqlite3_column_int64(pCsr->pStmt, 0); - break; + if( ePlan==FTS5_PLAN_SPECIAL ){ + *pRowid = 0; + }else{ + *pRowid = fts5CursorRowid(pCsr); } return SQLITE_OK; } + /* ** If the cursor requires seeking (bSeekRequired flag is set), seek it. ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise. @@ -246259,8 +253627,13 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ rc = FTS5_CORRUPT; + fts5SetVtabError((Fts5FullTable*)pTab, + "fts5: missing row %lld from content table %s", + fts5CursorRowid(pCsr), + pTab->pConfig->zContent + ); }else if( pTab->pConfig->pzErrmsg ){ - *pTab->pConfig->pzErrmsg = sqlite3_mprintf( + fts5SetVtabError((Fts5FullTable*)pTab, "%s", sqlite3_errmsg(pTab->pConfig->db) ); } @@ -246269,14 +253642,6 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ return rc; } -static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ - va_list ap; /* ... printf arguments */ - va_start(ap, zFormat); - assert( p->p.base.zErrMsg==0 ); - p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); - va_end(ap); -} - /* ** This function is called to handle an FTS INSERT command. In other words, ** an INSERT statement of the form: @@ -246314,7 +253679,7 @@ static int fts5SpecialInsert( } bLoadConfig = 1; }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ - if( pConfig->eContent==FTS5_CONTENT_NONE ){ + if( fts5IsContentless(pTab, 1) ){ fts5SetVtabError(pTab, "'rebuild' may not be used with a contentless fts5 table" ); @@ -246338,7 +253703,10 @@ static int fts5SpecialInsert( }else if( 0==sqlite3_stricmp("flush", zCmd) ){ rc = sqlite3Fts5FlushToDisk(&pTab->p); }else{ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + rc = sqlite3Fts5FlushToDisk(&pTab->p); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + } if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError); } @@ -246367,7 +253735,7 @@ static int fts5SpecialDelete( int eType1 = sqlite3_value_type(apVal[1]); if( eType1==SQLITE_INTEGER ){ sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0); } return rc; } @@ -246380,7 +253748,7 @@ static void fts5StorageInsert( ){ int rc = *pRc; if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid); + rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, 0, apVal, piRowid); } if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid); @@ -246388,6 +253756,67 @@ static void fts5StorageInsert( *pRc = rc; } +/* +** +** This function is called when the user attempts an UPDATE on a contentless +** table. Parameter bRowidModified is true if the UPDATE statement modifies +** the rowid value. Parameter apVal[] contains the new values for each user +** defined column of the fts5 table. pConfig is the configuration object of the +** table being updated (guaranteed to be contentless). The contentless_delete=1 +** and contentless_unindexed=1 options may or may not be set. +** +** This function returns SQLITE_OK if the UPDATE can go ahead, or an SQLite +** error code if it cannot. In this case an error message is also loaded into +** pConfig. Output parameter (*pbContent) is set to true if the caller should +** update the %_content table only - not the FTS index or any other shadow +** table. This occurs when an UPDATE modifies only UNINDEXED columns of the +** table. +** +** An UPDATE may proceed if: +** +** * The only columns modified are UNINDEXED columns, or +** +** * The contentless_delete=1 option was specified and all of the indexed +** columns (not a subset) have been modified. +*/ +static int fts5ContentlessUpdate( + Fts5Config *pConfig, + sqlite3_value **apVal, + int bRowidModified, + int *pbContent +){ + int ii; + int bSeenIndex = 0; /* Have seen modified indexed column */ + int bSeenIndexNC = 0; /* Have seen unmodified indexed column */ + int rc = SQLITE_OK; + + for(ii=0; ii<pConfig->nCol; ii++){ + if( pConfig->abUnindexed[ii]==0 ){ + if( sqlite3_value_nochange(apVal[ii]) ){ + bSeenIndexNC++; + }else{ + bSeenIndex++; + } + } + } + + if( bSeenIndex==0 && bRowidModified==0 ){ + *pbContent = 1; + }else{ + if( bSeenIndexNC || pConfig->bContentlessDelete==0 ){ + rc = SQLITE_ERROR; + sqlite3Fts5ConfigErrmsg(pConfig, + (pConfig->bContentlessDelete ? + "%s a subset of columns on fts5 contentless-delete table: %s" : + "%s contentless fts5 table: %s") + , "cannot UPDATE", pConfig->zName + ); + } + } + + return rc; +} + /* ** This function is the implementation of the xUpdate callback used by ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be @@ -246412,7 +253841,6 @@ static int fts5UpdateMethod( Fts5Config *pConfig = pTab->p.pConfig; int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ - int bUpdateOrDelete = 0; /* A transaction must be open when this is called. */ assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); @@ -246424,7 +253852,7 @@ static int fts5UpdateMethod( ); assert( pTab->p.pConfig->pzErrmsg==0 ); if( pConfig->pgsz==0 ){ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie); if( rc!=SQLITE_OK ) return rc; } @@ -246473,88 +253901,104 @@ static int fts5UpdateMethod( assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); assert( nArg!=1 || eType0==SQLITE_INTEGER ); - /* Filter out attempts to run UPDATE or DELETE on contentless tables. - ** This is not suported. Except - they are both supported if the CREATE - ** VIRTUAL TABLE statement contained "contentless_delete=1". */ - if( eType0==SQLITE_INTEGER - && pConfig->eContent==FTS5_CONTENT_NONE - && pConfig->bContentlessDelete==0 - ){ - pTab->p.base.zErrMsg = sqlite3_mprintf( - "cannot %s contentless fts5 table: %s", - (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName - ); - rc = SQLITE_ERROR; - } - /* DELETE */ - else if( nArg==1 ){ - i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); - bUpdateOrDelete = 1; + if( nArg==1 ){ + /* It is only possible to DELETE from a contentless table if the + ** contentless_delete=1 flag is set. */ + if( fts5IsContentless(pTab, 1) && pConfig->bContentlessDelete==0 ){ + fts5SetVtabError(pTab, + "cannot DELETE from contentless fts5 table: %s", pConfig->zName + ); + rc = SQLITE_ERROR; + }else{ + i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0); + } } /* INSERT or UPDATE */ else{ int eType1 = sqlite3_value_numeric_type(apVal[1]); - if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){ - rc = SQLITE_MISMATCH; + /* It is an error to write an fts5_locale() value to a table without + ** the locale=1 option. */ + if( pConfig->bLocale==0 ){ + int ii; + for(ii=0; ii<pConfig->nCol; ii++){ + sqlite3_value *pVal = apVal[ii+2]; + if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + fts5SetVtabError(pTab, "fts5_locale() requires locale=1"); + rc = SQLITE_MISMATCH; + goto update_out; + } + } } - else if( eType0!=SQLITE_INTEGER ){ + if( eType0!=SQLITE_INTEGER ){ /* An INSERT statement. If the conflict-mode is REPLACE, first remove ** the current entry (if any). */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); - bUpdateOrDelete = 1; + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); } /* UPDATE */ else{ + Fts5Storage *pStorage = pTab->pStorage; i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ - if( eType1==SQLITE_INTEGER && iOld!=iNew ){ + int bContent = 0; /* Content only update */ + + /* If this is a contentless table (including contentless_unindexed=1 + ** tables), check if the UPDATE may proceed. */ + if( fts5IsContentless(pTab, 1) ){ + rc = fts5ContentlessUpdate(pConfig, &apVal[2], iOld!=iNew, &bContent); + if( rc!=SQLITE_OK ) goto update_out; + } + + if( eType1!=SQLITE_INTEGER ){ + rc = SQLITE_MISMATCH; + }else if( iOld!=iNew ){ + assert( bContent==0 ); if( eConflict==SQLITE_REPLACE ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iNew, 0, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); }else{ - rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); + rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageContentInsert(pStorage, 0, apVal, pRowid); + } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 0); } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid); + rc = sqlite3Fts5StorageIndexInsert(pStorage, apVal, *pRowid); } } + }else if( bContent ){ + /* This occurs when an UPDATE on a contentless table affects *only* + ** UNINDEXED columns. This is a no-op for contentless_unindexed=0 + ** tables, or a write to the %_content table only for =1 tables. */ + assert( fts5IsContentless(pTab, 1) ); + rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid); + } }else{ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); fts5StorageInsert(&rc, pTab, apVal, pRowid); } - bUpdateOrDelete = 1; + sqlite3Fts5StorageReleaseDeleteRow(pStorage); } } } - if( rc==SQLITE_OK - && bUpdateOrDelete - && pConfig->bSecureDelete - && pConfig->iVersion==FTS5_CURRENT_VERSION - ){ - rc = sqlite3Fts5StorageConfigValue( - pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE - ); - if( rc==SQLITE_OK ){ - pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; - } - } - + update_out: pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -246576,9 +254020,11 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ ** Implementation of xBegin() method. */ static int fts5BeginMethod(sqlite3_vtab *pVtab){ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); - fts5NewTransaction((Fts5FullTable*)pVtab); - return SQLITE_OK; + int rc = fts5NewTransaction((Fts5FullTable*)pVtab); + if( rc==SQLITE_OK ){ + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); + } + return rc; } /* @@ -246601,6 +254047,7 @@ static int fts5RollbackMethod(sqlite3_vtab *pVtab){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0); rc = sqlite3Fts5StorageRollback(pTab->pStorage); + pTab->p.pConfig->pgsz = 0; return rc; } @@ -246632,17 +254079,40 @@ static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){ return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); } -static int fts5ApiTokenize( +/* +** Implementation of xTokenize_v2() API. +*/ +static int fts5ApiTokenize_v2( Fts5Context *pCtx, const char *pText, int nText, + const char *pLoc, int nLoc, void *pUserData, int (*xToken)(void*, int, const char*, int, int, int) ){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); - return sqlite3Fts5Tokenize( - pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken + int rc = SQLITE_OK; + + sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pTab->pConfig, + FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken ); + sqlite3Fts5SetLocale(pTab->pConfig, 0, 0); + + return rc; +} + +/* +** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0 +** passed as the locale. +*/ +static int fts5ApiTokenize( + Fts5Context *pCtx, + const char *pText, int nText, + void *pUserData, + int (*xToken)(void*, int, const char*, int, int, int) +){ + return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken); } static int fts5ApiPhraseCount(Fts5Context *pCtx){ @@ -246655,6 +254125,49 @@ static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){ return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase); } +/* +** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This +** function extracts the text value of column iCol of the current row. +** Additionally, if there is an associated locale, it invokes +** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller +** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point +** after this function returns. +** +** If successful, (*ppText) is set to point to a buffer containing the text +** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that +** buffer in bytes. It is not guaranteed to be nul-terminated. If an error +** occurs, an SQLite error code is returned. The final values of the two +** output parameters are undefined in this case. +*/ +static int fts5TextFromStmt( + Fts5Config *pConfig, + sqlite3_stmt *pStmt, + int iCol, + const char **ppText, + int *pnText +){ + sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1); + const char *pLoc = 0; + int nLoc = 0; + int rc = SQLITE_OK; + + if( pConfig->bLocale + && pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc); + }else{ + *ppText = (const char*)sqlite3_value_text(pVal); + *pnText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){ + pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol); + nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol); + } + } + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + return rc; +} + static int fts5ApiColumnText( Fts5Context *pCtx, int iCol, @@ -246663,46 +254176,69 @@ static int fts5ApiColumnText( ){ int rc = SQLITE_OK; Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) - || pCsr->ePlan==FTS5_PLAN_SPECIAL - ){ + Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); + if( iCol<0 || iCol>=pTab->pConfig->nCol ){ + rc = SQLITE_RANGE; + }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab), 0) ){ *pz = 0; *pn = 0; }else{ rc = fts5SeekCursor(pCsr, 0); if( rc==SQLITE_OK ){ - *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1); - *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1); + rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn); + sqlite3Fts5ClearLocale(pTab->pConfig); } } return rc; } +/* +** This is called by various API functions - xInst, xPhraseFirst, +** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase +** of the current row. This function works for both detail=full tables (in +** which case the position-list was read from the fts index) or for other +** detail= modes if the row content is available. +*/ static int fts5CsrPoslist( - Fts5Cursor *pCsr, - int iPhrase, - const u8 **pa, - int *pn + Fts5Cursor *pCsr, /* Fts5 cursor object */ + int iPhrase, /* Phrase to find position list for */ + const u8 **pa, /* OUT: Pointer to position list buffer */ + int *pn /* OUT: Size of (*pa) in bytes */ ){ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; int rc = SQLITE_OK; int bLive = (pCsr->pSorter==0); - if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ - + if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ + rc = SQLITE_RANGE; + }else if( pConfig->eDetail!=FTS5_DETAIL_FULL + && fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1) + ){ + *pa = 0; + *pn = 0; + return SQLITE_OK; + }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5PoslistPopulator *aPopulator; int i; + aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive); if( aPopulator==0 ) rc = SQLITE_NOMEM; + if( rc==SQLITE_OK ){ + rc = fts5SeekCursor(pCsr, 0); + } for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){ - int n; const char *z; - rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n); + const char *z = 0; + int n = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprPopulatePoslists( pConfig, pCsr->pExpr, aPopulator, i, z, n ); } + sqlite3Fts5ClearLocale(pConfig); } sqlite3_free(aPopulator); @@ -246713,13 +254249,18 @@ static int fts5CsrPoslist( CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST); } - if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){ - Fts5Sorter *pSorter = pCsr->pSorter; - int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); - *pn = pSorter->aIdx[iPhrase] - i1; - *pa = &pSorter->aPoslist[i1]; + if( rc==SQLITE_OK ){ + if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){ + Fts5Sorter *pSorter = pCsr->pSorter; + int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); + *pn = pSorter->aIdx[iPhrase] - i1; + *pa = &pSorter->aPoslist[i1]; + }else{ + *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); + } }else{ - *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); + *pa = 0; + *pn = 0; } return rc; @@ -246790,7 +254331,8 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ aInst[0] = iBest; aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos); aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos); - if( aInst[1]<0 || aInst[1]>=nCol ){ + assert( aInst[1]>=0 ); + if( aInst[1]>=nCol ){ rc = FTS5_CORRUPT; break; } @@ -246828,12 +254370,6 @@ static int fts5ApiInst( ){ if( iIdx<0 || iIdx>=pCsr->nInstCount ){ rc = SQLITE_RANGE; -#if 0 - }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){ - *piPhrase = pCsr->aInst[iIdx*3]; - *piCol = pCsr->aInst[iIdx*3 + 2]; - *piOff = -1; -#endif }else{ *piPhrase = pCsr->aInst[iIdx*3]; *piCol = pCsr->aInst[iIdx*3 + 1]; @@ -246874,7 +254410,7 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ if( pConfig->bColumnsize ){ i64 iRowid = fts5CursorRowid(pCsr); rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize); - }else if( pConfig->zContent==0 ){ + }else if( !pConfig->zContent || pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ int i; for(i=0; i<pConfig->nCol; i++){ if( pConfig->abUnindexed[i]==0 ){ @@ -246883,17 +254419,19 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ } }else{ int i; + rc = fts5SeekCursor(pCsr, 0); for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ if( pConfig->abUnindexed[i]==0 ){ - const char *z; int n; - void *p = (void*)(&pCsr->aColumnSize[i]); + const char *z = 0; + int n = 0; pCsr->aColumnSize[i] = 0; - rc = fts5ApiColumnText(pCtx, i, &z, &n); + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5Tokenize( - pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX, + z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb ); } + sqlite3Fts5ClearLocale(pConfig); } } } @@ -246973,11 +254511,10 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){ } static void fts5ApiPhraseNext( - Fts5Context *pUnused, + Fts5Context *pCtx, Fts5PhraseIter *pIter, int *piCol, int *piOff ){ - UNUSED_PARAM(pUnused); if( pIter->a>=pIter->b ){ *piCol = -1; *piOff = -1; @@ -246985,8 +254522,12 @@ static void fts5ApiPhraseNext( int iVal; pIter->a += fts5GetVarint32(pIter->a, iVal); if( iVal==1 ){ + /* Avoid returning a (*piCol) value that is too large for the table, + ** even if the position-list is corrupt. The caller might not be + ** expecting it. */ + int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol; pIter->a += fts5GetVarint32(pIter->a, iVal); - *piCol = iVal; + *piCol = (iVal>=nCol ? nCol-1 : iVal); *piOff = 0; pIter->a += fts5GetVarint32(pIter->a, iVal); } @@ -247088,13 +254629,96 @@ static int fts5ApiPhraseFirstColumn( return rc; } +/* +** xQueryToken() API implemenetation. +*/ +static int fts5ApiQueryToken( + Fts5Context* pCtx, + int iPhrase, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + return sqlite3Fts5ExprQueryToken(pCsr->pExpr, iPhrase, iToken, ppOut, pnOut); +} + +/* +** xInstToken() API implemenetation. +*/ +static int fts5ApiInstToken( + Fts5Context *pCtx, + int iIdx, + int iToken, + const char **ppOut, int *pnOut +){ + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + int rc = SQLITE_OK; + if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0 + || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) + ){ + if( iIdx<0 || iIdx>=pCsr->nInstCount ){ + rc = SQLITE_RANGE; + }else{ + int iPhrase = pCsr->aInst[iIdx*3]; + int iCol = pCsr->aInst[iIdx*3 + 1]; + int iOff = pCsr->aInst[iIdx*3 + 2]; + i64 iRowid = fts5CursorRowid(pCsr); + rc = sqlite3Fts5ExprInstToken( + pCsr->pExpr, iRowid, iPhrase, iCol, iOff, iToken, ppOut, pnOut + ); + } + } + return rc; +} + static int fts5ApiQueryPhrase(Fts5Context*, int, void*, int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) ); +/* +** The xColumnLocale() API. +*/ +static int fts5ApiColumnLocale( + Fts5Context *pCtx, + int iCol, + const char **pzLocale, + int *pnLocale +){ + int rc = SQLITE_OK; + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; + + *pzLocale = 0; + *pnLocale = 0; + + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); + if( iCol<0 || iCol>=pConfig->nCol ){ + rc = SQLITE_RANGE; + }else if( + pConfig->abUnindexed[iCol]==0 + && 0==fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1) + && pConfig->bLocale + ){ + rc = fts5SeekCursor(pCsr, 0); + if( rc==SQLITE_OK ){ + const char *zDummy = 0; + int nDummy = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy); + if( rc==SQLITE_OK ){ + *pzLocale = pConfig->t.pLocale; + *pnLocale = pConfig->t.nLocale; + } + sqlite3Fts5ClearLocale(pConfig); + } + } + + return rc; +} + static const Fts5ExtensionApi sFts5Api = { - 2, /* iVersion */ + 4, /* iVersion */ fts5ApiUserData, fts5ApiColumnCount, fts5ApiRowCount, @@ -247114,6 +254738,10 @@ static const Fts5ExtensionApi sFts5Api = { fts5ApiPhraseNext, fts5ApiPhraseFirstColumn, fts5ApiPhraseNextColumn, + fts5ApiQueryToken, + fts5ApiInstToken, + fts5ApiColumnLocale, + fts5ApiTokenize_v2 }; /* @@ -247164,6 +254792,7 @@ static void fts5ApiInvoke( sqlite3_value **argv ){ assert( pCsr->pAux==0 ); + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); pCsr->pAux = pAux; pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv); pCsr->pAux = 0; @@ -247177,6 +254806,21 @@ static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){ return pCsr; } +/* +** Parameter zFmt is a printf() style formatting string. This function +** formats it using the trailing arguments and returns the result as +** an error message to the context passed as the first argument. +*/ +static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){ + char *zErr = 0; + va_list ap; + va_start(ap, zFmt); + zErr = sqlite3_vmprintf(zFmt, ap); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); + va_end(ap); +} + static void fts5ApiCallback( sqlite3_context *context, int argc, @@ -247192,12 +254836,13 @@ static void fts5ApiCallback( iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); - if( pCsr==0 || pCsr->ePlan==0 ){ - char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); + if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){ + fts5ResultError(context, "no such cursor: %lld", iCsrId); }else{ + sqlite3_vtab *pTab = pCsr->base.pVtab; fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); + sqlite3_free(pTab->zErrMsg); + pTab->zErrMsg = 0; } } @@ -247315,8 +254960,8 @@ static int fts5ColumnMethod( ** auxiliary function. */ sqlite3_result_int64(pCtx, pCsr->iCsrId); }else if( iCol==pConfig->nCol+1 ){ - /* The value of the "rank" column. */ + if( pCsr->ePlan==FTS5_PLAN_SOURCE ){ fts5PoslistBlob(pCtx, pCsr); }else if( @@ -247327,20 +254972,32 @@ static int fts5ColumnMethod( fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg); } } - }else if( !fts5IsContentless(pTab) ){ - pConfig->pzErrmsg = &pTab->p.base.zErrMsg; - rc = fts5SeekCursor(pCsr, 1); - if( rc==SQLITE_OK ){ - sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); + }else{ + if( !sqlite3_vtab_nochange(pCtx) && pConfig->eContent!=FTS5_CONTENT_NONE ){ + pConfig->pzErrmsg = &pTab->p.base.zErrMsg; + rc = fts5SeekCursor(pCsr, 1); + if( rc==SQLITE_OK ){ + sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1); + if( pConfig->bLocale + && pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + const char *z = 0; + int n = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n); + if( rc==SQLITE_OK ){ + sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT); + } + sqlite3Fts5ClearLocale(pConfig); + }else{ + sqlite3_result_value(pCtx, pVal); + } + } + + pConfig->pzErrmsg = 0; } - pConfig->pzErrmsg = 0; - }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){ - char *zErr = sqlite3_mprintf("cannot UPDATE a subset of " - "columns on fts5 contentless-delete table: %s", pConfig->zName - ); - sqlite3_result_error(pCtx, zErr, -1); - sqlite3_free(zErr); } + return rc; } @@ -247380,9 +255037,7 @@ static int fts5RenameMethod( ){ int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - pTab->bInSavepoint = 1; rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); - pTab->bInSavepoint = 0; return rc; } @@ -247399,26 +255054,12 @@ static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; int rc = SQLITE_OK; - char *zSql = 0; - fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); - if( pTab->bInSavepoint==0 ){ - zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", - pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName - ); - if( zSql ){ - pTab->bInSavepoint = 1; - rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0); - pTab->bInSavepoint = 0; - sqlite3_free(zSql); - }else{ - rc = SQLITE_NOMEM; - } - if( rc==SQLITE_OK ){ - pTab->iSavepoint = iSavepoint+1; - } + fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); + rc = sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; } - return rc; } @@ -247450,8 +255091,8 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); - pTab->p.pConfig->pgsz = 0; if( (iSavepoint+1)<=pTab->iSavepoint ){ + pTab->p.pConfig->pgsz = 0; rc = sqlite3Fts5StorageRollback(pTab->pStorage); } return rc; @@ -247496,47 +255137,210 @@ static int fts5CreateAux( } /* -** Register a new tokenizer. This is the implementation of the -** fts5_api.xCreateTokenizer() method. +** This function is used by xCreateTokenizer_v2() and xCreateTokenizer(). +** It allocates and partially populates a new Fts5TokenizerModule object. +** The new object is already linked into the Fts5Global context before +** returning. +** +** If successful, SQLITE_OK is returned and a pointer to the new +** Fts5TokenizerModule object returned via output parameter (*ppNew). All +** that is required is for the caller to fill in the methods in +** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native +** as appropriate. +** +** If an error occurs, an SQLite error code is returned and the final value +** of (*ppNew) undefined. */ -static int fts5CreateTokenizer( - fts5_api *pApi, /* Global context (one per db handle) */ +static int fts5NewTokenizerModule( + Fts5Global *pGlobal, /* Global context (one per db handle) */ const char *zName, /* Name of new function */ void *pUserData, /* User data for aux. function */ - fts5_tokenizer *pTokenizer, /* Tokenizer implementation */ - void(*xDestroy)(void*) /* Destructor for pUserData */ + void(*xDestroy)(void*), /* Destructor for pUserData */ + Fts5TokenizerModule **ppNew ){ - Fts5Global *pGlobal = (Fts5Global*)pApi; - Fts5TokenizerModule *pNew; - sqlite3_int64 nName; /* Size of zName and its \0 terminator */ - sqlite3_int64 nByte; /* Bytes of space to allocate */ int rc = SQLITE_OK; + Fts5TokenizerModule *pNew; + sqlite3_int64 nName; /* Size of zName and its \0 terminator */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ nName = strlen(zName) + 1; nByte = sizeof(Fts5TokenizerModule) + nName; - pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte); + *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte); if( pNew ){ - memset(pNew, 0, (size_t)nByte); pNew->zName = (char*)&pNew[1]; memcpy(pNew->zName, zName, nName); pNew->pUserData = pUserData; - pNew->x = *pTokenizer; pNew->xDestroy = xDestroy; pNew->pNext = pGlobal->pTok; pGlobal->pTok = pNew; if( pNew->pNext==0 ){ pGlobal->pDfltTok = pNew; } + } + + return rc; +} + +/* +** An instance of this type is used as the Fts5Tokenizer object for +** wrapper tokenizers - those that provide access to a v1 tokenizer via +** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer +** via the fts5_tokenizer API. +*/ +typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer; +struct Fts5VtoVTokenizer { + int bV2Native; /* True if v2 native tokenizer */ + fts5_tokenizer x1; /* Tokenizer functions */ + fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ + Fts5Tokenizer *pReal; +}; + +/* +** Create a wrapper tokenizer. The context argument pCtx points to the +** Fts5TokenizerModule object. +*/ +static int fts5VtoVCreate( + void *pCtx, + const char **azArg, + int nArg, + Fts5Tokenizer **ppOut +){ + Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx; + Fts5VtoVTokenizer *pNew = 0; + int rc = SQLITE_OK; + + pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); + if( rc==SQLITE_OK ){ + pNew->x1 = pMod->x1; + pNew->x2 = pMod->x2; + pNew->bV2Native = pMod->bV2Native; + if( pMod->bV2Native ){ + rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); + }else{ + rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); + } + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew); + pNew = 0; + } + } + + *ppOut = (Fts5Tokenizer*)pNew; + return rc; +} + +/* +** Delete an Fts5VtoVTokenizer wrapper tokenizer. +*/ +static void fts5VtoVDelete(Fts5Tokenizer *pTok){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + if( p ){ + if( p->bV2Native ){ + p->x2.xDelete(p->pReal); + }else{ + p->x1.xDelete(p->pReal); + } + sqlite3_free(p); + } +} + + +/* +** xTokenizer method for a wrapper tokenizer that offers the v1 interface +** (no support for locales). +*/ +static int fts5V1toV2Tokenize( + Fts5Tokenizer *pTok, + void *pCtx, int flags, + const char *pText, int nText, + int (*xToken)(void*, int, const char*, int, int, int) +){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + assert( p->bV2Native ); + return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken); +} + +/* +** xTokenizer method for a wrapper tokenizer that offers the v2 interface +** (with locale support). +*/ +static int fts5V2toV1Tokenize( + Fts5Tokenizer *pTok, + void *pCtx, int flags, + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)(void*, int, const char*, int, int, int) +){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + assert( p->bV2Native==0 ); + UNUSED_PARAM2(pLocale,nLocale); + return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken); +} + +/* +** Register a new tokenizer. This is the implementation of the +** fts5_api.xCreateTokenizer_v2() method. +*/ +static int fts5CreateTokenizer_v2( + fts5_api *pApi, /* Global context (one per db handle) */ + const char *zName, /* Name of new function */ + void *pUserData, /* User data for aux. function */ + fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */ + void(*xDestroy)(void*) /* Destructor for pUserData */ +){ + Fts5Global *pGlobal = (Fts5Global*)pApi; + int rc = SQLITE_OK; + + if( pTokenizer->iVersion>2 ){ + rc = SQLITE_ERROR; }else{ - rc = SQLITE_NOMEM; + Fts5TokenizerModule *pNew = 0; + rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew); + if( pNew ){ + pNew->x2 = *pTokenizer; + pNew->bV2Native = 1; + pNew->x1.xCreate = fts5VtoVCreate; + pNew->x1.xTokenize = fts5V1toV2Tokenize; + pNew->x1.xDelete = fts5VtoVDelete; + } } return rc; } +/* +** The fts5_api.xCreateTokenizer() method. +*/ +static int fts5CreateTokenizer( + fts5_api *pApi, /* Global context (one per db handle) */ + const char *zName, /* Name of new function */ + void *pUserData, /* User data for aux. function */ + fts5_tokenizer *pTokenizer, /* Tokenizer implementation */ + void(*xDestroy)(void*) /* Destructor for pUserData */ +){ + Fts5TokenizerModule *pNew = 0; + int rc = SQLITE_OK; + + rc = fts5NewTokenizerModule( + (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew + ); + if( pNew ){ + pNew->x1 = *pTokenizer; + pNew->x2.xCreate = fts5VtoVCreate; + pNew->x2.xTokenize = fts5V2toV1Tokenize; + pNew->x2.xDelete = fts5VtoVDelete; + } + return rc; +} + +/* +** Search the global context passed as the first argument for a tokenizer +** module named zName. If found, return a pointer to the Fts5TokenizerModule +** object. Otherwise, return NULL. +*/ static Fts5TokenizerModule *fts5LocateTokenizer( - Fts5Global *pGlobal, - const char *zName + Fts5Global *pGlobal, /* Global (one per db handle) object */ + const char *zName /* Name of tokenizer module to find */ ){ Fts5TokenizerModule *pMod = 0; @@ -247551,6 +255355,36 @@ static Fts5TokenizerModule *fts5LocateTokenizer( return pMod; } +/* +** Find a tokenizer. This is the implementation of the +** fts5_api.xFindTokenizer_v2() method. +*/ +static int fts5FindTokenizer_v2( + fts5_api *pApi, /* Global context (one per db handle) */ + const char *zName, /* Name of tokenizer */ + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer /* Populate this object */ +){ + int rc = SQLITE_OK; + Fts5TokenizerModule *pMod; + + pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); + if( pMod ){ + if( pMod->bV2Native ){ + *ppUserData = pMod->pUserData; + }else{ + *ppUserData = (void*)pMod; + } + *ppTokenizer = &pMod->x2; + }else{ + *ppTokenizer = 0; + *ppUserData = 0; + rc = SQLITE_ERROR; + } + + return rc; +} + /* ** Find a tokenizer. This is the implementation of the ** fts5_api.xFindTokenizer() method. @@ -247566,53 +255400,75 @@ static int fts5FindTokenizer( pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); if( pMod ){ - *pTokenizer = pMod->x; - *ppUserData = pMod->pUserData; + if( pMod->bV2Native==0 ){ + *ppUserData = pMod->pUserData; + }else{ + *ppUserData = (void*)pMod; + } + *pTokenizer = pMod->x1; }else{ - memset(pTokenizer, 0, sizeof(fts5_tokenizer)); + memset(pTokenizer, 0, sizeof(*pTokenizer)); + *ppUserData = 0; rc = SQLITE_ERROR; } return rc; } -static int sqlite3Fts5GetTokenizer( - Fts5Global *pGlobal, - const char **azArg, - int nArg, - Fts5Config *pConfig, - char **pzErr -){ - Fts5TokenizerModule *pMod; +/* +** Attempt to instantiate the tokenizer. +*/ +static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){ + const char **azArg = pConfig->t.azArg; + const int nArg = pConfig->t.nArg; + Fts5TokenizerModule *pMod = 0; int rc = SQLITE_OK; - pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]); + pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]); if( pMod==0 ){ assert( nArg>0 ); rc = SQLITE_ERROR; - *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); + sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]); }else{ - rc = pMod->x.xCreate( - pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok + int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0; + if( pMod->bV2Native ){ + xCreate = pMod->x2.xCreate; + pConfig->t.pApi2 = &pMod->x2; + }else{ + pConfig->t.pApi1 = &pMod->x1; + xCreate = pMod->x1.xCreate; + } + + rc = xCreate(pMod->pUserData, + (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok ); - pConfig->pTokApi = &pMod->x; + if( rc!=SQLITE_OK ){ - if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor"); - }else{ - pConfig->ePattern = sqlite3Fts5TokenizerPattern( - pMod->x.xCreate, pConfig->pTok + if( rc!=SQLITE_NOMEM ){ + sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor"); + } + }else if( pMod->bV2Native==0 ){ + pConfig->t.ePattern = sqlite3Fts5TokenizerPattern( + pMod->x1.xCreate, pConfig->t.pTok ); } } if( rc!=SQLITE_OK ){ - pConfig->pTokApi = 0; - pConfig->pTok = 0; + pConfig->t.pApi1 = 0; + pConfig->t.pApi2 = 0; + pConfig->t.pTok = 0; } return rc; } + +/* +** xDestroy callback passed to sqlite3_create_module(). This is invoked +** when the db handle is being closed. Free memory associated with +** tokenizers and aux functions registered with this db handle. +*/ static void fts5ModuleDestroy(void *pCtx){ Fts5TokenizerModule *pTok, *pNextTok; Fts5Auxiliary *pAux, *pNextAux; @@ -247633,6 +255489,10 @@ static void fts5ModuleDestroy(void *pCtx){ sqlite3_free(pGlobal); } +/* +** Implementation of the fts5() function used by clients to obtain the +** API pointer. +*/ static void fts5Fts5Func( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ @@ -247656,7 +255516,82 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e84010", -1, SQLITE_TRANSIENT); +} + +/* +** Implementation of fts5_locale(LOCALE, TEXT) function. +** +** If parameter LOCALE is NULL, or a zero-length string, then a copy of +** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as +** text, and the value returned is a blob consisting of: +** +** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER). +** * The LOCALE, as utf-8 text, followed by +** * 0x00, followed by +** * The TEXT, as utf-8 text. +** +** There is no final nul-terminator following the TEXT value. +*/ +static void fts5LocaleFunc( + sqlite3_context *pCtx, /* Function call context */ + int nArg, /* Number of args */ + sqlite3_value **apArg /* Function arguments */ +){ + const char *zLocale = 0; + int nLocale = 0; + const char *zText = 0; + int nText = 0; + + assert( nArg==2 ); + UNUSED_PARAM(nArg); + + zLocale = (const char*)sqlite3_value_text(apArg[0]); + nLocale = sqlite3_value_bytes(apArg[0]); + + zText = (const char*)sqlite3_value_text(apArg[1]); + nText = sqlite3_value_bytes(apArg[1]); + + if( zLocale==0 || zLocale[0]=='\0' ){ + sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT); + }else{ + Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx); + u8 *pBlob = 0; + u8 *pCsr = 0; + int nBlob = 0; + + nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText; + pBlob = (u8*)sqlite3_malloc(nBlob); + if( pBlob==0 ){ + sqlite3_result_error_nomem(pCtx); + return; + } + + pCsr = pBlob; + memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE); + pCsr += FTS5_LOCALE_HDR_SIZE; + memcpy(pCsr, zLocale, nLocale); + pCsr += nLocale; + (*pCsr++) = 0x00; + if( zText ) memcpy(pCsr, zText, nText); + assert( &pCsr[nText]==&pBlob[nBlob] ); + + sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free); + } +} + +/* +** Implementation of fts5_insttoken() function. +*/ +static void fts5InsttokenFunc( + sqlite3_context *pCtx, /* Function call context */ + int nArg, /* Number of args */ + sqlite3_value **apArg /* Function arguments */ +){ + assert( nArg==1 ); + (void)nArg; + sqlite3_result_value(pCtx, apArg[0]); + sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE); } /* @@ -247679,7 +255614,7 @@ static int fts5ShadowName(const char *zName){ ** if anything is found amiss. Return a NULL pointer if everything is ** OK. */ -static int fts5Integrity( +static int fts5IntegrityMethod( sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */ const char *zSchema, /* Name of schema in which this table lives */ const char *zTabname, /* Name of the table itself */ @@ -247687,28 +255622,29 @@ static int fts5Integrity( char **pzErr /* Write error message here */ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - Fts5Config *pConfig = pTab->p.pConfig; - char *zSql; - char *zErr = 0; int rc; + assert( pzErr!=0 && *pzErr==0 ); UNUSED_PARAM(isQuick); - zSql = sqlite3_mprintf( - "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", - zSchema, zTabname, pConfig->zName); - if( zSql==0 ) return SQLITE_NOMEM; - rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr); - sqlite3_free(zSql); - if( (rc&0xff)==SQLITE_CORRUPT ){ - *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", - zSchema, zTabname); - }else if( rc!=SQLITE_OK ){ - *pzErr = sqlite3_mprintf("unable to validate the inverted index for" - " FTS5 table %s.%s: %s", - zSchema, zTabname, zErr); + assert( pTab->p.pConfig->pzErrmsg==0 ); + pTab->p.pConfig->pzErrmsg = pzErr; + rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0); + if( *pzErr==0 && rc!=SQLITE_OK ){ + if( (rc&0xff)==SQLITE_CORRUPT ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", + zSchema, zTabname); + rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM; + }else{ + *pzErr = sqlite3_mprintf("unable to validate the inverted index for" + " FTS5 table %s.%s: %s", + zSchema, zTabname, sqlite3_errstr(rc)); + } } - sqlite3_free(zErr); - return SQLITE_OK; + + sqlite3Fts5IndexCloseReader(pTab->p.pIndex); + pTab->p.pConfig->pzErrmsg = 0; + + return rc; } static int fts5Init(sqlite3 *db){ @@ -247737,7 +255673,7 @@ static int fts5Init(sqlite3 *db){ /* xRelease */ fts5ReleaseMethod, /* xRollbackTo */ fts5RollbackToMethod, /* xShadowName */ fts5ShadowName, - /* xIntegrity */ fts5Integrity + /* xIntegrity */ fts5IntegrityMethod }; int rc; @@ -247750,10 +255686,22 @@ static int fts5Init(sqlite3 *db){ void *p = (void*)pGlobal; memset(pGlobal, 0, sizeof(Fts5Global)); pGlobal->db = db; - pGlobal->api.iVersion = 2; + pGlobal->api.iVersion = 3; pGlobal->api.xCreateFunction = fts5CreateAux; pGlobal->api.xCreateTokenizer = fts5CreateTokenizer; pGlobal->api.xFindTokenizer = fts5FindTokenizer; + pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2; + pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2; + + /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector. + ** The constants below were generated randomly. */ + sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr); + pGlobal->aLocaleHdr[0] ^= 0xF924976D; + pGlobal->aLocaleHdr[1] ^= 0x16596E13; + pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA; + pGlobal->aLocaleHdr[3] ^= 0x9B03A67F; + assert( sizeof(pGlobal->aLocaleHdr)==16 ); + rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy); if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db); if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db); @@ -247772,6 +255720,20 @@ static int fts5Init(sqlite3 *db){ p, fts5SourceIdFunc, 0, 0 ); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function( + db, "fts5_locale", 2, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE|SQLITE_SUBTYPE, + p, fts5LocaleFunc, 0, 0 + ); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function( + db, "fts5_insttoken", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + p, fts5InsttokenFunc, 0, 0 + ); + } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file @@ -247846,13 +255808,40 @@ SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){ /* #include "fts5Int.h" */ +/* +** pSavedRow: +** SQL statement FTS5_STMT_LOOKUP2 is a copy of FTS5_STMT_LOOKUP, it +** does a by-rowid lookup to retrieve a single row from the %_content +** table or equivalent external-content table/view. +** +** However, FTS5_STMT_LOOKUP2 is only used when retrieving the original +** values for a row being UPDATEd. In that case, the SQL statement is +** not reset and pSavedRow is set to point at it. This is so that the +** insert operation that follows the delete may access the original +** row values for any new values for which sqlite3_value_nochange() returns +** true. i.e. if the user executes: +** +** CREATE VIRTUAL TABLE ft USING fts5(a, b, c, locale=1); +** ... +** UPDATE fts SET a=?, b=? WHERE rowid=?; +** +** then the value passed to the xUpdate() method of this table as the +** new.c value is an sqlite3_value_nochange() value. So in this case it +** must be read from the saved row stored in Fts5Storage.pSavedRow. +** +** This is necessary - using sqlite3_value_nochange() instead of just having +** SQLite pass the original value back via xUpdate() - so as not to discard +** any locale information associated with such values. +** +*/ struct Fts5Storage { Fts5Config *pConfig; Fts5Index *pIndex; int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ i64 nTotalRow; /* Total number of rows in FTS table */ i64 *aTotalSize; /* Total sizes of each column */ - sqlite3_stmt *aStmt[11]; + sqlite3_stmt *pSavedRow; + sqlite3_stmt *aStmt[12]; }; @@ -247866,14 +255855,15 @@ struct Fts5Storage { # error "FTS5_STMT_LOOKUP mismatch" #endif -#define FTS5_STMT_INSERT_CONTENT 3 -#define FTS5_STMT_REPLACE_CONTENT 4 -#define FTS5_STMT_DELETE_CONTENT 5 -#define FTS5_STMT_REPLACE_DOCSIZE 6 -#define FTS5_STMT_DELETE_DOCSIZE 7 -#define FTS5_STMT_LOOKUP_DOCSIZE 8 -#define FTS5_STMT_REPLACE_CONFIG 9 -#define FTS5_STMT_SCAN 10 +#define FTS5_STMT_LOOKUP2 3 +#define FTS5_STMT_INSERT_CONTENT 4 +#define FTS5_STMT_REPLACE_CONTENT 5 +#define FTS5_STMT_DELETE_CONTENT 6 +#define FTS5_STMT_REPLACE_DOCSIZE 7 +#define FTS5_STMT_DELETE_DOCSIZE 8 +#define FTS5_STMT_LOOKUP_DOCSIZE 9 +#define FTS5_STMT_REPLACE_CONFIG 10 +#define FTS5_STMT_SCAN 11 /* ** Prepare the two insert statements - Fts5Storage.pInsertContent and @@ -247903,6 +255893,7 @@ static int fts5StorageGetStmt( "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC", "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC", "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */ + "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP2 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ @@ -247918,6 +255909,8 @@ static int fts5StorageGetStmt( Fts5Config *pC = p->pConfig; char *zSql = 0; + assert( ArraySize(azStmt)==ArraySize(p->aStmt) ); + switch( eStmt ){ case FTS5_STMT_SCAN: zSql = sqlite3_mprintf(azStmt[eStmt], @@ -247934,6 +255927,7 @@ static int fts5StorageGetStmt( break; case FTS5_STMT_LOOKUP: + case FTS5_STMT_LOOKUP2: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid ); @@ -247941,20 +255935,35 @@ static int fts5StorageGetStmt( case FTS5_STMT_INSERT_CONTENT: case FTS5_STMT_REPLACE_CONTENT: { - int nCol = pC->nCol + 1; - char *zBind; + char *zBind = 0; int i; - zBind = sqlite3_malloc64(1 + nCol*2); - if( zBind ){ - for(i=0; i<nCol; i++){ - zBind[i*2] = '?'; - zBind[i*2 + 1] = ','; + assert( pC->eContent==FTS5_CONTENT_NORMAL + || pC->eContent==FTS5_CONTENT_UNINDEXED + ); + + /* Add bindings for the "c*" columns - those that store the actual + ** table content. If eContent==NORMAL, then there is one binding + ** for each column. Or, if eContent==UNINDEXED, then there are only + ** bindings for the UNINDEXED columns. */ + for(i=0; rc==SQLITE_OK && i<(pC->nCol+1); i++){ + if( !i || pC->eContent==FTS5_CONTENT_NORMAL || pC->abUnindexed[i-1] ){ + zBind = sqlite3Fts5Mprintf(&rc, "%z%s?%d", zBind, zBind?",":"",i+1); } - zBind[i*2-1] = '\0'; - zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind); - sqlite3_free(zBind); } + + /* Add bindings for any "l*" columns. Only non-UNINDEXED columns + ** require these. */ + if( pC->bLocale && pC->eContent==FTS5_CONTENT_NORMAL ){ + for(i=0; rc==SQLITE_OK && i<pC->nCol; i++){ + if( pC->abUnindexed[i]==0 ){ + zBind = sqlite3Fts5Mprintf(&rc, "%z,?%d", zBind, pC->nCol+i+2); + } + } + } + + zSql = sqlite3Fts5Mprintf(&rc, azStmt[eStmt], pC->zDb, pC->zName,zBind); + sqlite3_free(zBind); break; } @@ -247980,7 +255989,7 @@ static int fts5StorageGetStmt( rc = SQLITE_NOMEM; }else{ int f = SQLITE_PREPARE_PERSISTENT; - if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB; + if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB; p->pConfig->bLock++; rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); p->pConfig->bLock--; @@ -247988,6 +255997,11 @@ static int fts5StorageGetStmt( if( rc!=SQLITE_OK && pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); } + if( rc==SQLITE_ERROR && eStmt>FTS5_STMT_LOOKUP2 && eStmt<FTS5_STMT_SCAN ){ + /* One of the internal tables - not the %_content table - is missing. + ** This counts as a corrupted table. */ + rc = SQLITE_CORRUPT; + } } } @@ -248140,9 +256154,11 @@ static int sqlite3Fts5StorageOpen( p->pIndex = pIndex; if( bCreate ){ - if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ int nDefn = 32 + pConfig->nCol*10; - char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10); + char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); if( zDefn==0 ){ rc = SQLITE_NOMEM; }else{ @@ -248151,8 +256167,20 @@ static int sqlite3Fts5StorageOpen( sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); iOff = (int)strlen(zDefn); for(i=0; i<pConfig->nCol; i++){ - sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); - iOff += (int)strlen(&zDefn[iOff]); + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->abUnindexed[i] + ){ + sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); + iOff += (int)strlen(&zDefn[iOff]); + } + } + if( pConfig->bLocale ){ + for(i=0; i<pConfig->nCol; i++){ + if( pConfig->abUnindexed[i]==0 ){ + sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i); + iOff += (int)strlen(&zDefn[iOff]); + } + } } rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); } @@ -248229,15 +256257,49 @@ static int fts5StorageInsertCallback( return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); } +/* +** This function is used as part of an UPDATE statement that modifies the +** rowid of a row. In that case, this function is called first to set +** Fts5Storage.pSavedRow to point to a statement that may be used to +** access the original values of the row being deleted - iDel. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** It is not considered an error if row iDel does not exist. In this case +** pSavedRow is not set and SQLITE_OK returned. +*/ +static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel){ + int rc = SQLITE_OK; + sqlite3_stmt *pSeek = 0; + + assert( p->pSavedRow==0 ); + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+1, &pSeek, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pSeek, 1, iDel); + if( sqlite3_step(pSeek)!=SQLITE_ROW ){ + rc = sqlite3_reset(pSeek); + }else{ + p->pSavedRow = pSeek; + } + } + + return rc; +} + /* ** If a row with rowid iDel is present in the %_content table, add the ** delete-markers to the FTS index necessary to delete it. Do not actually ** remove the %_content row at this time though. +** +** If parameter bSaveRow is true, then Fts5Storage.pSavedRow is left +** pointing to a statement (FTS5_STMT_LOOKUP2) that may be used to access +** the original values of the row being deleted. This is used by UPDATE +** statements. */ static int fts5StorageDeleteFromIndex( Fts5Storage *p, i64 iDel, - sqlite3_value **apVal + sqlite3_value **apVal, + int bSaveRow /* True to set pSavedRow */ ){ Fts5Config *pConfig = p->pConfig; sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ @@ -248246,12 +256308,21 @@ static int fts5StorageDeleteFromIndex( int iCol; Fts5InsertCtx ctx; + assert( bSaveRow==0 || apVal==0 ); + assert( bSaveRow==0 || bSaveRow==1 ); + assert( FTS5_STMT_LOOKUP2==FTS5_STMT_LOOKUP+1 ); + if( apVal==0 ){ - rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0); - if( rc!=SQLITE_OK ) return rc; - sqlite3_bind_int64(pSeek, 1, iDel); - if( sqlite3_step(pSeek)!=SQLITE_ROW ){ - return sqlite3_reset(pSeek); + if( p->pSavedRow && bSaveRow ){ + pSeek = p->pSavedRow; + p->pSavedRow = 0; + }else{ + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+bSaveRow, &pSeek, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pSeek, 1, iDel); + if( sqlite3_step(pSeek)!=SQLITE_ROW ){ + return sqlite3_reset(pSeek); + } } } @@ -248259,26 +256330,42 @@ static int fts5StorageDeleteFromIndex( ctx.iCol = -1; for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ - const char *zText; - int nText; + sqlite3_value *pVal = 0; + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + assert( pSeek==0 || apVal==0 ); assert( pSeek!=0 || apVal!=0 ); if( pSeek ){ - zText = (const char*)sqlite3_column_text(pSeek, iCol); - nText = sqlite3_column_bytes(pSeek, iCol); - }else if( ALWAYS(apVal) ){ - zText = (const char*)sqlite3_value_text(apVal[iCol-1]); - nText = sqlite3_value_bytes(apVal[iCol-1]); + pVal = sqlite3_column_value(pSeek, iCol); }else{ - continue; + pVal = apVal[iCol-1]; } - ctx.szCol = 0; - rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - zText, nText, (void*)&ctx, fts5StorageInsertCallback - ); - p->aTotalSize[iCol-1] -= (i64)ctx.szCol; - if( p->aTotalSize[iCol-1]<0 ){ - rc = FTS5_CORRUPT; + + if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale && pSeek ){ + pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); + nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); + } + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + ctx.szCol = 0; + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, + pText, nText, (void*)&ctx, fts5StorageInsertCallback + ); + p->aTotalSize[iCol-1] -= (i64)ctx.szCol; + if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ + rc = FTS5_CORRUPT; + } + sqlite3Fts5ClearLocale(pConfig); } } } @@ -248288,11 +256375,29 @@ static int fts5StorageDeleteFromIndex( p->nTotalRow--; } - rc2 = sqlite3_reset(pSeek); - if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK && bSaveRow ){ + assert( p->pSavedRow==0 ); + p->pSavedRow = pSeek; + }else{ + rc2 = sqlite3_reset(pSeek); + if( rc==SQLITE_OK ) rc = rc2; + } return rc; } +/* +** Reset any saved statement pSavedRow. Zero pSavedRow as well. This +** should be called by the xUpdate() method of the fts5 table before +** returning from any operation that may have set Fts5Storage.pSavedRow. +*/ +static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){ + assert( pStorage->pSavedRow==0 + || pStorage->pSavedRow==pStorage->aStmt[FTS5_STMT_LOOKUP2] + ); + sqlite3_reset(pStorage->pSavedRow); + pStorage->pSavedRow = 0; +} + /* ** This function is called to process a DELETE on a contentless_delete=1 ** table. It adds the tombstone required to delete the entry with rowid @@ -248305,7 +256410,9 @@ static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ int rc = SQLITE_OK; assert( p->pConfig->bContentlessDelete ); - assert( p->pConfig->eContent==FTS5_CONTENT_NONE ); + assert( p->pConfig->eContent==FTS5_CONTENT_NONE + || p->pConfig->eContent==FTS5_CONTENT_UNINDEXED + ); /* Look up the origin of the document in the %_docsize table. Store ** this in stack variable iOrigin. */ @@ -248349,12 +256456,12 @@ static int fts5StorageInsertDocsize( rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); sqlite3_bind_int64(pReplace, 3, iOrigin); } - if( rc==SQLITE_OK ){ - sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); - sqlite3_bind_null(pReplace, 2); - } + } + if( rc==SQLITE_OK ){ + sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } } return rc; @@ -248408,7 +256515,12 @@ static int fts5StorageSaveTotals(Fts5Storage *p){ /* ** Remove a row from the FTS table. */ -static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){ +static int sqlite3Fts5StorageDelete( + Fts5Storage *p, /* Storage object */ + i64 iDel, /* Rowid to delete from table */ + sqlite3_value **apVal, /* Optional - values to remove from index */ + int bSaveRow /* If true, set pSavedRow for deleted row */ +){ Fts5Config *pConfig = p->pConfig; int rc; sqlite3_stmt *pDel = 0; @@ -248424,8 +256536,14 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap if( rc==SQLITE_OK ){ if( p->pConfig->bContentlessDelete ){ rc = fts5StorageContentlessDelete(p, iDel); + if( rc==SQLITE_OK + && bSaveRow + && p->pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ + rc = sqlite3Fts5StorageFindDeleteRow(p, iDel); + } }else{ - rc = fts5StorageDeleteFromIndex(p, iDel, apVal); + rc = fts5StorageDeleteFromIndex(p, iDel, apVal, bSaveRow); } } @@ -248440,7 +256558,9 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap } /* Delete the %_content record */ - if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ if( rc==SQLITE_OK ){ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0); } @@ -248472,8 +256592,13 @@ static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){ ); if( rc==SQLITE_OK && pConfig->bColumnsize ){ rc = fts5ExecPrintf(pConfig->db, 0, - "DELETE FROM %Q.'%q_docsize';", - pConfig->zDb, pConfig->zName + "DELETE FROM %Q.'%q_docsize';", pConfig->zDb, pConfig->zName + ); + } + + if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ + rc = fts5ExecPrintf(pConfig->db, 0, + "DELETE FROM %Q.'%q_content';", pConfig->zDb, pConfig->zName ); } @@ -248503,7 +256628,7 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ } if( rc==SQLITE_OK ){ - rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); + rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, pConfig->pzErrmsg); } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){ @@ -248514,14 +256639,36 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ - const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1); - int nText = sqlite3_column_bytes(pScan, ctx.iCol+1); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageInsertCallback - ); + int nText = 0; /* Size of pText in bytes */ + const char *pText = 0; /* Pointer to buffer containing text value */ + int nLoc = 0; /* Size of pLoc in bytes */ + const char *pLoc = 0; /* Pointer to buffer containing text value */ + + sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1); + if( pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale ){ + int iCol = ctx.iCol + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(pScan, iCol); + nLoc = sqlite3_column_bytes(pScan, iCol); + } + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, + pText, nText, + (void*)&ctx, + fts5StorageInsertCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } } sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; @@ -248587,6 +256734,7 @@ static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){ */ static int sqlite3Fts5StorageContentInsert( Fts5Storage *p, + int bReplace, /* True to use REPLACE instead of INSERT */ sqlite3_value **apVal, i64 *piRowid ){ @@ -248594,7 +256742,9 @@ static int sqlite3Fts5StorageContentInsert( int rc = SQLITE_OK; /* Insert the new row into the %_content table. */ - if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent!=FTS5_CONTENT_NORMAL + && pConfig->eContent!=FTS5_CONTENT_UNINDEXED + ){ if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){ *piRowid = sqlite3_value_int64(apVal[1]); }else{ @@ -248603,9 +256753,52 @@ static int sqlite3Fts5StorageContentInsert( }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ - rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); - for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ - rc = sqlite3_bind_value(pInsert, i, apVal[i]); + + assert( FTS5_STMT_INSERT_CONTENT+1==FTS5_STMT_REPLACE_CONTENT ); + assert( bReplace==0 || bReplace==1 ); + rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT+bReplace, &pInsert, 0); + if( pInsert ) sqlite3_clear_bindings(pInsert); + + /* Bind the rowid value */ + sqlite3_bind_value(pInsert, 1, apVal[1]); + + /* Loop through values for user-defined columns. i=2 is the leftmost + ** user-defined column. As is column 1 of pSavedRow. */ + for(i=2; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ + int bUnindexed = pConfig->abUnindexed[i-2]; + if( pConfig->eContent==FTS5_CONTENT_NORMAL || bUnindexed ){ + sqlite3_value *pVal = apVal[i]; + + if( sqlite3_value_nochange(pVal) && p->pSavedRow ){ + /* This is an UPDATE statement, and user-defined column (i-2) was not + ** modified. Retrieve the value from Fts5Storage.pSavedRow. */ + pVal = sqlite3_column_value(p->pSavedRow, i-1); + if( pConfig->bLocale && bUnindexed==0 ){ + sqlite3_bind_value(pInsert, pConfig->nCol + i, + sqlite3_column_value(p->pSavedRow, pConfig->nCol + i - 1) + ); + } + }else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + const char *pText = 0; + const char *pLoc = 0; + int nText = 0; + int nLoc = 0; + assert( pConfig->bLocale ); + + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + if( rc==SQLITE_OK ){ + sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT); + if( bUnindexed==0 ){ + int iLoc = pConfig->nCol + i; + sqlite3_bind_text(pInsert, iLoc, pLoc, nLoc, SQLITE_TRANSIENT); + } + } + + continue; + } + + rc = sqlite3_bind_value(pInsert, i, pVal); + } } if( rc==SQLITE_OK ){ sqlite3_step(pInsert); @@ -248640,14 +256833,38 @@ static int sqlite3Fts5StorageIndexInsert( for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ - const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]); - int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageInsertCallback - ); + int nText = 0; /* Size of pText in bytes */ + const char *pText = 0; /* Pointer to buffer containing text value */ + int nLoc = 0; /* Size of pText in bytes */ + const char *pLoc = 0; /* Pointer to buffer containing text value */ + + sqlite3_value *pVal = apVal[ctx.iCol+2]; + if( p->pSavedRow && sqlite3_value_nochange(pVal) ){ + pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1); + if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ + int iCol = ctx.iCol + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(p->pSavedRow, iCol); + nLoc = sqlite3_column_bytes(p->pSavedRow, iCol); + } + }else{ + pVal = apVal[ctx.iCol+2]; + } + + if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, + fts5StorageInsertCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } } sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; @@ -248811,29 +257028,61 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){ rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ - if( pConfig->abUnindexed[i] ) continue; - ctx.iCol = i; - ctx.szCol = 0; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - rc = sqlite3Fts5TermsetNew(&ctx.pTermset); - } - if( rc==SQLITE_OK ){ - const char *zText = (const char*)sqlite3_column_text(pScan, i+1); - int nText = sqlite3_column_bytes(pScan, i+1); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageIntegrityCallback - ); - } - if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ - rc = FTS5_CORRUPT; - } - aTotalSize[i] += ctx.szCol; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - sqlite3Fts5TermsetFree(ctx.pTermset); - ctx.pTermset = 0; + if( pConfig->abUnindexed[i]==0 ){ + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + sqlite3_value *pVal = sqlite3_column_value(pScan, i+1); + + if( pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue( + pVal, &pText, &nText, &pLoc, &nLoc + ); + }else{ + if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ + int iCol = i + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(pScan, iCol); + nLoc = sqlite3_column_bytes(pScan, iCol); + } + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + } + + ctx.iCol = i; + ctx.szCol = 0; + + if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, + pText, nText, + (void*)&ctx, + fts5StorageIntegrityCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } + + /* If this is not a columnsize=0 database, check that the number + ** of tokens in the value matches the aColSize[] value read from + ** the %_docsize table. */ + if( rc==SQLITE_OK + && pConfig->bColumnsize + && ctx.szCol!=aColSize[i] + ){ + rc = FTS5_CORRUPT; + } + aTotalSize[i] += ctx.szCol; + if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + sqlite3Fts5TermsetFree(ctx.pTermset); + ctx.pTermset = 0; + } } } sqlite3Fts5TermsetFree(ctx.pTermset); @@ -249259,7 +257508,7 @@ static const unsigned char sqlite3Utf8Trans1[] = { c = *(zIn++); \ if( c>=0xc0 ){ \ c = sqlite3Utf8Trans1[c-0xc0]; \ - while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + while( zIn<zTerm && (*zIn & 0xc0)==0x80 ){ \ c = (c<<6) + (0x3f & *(zIn++)); \ } \ if( c<0x80 \ @@ -249290,6 +257539,12 @@ static const unsigned char sqlite3Utf8Trans1[] = { #endif /* ifndef SQLITE_AMALGAMATION */ +#define FTS5_SKIP_UTF8(zIn) { \ + if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \ + while( (((unsigned char)*zIn) & 0xc0)==0x80 ){ zIn++; } \ + } \ +} + typedef struct Unicode61Tokenizer Unicode61Tokenizer; struct Unicode61Tokenizer { unsigned char aTokenChar[128]; /* ASCII range token characters */ @@ -249441,7 +257696,6 @@ static int fts5UnicodeCreate( zCat = azArg[i+1]; } } - if( rc==SQLITE_OK ){ rc = unicodeSetCategories(p, zCat); } @@ -249471,7 +257725,6 @@ static int fts5UnicodeCreate( rc = SQLITE_ERROR; } } - }else{ rc = SQLITE_NOMEM; } @@ -249610,7 +257863,7 @@ static int fts5UnicodeTokenize( typedef struct PorterTokenizer PorterTokenizer; struct PorterTokenizer { - fts5_tokenizer tokenizer; /* Parent tokenizer module */ + fts5_tokenizer_v2 tokenizer_v2; /* Parent tokenizer module */ Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */ char aBuf[FTS5_PORTER_MAX_TOKEN + 64]; }; @@ -249622,7 +257875,7 @@ static void fts5PorterDelete(Fts5Tokenizer *pTok){ if( pTok ){ PorterTokenizer *p = (PorterTokenizer*)pTok; if( p->pTokenizer ){ - p->tokenizer.xDelete(p->pTokenizer); + p->tokenizer_v2.xDelete(p->pTokenizer); } sqlite3_free(p); } @@ -249641,6 +257894,7 @@ static int fts5PorterCreate( PorterTokenizer *pRet; void *pUserdata = 0; const char *zBase = "unicode61"; + fts5_tokenizer_v2 *pV2 = 0; if( nArg>0 ){ zBase = azArg[0]; @@ -249649,14 +257903,15 @@ static int fts5PorterCreate( pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); if( pRet ){ memset(pRet, 0, sizeof(PorterTokenizer)); - rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer); + rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2); }else{ rc = SQLITE_NOMEM; } if( rc==SQLITE_OK ){ int nArg2 = (nArg>0 ? nArg-1 : 0); - const char **azArg2 = (nArg2 ? &azArg[1] : 0); - rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer); + const char **az2 = (nArg2 ? &azArg[1] : 0); + memcpy(&pRet->tokenizer_v2, pV2, sizeof(fts5_tokenizer_v2)); + rc = pRet->tokenizer_v2.xCreate(pUserdata, az2, nArg2, &pRet->pTokenizer); } if( rc!=SQLITE_OK ){ @@ -250307,6 +258562,7 @@ static int fts5PorterTokenize( void *pCtx, int flags, const char *pText, int nText, + const char *pLoc, int nLoc, int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd) ){ PorterTokenizer *p = (PorterTokenizer*)pTokenizer; @@ -250314,8 +258570,8 @@ static int fts5PorterTokenize( sCtx.xToken = xToken; sCtx.pCtx = pCtx; sCtx.aBuf = p->aBuf; - return p->tokenizer.xTokenize( - p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb + return p->tokenizer_v2.xTokenize( + p->pTokenizer, (void*)&sCtx, flags, pText, nText, pLoc, nLoc, fts5PorterCb ); } @@ -250325,6 +258581,7 @@ static int fts5PorterTokenize( typedef struct TrigramTokenizer TrigramTokenizer; struct TrigramTokenizer { int bFold; /* True to fold to lower-case */ + int iFoldParam; /* Parameter to pass to Fts5UnicodeFold() */ }; /* @@ -250344,28 +258601,46 @@ static int fts5TriCreate( Fts5Tokenizer **ppOut ){ int rc = SQLITE_OK; - TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); + TrigramTokenizer *pNew = 0; UNUSED_PARAM(pUnused); - if( pNew==0 ){ - rc = SQLITE_NOMEM; + if( nArg%2 ){ + rc = SQLITE_ERROR; }else{ int i; - pNew->bFold = 1; - for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ - const char *zArg = azArg[i+1]; - if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ - if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ - rc = SQLITE_ERROR; + pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + pNew->bFold = 1; + pNew->iFoldParam = 0; + + for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ + const char *zArg = azArg[i+1]; + if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ + rc = SQLITE_ERROR; + }else{ + pNew->bFold = (zArg[0]=='0'); + } + }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ + if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ + rc = SQLITE_ERROR; + }else{ + pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; + } }else{ - pNew->bFold = (zArg[0]=='0'); + rc = SQLITE_ERROR; } - }else{ + } + + if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ rc = SQLITE_ERROR; } - } - if( rc!=SQLITE_OK ){ - fts5TriDelete((Fts5Tokenizer*)pNew); - pNew = 0; + + if( rc!=SQLITE_OK ){ + fts5TriDelete((Fts5Tokenizer*)pNew); + pNew = 0; + } } } *ppOut = (Fts5Tokenizer*)pNew; @@ -250385,40 +258660,65 @@ static int fts5TriTokenize( TrigramTokenizer *p = (TrigramTokenizer*)pTok; int rc = SQLITE_OK; char aBuf[32]; + char *zOut = aBuf; + int ii; const unsigned char *zIn = (const unsigned char*)pText; - const unsigned char *zEof = &zIn[nText]; - u32 iCode; + const unsigned char *zEof = (zIn ? &zIn[nText] : 0); + u32 iCode = 0; + int aStart[3]; /* Input offset of each character in aBuf[] */ UNUSED_PARAM(unusedFlags); - while( 1 ){ - char *zOut = aBuf; - int iStart = zIn - (const unsigned char*)pText; - const unsigned char *zNext; - - READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; - zNext = zIn; - if( zIn<zEof ){ - if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); + + /* Populate aBuf[] with the characters for the first trigram. */ + for(ii=0; ii<3; ii++){ + do { + aStart[ii] = zIn - (const unsigned char*)pText; + if( zIn>=zEof ) return SQLITE_OK; READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; - }else{ - break; - } - if( zIn<zEof ){ - if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); + if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); + }while( iCode==0 ); + WRITE_UTF8(zOut, iCode); + } + + /* At the start of each iteration of this loop: + ** + ** aBuf: Contains 3 characters. The 3 characters of the next trigram. + ** zOut: Points to the byte following the last character in aBuf. + ** aStart[3]: Contains the byte offset in the input text corresponding + ** to the start of each of the three characters in the buffer. + */ + assert( zIn<=zEof ); + while( 1 ){ + int iNext; /* Start of character following current tri */ + const char *z1; + + /* Read characters from the input up until the first non-diacritic */ + do { + iNext = zIn - (const unsigned char*)pText; + if( zIn>=zEof ){ + iCode = 0; + break; + } READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; - if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); - }else{ - break; - } - rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf); - if( rc!=SQLITE_OK ) break; - zIn = zNext; + if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); + }while( iCode==0 ); + + /* Pass the current trigram back to fts5 */ + rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext); + if( iCode==0 || rc!=SQLITE_OK ) break; + + /* Remove the first character from buffer aBuf[]. Append the character + ** with codepoint iCode. */ + z1 = aBuf; + FTS5_SKIP_UTF8(z1); + memmove(aBuf, z1, zOut - z1); + zOut -= (z1 - aBuf); + WRITE_UTF8(zOut, iCode); + + /* Update the aStart[] array */ + aStart[0] = aStart[1]; + aStart[1] = aStart[2]; + aStart[2] = iNext; } return rc; @@ -250441,11 +258741,23 @@ static int sqlite3Fts5TokenizerPattern( ){ if( xCreate==fts5TriCreate ){ TrigramTokenizer *p = (TrigramTokenizer*)pTok; - return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; + if( p->iFoldParam==0 ){ + return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; + } } return FTS5_PATTERN_NONE; } +/* +** Return true if the tokenizer described by p->azArg[] is the trigram +** tokenizer. This tokenizer needs to be loaded before xBestIndex is +** called for the first time in order to correctly handle LIKE/GLOB. +*/ +static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig *p){ + return (p->nArg>=1 && 0==sqlite3_stricmp(p->azArg[0], "trigram")); +} + + /* ** Register all built-in tokenizers with FTS5. */ @@ -250456,7 +258768,6 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ } aBuiltin[] = { { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, - { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }}, { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}}, }; @@ -250471,7 +258782,20 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ 0 ); } - + if( rc==SQLITE_OK ){ + fts5_tokenizer_v2 sPorter = { + 2, + fts5PorterCreate, + fts5PorterDelete, + fts5PorterTokenize + }; + rc = pApi->xCreateTokenizer_v2(pApi, + "porter", + (void*)pApi, + &sPorter, + 0 + ); + } return rc; } @@ -250841,6 +259165,9 @@ static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ default: return 1; } break; + + default: + return 1; } return 0; } @@ -251665,6 +259992,7 @@ struct Fts5VocabCursor { int nLeTerm; /* Size of zLeTerm in bytes */ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ + int colUsed; /* Copy of sqlite3_index_info.colUsed */ /* These are used by 'col' tables only */ int iCol; @@ -251691,9 +260019,11 @@ struct Fts5VocabCursor { /* ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. */ -#define FTS5_VOCAB_TERM_EQ 0x01 -#define FTS5_VOCAB_TERM_GE 0x02 -#define FTS5_VOCAB_TERM_LE 0x04 +#define FTS5_VOCAB_TERM_EQ 0x0100 +#define FTS5_VOCAB_TERM_GE 0x0200 +#define FTS5_VOCAB_TERM_LE 0x0400 + +#define FTS5_VOCAB_COLUSED_MASK 0xFF /* @@ -251870,11 +260200,13 @@ static int fts5VocabBestIndexMethod( int iTermEq = -1; int iTermGe = -1; int iTermLe = -1; - int idxNum = 0; + int idxNum = (int)pInfo->colUsed; int nArg = 0; UNUSED_PARAM(pUnused); + assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed ); + for(i=0; i<pInfo->nConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; @@ -251966,7 +260298,7 @@ static int fts5VocabOpenMethod( if( rc==SQLITE_OK ){ pVTab->zErrMsg = sqlite3_mprintf( "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl - ); + ); rc = SQLITE_ERROR; } }else{ @@ -252126,9 +260458,19 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ switch( pTab->eType ){ case FTS5_VOCAB_ROW: - if( eDetail==FTS5_DETAIL_FULL ){ - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - pCsr->aCnt[0]++; + /* Do not bother counting the number of instances if the "cnt" + ** column is not being read (according to colUsed). */ + if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){ + while( iPos<nPos ){ + u32 ii; + fts5FastGetVarint32(pPos, iPos, ii); + if( ii==1 ){ + /* New column in the position list */ + fts5FastGetVarint32(pPos, iPos, ii); + }else{ + /* An instance - increment pCsr->aCnt[] */ + pCsr->aCnt[0]++; + } } } pCsr->aDoc[0]++; @@ -252226,11 +260568,12 @@ static int fts5VocabFilterMethod( if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; + pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK); if( pEq ){ zTerm = (const char *)sqlite3_value_text(pEq); nTerm = sqlite3_value_bytes(pEq); - f = 0; + f = FTS5INDEX_QUERY_NOTOKENDATA; }else{ if( pGe ){ zTerm = (const char *)sqlite3_value_text(pGe); @@ -252393,7 +260736,7 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ } - +/* Here ends the fts5.c composite file. */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */ /************** End of fts5.c ************************************************/ @@ -252749,4 +261092,5 @@ SQLITE_API int sqlite3_stmt_init( /************** End of stmt.c ************************************************/ /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } +#endif /* SQLITE_AMALGAMATION */ /************************** End of sqlite3.c ******************************/ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3userauth.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3userauth.h deleted file mode 100644 index c6fb200c1a..0000000000 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3userauth.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -** 2014-09-08 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains the application interface definitions for the -** user-authentication extension feature. -** -** To compile with the user-authentication feature, append this file to -** end of an SQLite amalgamation header file ("sqlite3.h"), then add -** the SQLITE_USER_AUTHENTICATION compile-time option. See the -** user-auth.txt file in the same source directory as this file for -** additional information. -*/ -#ifdef SQLITE_USER_AUTHENTICATION - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** If a database contains the SQLITE_USER table, then the -** sqlite3_user_authenticate() interface must be invoked with an -** appropriate username and password prior to enable read and write -** access to the database. -** -** Return SQLITE_OK on success or SQLITE_ERROR if the username/password -** combination is incorrect or unknown. -** -** If the SQLITE_USER table is not present in the database file, then -** this interface is a harmless no-op returnning SQLITE_OK. -*/ -SQLITE_API int sqlite3_user_authenticate( - sqlite3 *db, /* The database connection */ - const char *zUsername, /* Username */ - const char *aPW, /* Password or credentials */ - int nPW /* Number of bytes in aPW[] */ -); - -/* -** The sqlite3_user_add() interface can be used (by an admin user only) -** to create a new user. When called on a no-authentication-required -** database, this routine converts the database into an authentication- -** required database, automatically makes the added user an -** administrator, and logs in the current connection as that user. -** The sqlite3_user_add() interface only works for the "main" database, not -** for any ATTACH-ed databases. Any call to sqlite3_user_add() by a -** non-admin user results in an error. -*/ -SQLITE_API int sqlite3_user_add( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to be added */ - const char *aPW, /* Password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* True to give new user admin privilege */ -); - -/* -** The sqlite3_user_change() interface can be used to change a users -** login credentials or admin privilege. Any user can change their own -** login credentials. Only an admin user can change another users login -** credentials or admin privilege setting. No user may change their own -** admin privilege setting. -*/ -SQLITE_API int sqlite3_user_change( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to change */ - const char *aPW, /* New password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* Modified admin privilege for the user */ -); - -/* -** The sqlite3_user_delete() interface can be used (by an admin user only) -** to delete a user. The currently logged-in user cannot be deleted, -** which guarantees that there is always an admin user and hence that -** the database cannot be converted into a no-authentication-required -** database. -*/ -SQLITE_API int sqlite3_user_delete( - sqlite3 *db, /* Database connection */ - const char *zUsername /* Username to remove */ -); - -#ifdef __cplusplus -} /* end of the 'extern "C"' block */ -#endif - -#endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/tclsqlite.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/tclsqlite.c index d91b2fa3f1..a590de00f5 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/tclsqlite.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/tclsqlite.c @@ -35,14 +35,23 @@ # include "msvc.h" #endif +/****** Copy of tclsqlite.h ******/ #if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" +# include "sqlite_tcl.h" /* Special case for Windows using STDCALL */ #else -# include "tcl.h" +# include <tcl.h> /* All normal cases */ # ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI +# define SQLITE_TCLAPI # endif #endif +/* Compatability between Tcl8.6 and Tcl9.0 */ +#if TCL_MAJOR_VERSION==9 +# define CONST const +#elif !defined(Tcl_Size) + typedef int Tcl_Size; +#endif +/**** End copy of tclsqlite.h ****/ + #include <errno.h> /* @@ -209,7 +218,8 @@ struct SqliteDb { struct IncrblobChannel { sqlite3_blob *pBlob; /* sqlite3 blob handle */ SqliteDb *pDb; /* Associated database connection */ - int iSeek; /* Current seek offset */ + sqlite3_int64 iSeek; /* Current seek offset */ + unsigned int isClosed; /* TCL_CLOSE_READ or TCL_CLOSE_WRITE */ Tcl_Channel channel; /* Channel identifier */ IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ @@ -249,14 +259,23 @@ static void closeIncrblobChannels(SqliteDb *pDb){ /* ** Close an incremental blob channel. */ -static int SQLITE_TCLAPI incrblobClose( +static int SQLITE_TCLAPI incrblobClose2( ClientData instanceData, - Tcl_Interp *interp + Tcl_Interp *interp, + int flags ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; - int rc = sqlite3_blob_close(p->pBlob); + int rc; sqlite3 *db = p->pDb->db; + if( flags ){ + p->isClosed |= flags; + return TCL_OK; + } + + /* If we reach this point, then we really do need to close the channel */ + rc = sqlite3_blob_close(p->pBlob); + /* Remove the channel from the SqliteDb.pIncrblob list. */ if( p->pNext ){ p->pNext->pPrev = p->pPrev; @@ -277,6 +296,13 @@ static int SQLITE_TCLAPI incrblobClose( } return TCL_OK; } +static int SQLITE_TCLAPI incrblobClose( + ClientData instanceData, + Tcl_Interp *interp +){ + return incrblobClose2(instanceData, interp, 0); +} + /* ** Read data from an incremental blob channel. @@ -288,9 +314,9 @@ static int SQLITE_TCLAPI incrblobInput( int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; - int nRead = bufSize; /* Number of bytes to read */ - int nBlob; /* Total size of the blob */ - int rc; /* sqlite error code */ + sqlite3_int64 nRead = bufSize; /* Number of bytes to read */ + sqlite3_int64 nBlob; /* Total size of the blob */ + int rc; /* sqlite error code */ nBlob = sqlite3_blob_bytes(p->pBlob); if( (p->iSeek+nRead)>nBlob ){ @@ -300,7 +326,7 @@ static int SQLITE_TCLAPI incrblobInput( return 0; } - rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek); + rc = sqlite3_blob_read(p->pBlob, (void *)buf, (int)nRead, (int)p->iSeek); if( rc!=SQLITE_OK ){ *errorCodePtr = rc; return -1; @@ -315,14 +341,14 @@ static int SQLITE_TCLAPI incrblobInput( */ static int SQLITE_TCLAPI incrblobOutput( ClientData instanceData, - CONST char *buf, + const char *buf, int toWrite, int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; - int nWrite = toWrite; /* Number of bytes to write */ - int nBlob; /* Total size of the blob */ - int rc; /* sqlite error code */ + sqlite3_int64 nWrite = toWrite; /* Number of bytes to write */ + sqlite3_int64 nBlob; /* Total size of the blob */ + int rc; /* sqlite error code */ nBlob = sqlite3_blob_bytes(p->pBlob); if( (p->iSeek+nWrite)>nBlob ){ @@ -333,7 +359,7 @@ static int SQLITE_TCLAPI incrblobOutput( return 0; } - rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek); + rc = sqlite3_blob_write(p->pBlob, (void*)buf,(int)nWrite, (int)p->iSeek); if( rc!=SQLITE_OK ){ *errorCodePtr = EIO; return -1; @@ -343,12 +369,19 @@ static int SQLITE_TCLAPI incrblobOutput( return nWrite; } +/* The datatype of Tcl_DriverWideSeekProc changes between tcl8.6 and tcl9.0 */ +#if TCL_MAJOR_VERSION==9 +# define WideSeekProcType long long +#else +# define WideSeekProcType Tcl_WideInt +#endif + /* ** Seek an incremental blob channel. */ -static int SQLITE_TCLAPI incrblobSeek( +static WideSeekProcType SQLITE_TCLAPI incrblobWideSeek( ClientData instanceData, - long offset, + WideSeekProcType offset, int seekMode, int *errorCodePtr ){ @@ -370,6 +403,14 @@ static int SQLITE_TCLAPI incrblobSeek( return p->iSeek; } +static int SQLITE_TCLAPI incrblobSeek( + ClientData instanceData, + long offset, + int seekMode, + int *errorCodePtr +){ + return incrblobWideSeek(instanceData,offset,seekMode,errorCodePtr); +} static void SQLITE_TCLAPI incrblobWatch( @@ -388,7 +429,7 @@ static int SQLITE_TCLAPI incrblobHandle( static Tcl_ChannelType IncrblobChannelType = { "incrblob", /* typeName */ - TCL_CHANNEL_VERSION_2, /* version */ + TCL_CHANNEL_VERSION_5, /* version */ incrblobClose, /* closeProc */ incrblobInput, /* inputProc */ incrblobOutput, /* outputProc */ @@ -397,11 +438,11 @@ static Tcl_ChannelType IncrblobChannelType = { 0, /* getOptionProc */ incrblobWatch, /* watchProc (this is a no-op) */ incrblobHandle, /* getHandleProc (always returns error) */ - 0, /* close2Proc */ + incrblobClose2, /* close2Proc */ 0, /* blockModeProc */ 0, /* flushProc */ 0, /* handlerProc */ - 0, /* wideSeekProc */ + incrblobWideSeek, /* wideSeekProc */ }; /* @@ -433,8 +474,9 @@ static int createIncrblobChannel( } p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); - p->iSeek = 0; + memset(p, 0, sizeof(*p)); p->pBlob = pBlob; + if( (flags & TCL_WRITABLE)==0 ) p->isClosed |= TCL_CLOSE_WRITE; sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count); p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags); @@ -474,7 +516,7 @@ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ ** characters appear in pCmd, we will report the string as unsafe. */ const char *z; - int n; + Tcl_Size n; z = Tcl_GetStringFromObj(pCmd, &n); while( n-- > 0 ){ int c = *(z++); @@ -981,7 +1023,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ ** be preserved and reused on the next invocation. */ Tcl_Obj **aArg; - int nArg; + Tcl_Size nArg; if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); return; @@ -1044,7 +1086,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); - int n; + Tcl_Size n; u8 *data; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); char c = zType[0]; @@ -1055,9 +1097,10 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ /* Only return a BLOB type if the Tcl variable is a bytearray and ** has no string representation. */ eType = SQLITE_BLOB; - }else if( (c=='b' && strcmp(zType,"boolean")==0) + }else if( (c=='b' && pVar->bytes==0 && strcmp(zType,"boolean")==0 ) + || (c=='b' && pVar->bytes==0 && strcmp(zType,"booleanString")==0 ) || (c=='w' && strcmp(zType,"wideInt")==0) - || (c=='i' && strcmp(zType,"int")==0) + || (c=='i' && strcmp(zType,"int")==0) ){ eType = SQLITE_INTEGER; }else if( c=='d' && strcmp(zType,"double")==0 ){ @@ -1091,7 +1134,8 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ } default: { data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); - sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT); + sqlite3_result_text64(context, (char *)data, n, SQLITE_TRANSIENT, + SQLITE_UTF8); break; } } @@ -1113,9 +1157,6 @@ static int auth_callback( const char *zArg2, const char *zArg3, const char *zArg4 -#ifdef SQLITE_USER_AUTHENTICATION - ,const char *zArg5 -#endif ){ const char *zCode; Tcl_DString str; @@ -1175,9 +1216,6 @@ static int auth_callback( Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); -#ifdef SQLITE_USER_AUTHENTICATION - Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); -#endif rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; @@ -1455,7 +1493,7 @@ static int dbPrepareAndBind( } } if( pVar ){ - int n; + Tcl_Size n; u8 *data; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); c = zType[0]; @@ -1468,9 +1506,13 @@ static int dbPrepareAndBind( sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); Tcl_IncrRefCount(pVar); pPreStmt->apParm[iParm++] = pVar; - }else if( c=='b' && strcmp(zType,"boolean")==0 ){ - Tcl_GetIntFromObj(interp, pVar, &n); - sqlite3_bind_int(pStmt, i, n); + }else if( c=='b' && pVar->bytes==0 + && (strcmp(zType,"booleanString")==0 + || strcmp(zType,"boolean")==0) + ){ + int nn; + Tcl_GetBooleanFromObj(interp, pVar, &nn); + sqlite3_bind_int(pStmt, i, nn); }else if( c=='d' && strcmp(zType,"double")==0 ){ double r; Tcl_GetDoubleFromObj(interp, pVar, &r); @@ -1482,7 +1524,8 @@ static int dbPrepareAndBind( sqlite3_bind_int64(pStmt, i, v); }else{ data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); - sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC); + sqlite3_bind_text64(pStmt, i, (char *)data, n, SQLITE_STATIC, + SQLITE_UTF8); Tcl_IncrRefCount(pVar); pPreStmt->apParm[iParm++] = pVar; } @@ -1804,7 +1847,8 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){ ** are 8.6 or newer, the code still tests the Tcl version at runtime. ** This allows stubs-enabled builds to be used with older Tcl libraries. */ -#if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6) +#if TCL_MAJOR_VERSION>8 || !defined(TCL_MINOR_VERSION) \ + || TCL_MINOR_VERSION>=6 # define SQLITE_TCL_NRE 1 static int DbUseNre(void){ int major, minor; @@ -1857,9 +1901,9 @@ static int SQLITE_TCLAPI DbEvalNextCmd( if( pArray==0 ){ Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0); }else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0 - && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL + && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL ){ - Tcl_UnsetVar2(interp, Tcl_GetString(pArray), + Tcl_UnsetVar2(interp, Tcl_GetString(pArray), Tcl_GetString(apColName[i]), 0); }else{ Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0); @@ -1971,7 +2015,7 @@ static int SQLITE_TCLAPI DbObjCmd( "timeout", "total_changes", "trace", "trace_v2", "transaction", "unlock_notify", "update_hook", "version", "wal_hook", - 0 + 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, @@ -2034,7 +2078,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zAuth; - int len; + Tcl_Size len; if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); } @@ -2117,7 +2161,7 @@ static int SQLITE_TCLAPI DbObjCmd( ** value of the CALLBACK as the binding. If CALLBACK returns something ** other than TCL_OK or TCL_ERROR then bind a NULL. ** - ** If CALLBACK is an empty string, then revert to the default behavior + ** If CALLBACK is an empty string, then revert to the default behavior ** which is to set the binding to NULL. ** ** If CALLBACK returns an error, that causes the statement execution to @@ -2137,7 +2181,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zCallback; - int len; + Tcl_Size len; if( pDb->zBindFallback ){ Tcl_Free(pDb->zBindFallback); } @@ -2167,7 +2211,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zBusy; - int len; + Tcl_Size len; if( pDb->zBusy ){ Tcl_Free(pDb->zBusy); } @@ -2274,7 +2318,7 @@ static int SQLITE_TCLAPI DbObjCmd( SqlCollate *pCollate; char *zName; char *zScript; - int nScript; + Tcl_Size nScript; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); return TCL_ERROR; @@ -2333,7 +2377,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ const char *zCommit; - int len; + Tcl_Size len; if( pDb->zCommit ){ Tcl_Free(pDb->zCommit); } @@ -2653,7 +2697,8 @@ static int SQLITE_TCLAPI DbObjCmd( Tcl_Obj *pValue = 0; unsigned char *pBA; unsigned char *pData; - int len, xrc; + Tcl_Size len; + int xrc; sqlite3_int64 mxSize = 0; int i; int isReadonly = 0; @@ -2711,7 +2756,7 @@ static int SQLITE_TCLAPI DbObjCmd( } deserialize_error: #endif - break; + break; } /* @@ -2821,7 +2866,7 @@ static int SQLITE_TCLAPI DbObjCmd( objv++; } if( objc<3 || objc>5 ){ - Tcl_WrongNumArgs(interp, 2, objv, + Tcl_WrongNumArgs(interp, 2, objv, "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"); return TCL_ERROR; } @@ -3024,7 +3069,7 @@ static int SQLITE_TCLAPI DbObjCmd( return TCL_ERROR; } if( objc==3 ){ - int len; + Tcl_Size len; char *zNull = Tcl_GetStringFromObj(objv[2], &len); if( pDb->zNull ){ Tcl_Free(pDb->zNull); @@ -3078,7 +3123,7 @@ static int SQLITE_TCLAPI DbObjCmd( #endif }else if( objc==4 ){ char *zProgress; - int len; + Tcl_Size len; int N; if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ return TCL_ERROR; @@ -3124,7 +3169,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zProfile; - int len; + Tcl_Size len; if( pDb->zProfile ){ Tcl_Free(pDb->zProfile); } @@ -3224,7 +3269,7 @@ static int SQLITE_TCLAPI DbObjCmd( /* ** $db serialize ?DATABASE? ** - ** Return a serialization of a database. + ** Return a serialization of a database. */ case DB_SERIALIZE: { #ifdef SQLITE_OMIT_DESERIALIZE @@ -3335,7 +3380,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zTrace; - int len; + Tcl_Size len; if( pDb->zTrace ){ Tcl_Free(pDb->zTrace); } @@ -3375,7 +3420,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zTraceV2; - int len; + Tcl_Size len; Tcl_WideInt wMask = 0; if( objc==4 ){ static const char *TTYPE_strs[] = { @@ -3384,7 +3429,7 @@ static int SQLITE_TCLAPI DbObjCmd( enum TTYPE_enum { TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE }; - int i; + Tcl_Size i; if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){ return TCL_ERROR; } @@ -3550,7 +3595,7 @@ static int SQLITE_TCLAPI DbObjCmd( */ case DB_PREUPDATE: { #ifndef SQLITE_ENABLE_PREUPDATE_HOOK - Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time", + Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time", (char*)0); rc = TCL_ERROR; #else @@ -3689,7 +3734,7 @@ static int SQLITE_TCLAPI DbObjCmd( return TCL_ERROR; } } - if( i==2 ){ + if( i==2 ){ Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC); } break; @@ -3937,7 +3982,7 @@ static int SQLITE_TCLAPI DbMain( ** The EXTERN macros are required by TCL in order to work on windows. */ EXTERN int Sqlite3_Init(Tcl_Interp *interp){ - int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR; + int rc = Tcl_InitStubs(interp, "8.5-", 0) ? TCL_OK : TCL_ERROR; if( rc==TCL_OK ){ Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); #ifndef SQLITE_3_SUFFIX_ONLY @@ -3961,14 +4006,25 @@ EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} +/* +** Versions of all of the above entry points that omit the "3" at the end +** of the name. Years ago (circa 2004) the "3" was necessary to distinguish +** SQLite version 3 from Sqlite version 2. But two decades have elapsed. +** SQLite2 is not longer a conflict. So it is ok to omit the "3". +** +** Omitting the "3" helps TCL find the entry point. +*/ +EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} +EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } +EXTERN int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } +EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } +EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } +EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} +/* Also variants with a lowercase "s" */ +EXTERN int sqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} +EXTERN int sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} -#ifndef SQLITE_3_SUFFIX_ONLY -int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } -int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } -int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } -int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } -#endif /* ** If the TCLSH macro is defined, add code to make a stand-alone program. @@ -3982,6 +4038,23 @@ int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } static const char *tclsh_main_loop(void){ static const char zMainloop[] = "if {[llength $argv]>=1} {\n" +#ifdef WIN32 + "set new [list]\n" + "foreach arg $argv {\n" + "if {[string match -* $arg] || [file exists $arg]} {\n" + "lappend new $arg\n" + "} else {\n" + "set once 0\n" + "foreach match [lsort [glob -nocomplain $arg]] {\n" + "lappend new $match\n" + "set once 1\n" + "}\n" + "if {!$once} {lappend new $arg}\n" + "}\n" + "}\n" + "set argv $new\n" + "unset new\n" +#endif "set argv0 [lindex $argv 0]\n" "set argv [lrange $argv 1 end]\n" "source $argv0\n" diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/userauth.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/userauth.c deleted file mode 100644 index 61d0db2f75..0000000000 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/userauth.c +++ /dev/null @@ -1,359 +0,0 @@ -/* -** 2014-09-08 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains the bulk of the implementation of the -** user-authentication extension feature. Some parts of the user- -** authentication code are contained within the SQLite core (in the -** src/ subdirectory of the main source code tree) but those parts -** that could reasonable be separated out are moved into this file. -** -** To compile with the user-authentication feature, append this file to -** end of an SQLite amalgamation, then add the SQLITE_USER_AUTHENTICATION -** compile-time option. See the user-auth.txt file in the same source -** directory as this file for additional information. -*/ -#ifdef SQLITE_USER_AUTHENTICATION -#ifndef SQLITEINT_H -# include "sqliteInt.h" -#endif - -/* -** Prepare an SQL statement for use by the user authentication logic. -** Return a pointer to the prepared statement on success. Return a -** NULL pointer if there is an error of any kind. -*/ -static sqlite3_stmt *sqlite3UserAuthPrepare( - sqlite3 *db, - const char *zFormat, - ... -){ - sqlite3_stmt *pStmt; - char *zSql; - int rc; - va_list ap; - u64 savedFlags = db->flags; - - va_start(ap, zFormat); - zSql = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - if( zSql==0 ) return 0; - db->flags |= SQLITE_WriteSchema; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - db->flags = savedFlags; - sqlite3_free(zSql); - if( rc ){ - sqlite3_finalize(pStmt); - pStmt = 0; - } - return pStmt; -} - -/* -** Check to see if the sqlite_user table exists in database zDb. -*/ -static int userTableExists(sqlite3 *db, const char *zDb){ - int rc; - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); - if( db->init.busy==0 ){ - char *zErr = 0; - sqlite3Init(db, &zErr); - sqlite3DbFree(db, zErr); - } - rc = sqlite3FindTable(db, "sqlite_user", zDb)!=0; - sqlite3BtreeLeaveAll(db); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Check to see if database zDb has a "sqlite_user" table and if it does -** whether that table can authenticate zUser with nPw,zPw. Write one of -** the UAUTH_* user authorization level codes into *peAuth and return a -** result code. -*/ -static int userAuthCheckLogin( - sqlite3 *db, /* The database connection to check */ - const char *zDb, /* Name of specific database to check */ - u8 *peAuth /* OUT: One of UAUTH_* constants */ -){ - sqlite3_stmt *pStmt; - int rc; - - *peAuth = UAUTH_Unknown; - if( !userTableExists(db, zDb) ){ - *peAuth = UAUTH_Admin; /* No sqlite_user table. Everybody is admin. */ - return SQLITE_OK; - } - if( db->auth.zAuthUser==0 ){ - *peAuth = UAUTH_Fail; - return SQLITE_OK; - } - pStmt = sqlite3UserAuthPrepare(db, - "SELECT pw=sqlite_crypt(?1,pw), isAdmin FROM \"%w\".sqlite_user" - " WHERE uname=?2", zDb); - if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_bind_blob(pStmt, 1, db->auth.zAuthPW, db->auth.nAuthPW,SQLITE_STATIC); - sqlite3_bind_text(pStmt, 2, db->auth.zAuthUser, -1, SQLITE_STATIC); - rc = sqlite3_step(pStmt); - if( rc==SQLITE_ROW && sqlite3_column_int(pStmt,0) ){ - *peAuth = sqlite3_column_int(pStmt, 1) + UAUTH_User; - }else{ - *peAuth = UAUTH_Fail; - } - return sqlite3_finalize(pStmt); -} -int sqlite3UserAuthCheckLogin( - sqlite3 *db, /* The database connection to check */ - const char *zDb, /* Name of specific database to check */ - u8 *peAuth /* OUT: One of UAUTH_* constants */ -){ - int rc; - u8 savedAuthLevel; - assert( zDb!=0 ); - assert( peAuth!=0 ); - savedAuthLevel = db->auth.authLevel; - db->auth.authLevel = UAUTH_Admin; - rc = userAuthCheckLogin(db, zDb, peAuth); - db->auth.authLevel = savedAuthLevel; - return rc; -} - -/* -** If the current authLevel is UAUTH_Unknown, the take actions to figure -** out what authLevel should be -*/ -void sqlite3UserAuthInit(sqlite3 *db){ - if( db->auth.authLevel==UAUTH_Unknown ){ - u8 authLevel = UAUTH_Fail; - sqlite3UserAuthCheckLogin(db, "main", &authLevel); - db->auth.authLevel = authLevel; - if( authLevel<UAUTH_Admin ) db->flags &= ~SQLITE_WriteSchema; - } -} - -/* -** Implementation of the sqlite_crypt(X,Y) function. -** -** If Y is NULL then generate a new hash for password X and return that -** hash. If Y is not null, then generate a hash for password X using the -** same salt as the previous hash Y and return the new hash. -*/ -void sqlite3CryptFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - const char *zIn; - int nIn; - u8 *zData; - u8 *zOut; - char zSalt[16]; - int nHash = 32; - zIn = sqlite3_value_blob(argv[0]); - nIn = sqlite3_value_bytes(argv[0]); - if( sqlite3_value_type(argv[1])==SQLITE_BLOB - && sqlite3_value_bytes(argv[1])==nHash+sizeof(zSalt) - ){ - memcpy(zSalt, sqlite3_value_blob(argv[1]), sizeof(zSalt)); - }else{ - sqlite3_randomness(sizeof(zSalt), zSalt); - } - zData = sqlite3_malloc( nIn+sizeof(zSalt) ); - zOut = sqlite3_malloc( nHash+sizeof(zSalt) ); - if( zOut==0 ){ - sqlite3_result_error_nomem(context); - }else{ - memcpy(zData, zSalt, sizeof(zSalt)); - memcpy(zData+sizeof(zSalt), zIn, nIn); - memcpy(zOut, zSalt, sizeof(zSalt)); - sha256(zData, (unsigned int) nIn+sizeof(zSalt), zOut+sizeof(zSalt)); - sqlite3_result_blob(context, zOut, nHash+sizeof(zSalt), sqlite3_free); - } - if (zData != 0) sqlite3_free(zData); -} - -/* -** If a database contains the SQLITE_USER table, then the -** sqlite3_user_authenticate() interface must be invoked with an -** appropriate username and password prior to enable read and write -** access to the database. -** -** Return SQLITE_OK on success or SQLITE_ERROR if the username/password -** combination is incorrect or unknown. -** -** If the SQLITE_USER table is not present in the database file, then -** this interface is a harmless no-op returnning SQLITE_OK. -*/ -SQLITE_API int sqlite3_user_authenticate( - sqlite3 *db, /* The database connection */ - const char *zUsername, /* Username */ - const char *zPW, /* Password or credentials */ - int nPW /* Number of bytes in aPW[] */ -){ - int rc; - u8 authLevel = UAUTH_Fail; - db->auth.authLevel = UAUTH_Unknown; - sqlite3_free(db->auth.zAuthUser); - sqlite3_free(db->auth.zAuthPW); - memset(&db->auth, 0, sizeof(db->auth)); - db->auth.zAuthUser = sqlite3_mprintf("%s", zUsername); - if( db->auth.zAuthUser==0 ) return SQLITE_NOMEM; - db->auth.zAuthPW = sqlite3_malloc( nPW+1 ); - if( db->auth.zAuthPW==0 ) return SQLITE_NOMEM; - memcpy(db->auth.zAuthPW,zPW,nPW); - db->auth.nAuthPW = nPW; - rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel); - db->auth.authLevel = authLevel; - sqlite3ExpirePreparedStatements(db, 0); - if( rc ){ - return rc; /* OOM error, I/O error, etc. */ - } - if( authLevel<UAUTH_User ){ - return SQLITE_AUTH; /* Incorrect username and/or password */ - } - return SQLITE_OK; /* Successful login */ -} - -/* -** The sqlite3_user_add() interface can be used (by an admin user only) -** to create a new user. When called on a no-authentication-required -** database, this routine converts the database into an authentication- -** required database, automatically makes the added user an -** administrator, and logs in the current connection as that user. -** The sqlite3_user_add() interface only works for the "main" database, not -** for any ATTACH-ed databases. Any call to sqlite3_user_add() by a -** non-admin user results in an error. -*/ -SQLITE_API int sqlite3_user_add( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to be added */ - const char *aPW, /* Password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* True to give new user admin privilege */ -){ - sqlite3_stmt *pStmt; - int rc; - sqlite3UserAuthInit(db); - if( db->auth.authLevel<UAUTH_Admin ) return SQLITE_AUTH; - if( !userTableExists(db, "main") ){ - if( !isAdmin ) return SQLITE_AUTH; - pStmt = sqlite3UserAuthPrepare(db, - "CREATE TABLE sqlite_user(\n" - " uname TEXT PRIMARY KEY,\n" - " isAdmin BOOLEAN,\n" - " pw BLOB\n" - ") WITHOUT ROWID;"); - if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_step(pStmt); - rc = sqlite3_finalize(pStmt); - if( rc ) return rc; - } - pStmt = sqlite3UserAuthPrepare(db, - "INSERT INTO sqlite_user(uname,isAdmin,pw)" - " VALUES(%Q,%d,sqlite_crypt(?1,NULL))", - zUsername, isAdmin!=0); - if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); - sqlite3_step(pStmt); - rc = sqlite3_finalize(pStmt); - if( rc ) return rc; - if( db->auth.zAuthUser==0 ){ - assert( isAdmin!=0 ); - sqlite3_user_authenticate(db, zUsername, aPW, nPW); - } - return SQLITE_OK; -} - -/* -** The sqlite3_user_change() interface can be used to change a users -** login credentials or admin privilege. Any user can change their own -** login credentials. Only an admin user can change another users login -** credentials or admin privilege setting. No user may change their own -** admin privilege setting. -*/ -SQLITE_API int sqlite3_user_change( - sqlite3 *db, /* Database connection */ - const char *zUsername, /* Username to change */ - const char *aPW, /* Modified password or credentials */ - int nPW, /* Number of bytes in aPW[] */ - int isAdmin /* Modified admin privilege for the user */ -){ - sqlite3_stmt *pStmt; - int rc = SQLITE_OK; - u8 authLevel; - - authLevel = db->auth.authLevel; - if( authLevel<UAUTH_User ){ - /* Must be logged in to make a change */ - return SQLITE_AUTH; - } - if( strcmp(db->auth.zAuthUser, zUsername)!=0 ){ - if( db->auth.authLevel<UAUTH_Admin ){ - /* Must be an administrator to change a different user */ - return SQLITE_AUTH; - } - }else if( isAdmin!=(authLevel==UAUTH_Admin) ){ - /* Cannot change the isAdmin setting for self */ - return SQLITE_AUTH; - } - db->auth.authLevel = UAUTH_Admin; - if( !userTableExists(db, "main") ){ - /* This routine is a no-op if the user to be modified does not exist */ - }else{ - pStmt = sqlite3UserAuthPrepare(db, - "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)" - " WHERE uname=%Q", isAdmin, zUsername); - if( pStmt==0 ){ - rc = SQLITE_NOMEM; - }else{ - sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); - sqlite3_step(pStmt); - rc = sqlite3_finalize(pStmt); - } - } - db->auth.authLevel = authLevel; - return rc; -} - -/* -** The sqlite3_user_delete() interface can be used (by an admin user only) -** to delete a user. The currently logged-in user cannot be deleted, -** which guarantees that there is always an admin user and hence that -** the database cannot be converted into a no-authentication-required -** database. -*/ -SQLITE_API int sqlite3_user_delete( - sqlite3 *db, /* Database connection */ - const char *zUsername /* Username to remove */ -){ - sqlite3_stmt *pStmt; - if( db->auth.authLevel<UAUTH_Admin ){ - /* Must be an administrator to delete a user */ - return SQLITE_AUTH; - } - if( strcmp(db->auth.zAuthUser, zUsername)==0 ){ - /* Cannot delete self */ - return SQLITE_AUTH; - } - if( !userTableExists(db, "main") ){ - /* This routine is a no-op if the user to be deleted does not exist */ - return SQLITE_OK; - } - pStmt = sqlite3UserAuthPrepare(db, - "DELETE FROM sqlite_user WHERE uname=%Q", zUsername); - if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_step(pStmt); - return sqlite3_finalize(pStmt); -} - -#endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/uuid.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/uuid.c index 5b5b8085ad..9cc2b740d9 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/uuid.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/uuid.c @@ -206,9 +206,10 @@ static void sqlite3UuidBlobFunc( sqlite3_result_blob(context, pBlob, 16, SQLITE_TRANSIENT); } -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_uuid_init( sqlite3 *db, char **pzErrMsg, @@ -220,7 +221,7 @@ int sqlite3_uuid_init( rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, sqlite3UuidFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "uuid_str", 1, + rc = sqlite3_create_function(db, "uuid_str", 1, SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0, sqlite3UuidStrFunc, 0, 0); } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/vsv.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/vsv.c index 5de25eca06..3af6830830 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/vsv.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/vsv.c @@ -2003,11 +2003,10 @@ static sqlite3_module VsvModuleFauxWrite = { ** VSV virtual table module is registered with the calling database ** connection. */ -#ifndef SQLITE_CORE -#ifdef _WIN32 -__declspec(dllexport) -#endif +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_vsv_init( sqlite3 *db, char **pzErrMsg, diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/zipfile.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/zipfile.c index e731b8fe11..18f2e0fa75 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/zipfile.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/zipfile.c @@ -29,10 +29,20 @@ SQLITE_EXTENSION_INIT1 #include <stdio.h> #include <string.h> #include <assert.h> -#include <stdint.h> +#ifndef SQLITE_NO_STDINT +# include <stdint.h> +#endif #include "zlibwrap.h" +/* When used as part of the CLI, the sqlite3_stdio.h module will have +** been included before this one. In that case use the sqlite3_stdio.h +** #defines. If not, create our own for fopen(). +*/ +#ifndef _SQLITE3_STDIO_H_ +# define sqlite3_fopen fopen +#endif + #ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_AMALGAMATION @@ -76,10 +86,10 @@ typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ /* ** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK. ** -** In some ways it would be better to obtain these values from system +** In some ways it would be better to obtain these values from system ** header files. But, the dependency is undesirable and (a) these ** have been stable for decades, (b) the values are part of POSIX and -** are also made explicit in [man stat], and (c) are part of the +** are also made explicit in [man stat], and (c) are part of the ** file format for zip archives. */ #ifndef S_IFDIR @@ -92,7 +102,7 @@ typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ # define S_IFLNK 0120000 #endif -static const char ZIPFILE_SCHEMA[] = +static const char ZIPFILE_SCHEMA[] = "CREATE TABLE y(" "name PRIMARY KEY," /* 0: Name of file in zip archive */ "mode," /* 1: POSIX mode for file */ @@ -113,8 +123,8 @@ static const char ZIPFILE_SCHEMA[] = ** ** ZIPFILE_NEWENTRY_MADEBY: ** Use this value for the "version-made-by" field in new zip file -** entries. The upper byte indicates "unix", and the lower byte -** indicates that the zip file matches pkzip specification 3.0. +** entries. The upper byte indicates "unix", and the lower byte +** indicates that the zip file matches pkzip specification 3.0. ** This is what info-zip seems to do. ** ** ZIPFILE_NEWENTRY_REQUIRED: @@ -143,7 +153,7 @@ static const char ZIPFILE_SCHEMA[] = #define ZIPFILE_SIGNATURE_EOCD 0x06054b50 /* -** The sizes of the fixed-size part of each of the three main data +** The sizes of the fixed-size part of each of the three main data ** structures in a zip archive. */ #define ZIPFILE_LFH_FIXED_SZ 30 @@ -236,7 +246,7 @@ struct ZipfileCDS { *** uncompressed size 4 bytes *** file name length 2 bytes *** extra field length 2 bytes -*** +*** */ typedef struct ZipfileLFH ZipfileLFH; struct ZipfileLFH { @@ -262,7 +272,7 @@ struct ZipfileEntry { ZipfileEntry *pNext; /* Next element in in-memory CDS */ }; -/* +/* ** Cursor type for zipfile tables. */ typedef struct ZipfileCsr ZipfileCsr; @@ -335,7 +345,7 @@ static void zipfileDequote(char *zIn){ /* ** Construct a new ZipfileTab virtual table object. -** +** ** argv[0] -> module name ("zipfile") ** argv[1] -> database name ** argv[2] -> table name @@ -404,7 +414,7 @@ static void zipfileEntryFree(ZipfileEntry *p){ } /* -** Release resources that should be freed at the end of a write +** Release resources that should be freed at the end of a write ** transaction. */ static void zipfileCleanupTransaction(ZipfileTab *pTab){ @@ -513,7 +523,7 @@ static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){ /* ** Read nRead bytes of data from offset iOff of file pFile into buffer ** aRead[]. Return SQLITE_OK if successful, or an SQLite error code -** otherwise. +** otherwise. ** ** If an error does occur, output variable (*pzErrmsg) may be set to point ** to an English language error message. It is the responsibility of the @@ -721,7 +731,7 @@ static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){ ** File modification date: ** Bits 00-04: day ** Bits 05-08: month (1-12) -** Bits 09-15: years from 1980 +** Bits 09-15: years from 1980 ** ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx */ @@ -781,9 +791,9 @@ static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){ pCds->mDate = pCds->mTime = 0; } - assert( mUnixTime<315507600 - || mUnixTime==zipfileMtime(pCds) - || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) + assert( mUnixTime<315507600 + || mUnixTime==zipfileMtime(pCds) + || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) /* || (mUnixTime % 2) */ ); } @@ -851,7 +861,7 @@ static int zipfileGetEntry( if( rc==SQLITE_OK ){ u32 *pt = &pNew->mUnixTime; - pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead); + pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead); pNew->aExtra = (u8*)&pNew[1]; memcpy(pNew->aExtra, &aRead[nFile], nExtra); if( pNew->cds.zFile==0 ){ @@ -879,7 +889,7 @@ static int zipfileGetEntry( memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); } }else{ - *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", + *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", (int)pNew->cds.iOffset ); } @@ -931,8 +941,8 @@ static int zipfileNext(sqlite3_vtab_cursor *cur){ return rc; } -static void zipfileFree(void *p) { - sqlite3_free(p); +static void zipfileFree(void *p) { + sqlite3_free(p); } /* @@ -982,7 +992,7 @@ static void zipfileInflate( ** Buffer aIn (size nIn bytes) contains uncompressed data. This function ** compresses it and sets (*ppOut) to point to a buffer containing the ** compressed data. The caller is responsible for eventually calling -** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) +** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) ** is set to the size of buffer (*ppOut) in bytes. ** ** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error @@ -1171,8 +1181,8 @@ static int zipfileReadEOCD( /* Scan backwards looking for the signature bytes */ for(i=nRead-20; i>=0; i--){ - if( aRead[i]==0x50 && aRead[i+1]==0x4b - && aRead[i+2]==0x05 && aRead[i+3]==0x06 + if( aRead[i]==0x50 && aRead[i+1]==0x4b + && aRead[i+2]==0x05 && aRead[i+3]==0x06 ){ break; } @@ -1197,14 +1207,14 @@ static int zipfileReadEOCD( } /* -** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry +** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry ** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added ** to the end of the list. Otherwise, it is added to the list immediately ** before pBefore (which is guaranteed to be a part of said list). */ static void zipfileAddEntry( - ZipfileTab *pTab, - ZipfileEntry *pBefore, + ZipfileTab *pTab, + ZipfileEntry *pBefore, ZipfileEntry *pNew ){ assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) ); @@ -1250,7 +1260,7 @@ static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){ ** xFilter callback. */ static int zipfileFilter( - sqlite3_vtab_cursor *cur, + sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -1289,7 +1299,7 @@ static int zipfileFilter( } if( 0==pTab->pWriteFd && 0==bInMemory ){ - pCsr->pFile = zFile ? fopen(zFile, "rb") : 0; + pCsr->pFile = zFile ? sqlite3_fopen(zFile, "rb") : 0; if( pCsr->pFile==0 ){ zipfileCursorErr(pCsr, "cannot open file: %s", zFile); rc = SQLITE_ERROR; @@ -1413,7 +1423,7 @@ static int zipfileAppendEntry( } static int zipfileGetMode( - sqlite3_value *pVal, + sqlite3_value *pVal, int bIsDir, /* If true, default to directory */ u32 *pMode, /* OUT: Mode value */ char **pzErr /* OUT: Error message */ @@ -1476,10 +1486,10 @@ static int zipfileBegin(sqlite3_vtab *pVtab){ } /* Open a write fd on the file. Also load the entire central directory - ** structure into memory. During the transaction any new file data is + ** structure into memory. During the transaction any new file data is ** appended to the archive file, but the central directory is accumulated ** in main-memory until the transaction is committed. */ - pTab->pWriteFd = fopen(pTab->zFile, "ab+"); + pTab->pWriteFd = sqlite3_fopen(pTab->zFile, "ab+"); if( pTab->pWriteFd==0 ){ pTab->base.zErrMsg = sqlite3_mprintf( "zipfile: failed to open file %s for writing", pTab->zFile @@ -1559,9 +1569,9 @@ static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){ ** xUpdate method. */ static int zipfileUpdate( - sqlite3_vtab *pVtab, - int nVal, - sqlite3_value **apVal, + sqlite3_vtab *pVtab, + int nVal, + sqlite3_value **apVal, sqlite_int64 *pRowid ){ ZipfileTab *pTab = (ZipfileTab*)pVtab; @@ -1616,7 +1626,7 @@ static int zipfileUpdate( rc = SQLITE_CONSTRAINT; } if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){ - zipfileTableErr(pTab, "rawdata must be NULL"); + zipfileTableErr(pTab, "rawdata must be NULL"); rc = SQLITE_CONSTRAINT; } @@ -2208,7 +2218,7 @@ static int zipfileRegister(sqlite3 *db){ int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0); if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, + rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, zipfileStep, zipfileFinal ); } @@ -2222,12 +2232,13 @@ static int zipfileRegister(sqlite3 *db){ # define zipfileRegister(x) SQLITE_OK #endif -#ifdef _WIN32 -__declspec(dllexport) +#ifndef SQLITE_API +#define SQLITE_API #endif +SQLITE_API int sqlite3_zipfile_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi); From ea1426c2f1fbe1d9bab141b65617acbd5eaec9fb Mon Sep 17 00:00:00 2001 From: Pekka Enberg <penberg@iki.fi> Date: Thu, 28 May 2026 12:52:54 +0300 Subject: [PATCH 520/522] libsql-ffi: Update bundled SQLite to 3.48.0 Regenerate the bundled SQLite amalgamation and Rust bindings from the 3.48.0 libsql-sqlite3 source tree, produced by: ./scripts/update-sqlite-bundle.sh which runs `LIBSQL_DEV=1 cargo build` to refresh bindgen.rs / session_bindgen.rs, then `cargo xtask build-bundled` to regenerate the canonical sqlite3.{c,h} in both bundled/src/ and bundled/SQLite3MultipleCiphers/src/. That xtask is the same one CI validates in .github/workflows/c-bindings.yml. Together with the prior two commits (bcd6013d8a "Merge upstream SQLite 3.48.0" and 097ec793e4 "Bump bundled SQLite3MultipleCiphers from 1.8.1 to 2.0.2"), this completes the 3.48.0 update: the libsql tree, the sqlite3mc vendored copy, and the bundled amalgamation are all aligned on SQLite 3.48.0. Files: libsql-ffi/bundled/src/sqlite3.{c,h} (3.47.0 -> 3.48.0) libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.{c,h} (3.47.0 -> 3.48.0) libsql-ffi/bundled/bindings/{bindgen,session_bindgen}.rs (regenerated) --- .../SQLite3MultipleCiphers/src/sqlite3.c | 2064 +++++++++++------ .../SQLite3MultipleCiphers/src/sqlite3.h | 62 +- libsql-ffi/bundled/bindings/bindgen.rs | 9 +- .../bundled/bindings/session_bindgen.rs | 9 +- libsql-ffi/bundled/src/sqlite3.c | 2064 +++++++++++------ libsql-ffi/bundled/src/sqlite3.h | 62 +- 6 files changed, 2776 insertions(+), 1494 deletions(-) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c index 988693f341..adff2331b5 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.47.0. By combining all the individual C code files into this +** version 3.48.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,15 +18,12 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** 03a9703e27c44437c39363d0baf82db4ebc9 with changes in files: +** d2fe6b05f38d9d7cd78c5d252e99ac59f1ae with changes in files: ** ** .fossil-settings/empty-dirs ** .fossil-settings/ignore-glob -** LICENSE.md -** Makefile.in ** Makefile.msc ** README.md -** configure.ac ** doc/compile-for-windows.md ** doc/jsonb.md ** doc/trusted-schema.md @@ -91,7 +88,9 @@ ** tool/mksqlite3c.tcl ** tool/mksqlite3h.tcl ** tool/mksqlite3internalh.tcl +** */ +#ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE @@ -543,9 +542,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.47.0" -#define SQLITE_VERSION_NUMBER 3047000 -#define SQLITE_SOURCE_ID "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82alt1" +#define SQLITE_VERSION "3.48.0" +#define SQLITE_VERSION_NUMBER 3048000 +#define SQLITE_SOURCE_ID "2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e8alt1" #define LIBSQL_VERSION "0.2.3" @@ -1053,6 +1052,13 @@ SQLITE_API int sqlite3_exec( ** filesystem supports doing multiple write operations atomically when those ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. +** +** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read +** from the database file in amounts that are not a multiple of the +** page size and that do not begin at a page boundary. Without this +** property, SQLite is careful to only do full-page reads and write +** on aligned pages, with the one exception that it will do a sub-page +** read of the first page to access the database header. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -1069,6 +1075,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 +#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 /* ** CAPI3REF: File Locking Levels @@ -1215,6 +1222,7 @@ struct sqlite3_file { ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] ** <li> [SQLITE_IOCAP_IMMUTABLE] ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] +** <li> [SQLITE_IOCAP_SUBPAGE_READ] ** </ul> ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of @@ -1499,6 +1507,11 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +** <li>[[SQLITE_FCNTL_NULL_IO]] +** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor +** or file handle for the [sqlite3_file] object such that it will no longer +** read or write to the database file. +** ** <li>[[SQLITE_FCNTL_WAL_BLOCK]] ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might ** be advantageous to block on the next WAL lock if the lock is not immediately @@ -1652,6 +1665,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +#define SQLITE_FCNTL_NULL_IO 43 // libSQL extension #define SQLITE_FCNTL_WAL_METHODS_POINTER 129 @@ -3043,10 +3057,14 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** The two functions are identical except for the type of the return value -** and that if the number of rows modified by the most recent INSERT, UPDATE +** and that if the number of rows modified by the most recent INSERT, UPDATE, ** or DELETE is greater than the maximum value supported by type "int", then ** the return value of sqlite3_changes() is undefined. ^Executing any other ** type of SQL statement does not modify the value returned by these functions. +** For the purposes of this interface, a CREATE TABLE AS SELECT statement +** does not count as an INSERT, UPDATE or DELETE statement and hence the rows +** added to the new table by the CREATE TABLE AS SELECT statement are not +** counted. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], @@ -4640,11 +4658,22 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler ** to return an error (error code SQLITE_ERROR) if the statement uses ** any virtual tables. +** +** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt> +** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler +** errors from being sent to the error log defined by +** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test +** compiles to see if some SQL syntax is well-formed, without generating +** messages on the global error log when it is not. If the test compile +** fails, the sqlite3_prepare_v3() call returns the same error indications +** with or without this flag; it just omits the call to [sqlite3_log()] that +** logs the error. ** </dl> */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 #define SQLITE_PREPARE_NO_VTAB 0x04 +#define SQLITE_PREPARE_DONT_LOG 0x10 /* ** CAPI3REF: Compiling An SQL Statement @@ -11449,7 +11478,7 @@ SQLITE_API int sqlite3_deserialize( #if 0 } /* End of the 'extern "C"' block */ #endif -#endif /* SQLITE3_H */ +/* #endif for SQLITE3_H will be added by mksqlite3.tcl */ /******** Begin file sqlite3rtree.h *********/ /* @@ -13700,14 +13729,29 @@ struct Fts5PhraseIter { ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, ** output variable (*ppToken) is set to point to a buffer containing the ** matching document token, and (*pnToken) to the size of that buffer in -** bytes. This API is not available if the specified token matches a -** prefix query term. In that case both output variables are always set -** to 0. +** bytes. ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. ** @@ -14496,6 +14540,7 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); #endif //LIBSQL_ENABLE_WASM_RUNTIME /******** End of wasm_bindings.h *********/ +#endif /* SQLITE3_H */ /************** End of sqlite3.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14541,6 +14586,7 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); #ifndef SQLITE_MAX_LENGTH # define SQLITE_MAX_LENGTH 1000000000 #endif +#define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */ /* ** This is the maximum number of @@ -14606,9 +14652,13 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); /* ** The maximum number of arguments to an SQL function. +** +** This value has a hard upper limit of 32767 due to storage +** constraints (it needs to fit inside a i16). We keep it +** lower than that to prevent abuse. */ #ifndef SQLITE_MAX_FUNCTION_ARG -# define SQLITE_MAX_FUNCTION_ARG 127 +# define SQLITE_MAX_FUNCTION_ARG 1000 #endif /* @@ -16615,6 +16665,22 @@ typedef struct libsql_pghdr DbPage; #define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ #define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ +#define isWalMode(x) ((x)==PAGER_JOURNALMODE_WAL) + +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods!=0) + /* ** Flags that make up the mask passed to sqlite3PagerGet(). */ @@ -17660,7 +17726,7 @@ typedef struct VdbeOpList VdbeOpList; ** Additional non-public SQLITE_PREPARE_* flags */ #define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */ -#define SQLITE_PREPARE_MASK 0x0f /* Mask of public flags */ +#define SQLITE_PREPARE_MASK 0x1f /* Mask of public flags */ /* ** Prototypes for the VDBE interface. See comments on the implementation @@ -18394,54 +18460,11 @@ struct FuncDefHash { }; #define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) -/* The #warning directive below is a hard error under MSVC's default -** (traditional) C preprocessor (error C1021), which breaks Windows builds. -** Keep the deprecation notice for compilers that accept #warning and skip it -** on MSVC. This is purely a compile-time diagnostic; the extension itself is -** still controlled by SQLITE_USER_AUTHENTICATION below. Upstream SQLite -** removed this extension entirely in 3.48.0 (commit bc4df6079c), so this -** local patch becomes moot once the bundled SQLite is updated past 3.47.0. */ -#if defined(SQLITE_USER_AUTHENTICATION) && !defined(_MSC_VER) -# warning "The SQLITE_USER_AUTHENTICATION extension is deprecated. \ - See ext/userauth/user-auth.txt for details." -#endif -#ifdef SQLITE_USER_AUTHENTICATION -/* -** Information held in the "sqlite3" database connection object and used -** to manage user authentication. -*/ -typedef struct sqlite3_userauth sqlite3_userauth; -struct sqlite3_userauth { - u8 authLevel; /* Current authentication level */ - int nAuthPW; /* Size of the zAuthPW in bytes */ - char *zAuthPW; /* Password used to authenticate */ - char *zAuthUser; /* User name used to authenticate */ -}; - -/* Allowed values for sqlite3_userauth.authLevel */ -#define UAUTH_Unknown 0 /* Authentication not yet checked */ -#define UAUTH_Fail 1 /* User authentication failed */ -#define UAUTH_User 2 /* Authenticated as a normal user */ -#define UAUTH_Admin 3 /* Authenticated as an administrator */ - -/* Functions used only by user authorization logic */ -SQLITE_PRIVATE int sqlite3UserAuthTable(const char*); -SQLITE_PRIVATE int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); -SQLITE_PRIVATE void sqlite3UserAuthInit(sqlite3*); -SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); - -#endif /* SQLITE_USER_AUTHENTICATION */ - /* ** typedef for the authorization callback function. */ -#ifdef SQLITE_USER_AUTHENTICATION - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*, const char*); -#else - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*); -#endif +typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*); #ifndef SQLITE_OMIT_DEPRECATED /* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing @@ -18611,9 +18634,6 @@ struct sqlite3 { void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif -#ifdef SQLITE_USER_AUTHENTICATION - sqlite3_userauth auth; /* User authentication information */ -#endif #ifdef LIBSQL_ENABLE_WASM_RUNTIME libsql_wasm_ctx wasm; /* WebAssembly runtime context */ #endif @@ -18782,7 +18802,7 @@ struct sqlite3 { ** field is used by per-connection app-def functions. */ struct FuncDef { - i8 nArg; /* Number of arguments. -1 means unlimited */ + i16 nArg; /* Number of arguments. -1 means unlimited */ u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ @@ -23548,9 +23568,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_UNTESTABLE "UNTESTABLE", #endif -#ifdef SQLITE_USER_AUTHENTICATION - "USER_AUTHENTICATION", -#endif #ifdef SQLITE_USE_ALLOCA "USE_ALLOCA", #endif @@ -24411,7 +24428,7 @@ struct sqlite3_context { int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ - u8 argc; /* Number of arguments */ + u16 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; @@ -24562,6 +24579,7 @@ struct PreUpdate { int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ + Mem oldipk; /* Memory cell holding "old" IPK value */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ @@ -33029,6 +33047,7 @@ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExp pExpr = pExpr->pLeft; } if( pExpr==0 ) return; + if( ExprHasProperty(pExpr, EP_FromDDL) ) return; db->errByteOffset = pExpr->w.iOfst; } @@ -33755,10 +33774,13 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3_str_appendf(&x, " DDL"); } if( pItem->fg.isCte ){ - sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); + static const char *aMat[] = {",MAT", "", ",NO-MAT"}; + sqlite3_str_appendf(&x, " CteUse=%d%s", + pItem->u2.pCteUse->nUse, + aMat[pItem->u2.pCteUse->eM10d]); } if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ - sqlite3_str_appendf(&x, " ON"); + sqlite3_str_appendf(&x, " isOn"); } if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); @@ -33786,9 +33808,6 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); - sqlite3TreeViewPush(&pView, 0); - sqlite3TreeViewLine(pView, "SUBQUERY"); - sqlite3TreeViewPop(&pView); sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); } if( pItem->fg.isTabFunc ){ @@ -34842,6 +34861,10 @@ SQLITE_PRIVATE void sqlite3TreeViewTrigger( ** accessible to the debugging, and to avoid warnings about unused ** functions. But these routines only exist in debugging builds, so they ** do not contaminate the interface. +** +** See Also: +** +** sqlite3ShowWhereTerm() in where.c */ SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} @@ -36418,8 +36441,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en int eValid = 1; /* True exponent is either not used or is well-formed */ int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ + u64 s2; /* round-tripped significand */ double rr[2]; - u64 s2; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ @@ -36522,7 +36545,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en e = (e*esign) + d; /* Try to adjust the exponent to make it smaller */ - while( e>0 && s<(LARGEST_UINT64/10) ){ + while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){ s *= 10; e--; } @@ -36532,11 +36555,22 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en } rr[0] = (double)s; - s2 = (u64)rr[0]; -#if defined(_MSC_VER) && _MSC_VER<1700 - if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } + assert( sizeof(s2)==sizeof(rr[0]) ); +#ifdef SQLITE_DEBUG + rr[1] = 18446744073709549568.0; + memcpy(&s2, &rr[1], sizeof(s2)); + assert( s2==0x43efffffffffffffLL ); #endif - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + /* Largest double that can be safely converted to u64 + ** vvvvvvvvvvvvvvvvvvvvvv */ + if( rr[0]<=18446744073709549568.0 ){ + s2 = (u64)rr[0]; + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + }else{ + rr[1] = 0.0; + } + assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */ + if( e>0 ){ while( e>=100 ){ e -= 100; @@ -39411,7 +39445,7 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void){ # endif #else /* !SQLITE_WASI */ # ifndef HAVE_FCHMOD -# define HAVE_FCHMOD +# define HAVE_FCHMOD 1 # endif #endif /* SQLITE_WASI */ @@ -43185,6 +43219,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } #endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + case SQLITE_FCNTL_NULL_IO: { + osClose(pFile->h); + pFile->h = -1; + return SQLITE_OK; + } case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; @@ -43326,6 +43365,7 @@ static void setDeviceCharacteristics(unixFile *pFd){ if( pFd->ctrlFlags & UNIXFILE_PSOW ){ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; } + pFd->deviceCharacteristics |= SQLITE_IOCAP_SUBPAGE_READ; pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; } @@ -51065,6 +51105,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } #endif + case SQLITE_FCNTL_NULL_IO: { + (void)osCloseHandle(pFile->h); + pFile->h = NULL; + return SQLITE_OK; + } case SQLITE_FCNTL_TEMPFILENAME: { char *zTFile = 0; int rc = winGetTempname(pFile->pVfs, &zTFile); @@ -51126,7 +51171,7 @@ static int winSectorSize(sqlite3_file *id){ */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_SUBPAGE_READ | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } @@ -52514,7 +52559,7 @@ static int winOpen( int rc = SQLITE_OK; /* Function Return Code */ #if !defined(NDEBUG) || SQLITE_OS_WINCE - int eType = flags&0xFFFFFF00; /* Type of file to open */ + int eType = flags&0x0FFF00; /* Type of file to open */ #endif int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); @@ -58843,20 +58888,6 @@ static const unsigned char aJournalMagic[] = { # define USEFETCH(x) 0 #endif -/* -** The argument to this macro is a file descriptor (type sqlite3_file*). -** Return 0 if it is not open, or non-zero (but not 1) if it is. -** -** This is so that expressions can be written as: -** -** if( isOpen(pPager->jfd) ){ ... -** -** instead of -** -** if( pPager->jfd->pMethods ){ ... -*/ -#define isOpen(pFd) ((pFd)->pMethods!=0) - #ifndef SQLITE_OMIT_WAL # define pagerUseWal(x) ((x)->wal!=0) // check that methods have been initialized #else @@ -58872,21 +58903,29 @@ static const unsigned char aJournalMagic[] = { ** Return true if page pgno can be read directly from the database file ** by the b-tree layer. This is the case if: ** -** * the database file is open, -** * there are no dirty pages in the cache, and -** * the desired page is not currently in the wal file. +** (1) the database file is open +** (2) the VFS for the database is able to do unaligned sub-page reads +** (3) there are no dirty pages in the cache, and +** (4) the desired page is not currently in the wal file. */ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ - if( pPager->fd->pMethods==0 ) return 0; - if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; + assert( pPager!=0 ); + assert( pPager->fd!=0 ); + if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ if( pPager->hasCodec ) return 0; #ifndef SQLITE_OMIT_WAL if( pagerUseWal(pPager) ){ u32 iRead = 0; (void)pPager->wal->methods.xFindFrame(pPager->wal->pData, pgno, &iRead); - return iRead==0; + return iRead==0; /* Condition (4) */ } #endif + assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); + if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) + & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ + return 0; /* Case (2) */ + } return 1; } #endif @@ -60137,7 +60176,7 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ } pPager->journalOff = 0; }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST - || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) + || (pPager->exclusiveMode && pPager->journalMode<PAGER_JOURNALMODE_WAL) ){ rc = zeroJournalHdr(pPager, hasSuper||pPager->tempFile); pPager->journalOff = 0; @@ -67951,6 +67990,7 @@ static int walLockWriter(Wal *pWal){ #else # define walEnableBlocking(x) 0 # define walDisableBlocking(x) +# define walEnableBlockingMs(pWal, ms) 0 # define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1) #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ @@ -68806,11 +68846,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ */ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ - u32 mxReadMark; /* Largest aReadMark[] value */ - int mxI; /* Index of largest aReadMark[] value */ - int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ - u32 mxFrame; /* Wal frame to lock to */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT int nBlockTmout = 0; #endif @@ -68916,145 +68952,147 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ assert( pWal->apWiData[0]!=0 ); pInfo = walCkptInfo(pWal); SEH_INJECT_FAULT; - if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame + { + u32 mxReadMark; /* Largest aReadMark[] value */ + int mxI; /* Index of largest aReadMark[] value */ + int i; /* Loop counter */ + u32 mxFrame; /* Wal frame to lock to */ + if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT - && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) + && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) #endif - ){ - /* The WAL has been completely backfilled (or it is empty). - ** and can be safely ignored. - */ - rc = walLockShared(pWal, WAL_READ_LOCK(0)); - walShmBarrier(pWal); - if( rc==SQLITE_OK ){ - if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ - /* It is not safe to allow the reader to continue here if frames - ** may have been appended to the log before READ_LOCK(0) was obtained. - ** When holding READ_LOCK(0), the reader ignores the entire log file, - ** which implies that the database file contains a trustworthy - ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from - ** happening, this is usually correct. - ** - ** However, if frames have been appended to the log (or if the log - ** is wrapped and written for that matter) before the READ_LOCK(0) - ** is obtained, that is not necessarily true. A checkpointer may - ** have started to backfill the appended frames but crashed before - ** it finished. Leaving a corrupt image in the database file. - */ - walUnlockShared(pWal, WAL_READ_LOCK(0)); - return WAL_RETRY; + ){ + /* The WAL has been completely backfilled (or it is empty). + ** and can be safely ignored. + */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + walShmBarrier(pWal); + if( rc==SQLITE_OK ){ + if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr,sizeof(WalIndexHdr)) ){ + /* It is not safe to allow the reader to continue here if frames + ** may have been appended to the log before READ_LOCK(0) was obtained. + ** When holding READ_LOCK(0), the reader ignores the entire log file, + ** which implies that the database file contains a trustworthy + ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from + ** happening, this is usually correct. + ** + ** However, if frames have been appended to the log (or if the log + ** is wrapped and written for that matter) before the READ_LOCK(0) + ** is obtained, that is not necessarily true. A checkpointer may + ** have started to backfill the appended frames but crashed before + ** it finished. Leaving a corrupt image in the database file. + */ + walUnlockShared(pWal, WAL_READ_LOCK(0)); + return WAL_RETRY; + } + pWal->readLock = 0; + return SQLITE_OK; + }else if( rc!=SQLITE_BUSY ){ + return rc; } - pWal->readLock = 0; - return SQLITE_OK; - }else if( rc!=SQLITE_BUSY ){ - return rc; } - } - /* If we get this far, it means that the reader will want to use - ** the WAL to get at content from recent commits. The job now is - ** to select one of the aReadMark[] entries that is closest to - ** but not exceeding pWal->hdr.mxFrame and lock that entry. - */ - mxReadMark = 0; - mxI = 0; - mxFrame = pWal->hdr.mxFrame; + /* If we get this far, it means that the reader will want to use + ** the WAL to get at content from recent commits. The job now is + ** to select one of the aReadMark[] entries that is closest to + ** but not exceeding pWal->hdr.mxFrame and lock that entry. + */ + mxReadMark = 0; + mxI = 0; + mxFrame = pWal->hdr.mxFrame; #ifdef SQLITE_ENABLE_SNAPSHOT - if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){ - mxFrame = pWal->pSnapshot->mxFrame; - } -#endif - for(i=1; i<WAL_NREADER; i++){ - u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; - if( mxReadMark<=thisMark && thisMark<=mxFrame ){ - assert( thisMark!=READMARK_NOT_USED ); - mxReadMark = thisMark; - mxI = i; + if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){ + mxFrame = pWal->pSnapshot->mxFrame; } - } - if( (pWal->readOnly & WAL_SHM_RDONLY)==0 - && (mxReadMark<mxFrame || mxI==0) - ){ +#endif for(i=1; i<WAL_NREADER; i++){ - rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); - if( rc==SQLITE_OK ){ - AtomicStore(pInfo->aReadMark+i,mxFrame); - mxReadMark = mxFrame; + u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; + if( mxReadMark<=thisMark && thisMark<=mxFrame ){ + assert( thisMark!=READMARK_NOT_USED ); + mxReadMark = thisMark; mxI = i; - walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); - break; - }else if( rc!=SQLITE_BUSY ){ - return rc; } } - } - if( mxI==0 ){ - assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); - return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; - } + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMark<mxFrame || mxI==0) + ){ + for(i=1; i<WAL_NREADER; i++){ + rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ + AtomicStore(pInfo->aReadMark+i,mxFrame); + mxReadMark = mxFrame; + mxI = i; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + break; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + } + if( mxI==0 ){ + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; + } + (void)walEnableBlockingMs(pWal, nBlockTmout); + rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + walDisableBlocking(pWal); + if( rc ){ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - (void)walEnableBlockingMs(pWal, nBlockTmout); -#endif - rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - walDisableBlocking(pWal); -#endif - if( rc ){ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - if( rc==SQLITE_BUSY_TIMEOUT ){ - *pCnt |= WAL_RETRY_BLOCKED_MASK; - } + if( rc==SQLITE_BUSY_TIMEOUT ){ + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } #else - assert( rc!=SQLITE_BUSY_TIMEOUT ); + assert( rc!=SQLITE_BUSY_TIMEOUT ); #endif - assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT ); - return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; - } - /* Now that the read-lock has been obtained, check that neither the - ** value in the aReadMark[] array or the contents of the wal-index - ** header have changed. - ** - ** It is necessary to check that the wal-index header did not change - ** between the time it was read and when the shared-lock was obtained - ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility - ** that the log file may have been wrapped by a writer, or that frames - ** that occur later in the log than pWal->hdr.mxFrame may have been - ** copied into the database by a checkpointer. If either of these things - ** happened, then reading the database with the current value of - ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry - ** instead. - ** - ** Before checking that the live wal-index header has not changed - ** since it was read, set Wal.minFrame to the first frame in the wal - ** file that has not yet been checkpointed. This client will not need - ** to read any frames earlier than minFrame from the wal file - they - ** can be safely read directly from the database file. - ** - ** Because a ShmBarrier() call is made between taking the copy of - ** nBackfill and checking that the wal-header in shared-memory still - ** matches the one cached in pWal->hdr, it is guaranteed that the - ** checkpointer that set nBackfill was not working with a wal-index - ** header newer than that cached in pWal->hdr. If it were, that could - ** cause a problem. The checkpointer could omit to checkpoint - ** a version of page X that lies before pWal->minFrame (call that version - ** A) on the basis that there is a newer version (version B) of the same - ** page later in the wal file. But if version B happens to like past - ** frame pWal->hdr.mxFrame - then the client would incorrectly assume - ** that it can read version A from the database file. However, since - ** we can guarantee that the checkpointer that set nBackfill could not - ** see any pages past pWal->hdr.mxFrame, this problem does not come up. - */ - pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; - walShmBarrier(pWal); - if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark - || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) - ){ - walUnlockShared(pWal, WAL_READ_LOCK(mxI)); - return WAL_RETRY; - }else{ - assert( mxReadMark<=pWal->hdr.mxFrame ); - pWal->readLock = (i16)mxI; + assert((rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT); + return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; + } + /* Now that the read-lock has been obtained, check that neither the + ** value in the aReadMark[] array or the contents of the wal-index + ** header have changed. + ** + ** It is necessary to check that the wal-index header did not change + ** between the time it was read and when the shared-lock was obtained + ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility + ** that the log file may have been wrapped by a writer, or that frames + ** that occur later in the log than pWal->hdr.mxFrame may have been + ** copied into the database by a checkpointer. If either of these things + ** happened, then reading the database with the current value of + ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry + ** instead. + ** + ** Before checking that the live wal-index header has not changed + ** since it was read, set Wal.minFrame to the first frame in the wal + ** file that has not yet been checkpointed. This client will not need + ** to read any frames earlier than minFrame from the wal file - they + ** can be safely read directly from the database file. + ** + ** Because a ShmBarrier() call is made between taking the copy of + ** nBackfill and checking that the wal-header in shared-memory still + ** matches the one cached in pWal->hdr, it is guaranteed that the + ** checkpointer that set nBackfill was not working with a wal-index + ** header newer than that cached in pWal->hdr. If it were, that could + ** cause a problem. The checkpointer could omit to checkpoint + ** a version of page X that lies before pWal->minFrame (call that version + ** A) on the basis that there is a newer version (version B) of the same + ** page later in the wal file. But if version B happens to like past + ** frame pWal->hdr.mxFrame - then the client would incorrectly assume + ** that it can read version A from the database file. However, since + ** we can guarantee that the checkpointer that set nBackfill could not + ** see any pages past pWal->hdr.mxFrame, this problem does not come up. + */ + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; + walShmBarrier(pWal); + if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark + || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) + ){ + walUnlockShared(pWal, WAL_READ_LOCK(mxI)); + return WAL_RETRY; + }else{ + assert( mxReadMark<=pWal->hdr.mxFrame ); + pWal->readLock = (i16)mxI; + } } return rc; } @@ -88717,6 +88755,7 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ ** will be initialized before use. */ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ + assert( db!=0 ); if( N>0 ){ do{ p->flags = flags; @@ -88742,6 +88781,7 @@ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; + assert( db!=0 ); if( db->pnBytesFreed ){ do{ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); @@ -89222,6 +89262,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( assert( pParse!=0 ); assert( p->eVdbeState==VDBE_INIT_STATE ); assert( pParse==p->pParse ); + assert( pParse->db==p->db ); p->pVList = pParse->pVList; pParse->pVList = 0; db = p->db; @@ -92125,6 +92166,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( sqlite3DbFree(db, preupdate.aRecord); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); + sqlite3VdbeMemRelease(&preupdate.oldipk); if( preupdate.aNew ){ int i; for(i=0; i<pCsr->nField; i++){ @@ -93499,7 +93541,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ ** sqlite3_column_int64() ** sqlite3_column_text() ** sqlite3_column_text16() -** sqlite3_column_real() +** sqlite3_column_double() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() ** sqlite3_column_blob() @@ -94364,60 +94406,64 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa goto preupdate_old_out; } - /* If the old.* record has not yet been loaded into memory, do so now. */ - if( p->pUnpacked==0 ){ - u32 nRec; - u8 *aRec; + if( iIdx==p->pTab->iPKey ){ + *ppValue = pMem = &p->oldipk; + sqlite3VdbeMemSetInt64(pMem, p->iKey1); + }else{ - assert( p->pCsr->eCurType==CURTYPE_BTREE ); - nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); - aRec = sqlite3DbMallocRaw(db, nRec); - if( !aRec ) goto preupdate_old_out; - rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); - if( rc==SQLITE_OK ){ - p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); - if( !p->pUnpacked ) rc = SQLITE_NOMEM; - } - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, aRec); - goto preupdate_old_out; + /* If the old.* record has not yet been loaded into memory, do so now. */ + if( p->pUnpacked==0 ){ + u32 nRec; + u8 *aRec; + + assert( p->pCsr->eCurType==CURTYPE_BTREE ); + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); + aRec = sqlite3DbMallocRaw(db, nRec); + if( !aRec ) goto preupdate_old_out; + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); + if( rc==SQLITE_OK ){ + p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); + if( !p->pUnpacked ) rc = SQLITE_NOMEM; + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, aRec); + goto preupdate_old_out; + } + p->aRecord = aRec; } - p->aRecord = aRec; - } - pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; - if( iIdx==p->pTab->iPKey ){ - sqlite3VdbeMemSetInt64(pMem, p->iKey1); - }else if( iIdx>=p->pUnpacked->nField ){ - /* This occurs when the table has been extended using ALTER TABLE - ** ADD COLUMN. The value to return is the default value of the column. */ - Column *pCol = &p->pTab->aCol[iIdx]; - if( pCol->iDflt>0 ){ - if( p->apDflt==0 ){ - int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; - p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); - if( p->apDflt==0 ) goto preupdate_old_out; - } - if( p->apDflt[iIdx]==0 ){ - sqlite3_value *pVal = 0; - Expr *pDflt; - assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); - pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; - rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); - if( rc==SQLITE_OK && pVal==0 ){ - rc = SQLITE_CORRUPT_BKPT; + pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; + if( iIdx>=p->pUnpacked->nField ){ + /* This occurs when the table has been extended using ALTER TABLE + ** ADD COLUMN. The value to return is the default value of the column. */ + Column *pCol = &p->pTab->aCol[iIdx]; + if( pCol->iDflt>0 ){ + if( p->apDflt==0 ){ + int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); + if( p->apDflt==0 ) goto preupdate_old_out; + } + if( p->apDflt[iIdx]==0 ){ + sqlite3_value *pVal = 0; + Expr *pDflt; + assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); + pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; + rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); + if( rc==SQLITE_OK && pVal==0 ){ + rc = SQLITE_CORRUPT_BKPT; + } + p->apDflt[iIdx] = pVal; } - p->apDflt[iIdx] = pVal; + *ppValue = p->apDflt[iIdx]; + }else{ + *ppValue = (sqlite3_value *)columnNullValue(); + } + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pMem); } - *ppValue = p->apDflt[iIdx]; - }else{ - *ppValue = (sqlite3_value *)columnNullValue(); - } - }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ - if( pMem->flags & (MEM_Int|MEM_IntReal) ){ - testcase( pMem->flags & MEM_Int ); - testcase( pMem->flags & MEM_IntReal ); - sqlite3VdbeMemRealify(pMem); } } @@ -99645,9 +99691,11 @@ case OP_OpenEphemeral: { /* ncycle */ } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + assert( p->apCsr[pOp->p1]==pCx ); if( rc ){ assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); sqlite3BtreeClose(pCx->ub.pBtx); + p->apCsr[pOp->p1] = 0; /* Not required; helps with static analysis */ }else{ assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); } @@ -111722,7 +111770,7 @@ static int codeCompare( p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); - sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); + sqlite3VdbeChangeP5(pParse->pVdbe, (u16)p5); return addr; } @@ -113889,7 +113937,7 @@ static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){ ** (4a) pExpr must come from an ON clause.. ** (4b) and specifically the ON clause associated with the LEFT JOIN. ** -** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** (5) If pSrc is the right operand of a LEFT JOIN or the left ** operand of a RIGHT JOIN, then pExpr must be from the WHERE ** clause, not an ON clause. ** @@ -114528,6 +114576,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( if( aiMap ) aiMap[i] = j; } + assert( nExpr>0 && nExpr<BMS ); assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); if( colUsed==(MASKBIT(nExpr)-1) ){ /* If we reach this point, that means the index pIdx is usable */ @@ -117423,16 +117472,23 @@ SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,i ** same as that currently bound to variable pVar, non-zero is returned. ** Otherwise, if the values are not the same or if pExpr is not a simple ** SQL value, zero is returned. +** +** If the SQLITE_EnableQPSG flag is set on the database connection, then +** this routine always returns false. */ -static int exprCompareVariable( +static SQLITE_NOINLINE int exprCompareVariable( const Parse *pParse, const Expr *pVar, const Expr *pExpr ){ - int res = 0; + int res = 2; int iVar; sqlite3_value *pL, *pR = 0; + if( pExpr->op==TK_VARIABLE && pVar->iColumn==pExpr->iColumn ){ + return 0; + } + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2; sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); if( pR ){ iVar = pVar->iColumn; @@ -117442,12 +117498,11 @@ static int exprCompareVariable( if( sqlite3_value_type(pL)==SQLITE_TEXT ){ sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */ } - res = 0==sqlite3MemCompare(pL, pR, 0); + res = sqlite3MemCompare(pL, pR, 0) ? 2 : 0; } sqlite3ValueFree(pR); sqlite3ValueFree(pL); } - return res; } @@ -117473,12 +117528,10 @@ static int exprCompareVariable( ** just might result in some slightly slower code. But returning ** an incorrect 0 or 1 could lead to a malfunction. ** -** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in -** pParse->pReprepare can be matched against literals in pB. The -** pParse->pVdbe->expmask bitmask is updated for each variable referenced. -** If pParse is NULL (the normal case) then any TK_VARIABLE term in -** Argument pParse should normally be NULL. If it is not NULL and pA or -** pB causes a return value of 2. +** If pParse is not NULL and SQLITE_EnableQPSG is off then TK_VARIABLE +** terms in pA with bindings in pParse->pReprepare can be matched against +** literals in pB. The pParse->pVdbe->expmask bitmask is updated for +** each variable referenced. */ SQLITE_PRIVATE int sqlite3ExprCompare( const Parse *pParse, @@ -117490,8 +117543,8 @@ SQLITE_PRIVATE int sqlite3ExprCompare( if( pA==0 || pB==0 ){ return pB==pA ? 0 : 2; } - if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){ - return 0; + if( pParse && pA->op==TK_VARIABLE ){ + return exprCompareVariable(pParse, pA, pB); } combinedFlags = pA->flags | pB->flags; if( combinedFlags & EP_IntValue ){ @@ -117686,18 +117739,70 @@ static int exprImpliesNotNull( return 0; } +/* +** Return true if the boolean value of the expression is always either +** FALSE or NULL. +*/ +static int sqlite3ExprIsNotTrue(Expr *pExpr){ + int v; + if( pExpr->op==TK_NULL ) return 1; + if( pExpr->op==TK_TRUEFALSE && sqlite3ExprTruthValue(pExpr)==0 ) return 1; + v = 1; + if( sqlite3ExprIsInteger(pExpr, &v, 0) && v==0 ) return 1; + return 0; +} + +/* +** Return true if the expression is one of the following: +** +** CASE WHEN x THEN y END +** CASE WHEN x THEN y ELSE NULL END +** CASE WHEN x THEN y ELSE false END +** iif(x,y) +** iif(x,y,NULL) +** iif(x,y,false) +*/ +static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){ + ExprList *pList; + if( pExpr->op==TK_FUNCTION ){ + const char *z = pExpr->u.zToken; + FuncDef *pDef; + if( (z[0]!='i' && z[0]!='I') ) return 0; + if( pExpr->x.pList==0 ) return 0; + pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 ) return 0; +#else + if( NEVER(pDef==0) ) return 0; +#endif + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0; + if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0; + }else if( pExpr->op==TK_CASE ){ + if( pExpr->pLeft!=0 ) return 0; + }else{ + return 0; + } + pList = pExpr->x.pList; + assert( pList!=0 ); + if( pList->nExpr==2 ) return 1; + if( pList->nExpr==3 && sqlite3ExprIsNotTrue(pList->a[2].pExpr) ) return 1; + return 0; +} + /* ** Return true if we can prove the pE2 will always be true if pE1 is ** true. Return false if we cannot complete the proof or if pE2 might ** be false. Examples: ** -** pE1: x==5 pE2: x==5 Result: true -** pE1: x>0 pE2: x==5 Result: false -** pE1: x=21 pE2: x=21 OR y=43 Result: true -** pE1: x!=123 pE2: x IS NOT NULL Result: true -** pE1: x!=?1 pE2: x IS NOT NULL Result: true -** pE1: x IS NULL pE2: x IS NOT NULL Result: false -** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: iif(x,y) pE2: x Result: true +** PE1: iif(x,y,0) pE2: x Result: true ** ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has ** Expr.iTable<0 then assume a table number given by iTab. @@ -117731,6 +117836,9 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr( ){ return 1; } + if( sqlite3ExprIsIIF(pParse->db, pE1) ){ + return sqlite3ExprImpliesExpr(pParse,pE1->x.pList->a[0].pExpr,pE2,iTab); + } return 0; } @@ -123449,15 +123557,6 @@ static void attachFunc( sqlite3BtreeLeaveAll(db); assert( zErrDyn==0 || rc!=SQLITE_OK ); } -#ifdef SQLITE_USER_AUTHENTICATION - if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){ - u8 newAuth = 0; - rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); - if( newAuth<db->auth.authLevel ){ - rc = SQLITE_AUTH_USER; - } - } -#endif if( rc ){ if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ int iDb = db->nDb - 1; @@ -123955,11 +124054,7 @@ SQLITE_PRIVATE int sqlite3AuthReadCol( int rc; /* Auth callback return code */ if( db->init.busy ) return SQLITE_OK; - rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext); if( rc==SQLITE_DENY ){ char *z = sqlite3_mprintf("%s.%s", zTab, zCol); if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); @@ -124066,11 +124161,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( testcase( zArg3==0 ); testcase( pParse->zAuthContext==0 ); - rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); + rc = db->xAuth(db->pAuthArg,code,zArg1,zArg2,zArg3,pParse->zAuthContext); if( rc==SQLITE_DENY ){ sqlite3ErrorMsg(pParse, "not authorized"); pParse->rc = SQLITE_AUTH; @@ -124306,17 +124397,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } sqlite3VdbeAddOp0(v, OP_Halt); -#if SQLITE_USER_AUTHENTICATION && !defined(SQLITE_OMIT_SHARED_CACHE) - if( pParse->nTableLock>0 && db->init.busy==0 ){ - sqlite3UserAuthInit(db); - if( db->auth.authLevel<UAUTH_User ){ - sqlite3ErrorMsg(pParse, "user not authenticated"); - pParse->rc = SQLITE_AUTH_USER; - return; - } - } -#endif - /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a @@ -124445,16 +124525,6 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ pParse->nested--; } -#if SQLITE_USER_AUTHENTICATION -/* -** Return TRUE if zTable is the name of the system table that stores the -** list of users and their access credentials. -*/ -SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){ - return sqlite3_stricmp(zTable, "sqlite_user")==0; -} -#endif - /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -124473,13 +124543,6 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha /* All mutexes are required for schema access. Make sure we hold them. */ assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); -#if SQLITE_USER_AUTHENTICATION - /* Only the admin user is allowed to know that the sqlite_user table - ** exists */ - if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){ - return 0; - } -#endif if( zDatabase ){ for(i=0; i<db->nDb; i++){ if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break; @@ -128194,9 +128257,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex( if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && db->init.busy==0 && pTblName!=0 -#if SQLITE_USER_AUTHENTICATION - && sqlite3UserAuthTable(pTab->zName)==0 -#endif ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; @@ -132094,7 +132154,6 @@ static void substrFunc( int len; int p0type; i64 p1, p2; - int negP2 = 0; assert( argc==3 || argc==2 ); if( sqlite3_value_type(argv[1])==SQLITE_NULL @@ -132103,7 +132162,7 @@ static void substrFunc( return; } p0type = sqlite3_value_type(argv[0]); - p1 = sqlite3_value_int(argv[1]); + p1 = sqlite3_value_int64(argv[1]); if( p0type==SQLITE_BLOB ){ len = sqlite3_value_bytes(argv[0]); z = sqlite3_value_blob(argv[0]); @@ -132128,19 +132187,18 @@ static void substrFunc( if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */ #endif if( argc==3 ){ - p2 = sqlite3_value_int(argv[2]); - if( p2<0 ){ - p2 = -p2; - negP2 = 1; - } + p2 = sqlite3_value_int64(argv[2]); }else{ p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; } if( p1<0 ){ p1 += len; if( p1<0 ){ - p2 += p1; - if( p2<0 ) p2 = 0; + if( p2<0 ){ + p2 = 0; + }else{ + p2 += p1; + } p1 = 0; } }else if( p1>0 ){ @@ -132148,12 +132206,13 @@ static void substrFunc( }else if( p2>0 ){ p2--; } - if( negP2 ){ - p1 -= p2; - if( p1<0 ){ - p2 += p1; - p1 = 0; + if( p2<0 ){ + if( p2<-p1 ){ + p2 = p1; + }else{ + p2 = -p2; } + p1 -= p2; } assert( p1>=0 && p2>=0 ); if( p0type!=SQLITE_BLOB ){ @@ -132167,9 +132226,11 @@ static void substrFunc( sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, SQLITE_UTF8); }else{ - if( p1+p2>len ){ + if( p1>=len ){ + p1 = p2 = 0; + }else if( p2>len-p1 ){ p2 = len-p1; - if( p2<0 ) p2 = 0; + assert( p2>0 ); } sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); } @@ -132180,13 +132241,13 @@ static void substrFunc( */ #ifndef SQLITE_OMIT_FLOATING_POINT static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - int n = 0; + i64 n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; - n = sqlite3_value_int(argv[1]); + n = sqlite3_value_int64(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } @@ -132201,7 +132262,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ - zBuf = sqlite3_mprintf("%!.*f",n,r); + zBuf = sqlite3_mprintf("%!.*f",(int)n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; @@ -134549,9 +134610,6 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ SFUNCTION(load_extension, 1, 0, 0, loadExt ), SFUNCTION(load_extension, 2, 0, 0, loadExt ), #endif -#if SQLITE_USER_AUTHENTICATION - FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), -#endif #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), @@ -134688,7 +134746,10 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ FUNCTION(sign, 1, 0, 0, signFunc ), INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), + INLINE_FUNC(iif, 2, INLINEFUNC_iif, 0 ), INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), + INLINE_FUNC(if, 2, INLINEFUNC_iif, 0 ), + INLINE_FUNC(if, 3, INLINEFUNC_iif, 0 ), }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); @@ -143272,12 +143333,6 @@ SQLITE_PRIVATE void sqlite3Pragma( ** in auto-commit mode. */ mask &= ~(SQLITE_ForeignKeys); } -#if SQLITE_USER_AUTHENTICATION - if( db->auth.authLevel==UAUTH_User ){ - /* Do not allow non-admin users to modify the schema arbitrarily */ - mask &= ~(SQLITE_WriteSchema); - } -#endif if( sqlite3GetBoolean(zRight, 0) ){ if( (mask & SQLITE_WriteSchema)==0 @@ -143413,7 +143468,8 @@ SQLITE_PRIVATE void sqlite3Pragma( char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName); if( zSql ){ sqlite3_stmt *pDummy = 0; - (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0); + (void)sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_DONT_LOG, + &pDummy, 0); (void)sqlite3_finalize(pDummy); sqlite3DbFree(db, zSql); } @@ -143894,7 +143950,7 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Do the b-tree integrity checks */ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); - sqlite3VdbeChangeP5(v, (u8)i); + sqlite3VdbeChangeP5(v, (u16)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), @@ -145515,14 +145571,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl #else encoding = SQLITE_UTF8; #endif - if( db->nVdbeActive>0 && encoding!=ENC(db) - && (db->mDbFlags & DBFLAG_Vacuum)==0 - ){ - rc = SQLITE_LOCKED; - goto initone_error_out; - }else{ - sqlite3SetTextEncoding(db, encoding); - } + sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ @@ -150230,32 +150279,32 @@ static Expr *substExpr( if( pSubst->isOuterJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } - if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ - sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, - pExpr->flags & (EP_OuterON|EP_InnerON)); - } - sqlite3ExprDelete(db, pExpr); - pExpr = pNew; - if( pExpr->op==TK_TRUEFALSE ){ - pExpr->u.iValue = sqlite3ExprTruthValue(pExpr); - pExpr->op = TK_INTEGER; - ExprSetProperty(pExpr, EP_IntValue); + if( pNew->op==TK_TRUEFALSE ){ + pNew->u.iValue = sqlite3ExprTruthValue(pNew); + pNew->op = TK_INTEGER; + ExprSetProperty(pNew, EP_IntValue); } /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ { - CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pNew); CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pSubst->pCList->a[iColumn].pExpr ); - if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){ - pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + if( pNat!=pColl || (pNew->op!=TK_COLUMN && pNew->op!=TK_COLLATE) ){ + pNew = sqlite3ExprAddCollateString(pSubst->pParse, pNew, (pColl ? pColl->zName : "BINARY") ); } } - ExprClearProperty(pExpr, EP_Collate); + ExprClearProperty(pNew, EP_Collate); + if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, + pExpr->flags & (EP_OuterON|EP_InnerON)); + } + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; } } }else{ @@ -150992,6 +151041,7 @@ static int flattenSubquery( /* Transfer the FROM clause terms from the subquery into the ** outer query. */ + iNewParent = pSubSrc->a[0].iCursor; for(i=0; i<nSubSrc; i++){ SrcItem *pItem = &pSrc->a[i+iFrom]; assert( pItem->fg.isTabFunc==0 ); @@ -151001,7 +151051,6 @@ static int flattenSubquery( if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); *pItem = pSubSrc->a[i]; pItem->fg.jointype |= ltorj; - iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].fg.jointype &= JT_LTORJ; @@ -151041,6 +151090,7 @@ static int flattenSubquery( pWhere = pSub->pWhere; pSub->pWhere = 0; if( isOuterJoin>0 ){ + assert( pSubSrc->nSrc==1 ); sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON); } if( pWhere ){ @@ -153144,7 +153194,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, iTop); sqlite3ReleaseTempRange(pParse, regAgg, nArg); @@ -153307,7 +153357,7 @@ static void updateAccumulator( } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); } if( addrNext ){ @@ -154140,7 +154190,7 @@ SQLITE_PRIVATE int sqlite3Select( #endif assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); }else{ - TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); + TREETRACE(0x4000,pParse,p,("WHERE-clause push-down not possible\n")); } /* Convert unused result columns of the subquery into simple NULL @@ -156702,7 +156752,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ - sqlite3VdbeChangeP5(v, (u8)bRecursive); + sqlite3VdbeChangeP5(v, (u16)bRecursive); } } @@ -160941,9 +160991,17 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( const WhereInfo *pWInfo, /* WHERE clause */ const WhereLevel *pLevel /* Bloom filter on this level */ ); +SQLITE_PRIVATE void sqlite3WhereAddExplainText( + Parse *pParse, /* Parse context */ + int addr, + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +); #else # define sqlite3WhereExplainOneScan(u,v,w,x) 0 # define sqlite3WhereExplainBloomFilter(u,v,w) 0 +# define sqlite3WhereAddExplainText(u,v,w,x,y) #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS SQLITE_PRIVATE void sqlite3WhereAddScanStatus( @@ -161145,38 +161203,38 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ } /* -** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN -** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG -** was defined at compile-time. If it is not a no-op, a single OP_Explain -** opcode is added to the output to describe the table scan strategy in pLevel. -** -** If an OP_Explain opcode is added to the VM, its address is returned. -** Otherwise, if no OP_Explain is coded, zero is returned. +** This function sets the P4 value of an existing OP_Explain opcode to +** text describing the loop in pLevel. If the OP_Explain opcode already has +** a P4 value, it is freed before it is overwritten. */ -SQLITE_PRIVATE int sqlite3WhereExplainOneScan( +SQLITE_PRIVATE void sqlite3WhereAddExplainText( Parse *pParse, /* Parse context */ + int addr, /* Address of OP_Explain opcode */ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ - int ret = 0; #if !defined(SQLITE_DEBUG) if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) #endif { + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr); + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; - Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ WhereLoop *pLoop; /* The controlling WhereLoop object */ u32 flags; /* Flags that describe this loop */ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) char *zMsg; /* Text to add to EQP output */ +#endif StrAccum str; /* EQP output string */ char zBuf[100]; /* Initial space for EQP output string */ + if( db->mallocFailed ) return; + pLoop = pLevel->pWLoop; flags = pLoop->wsFlags; - if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0; isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) @@ -161200,7 +161258,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; }else if( flags & WHERE_AUTO_INDEX ){ zFmt = "AUTOMATIC COVERING INDEX"; - }else if( flags & WHERE_IDX_ONLY ){ + }else if( flags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ zFmt = "COVERING INDEX %s"; }else{ zFmt = "INDEX %s"; @@ -161252,11 +161310,50 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( sqlite3_str_append(&str, " (~1 row)", 9); } #endif +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) zMsg = sqlite3StrAccumFinish(&str); sqlite3ExplainBreakpoint("",zMsg); - ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), - pParse->addrExplain, pLoop->rRun, - zMsg, P4_DYNAMIC); +#endif + + assert( pOp->opcode==OP_Explain ); + assert( pOp->p4type==P4_DYNAMIC || pOp->p4.z==0 ); + sqlite3DbFree(db, pOp->p4.z); + pOp->p4type = P4_DYNAMIC; + pOp->p4.z = sqlite3StrAccumFinish(&str); + } +} + + +/* +** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN +** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG +** was defined at compile-time. If it is not a no-op, a single OP_Explain +** opcode is added to the output to describe the table scan strategy in pLevel. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ + int ret = 0; +#if !defined(SQLITE_DEBUG) + if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + if( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + ){ + Vdbe *v = pParse->pVdbe; + int addr = sqlite3VdbeCurrentAddr(v); + ret = sqlite3VdbeAddOp3( + v, OP_Explain, addr, pParse->addrExplain, pLevel->pWLoop->rRun + ); + sqlite3WhereAddExplainText(pParse, addr, pTabList, pLevel, wctrlFlags); + } } return ret; } @@ -161355,9 +161452,10 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( } }else{ int addr; + VdbeOp *pOp; assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; - VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); + pOp = sqlite3VdbeGetOp(v, addr-1); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); @@ -161610,6 +161708,7 @@ static Expr *removeUnindexableInClauseTerms( pNew->pLeft->x.pList = pLhs; } pSelect->pEList = pRhs; + pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */ if( pLhs && pLhs->nExpr==1 ){ /* Take care here not to generate a TK_VECTOR containing only a ** single value. Since the parser never creates such a vector, some @@ -166684,7 +166783,7 @@ static int constraintCompatibleWithOuterJoin( return 0; } if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 - && ExprHasProperty(pTerm->pExpr, EP_InnerON) + && NEVER(ExprHasProperty(pTerm->pExpr, EP_InnerON)) ){ return 0; } @@ -166705,6 +166804,11 @@ static int constraintCompatibleWithOuterJoin( ** more than 20, then return false. ** ** 3. If no disqualifying conditions above are found, return true. +** +** 2025-01-03: I experimented with a new rule that returns false if the +** the datatype of the column is "BOOLEAN". This did not improve +** performance on any queries at hand, but it did burn CPU cycles, so the +** idea was not committed. */ static SQLITE_NOINLINE int columnIsGoodIndexCandidate( const Table *pTab, @@ -168177,7 +168281,7 @@ static int whereInScanEst( #endif /* SQLITE_ENABLE_STAT4 */ -#ifdef WHERETRACE_ENABLED +#if defined(WHERETRACE_ENABLED) || defined(SQLITE_DEBUG) /* ** Print the content of a WhereTerm object */ @@ -168221,6 +168325,9 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } +SQLITE_PRIVATE void sqlite3ShowWhereTerm(WhereTerm *pTerm){ + sqlite3WhereTermPrint(pTerm, 0); +} #endif #ifdef WHERETRACE_ENABLED @@ -169407,7 +169514,6 @@ static int whereUsablePartialIndex( if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } - if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ Expr *pExpr; pExpr = pTerm->pExpr; @@ -172074,7 +172180,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( } if( hasRightJoin && ExprHasProperty(pTerm->pExpr, EP_InnerON) - && pTerm->pExpr->w.iJoin==pItem->iCursor + && NEVER(pTerm->pExpr->w.iJoin==pItem->iCursor) ){ break; /* restriction (5) */ } @@ -172994,6 +173100,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; sqlite3VdbePrintOp(0, pc, pOp); + sqlite3ShowWhereTerm(0); /* So compiler won't complain about unused func */ } #endif @@ -173293,14 +173400,28 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); - }else{ - /* Unable to translate the table reference into an index - ** reference. Verify that this is harmless - that the - ** table being referenced really is open. - */ + }else if( pLoop->wsFlags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ if( pLoop->wsFlags & WHERE_IDX_ONLY ){ + /* An error. pLoop is supposed to be a covering index loop, + ** and yet the VM code refers to a column of the table that + ** is not part of the index. */ sqlite3ErrorMsg(pParse, "internal query planner error"); pParse->rc = SQLITE_INTERNAL; + }else{ + /* The WHERE_EXPRIDX flag is set by the planner when it is likely + ** that pLoop is a covering index loop, but it is not possible + ** to be 100% sure. In this case, any OP_Explain opcode + ** corresponding to this loop describes the index as a "COVERING + ** INDEX". But, pOp proves that pLoop is not actually a covering + ** index loop. So clear the WHERE_EXPRIDX flag and rewrite the + ** text that accompanies the OP_Explain opcode, if any. */ + pLoop->wsFlags &= ~WHERE_EXPRIDX; + sqlite3WhereAddExplainText(pParse, + pLevel->addrBody-1, + pTabList, + pLevel, + pWInfo->wctrlFlags + ); } } }else if( pOp->opcode==OP_Rowid ){ @@ -175008,6 +175129,7 @@ static void windowAggStep( int regArg; int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); int i; + int addrIf = 0; assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); @@ -175024,6 +175146,18 @@ static void windowAggStep( } regArg = reg; + if( pWin->pFilter ){ + int regTmp; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); + assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regTmp); + } + if( pMWin->regStartRowid==0 && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) @@ -175043,25 +175177,13 @@ static void windowAggStep( } sqlite3VdbeJumpHere(v, addrIsNull); }else if( pWin->regApp ){ + assert( pWin->pFilter==0 ); assert( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ); assert( bInverse==0 || bInverse==1 ); sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); }else if( pFunc->xSFunc!=noopStepFunc ){ - int addrIf = 0; - if( pWin->pFilter ){ - int regTmp; - assert( ExprUseXList(pWin->pOwner) ); - assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); - assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); - regTmp = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); - addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); - VdbeCoverage(v); - sqlite3ReleaseTempReg(pParse, regTmp); - } - if( pWin->bExprArgs ){ int iOp = sqlite3VdbeCurrentAddr(v); int iEnd; @@ -175088,12 +175210,13 @@ static void windowAggStep( sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); if( pWin->bExprArgs ){ sqlite3ReleaseTempRange(pParse, regArg, nArg); } - if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } + + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } } @@ -176520,6 +176643,13 @@ struct TrigEvent { int a; IdList * b; }; struct FrameBound { int eType; Expr *pExpr; }; +/* +** Generate a syntax error +*/ +static void parserSyntaxError(Parse *pParse, Token *p){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", p); +} + /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. @@ -180483,7 +180613,11 @@ static YYACTIONTYPE yy_reduce( case 89: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy599, &dest); + if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0 + || sqlite3ReadSchema(pParse)==SQLITE_OK + ){ + sqlite3Select(pParse, yymsp[0].minor.yy599, &dest); + } sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy599); } break; @@ -180955,7 +181089,7 @@ static YYACTIONTYPE yy_reduce( Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/ assert( t.n>=2 ); if( pParse->nested==0 ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); + parserSyntaxError(pParse, &t); yymsp[0].minor.yy66 = 0; }else{ yymsp[0].minor.yy66 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); @@ -181813,7 +181947,7 @@ static void yy_syntax_error( UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ if( TOKEN.z[0] ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + parserSyntaxError(pParse, &TOKEN); }else{ sqlite3ErrorMsg(pParse, "incomplete input"); } @@ -183311,7 +183445,9 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ if( pParse->zErrMsg==0 ){ pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); } - sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){ + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + } nErr++; } pParse->zTail = zSql; @@ -185302,10 +185438,6 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ sqlite3ValueFree(db->pErr); sqlite3CloseExtensions(db); -#if SQLITE_USER_AUTHENTICATION - sqlite3_free(db->auth.zAuthUser); - sqlite3_free(db->auth.zAuthPW); -#endif db->eOpenState = SQLITE_STATE_ERROR; @@ -186922,8 +187054,8 @@ static const int aHardLimit[] = { #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif -#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127 -# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127 +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>32767 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 32767 #endif #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 # error SQLITE_MAX_ATTACHED must be between 0 and 125 @@ -186990,8 +187122,8 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ if( newLimit>=0 ){ /* IMP: R-52476-28732 */ if( newLimit>aHardLimit[limitId] ){ newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ - }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){ - newLimit = 1; + }else if( newLimit<SQLITE_MIN_LENGTH && limitId==SQLITE_LIMIT_LENGTH ){ + newLimit = SQLITE_MIN_LENGTH; } db->aLimit[limitId] = newLimit; } @@ -188414,7 +188546,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ /* Invoke these debugging routines so that the compiler does not ** issue "defined but not used" warnings. */ if( x==9999 ){ - sqlite3ShowExpr(0); sqlite3ShowExpr(0); sqlite3ShowExprList(0); sqlite3ShowIdList(0); @@ -192846,10 +192977,15 @@ static int fts3PoslistPhraseMerge( if( *p1==POS_COLUMN ){ p1++; p1 += fts3GetVarint32(p1, &iCol1); + /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN + ** entry, so this is actually end-of-doclist. */ + if( iCol1==0 ) return 0; } if( *p2==POS_COLUMN ){ p2++; p2 += fts3GetVarint32(p2, &iCol2); + /* As above, iCol2==0 indicates corruption. */ + if( iCol2==0 ) return 0; } while( 1 ){ @@ -196020,7 +196156,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ nTmp += p->pRight->pPhrase->doclist.nList; } nTmp += p->pPhrase->doclist.nList; - aTmp = sqlite3_malloc64(nTmp*2); + aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX); if( !aTmp ){ *pRc = SQLITE_NOMEM; res = 0; @@ -196671,7 +196807,7 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ } #endif -#if !SQLITE_CORE +#if !defined(SQLITE_CORE) /* ** Initialize API pointer table, if required. */ @@ -197573,10 +197709,11 @@ static int getNextString( Fts3PhraseToken *pToken; p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); - if( !p ) goto no_mem; - zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); - if( !zTemp ) goto no_mem; + if( !zTemp || !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } assert( nToken==ii ); pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; @@ -197591,9 +197728,6 @@ static int getNextString( nToken = ii+1; } } - - pModule->xClose(pCursor); - pCursor = 0; } if( rc==SQLITE_DONE ){ @@ -197601,7 +197735,10 @@ static int getNextString( char *zBuf = 0; p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); - if( !p ) goto no_mem; + if( !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); p->eType = FTSQUERY_PHRASE; p->pPhrase = (Fts3Phrase *)&p[1]; @@ -197609,11 +197746,9 @@ static int getNextString( p->pPhrase->nToken = nToken; zBuf = (char *)&p->pPhrase->aToken[nToken]; + assert( nTemp==0 || zTemp ); if( zTemp ){ memcpy(zBuf, zTemp, nTemp); - sqlite3_free(zTemp); - }else{ - assert( nTemp==0 ); } for(jj=0; jj<p->pPhrase->nToken; jj++){ @@ -197623,17 +197758,17 @@ static int getNextString( rc = SQLITE_OK; } - *ppExpr = p; - return rc; -no_mem: - + getnextstring_out: if( pCursor ){ pModule->xClose(pCursor); } sqlite3_free(zTemp); - sqlite3_free(p); - *ppExpr = 0; - return SQLITE_NOMEM; + if( rc!=SQLITE_OK ){ + sqlite3_free(p); + p = 0; + } + *ppExpr = p; + return rc; } /* @@ -223968,8 +224103,8 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ sqlite3_str_append(pOut, "}", 1); } errCode = sqlite3_str_errcode(pOut); - sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free); sqlite3_result_error_code(ctx, errCode); + sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free); } /* This routine implements an SQL function that returns the "depth" parameter @@ -226485,7 +226620,7 @@ SQLITE_API int sqlite3_rtree_query_callback( ); } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif @@ -227076,7 +227211,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ return rc; } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif @@ -234674,6 +234809,24 @@ static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ return SQLITE_OK; } +/* +** Open write transactions. Since we do not know in advance which database +** files will be written by the sqlite_dbpage virtual table, start a write +** transaction on them all. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int dbpageBeginTrans(DbpageTable *pTab){ + sqlite3 *db = pTab->db; + int rc = SQLITE_OK; + int i; + for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ) rc = sqlite3BtreeBeginTrans(pBt, 1, 0); + } + return rc; +} + static int dbpageUpdate( sqlite3_vtab *pVtab, int argc, @@ -234741,6 +234894,12 @@ static int dbpageUpdate( goto update_fail; } } + + if( dbpageBeginTrans(pTab)!=SQLITE_OK ){ + zErr = "failed to open transaction"; + goto update_fail; + } + pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ @@ -234750,6 +234909,8 @@ static int dbpageUpdate( memcpy(aPage, pData, szPage); pTab->pgnoTrunc = 0; } + }else{ + pTab->pgnoTrunc = 0; } sqlite3PagerUnref(pDbPage); return rc; @@ -234760,18 +234921,8 @@ static int dbpageUpdate( return SQLITE_ERROR; } -/* Since we do not know in advance which database files will be -** written by the sqlite_dbpage virtual table, start a write transaction -** on them all. -*/ static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; - sqlite3 *db = pTab->db; - int i; - for(i=0; i<db->nDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); - } pTab->pgnoTrunc = 0; return SQLITE_OK; } @@ -234783,7 +234934,11 @@ static int dbpageSync(sqlite3_vtab *pVtab){ if( pTab->pgnoTrunc>0 ){ Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt; Pager *pPager = sqlite3BtreePager(pBt); - sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); + sqlite3BtreeEnter(pBt); + if( pTab->pgnoTrunc<sqlite3BtreeLastPage(pBt) ){ + sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); + } + sqlite3BtreeLeave(pBt); } pTab->pgnoTrunc = 0; return SQLITE_OK; @@ -234803,7 +234958,7 @@ static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){ */ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ static sqlite3_module dbpage_module = { - 0, /* iVersion */ + 2, /* iVersion */ dbpageConnect, /* xCreate */ dbpageConnect, /* xConnect */ dbpageBestIndex, /* xBestIndex */ @@ -240122,12 +240277,12 @@ static int sessionChangesetApply( } } } - sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); - }else{ + } + if( rc!=SQLITE_OK ){ sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); } @@ -241377,7 +241532,27 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ /************** End of sqlite3session.c **************************************/ /************** Begin file fts5.c ********************************************/ - +/* +** This, the "fts5.c" source file, is a composite file that is itself +** assembled from the following files: +** +** fts5.h +** fts5Int.h +** fts5parse.h <--- Generated from fts5parse.y by Lemon +** fts5parse.c <--- Generated from fts5parse.y by Lemon +** fts5_aux.c +** fts5_buffer.c +** fts5_config.c +** fts5_expr.c +** fts5_hash.c +** fts5_index.c +** fts5_main.c +** fts5_storage.c +** fts5_tokenize.c +** fts5_unicode2.c +** fts5_varint.c +** fts5_vocab.c +*/ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) @@ -241387,6 +241562,12 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ # undef NDEBUG #endif +#ifdef HAVE_STDINT_H +/* #include <stdint.h> */ +#endif +#ifdef HAVE_INTTYPES_H +/* #include <inttypes.h> */ +#endif /* ** 2014 May 31 ** @@ -241687,14 +241868,29 @@ struct Fts5PhraseIter { ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, ** output variable (*ppToken) is set to point to a buffer containing the ** matching document token, and (*pnToken) to the size of that buffer in -** bytes. This API is not available if the specified token matches a -** prefix query term. In that case both output variables are always set -** to 0. +** bytes. ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. ** @@ -242376,7 +242572,8 @@ struct Fts5Config { char *zRank; /* Name of rank function */ char *zRankArgs; /* Arguments to rank function */ int bSecureDelete; /* 'secure-delete' */ - int nDeleteMerge; /* 'deletemerge' */ + int nDeleteMerge; /* 'deletemerge' */ + int bPrefixInsttoken; /* 'prefix-insttoken' */ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ char **pzErrmsg; @@ -242633,7 +242830,14 @@ static int sqlite3Fts5StructureTest(Fts5Index*, void*); /* ** Used by xInstToken(): */ -static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*); +static int sqlite3Fts5IterToken( + Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, + i64 iRowid, + int iCol, + int iOff, + const char **ppOut, int *pnOut +); /* ** Insert or remove data to or from the index. Each time a document is @@ -246847,6 +247051,19 @@ static int sqlite3Fts5ConfigSetValue( }else{ pConfig->bSecureDelete = (bVal ? 1 : 0); } + } + + else if( 0==sqlite3_stricmp(zKey, "insttoken") ){ + int bVal = -1; + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + bVal = sqlite3_value_int(pVal); + } + if( bVal<0 ){ + *pbBadkey = 1; + }else{ + pConfig->bPrefixInsttoken = (bVal ? 1 : 0); + } + }else{ *pbBadkey = 1; } @@ -249982,7 +250199,7 @@ static int fts5ExprPopulatePoslistsCb( int rc = sqlite3Fts5PoslistWriterAppend( &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff ); - if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){ + if( rc==SQLITE_OK && (pExpr->pConfig->bTokendata || pT->bPrefix) ){ int iCol = p->iOff>>32; int iTokOff = p->iOff & 0x7FFFFFFF; rc = sqlite3Fts5IndexIterWriteTokendata( @@ -250175,15 +250392,14 @@ static int sqlite3Fts5ExprInstToken( return SQLITE_RANGE; } pTerm = &pPhrase->aTerm[iToken]; - if( pTerm->bPrefix==0 ){ - if( pExpr->pConfig->bTokendata ){ - rc = sqlite3Fts5IterToken( - pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut - ); - }else{ - *ppOut = pTerm->pTerm; - *pnOut = pTerm->nFullTerm; - } + if( pExpr->pConfig->bTokendata || pTerm->bPrefix ){ + rc = sqlite3Fts5IterToken( + pTerm->pIter, pTerm->pTerm, pTerm->nQueryTerm, + iRowid, iCol, iOff+iToken, ppOut, pnOut + ); + }else{ + *ppOut = pTerm->pTerm; + *pnOut = pTerm->nFullTerm; } return rc; } @@ -251686,9 +251902,13 @@ static int fts5IndexPrepareStmt( ){ if( p->rc==SQLITE_OK ){ if( zSql ){ - p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, + int rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB, ppStmt, 0); + /* If this prepare() call fails with SQLITE_ERROR, then one of the + ** %_idx or %_data tables has been removed or modified. Call this + ** corruption. */ + p->rc = (rc==SQLITE_ERROR ? SQLITE_CORRUPT : rc); }else{ p->rc = SQLITE_NOMEM; } @@ -256268,6 +256488,24 @@ static void fts5FlushSecureDelete( const int f = FTS5INDEX_QUERY_SKIPHASH; Fts5Iter *pIter = 0; /* Used to find term instance */ + /* If the version number has not been set to SECUREDELETE, do so now. */ + if( p->pConfig->iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ + Fts5Config *pConfig = p->pConfig; + sqlite3_stmt *pStmt = 0; + fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf( + "REPLACE INTO %Q.'%q_config' VALUES ('version', %d)", + pConfig->zDb, pConfig->zName, FTS5_CURRENT_VERSION_SECUREDELETE + )); + if( p->rc==SQLITE_OK ){ + int rc; + sqlite3_step(pStmt); + rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK ) p->rc = rc; + pConfig->iCookie++; + pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; + } + } + fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); if( fts5MultiIterEof(p, pIter)==0 ){ i64 iThis = fts5MultiIterRowid(pIter); @@ -256998,6 +257236,383 @@ static void fts5MergePrefixLists( *p1 = out; } + +/* +** Iterate through a range of entries in the FTS index, invoking the xVisit +** callback for each of them. +** +** Parameter pToken points to an nToken buffer containing an FTS index term +** (i.e. a document term with the preceding 1 byte index identifier - +** FTS5_MAIN_PREFIX or similar). If bPrefix is true, then the call visits +** all entries for terms that have pToken/nToken as a prefix. If bPrefix +** is false, then only entries with pToken/nToken as the entire key are +** visited. +** +** If the current table is a tokendata=1 table, then if bPrefix is true then +** each index term is treated separately. However, if bPrefix is false, then +** all index terms corresponding to pToken/nToken are collapsed into a single +** term before the callback is invoked. +** +** The callback invoked for each entry visited is specified by paramter xVisit. +** Each time it is invoked, it is passed a pointer to the Fts5Index object, +** a copy of the 7th paramter to this function (pCtx) and a pointer to the +** iterator that indicates the current entry. If the current entry is the +** first with a new term (i.e. different from that of the previous entry, +** including the very first term), then the final two parameters are passed +** a pointer to the term and its size in bytes, respectively. If the current +** entry is not the first associated with its term, these two parameters +** are passed 0. +** +** If parameter pColset is not NULL, then it is used to filter entries before +** the callback is invoked. +*/ +static int fts5VisitEntries( + Fts5Index *p, /* Fts5 index object */ + Fts5Colset *pColset, /* Columns filter to apply, or NULL */ + u8 *pToken, /* Buffer containing token */ + int nToken, /* Size of buffer pToken in bytes */ + int bPrefix, /* True for a prefix scan */ + void (*xVisit)(Fts5Index*, void *pCtx, Fts5Iter *pIter, const u8*, int), + void *pCtx /* Passed as second argument to xVisit() */ +){ + const int flags = (bPrefix ? FTS5INDEX_QUERY_SCAN : 0) + | FTS5INDEX_QUERY_SKIPEMPTY + | FTS5INDEX_QUERY_NOOUTPUT; + Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ + int bNewTerm = 1; + Fts5Structure *pStruct = fts5StructureRead(p); + + fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for( /* no-op */ ; + fts5MultiIterEof(p, p1)==0; + fts5MultiIterNext2(p, p1, &bNewTerm) + ){ + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + int nNew = 0; + const u8 *pNew = 0; + + p1->xSetOutputs(p1, pSeg); + if( p->rc ) break; + + if( bNewTerm ){ + nNew = pSeg->term.n; + pNew = pSeg->term.p; + if( nNew<nToken || memcmp(pToken, pNew, nToken) ) break; + } + + xVisit(p, pCtx, p1, pNew, nNew); + } + fts5MultiIterFree(p1); + + fts5StructureRelease(pStruct); + return p->rc; +} + + +/* +** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an +** array of these for each row it visits (so all iRowid fields are the same). +** Or, for an iterator used by an "ORDER BY rank" query, it accumulates an +** array of these for the entire query (in which case iRowid fields may take +** a variety of values). +** +** Each instance in the array indicates the iterator (and therefore term) +** associated with position iPos of rowid iRowid. This is used by the +** xInstToken() API. +** +** iRowid: +** Rowid for the current entry. +** +** iPos: +** Position of current entry within row. In the usual ((iCol<<32)+iOff) +** format (e.g. see macros FTS5_POS2COLUMN() and FTS5_POS2OFFSET()). +** +** iIter: +** If the Fts5TokenDataIter iterator that the entry is part of is +** actually an iterator (i.e. with nIter>0, not just a container for +** Fts5TokenDataMap structures), then this variable is an index into +** the apIter[] array. The corresponding term is that which the iterator +** at apIter[iIter] currently points to. +** +** Or, if the Fts5TokenDataIter iterator is just a container object +** (nIter==0), then iIter is an index into the term.p[] buffer where +** the term is stored. +** +** nByte: +** In the case where iIter is an index into term.p[], this variable +** is the size of the term in bytes. If iIter is an index into apIter[], +** this variable is unused. +*/ +struct Fts5TokenDataMap { + i64 iRowid; /* Row this token is located in */ + i64 iPos; /* Position of token */ + int iIter; /* Iterator token was read from */ + int nByte; /* Length of token in bytes (or 0) */ +}; + +/* +** An object used to supplement Fts5Iter for tokendata=1 iterators. +** +** This object serves two purposes. The first is as a container for an array +** of Fts5TokenDataMap structures, which are used to find the token required +** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and +** aMap[] variables. +*/ +struct Fts5TokenDataIter { + int nMapAlloc; /* Allocated size of aMap[] in entries */ + int nMap; /* Number of valid entries in aMap[] */ + Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */ + + /* The following are used for prefix-queries only. */ + Fts5Buffer terms; + + /* The following are used for other full-token tokendata queries only. */ + int nIter; + int nIterAlloc; + Fts5PoslistReader *aPoslistReader; + int *aPoslistToIter; + Fts5Iter *apIter[1]; +}; + +/* +** The two input arrays - a1[] and a2[] - are in sorted order. This function +** merges the two arrays together and writes the result to output array +** aOut[]. aOut[] is guaranteed to be large enough to hold the result. +** +** Duplicate entries are copied into the output. So the size of the output +** array is always (n1+n2) entries. +*/ +static void fts5TokendataMerge( + Fts5TokenDataMap *a1, int n1, /* Input array 1 */ + Fts5TokenDataMap *a2, int n2, /* Input array 2 */ + Fts5TokenDataMap *aOut /* Output array */ +){ + int i1 = 0; + int i2 = 0; + + assert( n1>=0 && n2>=0 ); + while( i1<n1 || i2<n2 ){ + Fts5TokenDataMap *pOut = &aOut[i1+i2]; + if( i2>=n2 || (i1<n1 && ( + a1[i1].iRowid<a2[i2].iRowid + || (a1[i1].iRowid==a2[i2].iRowid && a1[i1].iPos<=a2[i2].iPos) + ))){ + memcpy(pOut, &a1[i1], sizeof(Fts5TokenDataMap)); + i1++; + }else{ + memcpy(pOut, &a2[i2], sizeof(Fts5TokenDataMap)); + i2++; + } + } +} + + +/* +** Append a mapping to the token-map belonging to object pT. +*/ +static void fts5TokendataIterAppendMap( + Fts5Index *p, + Fts5TokenDataIter *pT, + int iIter, + int nByte, + i64 iRowid, + i64 iPos +){ + if( p->rc==SQLITE_OK ){ + if( pT->nMap==pT->nMapAlloc ){ + int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; + int nAlloc = nNew * sizeof(Fts5TokenDataMap); + Fts5TokenDataMap *aNew; + + aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc); + if( aNew==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pT->aMap[pT->nMap].iRowid = iRowid; + pT->aMap[pT->nMap].iPos = iPos; + pT->aMap[pT->nMap].iIter = iIter; + pT->aMap[pT->nMap].nByte = nByte; + pT->nMap++; + } +} + +/* +** Sort the contents of the pT->aMap[] array. +** +** The sorting algorithm requries a malloc(). If this fails, an error code +** is left in Fts5Index.rc before returning. +*/ +static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ + Fts5TokenDataMap *aTmp = 0; + int nByte = pT->nMap * sizeof(Fts5TokenDataMap); + + aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( aTmp ){ + Fts5TokenDataMap *a1 = pT->aMap; + Fts5TokenDataMap *a2 = aTmp; + i64 nHalf; + + for(nHalf=1; nHalf<pT->nMap; nHalf=nHalf*2){ + int i1; + for(i1=0; i1<pT->nMap; i1+=(nHalf*2)){ + int n1 = MIN(nHalf, pT->nMap-i1); + int n2 = MIN(nHalf, pT->nMap-i1-n1); + fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]); + } + SWAPVAL(Fts5TokenDataMap*, a1, a2); + } + + if( a1!=pT->aMap ){ + memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap)); + } + sqlite3_free(aTmp); + +#ifdef SQLITE_DEBUG + { + int ii; + for(ii=1; ii<pT->nMap; ii++){ + Fts5TokenDataMap *p1 = &pT->aMap[ii-1]; + Fts5TokenDataMap *p2 = &pT->aMap[ii]; + assert( p1->iRowid<p2->iRowid + || (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos) + ); + } + } +#endif + } +} + +/* +** Delete an Fts5TokenDataIter structure and its contents. +*/ +static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ + if( pSet ){ + int ii; + for(ii=0; ii<pSet->nIter; ii++){ + fts5MultiIterFree(pSet->apIter[ii]); + } + fts5BufferFree(&pSet->terms); + sqlite3_free(pSet->aPoslistReader); + sqlite3_free(pSet->aMap); + sqlite3_free(pSet); + } +} + + +/* +** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata() +** to pass data to prefixIterSetupTokendataCb(). +*/ +typedef struct TokendataSetupCtx TokendataSetupCtx; +struct TokendataSetupCtx { + Fts5TokenDataIter *pT; /* Object being populated with mappings */ + int iTermOff; /* Offset of current term in terms.p[] */ + int nTermByte; /* Size of current term in bytes */ +}; + +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This +** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each +** position in the current position-list. It doesn't matter that some of +** these may be out of order - they will be sorted later. +*/ +static void prefixIterSetupTokendataCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx; + int iPosOff = 0; + i64 iPos = 0; + + if( pNew ){ + pSetup->nTermByte = nNew-1; + pSetup->iTermOff = pSetup->pT->terms.n; + fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1); + } + + while( 0==sqlite3Fts5PoslistNext64( + p1->base.pData, p1->base.nData, &iPosOff, &iPos + ) ){ + fts5TokendataIterAppendMap(p, + pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos + ); + } +} + + +/* +** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries(). +*/ +typedef struct PrefixSetupCtx PrefixSetupCtx; +struct PrefixSetupCtx { + void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); + void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); + i64 iLastRowid; + int nMerge; + Fts5Buffer *aBuf; + int nBuf; + Fts5Buffer doclist; + TokendataSetupCtx *pTokendata; +}; + +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIter() +*/ +static void prefixIterSetupCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + PrefixSetupCtx *pSetup = (PrefixSetupCtx*)pCtx; + const int nMerge = pSetup->nMerge; + + if( p1->base.nData>0 ){ + if( p1->base.iRowid<=pSetup->iLastRowid && pSetup->doclist.n>0 ){ + int i; + for(i=0; p->rc==SQLITE_OK && pSetup->doclist.n; i++){ + int i1 = i*nMerge; + int iStore; + assert( i1+nMerge<=pSetup->nBuf ); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + if( pSetup->aBuf[iStore].n==0 ){ + fts5BufferSwap(&pSetup->doclist, &pSetup->aBuf[iStore]); + fts5BufferZero(&pSetup->doclist); + break; + } + } + if( iStore==i1+nMerge ){ + pSetup->xMerge(p, &pSetup->doclist, nMerge, &pSetup->aBuf[i1]); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + fts5BufferZero(&pSetup->aBuf[iStore]); + } + } + } + pSetup->iLastRowid = 0; + } + + pSetup->xAppend( + p, (u64)p1->base.iRowid-(u64)pSetup->iLastRowid, p1, &pSetup->doclist + ); + pSetup->iLastRowid = p1->base.iRowid; + } + + if( pSetup->pTokendata ){ + prefixIterSetupTokendataCb(p, (void*)pSetup->pTokendata, p1, pNew, nNew); + } +} + static void fts5SetupPrefixIter( Fts5Index *p, /* Index to read from */ int bDesc, /* True for "ORDER BY rowid DESC" */ @@ -257008,38 +257623,41 @@ static void fts5SetupPrefixIter( Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; - Fts5Buffer *aBuf; - int nBuf = 32; - int nMerge = 1; + PrefixSetupCtx s; + TokendataSetupCtx s2; + + memset(&s, 0, sizeof(s)); + memset(&s2, 0, sizeof(s2)); + + s.nMerge = 1; + s.iLastRowid = 0; + s.nBuf = 32; + if( iIdx==0 + && p->pConfig->eDetail==FTS5_DETAIL_FULL + && p->pConfig->bPrefixInsttoken + ){ + s.pTokendata = &s2; + s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT)); + } - void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); - void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ - xMerge = fts5MergeRowidLists; - xAppend = fts5AppendRowid; + s.xMerge = fts5MergeRowidLists; + s.xAppend = fts5AppendRowid; }else{ - nMerge = FTS5_MERGE_NLIST-1; - nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ - xMerge = fts5MergePrefixLists; - xAppend = fts5AppendPoslist; + s.nMerge = FTS5_MERGE_NLIST-1; + s.nBuf = s.nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ + s.xMerge = fts5MergePrefixLists; + s.xAppend = fts5AppendPoslist; } - aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); + s.aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*s.nBuf); pStruct = fts5StructureRead(p); - assert( p->rc!=SQLITE_OK || (aBuf && pStruct) ); + assert( p->rc!=SQLITE_OK || (s.aBuf && pStruct) ); if( p->rc==SQLITE_OK ){ - const int flags = FTS5INDEX_QUERY_SCAN - | FTS5INDEX_QUERY_SKIPEMPTY - | FTS5INDEX_QUERY_NOOUTPUT; + void *pCtx = (void*)&s; int i; - i64 iLastRowid = 0; - Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; - Fts5Buffer doclist; - int bNewTerm = 1; - - memset(&doclist, 0, sizeof(doclist)); /* If iIdx is non-zero, then it is the number of a prefix-index for ** prefixes 1 character longer than the prefix being queried for. That @@ -257047,94 +257665,45 @@ static void fts5SetupPrefixIter( ** corresponding to the prefix itself. That one is extracted from the ** main term index here. */ if( iIdx!=0 ){ - int dummy = 0; - const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; pToken[0] = FTS5_MAIN_PREFIX; - fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); - for(; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &dummy) - ){ - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - p1->xSetOutputs(p1, pSeg); - if( p1->base.nData ){ - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); - iLastRowid = p1->base.iRowid; - } - } - fts5MultiIterFree(p1); + fts5VisitEntries(p, pColset, pToken, nToken, 0, prefixIterSetupCb, pCtx); } pToken[0] = FTS5_MAIN_PREFIX + iIdx; - fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); + fts5VisitEntries(p, pColset, pToken, nToken, 1, prefixIterSetupCb, pCtx); - for( /* no-op */ ; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &bNewTerm) - ){ - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - int nTerm = pSeg->term.n; - const u8 *pTerm = pSeg->term.p; - p1->xSetOutputs(p1, pSeg); - - assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 ); - if( bNewTerm ){ - if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break; - } - - if( p1->base.nData==0 ) continue; - if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ - for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - int i1 = i*nMerge; - int iStore; - assert( i1+nMerge<=nBuf ); - for(iStore=i1; iStore<i1+nMerge; iStore++){ - if( aBuf[iStore].n==0 ){ - fts5BufferSwap(&doclist, &aBuf[iStore]); - fts5BufferZero(&doclist); - break; - } - } - if( iStore==i1+nMerge ){ - xMerge(p, &doclist, nMerge, &aBuf[i1]); - for(iStore=i1; iStore<i1+nMerge; iStore++){ - fts5BufferZero(&aBuf[iStore]); - } - } - } - iLastRowid = 0; - } - - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); - iLastRowid = p1->base.iRowid; - } - - assert( (nBuf%nMerge)==0 ); - for(i=0; i<nBuf; i+=nMerge){ + assert( (s.nBuf%s.nMerge)==0 ); + for(i=0; i<s.nBuf; i+=s.nMerge){ int iFree; if( p->rc==SQLITE_OK ){ - xMerge(p, &doclist, nMerge, &aBuf[i]); + s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]); } - for(iFree=i; iFree<i+nMerge; iFree++){ - fts5BufferFree(&aBuf[iFree]); + for(iFree=i; iFree<i+s.nMerge; iFree++){ + fts5BufferFree(&s.aBuf[iFree]); } } - fts5MultiIterFree(p1); - pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING); + pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING); + assert( pData!=0 || p->rc!=SQLITE_OK ); if( pData ){ pData->p = (u8*)&pData[1]; - pData->nn = pData->szLeaf = doclist.n; - if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n); + pData->nn = pData->szLeaf = s.doclist.n; + if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n); fts5MultiIterNew2(p, pData, bDesc, ppIter); } - fts5BufferFree(&doclist); + + assert( (*ppIter)!=0 || p->rc!=SQLITE_OK ); + if( p->rc==SQLITE_OK && s.pTokendata ){ + fts5TokendataIterSortMap(p, s2.pT); + (*ppIter)->pTokenDataIter = s2.pT; + s2.pT = 0; + } } + fts5TokendataIterDelete(s2.pT); + fts5BufferFree(&s.doclist); fts5StructureRelease(pStruct); - sqlite3_free(aBuf); + sqlite3_free(s.aBuf); } @@ -257388,38 +257957,6 @@ static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ pSeg->pLeaf = 0; } -/* -** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an -** array of these for each row it visits. Or, for an iterator used by an -** "ORDER BY rank" query, it accumulates an array of these for the entire -** query. -** -** Each instance in the array indicates the iterator (and therefore term) -** associated with position iPos of rowid iRowid. This is used by the -** xInstToken() API. -*/ -struct Fts5TokenDataMap { - i64 iRowid; /* Row this token is located in */ - i64 iPos; /* Position of token */ - int iIter; /* Iterator token was read from */ -}; - -/* -** An object used to supplement Fts5Iter for tokendata=1 iterators. -*/ -struct Fts5TokenDataIter { - int nIter; - int nIterAlloc; - - int nMap; - int nMapAlloc; - Fts5TokenDataMap *aMap; - - Fts5PoslistReader *aPoslistReader; - int *aPoslistToIter; - Fts5Iter *apIter[1]; -}; - /* ** This function appends iterator pAppend to Fts5TokenDataIter pIn and ** returns the result. @@ -257456,54 +257993,6 @@ static Fts5TokenDataIter *fts5AppendTokendataIter( return pRet; } -/* -** Delete an Fts5TokenDataIter structure and its contents. -*/ -static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ - if( pSet ){ - int ii; - for(ii=0; ii<pSet->nIter; ii++){ - fts5MultiIterFree(pSet->apIter[ii]); - } - sqlite3_free(pSet->aPoslistReader); - sqlite3_free(pSet->aMap); - sqlite3_free(pSet); - } -} - -/* -** Append a mapping to the token-map belonging to object pT. -*/ -static void fts5TokendataIterAppendMap( - Fts5Index *p, - Fts5TokenDataIter *pT, - int iIter, - i64 iRowid, - i64 iPos -){ - if( p->rc==SQLITE_OK ){ - if( pT->nMap==pT->nMapAlloc ){ - int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; - int nByte = nNew * sizeof(Fts5TokenDataMap); - Fts5TokenDataMap *aNew; - - aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte); - if( aNew==0 ){ - p->rc = SQLITE_NOMEM; - return; - } - - pT->aMap = aNew; - pT->nMapAlloc = nNew; - } - - pT->aMap[pT->nMap].iRowid = iRowid; - pT->aMap[pT->nMap].iPos = iPos; - pT->aMap[pT->nMap].iIter = iIter; - pT->nMap++; - } -} - /* ** The iterator passed as the only argument must be a tokendata=1 iterator ** (pIter->pTokenDataIter!=0). This function sets the iterator output @@ -257544,7 +258033,7 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ pIter->base.iRowid = iRowid; if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){ - fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1); + fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, 0, iRowid, -1); }else if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){ int nReader = 0; @@ -257797,6 +258286,7 @@ static Fts5Iter *fts5SetupTokendataIter( pRet = fts5MultiIterAlloc(p, 0); } if( pRet ){ + pRet->nSeg = 0; pRet->pTokenDataIter = pSet; if( pSet ){ fts5IterSetOutputsTokendata(pRet); @@ -257812,7 +258302,6 @@ static Fts5Iter *fts5SetupTokendataIter( return pRet; } - /* ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. @@ -257835,8 +258324,14 @@ static int sqlite3Fts5IndexQuery( int iIdx = 0; /* Index to search */ int iPrefixIdx = 0; /* +1 prefix index */ int bTokendata = pConfig->bTokendata; + assert( buf.p!=0 ); if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); + /* The NOTOKENDATA flag is set when each token in a tokendata=1 table + ** should be treated individually, instead of merging all those with + ** a common prefix into a single entry. This is used, for example, by + ** queries performed as part of an integrity-check, or by the fts5vocab + ** module. */ if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){ bTokendata = 0; } @@ -257867,7 +258362,7 @@ static int sqlite3Fts5IndexQuery( } if( bTokendata && iIdx==0 ){ - buf.p[0] = '0'; + buf.p[0] = FTS5_MAIN_PREFIX; pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset); }else if( iIdx<=pConfig->nPrefix ){ /* Straight index lookup */ @@ -257880,7 +258375,7 @@ static int sqlite3Fts5IndexQuery( fts5StructureRelease(pStruct); } }else{ - /* Scan multiple terms in the main index */ + /* Scan multiple terms in the main index for a prefix query. */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); if( pRet==0 ){ @@ -257916,7 +258411,8 @@ static int sqlite3Fts5IndexQuery( static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); - if( pIter->pTokenDataIter ){ + if( pIter->nSeg==0 ){ + assert( pIter->pTokenDataIter ); fts5TokendataIterNext(pIter, 0, 0); }else{ fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); @@ -257953,7 +258449,8 @@ static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ */ static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - if( pIter->pTokenDataIter ){ + if( pIter->nSeg==0 ){ + assert( pIter->pTokenDataIter ); fts5TokendataIterNext(pIter, 1, iMatch); }else{ fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); @@ -257972,14 +258469,61 @@ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return (z ? &z[1] : 0); } +/* +** pIter is a prefix query. This function populates pIter->pTokenDataIter +** with an Fts5TokenDataIter object containing mappings for all rows +** matched by the query. +*/ +static int fts5SetupPrefixIterTokendata( + Fts5Iter *pIter, + const char *pToken, /* Token prefix to search for */ + int nToken /* Size of pToken in bytes */ +){ + Fts5Index *p = pIter->pIndex; + Fts5Buffer token = {0, 0, 0}; + TokendataSetupCtx ctx; + + memset(&ctx, 0, sizeof(ctx)); + + fts5BufferGrow(&p->rc, &token, nToken+1); + assert( token.p!=0 || p->rc!=SQLITE_OK ); + ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT)); + + if( p->rc==SQLITE_OK ){ + + /* Fill in the token prefix to search for */ + token.p[0] = FTS5_MAIN_PREFIX; + memcpy(&token.p[1], pToken, nToken); + token.n = nToken+1; + + fts5VisitEntries( + p, 0, token.p, token.n, 1, prefixIterSetupTokendataCb, (void*)&ctx + ); + + fts5TokendataIterSortMap(p, ctx.pT); + } + + if( p->rc==SQLITE_OK ){ + pIter->pTokenDataIter = ctx.pT; + }else{ + fts5TokendataIterDelete(ctx.pT); + } + fts5BufferFree(&token); + + return fts5IndexReturn(p); +} + /* ** This is used by xInstToken() to access the token at offset iOff, column ** iCol of row iRowid. The token is returned via output variables *ppOut ** and *pnOut. The iterator passed as the first argument must be a tokendata=1 ** iterator (pIter->pTokenDataIter!=0). +** +** pToken/nToken: */ static int sqlite3Fts5IterToken( Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, i64 iRowid, int iCol, int iOff, @@ -257987,13 +258531,22 @@ static int sqlite3Fts5IterToken( ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5TokenDataIter *pT = pIter->pTokenDataIter; - Fts5TokenDataMap *aMap = pT->aMap; i64 iPos = (((i64)iCol)<<32) + iOff; - + Fts5TokenDataMap *aMap = 0; int i1 = 0; - int i2 = pT->nMap; + int i2 = 0; int iTest = 0; + assert( pT || (pToken && pIter->nSeg>0) ); + if( pT==0 ){ + int rc = fts5SetupPrefixIterTokendata(pIter, pToken, nToken); + if( rc!=SQLITE_OK ) return rc; + pT = pIter->pTokenDataIter; + } + + i2 = pT->nMap; + aMap = pT->aMap; + while( i2>i1 ){ iTest = (i1 + i2) / 2; @@ -258016,9 +258569,15 @@ static int sqlite3Fts5IterToken( } if( i2>i1 ){ - Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; - *ppOut = (const char*)pMap->aSeg[0].term.p+1; - *pnOut = pMap->aSeg[0].term.n-1; + if( pIter->nSeg==0 ){ + Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; + *ppOut = (const char*)pMap->aSeg[0].term.p+1; + *pnOut = pMap->aSeg[0].term.n-1; + }else{ + Fts5TokenDataMap *p = &aMap[iTest]; + *ppOut = (const char*)&pT->terms.p[p->iIter]; + *pnOut = aMap[iTest].nByte; + } } return SQLITE_OK; @@ -258030,7 +258589,9 @@ static int sqlite3Fts5IterToken( */ static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - if( pIter && pIter->pTokenDataIter ){ + if( pIter && pIter->pTokenDataIter + && (pIter->nSeg==0 || pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_FULL) + ){ pIter->pTokenDataIter->nMap = 0; } } @@ -258050,17 +258611,29 @@ static int sqlite3Fts5IndexIterWriteTokendata( Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5TokenDataIter *pT = pIter->pTokenDataIter; Fts5Index *p = pIter->pIndex; - int ii; + i64 iPos = (((i64)iCol)<<32) + iOff; assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); - assert( pIter->pTokenDataIter ); - - for(ii=0; ii<pT->nIter; ii++){ - Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; - if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; - } - if( ii<pT->nIter ){ - fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff); + assert( pIter->pTokenDataIter || pIter->nSeg>0 ); + if( pIter->nSeg>0 ){ + /* This is a prefix term iterator. */ + if( pT==0 ){ + pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); + pIter->pTokenDataIter = pT; + } + if( pT ){ + fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos); + fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken); + } + }else{ + int ii; + for(ii=0; ii<pT->nIter; ii++){ + Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; + if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; + } + if( ii<pT->nIter ){ + fts5TokendataIterAppendMap(p, pT, ii, 0, iRowid, iPos); + } } return fts5IndexReturn(p); } @@ -259965,6 +260538,7 @@ struct Fts5Global { #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr )) #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr)) +#define FTS5_INSTTOKEN_SUBTYPE 73 /* ** Each auxiliary function registered with the FTS5 module is represented @@ -260504,6 +261078,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an ** unusable plan. Return SQLITE_CONSTRAINT. */ + idxStr[iIdxStr] = 0; return SQLITE_CONSTRAINT; }else{ if( iCol==nCol+1 ){ @@ -261289,6 +261864,7 @@ static int fts5FilterMethod( sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; + int bPrefixInsttoken = pConfig->bPrefixInsttoken; int i; int iIdxStr = 0; Fts5Expr *pExpr = 0; @@ -261324,6 +261900,9 @@ static int fts5FilterMethod( rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset); if( rc!=SQLITE_OK ) goto filter_out; if( zText==0 ) zText = ""; + if( sqlite3_value_subtype(apVal[i])==FTS5_INSTTOKEN_SUBTYPE ){ + pConfig->bPrefixInsttoken = 1; + } iCol = 0; do{ @@ -261464,6 +262043,7 @@ static int fts5FilterMethod( filter_out: sqlite3Fts5ExprFree(pExpr); pConfig->pzErrmsg = pzErrmsg; + pConfig->bPrefixInsttoken = bPrefixInsttoken; return rc; } @@ -261766,7 +262346,6 @@ static int fts5UpdateMethod( Fts5Config *pConfig = pTab->p.pConfig; int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ - int bUpdateOrDelete = 0; /* A transaction must be open when this is called. */ assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); @@ -261778,7 +262357,7 @@ static int fts5UpdateMethod( ); assert( pTab->p.pConfig->pzErrmsg==0 ); if( pConfig->pgsz==0 ){ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie); if( rc!=SQLITE_OK ) return rc; } @@ -261803,7 +262382,6 @@ static int fts5UpdateMethod( rc = SQLITE_ERROR; }else{ rc = fts5SpecialDelete(pTab, apVal); - bUpdateOrDelete = 1; } }else{ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); @@ -261840,7 +262418,6 @@ static int fts5UpdateMethod( }else{ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0); - bUpdateOrDelete = 1; } } @@ -261868,7 +262445,6 @@ static int fts5UpdateMethod( if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); - bUpdateOrDelete = 1; } fts5StorageInsert(&rc, pTab, apVal, pRowid); } @@ -261922,23 +262498,8 @@ static int fts5UpdateMethod( rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); fts5StorageInsert(&rc, pTab, apVal, pRowid); } - bUpdateOrDelete = 1; sqlite3Fts5StorageReleaseDeleteRow(pStorage); } - - } - } - - if( rc==SQLITE_OK - && bUpdateOrDelete - && pConfig->bSecureDelete - && pConfig->iVersion==FTS5_CURRENT_VERSION - ){ - rc = sqlite3Fts5StorageConfigValue( - pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE - ); - if( rc==SQLITE_OK ){ - pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; } } @@ -261991,6 +262552,7 @@ static int fts5RollbackMethod(sqlite3_vtab *pVtab){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0); rc = sqlite3Fts5StorageRollback(pTab->pStorage); + pTab->p.pConfig->pgsz = 0; return rc; } @@ -263459,7 +264021,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e84010", -1, SQLITE_TRANSIENT); } /* @@ -263523,6 +264085,20 @@ static void fts5LocaleFunc( } } +/* +** Implementation of fts5_insttoken() function. +*/ +static void fts5InsttokenFunc( + sqlite3_context *pCtx, /* Function call context */ + int nArg, /* Number of args */ + sqlite3_value **apArg /* Function arguments */ +){ + assert( nArg==1 ); + (void)nArg; + sqlite3_result_value(pCtx, apArg[0]); + sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE); +} + /* ** Return true if zName is the extension on one of the shadow tables used ** by this module. @@ -263652,10 +264228,17 @@ static int fts5Init(sqlite3 *db){ if( rc==SQLITE_OK ){ rc = sqlite3_create_function( db, "fts5_locale", 2, - SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE|SQLITE_SUBTYPE, p, fts5LocaleFunc, 0, 0 ); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function( + db, "fts5_insttoken", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + p, fts5InsttokenFunc, 0, 0 + ); + } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file @@ -263919,6 +264502,11 @@ static int fts5StorageGetStmt( if( rc!=SQLITE_OK && pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); } + if( rc==SQLITE_ERROR && eStmt>FTS5_STMT_LOOKUP2 && eStmt<FTS5_STMT_SCAN ){ + /* One of the internal tables - not the %_content table - is missing. + ** This counts as a corrupted table. */ + rc = SQLITE_CORRUPT; + } } } @@ -266580,8 +267168,8 @@ static int fts5TriTokenize( char *zOut = aBuf; int ii; const unsigned char *zIn = (const unsigned char*)pText; - const unsigned char *zEof = &zIn[nText]; - u32 iCode; + const unsigned char *zEof = (zIn ? &zIn[nText] : 0); + u32 iCode = 0; int aStart[3]; /* Input offset of each character in aBuf[] */ UNUSED_PARAM(unusedFlags); @@ -266590,8 +267178,8 @@ static int fts5TriTokenize( for(ii=0; ii<3; ii++){ do { aStart[ii] = zIn - (const unsigned char*)pText; + if( zIn>=zEof ) return SQLITE_OK; READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) return SQLITE_OK; if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); }while( iCode==0 ); WRITE_UTF8(zOut, iCode); @@ -266612,8 +267200,11 @@ static int fts5TriTokenize( /* Read characters from the input up until the first non-diacritic */ do { iNext = zIn - (const unsigned char*)pText; + if( zIn>=zEof ){ + iCode = 0; + break; + } READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); }while( iCode==0 ); @@ -268650,7 +269241,7 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ } - +/* Here ends the fts5.c composite file. */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */ /************** End of fts5.c ************************************************/ @@ -269223,4 +269814,5 @@ void libsql_wasm_free_msg_buf(char *err_msg_buf) { /************** End of wasmedge_bindings.c ***********************************/ /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } +#endif /* SQLITE_AMALGAMATION */ /************************** End of sqlite3.c ******************************/ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h index 77de0af6c3..d7711ed77f 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h @@ -149,9 +149,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.47.0" -#define SQLITE_VERSION_NUMBER 3047000 -#define SQLITE_SOURCE_ID "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82alt1" +#define SQLITE_VERSION "3.48.0" +#define SQLITE_VERSION_NUMBER 3048000 +#define SQLITE_SOURCE_ID "2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e8alt1" #define LIBSQL_VERSION "0.2.3" @@ -659,6 +659,13 @@ SQLITE_API int sqlite3_exec( ** filesystem supports doing multiple write operations atomically when those ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. +** +** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read +** from the database file in amounts that are not a multiple of the +** page size and that do not begin at a page boundary. Without this +** property, SQLite is careful to only do full-page reads and write +** on aligned pages, with the one exception that it will do a sub-page +** read of the first page to access the database header. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -675,6 +682,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 +#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 /* ** CAPI3REF: File Locking Levels @@ -821,6 +829,7 @@ struct sqlite3_file { ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] ** <li> [SQLITE_IOCAP_IMMUTABLE] ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] +** <li> [SQLITE_IOCAP_SUBPAGE_READ] ** </ul> ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of @@ -1105,6 +1114,11 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +** <li>[[SQLITE_FCNTL_NULL_IO]] +** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor +** or file handle for the [sqlite3_file] object such that it will no longer +** read or write to the database file. +** ** <li>[[SQLITE_FCNTL_WAL_BLOCK]] ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might ** be advantageous to block on the next WAL lock if the lock is not immediately @@ -1258,6 +1272,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +#define SQLITE_FCNTL_NULL_IO 43 // libSQL extension #define SQLITE_FCNTL_WAL_METHODS_POINTER 129 @@ -2649,10 +2664,14 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** The two functions are identical except for the type of the return value -** and that if the number of rows modified by the most recent INSERT, UPDATE +** and that if the number of rows modified by the most recent INSERT, UPDATE, ** or DELETE is greater than the maximum value supported by type "int", then ** the return value of sqlite3_changes() is undefined. ^Executing any other ** type of SQL statement does not modify the value returned by these functions. +** For the purposes of this interface, a CREATE TABLE AS SELECT statement +** does not count as an INSERT, UPDATE or DELETE statement and hence the rows +** added to the new table by the CREATE TABLE AS SELECT statement are not +** counted. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], @@ -4246,11 +4265,22 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler ** to return an error (error code SQLITE_ERROR) if the statement uses ** any virtual tables. +** +** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt> +** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler +** errors from being sent to the error log defined by +** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test +** compiles to see if some SQL syntax is well-formed, without generating +** messages on the global error log when it is not. If the test compile +** fails, the sqlite3_prepare_v3() call returns the same error indications +** with or without this flag; it just omits the call to [sqlite3_log()] that +** logs the error. ** </dl> */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 #define SQLITE_PREPARE_NO_VTAB 0x04 +#define SQLITE_PREPARE_DONT_LOG 0x10 /* ** CAPI3REF: Compiling An SQL Statement @@ -11055,7 +11085,7 @@ SQLITE_API int sqlite3_deserialize( #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif -#endif /* SQLITE3_H */ +/* #endif for SQLITE3_H will be added by mksqlite3.tcl */ /******** Begin file sqlite3rtree.h *********/ /* @@ -13306,14 +13336,29 @@ struct Fts5PhraseIter { ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, ** output variable (*ppToken) is set to point to a buffer containing the ** matching document token, and (*pnToken) to the size of that buffer in -** bytes. This API is not available if the specified token matches a -** prefix query term. In that case both output variables are always set -** to 0. +** bytes. ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. ** @@ -14102,3 +14147,4 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); #endif //LIBSQL_ENABLE_WASM_RUNTIME /******** End of wasm_bindings.h *********/ +#endif /* SQLITE3_H */ diff --git a/libsql-ffi/bundled/bindings/bindgen.rs b/libsql-ffi/bundled/bindings/bindgen.rs index e94ea459b0..fa49c6bb13 100644 --- a/libsql-ffi/bundled/bindings/bindgen.rs +++ b/libsql-ffi/bundled/bindings/bindgen.rs @@ -23,10 +23,10 @@ extern "C" { ) -> ::std::os::raw::c_int; } -pub const SQLITE_VERSION: &[u8; 7] = b"3.47.0\0"; -pub const SQLITE_VERSION_NUMBER: i32 = 3047000; +pub const SQLITE_VERSION: &[u8; 7] = b"3.48.0\0"; +pub const SQLITE_VERSION_NUMBER: i32 = 3048000; pub const SQLITE_SOURCE_ID: &[u8; 85] = - b"2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82alt1\0"; + b"2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e8alt1\0"; pub const LIBSQL_VERSION: &[u8; 6] = b"0.2.3\0"; pub const SQLITE_OK: i32 = 0; pub const SQLITE_ERROR: i32 = 1; @@ -174,6 +174,7 @@ pub const SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN: i32 = 2048; pub const SQLITE_IOCAP_POWERSAFE_OVERWRITE: i32 = 4096; pub const SQLITE_IOCAP_IMMUTABLE: i32 = 8192; pub const SQLITE_IOCAP_BATCH_ATOMIC: i32 = 16384; +pub const SQLITE_IOCAP_SUBPAGE_READ: i32 = 32768; pub const SQLITE_LOCK_NONE: i32 = 0; pub const SQLITE_LOCK_SHARED: i32 = 1; pub const SQLITE_LOCK_RESERVED: i32 = 2; @@ -223,6 +224,7 @@ pub const SQLITE_FCNTL_CKPT_START: i32 = 39; pub const SQLITE_FCNTL_EXTERNAL_READER: i32 = 40; pub const SQLITE_FCNTL_CKSM_FILE: i32 = 41; pub const SQLITE_FCNTL_RESET_CACHE: i32 = 42; +pub const SQLITE_FCNTL_NULL_IO: i32 = 43; pub const SQLITE_FCNTL_WAL_METHODS_POINTER: i32 = 129; pub const SQLITE_GET_LOCKPROXYFILE: i32 = 2; pub const SQLITE_SET_LOCKPROXYFILE: i32 = 3; @@ -340,6 +342,7 @@ pub const SQLITE_LIMIT_WORKER_THREADS: i32 = 11; pub const SQLITE_PREPARE_PERSISTENT: i32 = 1; pub const SQLITE_PREPARE_NORMALIZE: i32 = 2; pub const SQLITE_PREPARE_NO_VTAB: i32 = 4; +pub const SQLITE_PREPARE_DONT_LOG: i32 = 16; pub const SQLITE_INTEGER: i32 = 1; pub const SQLITE_FLOAT: i32 = 2; pub const SQLITE_BLOB: i32 = 4; diff --git a/libsql-ffi/bundled/bindings/session_bindgen.rs b/libsql-ffi/bundled/bindings/session_bindgen.rs index 75cc5037e6..f45bb28e4a 100644 --- a/libsql-ffi/bundled/bindings/session_bindgen.rs +++ b/libsql-ffi/bundled/bindings/session_bindgen.rs @@ -23,10 +23,10 @@ extern "C" { ) -> ::std::os::raw::c_int; } -pub const SQLITE_VERSION: &[u8; 7] = b"3.47.0\0"; -pub const SQLITE_VERSION_NUMBER: i32 = 3047000; +pub const SQLITE_VERSION: &[u8; 7] = b"3.48.0\0"; +pub const SQLITE_VERSION_NUMBER: i32 = 3048000; pub const SQLITE_SOURCE_ID: &[u8; 85] = - b"2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82alt1\0"; + b"2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e8alt1\0"; pub const LIBSQL_VERSION: &[u8; 6] = b"0.2.3\0"; pub const SQLITE_OK: i32 = 0; pub const SQLITE_ERROR: i32 = 1; @@ -174,6 +174,7 @@ pub const SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN: i32 = 2048; pub const SQLITE_IOCAP_POWERSAFE_OVERWRITE: i32 = 4096; pub const SQLITE_IOCAP_IMMUTABLE: i32 = 8192; pub const SQLITE_IOCAP_BATCH_ATOMIC: i32 = 16384; +pub const SQLITE_IOCAP_SUBPAGE_READ: i32 = 32768; pub const SQLITE_LOCK_NONE: i32 = 0; pub const SQLITE_LOCK_SHARED: i32 = 1; pub const SQLITE_LOCK_RESERVED: i32 = 2; @@ -223,6 +224,7 @@ pub const SQLITE_FCNTL_CKPT_START: i32 = 39; pub const SQLITE_FCNTL_EXTERNAL_READER: i32 = 40; pub const SQLITE_FCNTL_CKSM_FILE: i32 = 41; pub const SQLITE_FCNTL_RESET_CACHE: i32 = 42; +pub const SQLITE_FCNTL_NULL_IO: i32 = 43; pub const SQLITE_FCNTL_WAL_METHODS_POINTER: i32 = 129; pub const SQLITE_GET_LOCKPROXYFILE: i32 = 2; pub const SQLITE_SET_LOCKPROXYFILE: i32 = 3; @@ -340,6 +342,7 @@ pub const SQLITE_LIMIT_WORKER_THREADS: i32 = 11; pub const SQLITE_PREPARE_PERSISTENT: i32 = 1; pub const SQLITE_PREPARE_NORMALIZE: i32 = 2; pub const SQLITE_PREPARE_NO_VTAB: i32 = 4; +pub const SQLITE_PREPARE_DONT_LOG: i32 = 16; pub const SQLITE_INTEGER: i32 = 1; pub const SQLITE_FLOAT: i32 = 2; pub const SQLITE_BLOB: i32 = 4; diff --git a/libsql-ffi/bundled/src/sqlite3.c b/libsql-ffi/bundled/src/sqlite3.c index 988693f341..adff2331b5 100644 --- a/libsql-ffi/bundled/src/sqlite3.c +++ b/libsql-ffi/bundled/src/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.47.0. By combining all the individual C code files into this +** version 3.48.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,15 +18,12 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** 03a9703e27c44437c39363d0baf82db4ebc9 with changes in files: +** d2fe6b05f38d9d7cd78c5d252e99ac59f1ae with changes in files: ** ** .fossil-settings/empty-dirs ** .fossil-settings/ignore-glob -** LICENSE.md -** Makefile.in ** Makefile.msc ** README.md -** configure.ac ** doc/compile-for-windows.md ** doc/jsonb.md ** doc/trusted-schema.md @@ -91,7 +88,9 @@ ** tool/mksqlite3c.tcl ** tool/mksqlite3h.tcl ** tool/mksqlite3internalh.tcl +** */ +#ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE @@ -543,9 +542,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.47.0" -#define SQLITE_VERSION_NUMBER 3047000 -#define SQLITE_SOURCE_ID "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82alt1" +#define SQLITE_VERSION "3.48.0" +#define SQLITE_VERSION_NUMBER 3048000 +#define SQLITE_SOURCE_ID "2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e8alt1" #define LIBSQL_VERSION "0.2.3" @@ -1053,6 +1052,13 @@ SQLITE_API int sqlite3_exec( ** filesystem supports doing multiple write operations atomically when those ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. +** +** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read +** from the database file in amounts that are not a multiple of the +** page size and that do not begin at a page boundary. Without this +** property, SQLite is careful to only do full-page reads and write +** on aligned pages, with the one exception that it will do a sub-page +** read of the first page to access the database header. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -1069,6 +1075,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 +#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 /* ** CAPI3REF: File Locking Levels @@ -1215,6 +1222,7 @@ struct sqlite3_file { ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] ** <li> [SQLITE_IOCAP_IMMUTABLE] ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] +** <li> [SQLITE_IOCAP_SUBPAGE_READ] ** </ul> ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of @@ -1499,6 +1507,11 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +** <li>[[SQLITE_FCNTL_NULL_IO]] +** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor +** or file handle for the [sqlite3_file] object such that it will no longer +** read or write to the database file. +** ** <li>[[SQLITE_FCNTL_WAL_BLOCK]] ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might ** be advantageous to block on the next WAL lock if the lock is not immediately @@ -1652,6 +1665,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +#define SQLITE_FCNTL_NULL_IO 43 // libSQL extension #define SQLITE_FCNTL_WAL_METHODS_POINTER 129 @@ -3043,10 +3057,14 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** The two functions are identical except for the type of the return value -** and that if the number of rows modified by the most recent INSERT, UPDATE +** and that if the number of rows modified by the most recent INSERT, UPDATE, ** or DELETE is greater than the maximum value supported by type "int", then ** the return value of sqlite3_changes() is undefined. ^Executing any other ** type of SQL statement does not modify the value returned by these functions. +** For the purposes of this interface, a CREATE TABLE AS SELECT statement +** does not count as an INSERT, UPDATE or DELETE statement and hence the rows +** added to the new table by the CREATE TABLE AS SELECT statement are not +** counted. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], @@ -4640,11 +4658,22 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler ** to return an error (error code SQLITE_ERROR) if the statement uses ** any virtual tables. +** +** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt> +** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler +** errors from being sent to the error log defined by +** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test +** compiles to see if some SQL syntax is well-formed, without generating +** messages on the global error log when it is not. If the test compile +** fails, the sqlite3_prepare_v3() call returns the same error indications +** with or without this flag; it just omits the call to [sqlite3_log()] that +** logs the error. ** </dl> */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 #define SQLITE_PREPARE_NO_VTAB 0x04 +#define SQLITE_PREPARE_DONT_LOG 0x10 /* ** CAPI3REF: Compiling An SQL Statement @@ -11449,7 +11478,7 @@ SQLITE_API int sqlite3_deserialize( #if 0 } /* End of the 'extern "C"' block */ #endif -#endif /* SQLITE3_H */ +/* #endif for SQLITE3_H will be added by mksqlite3.tcl */ /******** Begin file sqlite3rtree.h *********/ /* @@ -13700,14 +13729,29 @@ struct Fts5PhraseIter { ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, ** output variable (*ppToken) is set to point to a buffer containing the ** matching document token, and (*pnToken) to the size of that buffer in -** bytes. This API is not available if the specified token matches a -** prefix query term. In that case both output variables are always set -** to 0. +** bytes. ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. ** @@ -14496,6 +14540,7 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); #endif //LIBSQL_ENABLE_WASM_RUNTIME /******** End of wasm_bindings.h *********/ +#endif /* SQLITE3_H */ /************** End of sqlite3.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14541,6 +14586,7 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); #ifndef SQLITE_MAX_LENGTH # define SQLITE_MAX_LENGTH 1000000000 #endif +#define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */ /* ** This is the maximum number of @@ -14606,9 +14652,13 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); /* ** The maximum number of arguments to an SQL function. +** +** This value has a hard upper limit of 32767 due to storage +** constraints (it needs to fit inside a i16). We keep it +** lower than that to prevent abuse. */ #ifndef SQLITE_MAX_FUNCTION_ARG -# define SQLITE_MAX_FUNCTION_ARG 127 +# define SQLITE_MAX_FUNCTION_ARG 1000 #endif /* @@ -16615,6 +16665,22 @@ typedef struct libsql_pghdr DbPage; #define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ #define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ +#define isWalMode(x) ((x)==PAGER_JOURNALMODE_WAL) + +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods!=0) + /* ** Flags that make up the mask passed to sqlite3PagerGet(). */ @@ -17660,7 +17726,7 @@ typedef struct VdbeOpList VdbeOpList; ** Additional non-public SQLITE_PREPARE_* flags */ #define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */ -#define SQLITE_PREPARE_MASK 0x0f /* Mask of public flags */ +#define SQLITE_PREPARE_MASK 0x1f /* Mask of public flags */ /* ** Prototypes for the VDBE interface. See comments on the implementation @@ -18394,54 +18460,11 @@ struct FuncDefHash { }; #define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) -/* The #warning directive below is a hard error under MSVC's default -** (traditional) C preprocessor (error C1021), which breaks Windows builds. -** Keep the deprecation notice for compilers that accept #warning and skip it -** on MSVC. This is purely a compile-time diagnostic; the extension itself is -** still controlled by SQLITE_USER_AUTHENTICATION below. Upstream SQLite -** removed this extension entirely in 3.48.0 (commit bc4df6079c), so this -** local patch becomes moot once the bundled SQLite is updated past 3.47.0. */ -#if defined(SQLITE_USER_AUTHENTICATION) && !defined(_MSC_VER) -# warning "The SQLITE_USER_AUTHENTICATION extension is deprecated. \ - See ext/userauth/user-auth.txt for details." -#endif -#ifdef SQLITE_USER_AUTHENTICATION -/* -** Information held in the "sqlite3" database connection object and used -** to manage user authentication. -*/ -typedef struct sqlite3_userauth sqlite3_userauth; -struct sqlite3_userauth { - u8 authLevel; /* Current authentication level */ - int nAuthPW; /* Size of the zAuthPW in bytes */ - char *zAuthPW; /* Password used to authenticate */ - char *zAuthUser; /* User name used to authenticate */ -}; - -/* Allowed values for sqlite3_userauth.authLevel */ -#define UAUTH_Unknown 0 /* Authentication not yet checked */ -#define UAUTH_Fail 1 /* User authentication failed */ -#define UAUTH_User 2 /* Authenticated as a normal user */ -#define UAUTH_Admin 3 /* Authenticated as an administrator */ - -/* Functions used only by user authorization logic */ -SQLITE_PRIVATE int sqlite3UserAuthTable(const char*); -SQLITE_PRIVATE int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); -SQLITE_PRIVATE void sqlite3UserAuthInit(sqlite3*); -SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); - -#endif /* SQLITE_USER_AUTHENTICATION */ - /* ** typedef for the authorization callback function. */ -#ifdef SQLITE_USER_AUTHENTICATION - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*, const char*); -#else - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*); -#endif +typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*); #ifndef SQLITE_OMIT_DEPRECATED /* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing @@ -18611,9 +18634,6 @@ struct sqlite3 { void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif -#ifdef SQLITE_USER_AUTHENTICATION - sqlite3_userauth auth; /* User authentication information */ -#endif #ifdef LIBSQL_ENABLE_WASM_RUNTIME libsql_wasm_ctx wasm; /* WebAssembly runtime context */ #endif @@ -18782,7 +18802,7 @@ struct sqlite3 { ** field is used by per-connection app-def functions. */ struct FuncDef { - i8 nArg; /* Number of arguments. -1 means unlimited */ + i16 nArg; /* Number of arguments. -1 means unlimited */ u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ @@ -23548,9 +23568,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_UNTESTABLE "UNTESTABLE", #endif -#ifdef SQLITE_USER_AUTHENTICATION - "USER_AUTHENTICATION", -#endif #ifdef SQLITE_USE_ALLOCA "USE_ALLOCA", #endif @@ -24411,7 +24428,7 @@ struct sqlite3_context { int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ - u8 argc; /* Number of arguments */ + u16 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; @@ -24562,6 +24579,7 @@ struct PreUpdate { int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ + Mem oldipk; /* Memory cell holding "old" IPK value */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ @@ -33029,6 +33047,7 @@ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExp pExpr = pExpr->pLeft; } if( pExpr==0 ) return; + if( ExprHasProperty(pExpr, EP_FromDDL) ) return; db->errByteOffset = pExpr->w.iOfst; } @@ -33755,10 +33774,13 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3_str_appendf(&x, " DDL"); } if( pItem->fg.isCte ){ - sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); + static const char *aMat[] = {",MAT", "", ",NO-MAT"}; + sqlite3_str_appendf(&x, " CteUse=%d%s", + pItem->u2.pCteUse->nUse, + aMat[pItem->u2.pCteUse->eM10d]); } if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ - sqlite3_str_appendf(&x, " ON"); + sqlite3_str_appendf(&x, " isOn"); } if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); @@ -33786,9 +33808,6 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); - sqlite3TreeViewPush(&pView, 0); - sqlite3TreeViewLine(pView, "SUBQUERY"); - sqlite3TreeViewPop(&pView); sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); } if( pItem->fg.isTabFunc ){ @@ -34842,6 +34861,10 @@ SQLITE_PRIVATE void sqlite3TreeViewTrigger( ** accessible to the debugging, and to avoid warnings about unused ** functions. But these routines only exist in debugging builds, so they ** do not contaminate the interface. +** +** See Also: +** +** sqlite3ShowWhereTerm() in where.c */ SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} @@ -36418,8 +36441,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en int eValid = 1; /* True exponent is either not used or is well-formed */ int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ + u64 s2; /* round-tripped significand */ double rr[2]; - u64 s2; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ @@ -36522,7 +36545,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en e = (e*esign) + d; /* Try to adjust the exponent to make it smaller */ - while( e>0 && s<(LARGEST_UINT64/10) ){ + while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){ s *= 10; e--; } @@ -36532,11 +36555,22 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en } rr[0] = (double)s; - s2 = (u64)rr[0]; -#if defined(_MSC_VER) && _MSC_VER<1700 - if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } + assert( sizeof(s2)==sizeof(rr[0]) ); +#ifdef SQLITE_DEBUG + rr[1] = 18446744073709549568.0; + memcpy(&s2, &rr[1], sizeof(s2)); + assert( s2==0x43efffffffffffffLL ); #endif - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + /* Largest double that can be safely converted to u64 + ** vvvvvvvvvvvvvvvvvvvvvv */ + if( rr[0]<=18446744073709549568.0 ){ + s2 = (u64)rr[0]; + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + }else{ + rr[1] = 0.0; + } + assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */ + if( e>0 ){ while( e>=100 ){ e -= 100; @@ -39411,7 +39445,7 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void){ # endif #else /* !SQLITE_WASI */ # ifndef HAVE_FCHMOD -# define HAVE_FCHMOD +# define HAVE_FCHMOD 1 # endif #endif /* SQLITE_WASI */ @@ -43185,6 +43219,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } #endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + case SQLITE_FCNTL_NULL_IO: { + osClose(pFile->h); + pFile->h = -1; + return SQLITE_OK; + } case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; @@ -43326,6 +43365,7 @@ static void setDeviceCharacteristics(unixFile *pFd){ if( pFd->ctrlFlags & UNIXFILE_PSOW ){ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; } + pFd->deviceCharacteristics |= SQLITE_IOCAP_SUBPAGE_READ; pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; } @@ -51065,6 +51105,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } #endif + case SQLITE_FCNTL_NULL_IO: { + (void)osCloseHandle(pFile->h); + pFile->h = NULL; + return SQLITE_OK; + } case SQLITE_FCNTL_TEMPFILENAME: { char *zTFile = 0; int rc = winGetTempname(pFile->pVfs, &zTFile); @@ -51126,7 +51171,7 @@ static int winSectorSize(sqlite3_file *id){ */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_SUBPAGE_READ | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } @@ -52514,7 +52559,7 @@ static int winOpen( int rc = SQLITE_OK; /* Function Return Code */ #if !defined(NDEBUG) || SQLITE_OS_WINCE - int eType = flags&0xFFFFFF00; /* Type of file to open */ + int eType = flags&0x0FFF00; /* Type of file to open */ #endif int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); @@ -58843,20 +58888,6 @@ static const unsigned char aJournalMagic[] = { # define USEFETCH(x) 0 #endif -/* -** The argument to this macro is a file descriptor (type sqlite3_file*). -** Return 0 if it is not open, or non-zero (but not 1) if it is. -** -** This is so that expressions can be written as: -** -** if( isOpen(pPager->jfd) ){ ... -** -** instead of -** -** if( pPager->jfd->pMethods ){ ... -*/ -#define isOpen(pFd) ((pFd)->pMethods!=0) - #ifndef SQLITE_OMIT_WAL # define pagerUseWal(x) ((x)->wal!=0) // check that methods have been initialized #else @@ -58872,21 +58903,29 @@ static const unsigned char aJournalMagic[] = { ** Return true if page pgno can be read directly from the database file ** by the b-tree layer. This is the case if: ** -** * the database file is open, -** * there are no dirty pages in the cache, and -** * the desired page is not currently in the wal file. +** (1) the database file is open +** (2) the VFS for the database is able to do unaligned sub-page reads +** (3) there are no dirty pages in the cache, and +** (4) the desired page is not currently in the wal file. */ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ - if( pPager->fd->pMethods==0 ) return 0; - if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; + assert( pPager!=0 ); + assert( pPager->fd!=0 ); + if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ if( pPager->hasCodec ) return 0; #ifndef SQLITE_OMIT_WAL if( pagerUseWal(pPager) ){ u32 iRead = 0; (void)pPager->wal->methods.xFindFrame(pPager->wal->pData, pgno, &iRead); - return iRead==0; + return iRead==0; /* Condition (4) */ } #endif + assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); + if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) + & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ + return 0; /* Case (2) */ + } return 1; } #endif @@ -60137,7 +60176,7 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ } pPager->journalOff = 0; }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST - || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) + || (pPager->exclusiveMode && pPager->journalMode<PAGER_JOURNALMODE_WAL) ){ rc = zeroJournalHdr(pPager, hasSuper||pPager->tempFile); pPager->journalOff = 0; @@ -67951,6 +67990,7 @@ static int walLockWriter(Wal *pWal){ #else # define walEnableBlocking(x) 0 # define walDisableBlocking(x) +# define walEnableBlockingMs(pWal, ms) 0 # define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1) #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ @@ -68806,11 +68846,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ */ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ - u32 mxReadMark; /* Largest aReadMark[] value */ - int mxI; /* Index of largest aReadMark[] value */ - int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ - u32 mxFrame; /* Wal frame to lock to */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT int nBlockTmout = 0; #endif @@ -68916,145 +68952,147 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ assert( pWal->apWiData[0]!=0 ); pInfo = walCkptInfo(pWal); SEH_INJECT_FAULT; - if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame + { + u32 mxReadMark; /* Largest aReadMark[] value */ + int mxI; /* Index of largest aReadMark[] value */ + int i; /* Loop counter */ + u32 mxFrame; /* Wal frame to lock to */ + if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT - && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) + && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) #endif - ){ - /* The WAL has been completely backfilled (or it is empty). - ** and can be safely ignored. - */ - rc = walLockShared(pWal, WAL_READ_LOCK(0)); - walShmBarrier(pWal); - if( rc==SQLITE_OK ){ - if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ - /* It is not safe to allow the reader to continue here if frames - ** may have been appended to the log before READ_LOCK(0) was obtained. - ** When holding READ_LOCK(0), the reader ignores the entire log file, - ** which implies that the database file contains a trustworthy - ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from - ** happening, this is usually correct. - ** - ** However, if frames have been appended to the log (or if the log - ** is wrapped and written for that matter) before the READ_LOCK(0) - ** is obtained, that is not necessarily true. A checkpointer may - ** have started to backfill the appended frames but crashed before - ** it finished. Leaving a corrupt image in the database file. - */ - walUnlockShared(pWal, WAL_READ_LOCK(0)); - return WAL_RETRY; + ){ + /* The WAL has been completely backfilled (or it is empty). + ** and can be safely ignored. + */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + walShmBarrier(pWal); + if( rc==SQLITE_OK ){ + if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr,sizeof(WalIndexHdr)) ){ + /* It is not safe to allow the reader to continue here if frames + ** may have been appended to the log before READ_LOCK(0) was obtained. + ** When holding READ_LOCK(0), the reader ignores the entire log file, + ** which implies that the database file contains a trustworthy + ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from + ** happening, this is usually correct. + ** + ** However, if frames have been appended to the log (or if the log + ** is wrapped and written for that matter) before the READ_LOCK(0) + ** is obtained, that is not necessarily true. A checkpointer may + ** have started to backfill the appended frames but crashed before + ** it finished. Leaving a corrupt image in the database file. + */ + walUnlockShared(pWal, WAL_READ_LOCK(0)); + return WAL_RETRY; + } + pWal->readLock = 0; + return SQLITE_OK; + }else if( rc!=SQLITE_BUSY ){ + return rc; } - pWal->readLock = 0; - return SQLITE_OK; - }else if( rc!=SQLITE_BUSY ){ - return rc; } - } - /* If we get this far, it means that the reader will want to use - ** the WAL to get at content from recent commits. The job now is - ** to select one of the aReadMark[] entries that is closest to - ** but not exceeding pWal->hdr.mxFrame and lock that entry. - */ - mxReadMark = 0; - mxI = 0; - mxFrame = pWal->hdr.mxFrame; + /* If we get this far, it means that the reader will want to use + ** the WAL to get at content from recent commits. The job now is + ** to select one of the aReadMark[] entries that is closest to + ** but not exceeding pWal->hdr.mxFrame and lock that entry. + */ + mxReadMark = 0; + mxI = 0; + mxFrame = pWal->hdr.mxFrame; #ifdef SQLITE_ENABLE_SNAPSHOT - if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){ - mxFrame = pWal->pSnapshot->mxFrame; - } -#endif - for(i=1; i<WAL_NREADER; i++){ - u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; - if( mxReadMark<=thisMark && thisMark<=mxFrame ){ - assert( thisMark!=READMARK_NOT_USED ); - mxReadMark = thisMark; - mxI = i; + if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){ + mxFrame = pWal->pSnapshot->mxFrame; } - } - if( (pWal->readOnly & WAL_SHM_RDONLY)==0 - && (mxReadMark<mxFrame || mxI==0) - ){ +#endif for(i=1; i<WAL_NREADER; i++){ - rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); - if( rc==SQLITE_OK ){ - AtomicStore(pInfo->aReadMark+i,mxFrame); - mxReadMark = mxFrame; + u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; + if( mxReadMark<=thisMark && thisMark<=mxFrame ){ + assert( thisMark!=READMARK_NOT_USED ); + mxReadMark = thisMark; mxI = i; - walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); - break; - }else if( rc!=SQLITE_BUSY ){ - return rc; } } - } - if( mxI==0 ){ - assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); - return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; - } + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMark<mxFrame || mxI==0) + ){ + for(i=1; i<WAL_NREADER; i++){ + rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ + AtomicStore(pInfo->aReadMark+i,mxFrame); + mxReadMark = mxFrame; + mxI = i; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + break; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + } + if( mxI==0 ){ + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; + } + (void)walEnableBlockingMs(pWal, nBlockTmout); + rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + walDisableBlocking(pWal); + if( rc ){ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - (void)walEnableBlockingMs(pWal, nBlockTmout); -#endif - rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - walDisableBlocking(pWal); -#endif - if( rc ){ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT - if( rc==SQLITE_BUSY_TIMEOUT ){ - *pCnt |= WAL_RETRY_BLOCKED_MASK; - } + if( rc==SQLITE_BUSY_TIMEOUT ){ + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } #else - assert( rc!=SQLITE_BUSY_TIMEOUT ); + assert( rc!=SQLITE_BUSY_TIMEOUT ); #endif - assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT ); - return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; - } - /* Now that the read-lock has been obtained, check that neither the - ** value in the aReadMark[] array or the contents of the wal-index - ** header have changed. - ** - ** It is necessary to check that the wal-index header did not change - ** between the time it was read and when the shared-lock was obtained - ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility - ** that the log file may have been wrapped by a writer, or that frames - ** that occur later in the log than pWal->hdr.mxFrame may have been - ** copied into the database by a checkpointer. If either of these things - ** happened, then reading the database with the current value of - ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry - ** instead. - ** - ** Before checking that the live wal-index header has not changed - ** since it was read, set Wal.minFrame to the first frame in the wal - ** file that has not yet been checkpointed. This client will not need - ** to read any frames earlier than minFrame from the wal file - they - ** can be safely read directly from the database file. - ** - ** Because a ShmBarrier() call is made between taking the copy of - ** nBackfill and checking that the wal-header in shared-memory still - ** matches the one cached in pWal->hdr, it is guaranteed that the - ** checkpointer that set nBackfill was not working with a wal-index - ** header newer than that cached in pWal->hdr. If it were, that could - ** cause a problem. The checkpointer could omit to checkpoint - ** a version of page X that lies before pWal->minFrame (call that version - ** A) on the basis that there is a newer version (version B) of the same - ** page later in the wal file. But if version B happens to like past - ** frame pWal->hdr.mxFrame - then the client would incorrectly assume - ** that it can read version A from the database file. However, since - ** we can guarantee that the checkpointer that set nBackfill could not - ** see any pages past pWal->hdr.mxFrame, this problem does not come up. - */ - pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; - walShmBarrier(pWal); - if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark - || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) - ){ - walUnlockShared(pWal, WAL_READ_LOCK(mxI)); - return WAL_RETRY; - }else{ - assert( mxReadMark<=pWal->hdr.mxFrame ); - pWal->readLock = (i16)mxI; + assert((rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT); + return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; + } + /* Now that the read-lock has been obtained, check that neither the + ** value in the aReadMark[] array or the contents of the wal-index + ** header have changed. + ** + ** It is necessary to check that the wal-index header did not change + ** between the time it was read and when the shared-lock was obtained + ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility + ** that the log file may have been wrapped by a writer, or that frames + ** that occur later in the log than pWal->hdr.mxFrame may have been + ** copied into the database by a checkpointer. If either of these things + ** happened, then reading the database with the current value of + ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry + ** instead. + ** + ** Before checking that the live wal-index header has not changed + ** since it was read, set Wal.minFrame to the first frame in the wal + ** file that has not yet been checkpointed. This client will not need + ** to read any frames earlier than minFrame from the wal file - they + ** can be safely read directly from the database file. + ** + ** Because a ShmBarrier() call is made between taking the copy of + ** nBackfill and checking that the wal-header in shared-memory still + ** matches the one cached in pWal->hdr, it is guaranteed that the + ** checkpointer that set nBackfill was not working with a wal-index + ** header newer than that cached in pWal->hdr. If it were, that could + ** cause a problem. The checkpointer could omit to checkpoint + ** a version of page X that lies before pWal->minFrame (call that version + ** A) on the basis that there is a newer version (version B) of the same + ** page later in the wal file. But if version B happens to like past + ** frame pWal->hdr.mxFrame - then the client would incorrectly assume + ** that it can read version A from the database file. However, since + ** we can guarantee that the checkpointer that set nBackfill could not + ** see any pages past pWal->hdr.mxFrame, this problem does not come up. + */ + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; + walShmBarrier(pWal); + if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark + || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) + ){ + walUnlockShared(pWal, WAL_READ_LOCK(mxI)); + return WAL_RETRY; + }else{ + assert( mxReadMark<=pWal->hdr.mxFrame ); + pWal->readLock = (i16)mxI; + } } return rc; } @@ -88717,6 +88755,7 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ ** will be initialized before use. */ static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ + assert( db!=0 ); if( N>0 ){ do{ p->flags = flags; @@ -88742,6 +88781,7 @@ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; + assert( db!=0 ); if( db->pnBytesFreed ){ do{ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); @@ -89222,6 +89262,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( assert( pParse!=0 ); assert( p->eVdbeState==VDBE_INIT_STATE ); assert( pParse==p->pParse ); + assert( pParse->db==p->db ); p->pVList = pParse->pVList; pParse->pVList = 0; db = p->db; @@ -92125,6 +92166,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( sqlite3DbFree(db, preupdate.aRecord); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); + sqlite3VdbeMemRelease(&preupdate.oldipk); if( preupdate.aNew ){ int i; for(i=0; i<pCsr->nField; i++){ @@ -93499,7 +93541,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ ** sqlite3_column_int64() ** sqlite3_column_text() ** sqlite3_column_text16() -** sqlite3_column_real() +** sqlite3_column_double() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() ** sqlite3_column_blob() @@ -94364,60 +94406,64 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa goto preupdate_old_out; } - /* If the old.* record has not yet been loaded into memory, do so now. */ - if( p->pUnpacked==0 ){ - u32 nRec; - u8 *aRec; + if( iIdx==p->pTab->iPKey ){ + *ppValue = pMem = &p->oldipk; + sqlite3VdbeMemSetInt64(pMem, p->iKey1); + }else{ - assert( p->pCsr->eCurType==CURTYPE_BTREE ); - nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); - aRec = sqlite3DbMallocRaw(db, nRec); - if( !aRec ) goto preupdate_old_out; - rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); - if( rc==SQLITE_OK ){ - p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); - if( !p->pUnpacked ) rc = SQLITE_NOMEM; - } - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, aRec); - goto preupdate_old_out; + /* If the old.* record has not yet been loaded into memory, do so now. */ + if( p->pUnpacked==0 ){ + u32 nRec; + u8 *aRec; + + assert( p->pCsr->eCurType==CURTYPE_BTREE ); + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); + aRec = sqlite3DbMallocRaw(db, nRec); + if( !aRec ) goto preupdate_old_out; + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); + if( rc==SQLITE_OK ){ + p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); + if( !p->pUnpacked ) rc = SQLITE_NOMEM; + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, aRec); + goto preupdate_old_out; + } + p->aRecord = aRec; } - p->aRecord = aRec; - } - pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; - if( iIdx==p->pTab->iPKey ){ - sqlite3VdbeMemSetInt64(pMem, p->iKey1); - }else if( iIdx>=p->pUnpacked->nField ){ - /* This occurs when the table has been extended using ALTER TABLE - ** ADD COLUMN. The value to return is the default value of the column. */ - Column *pCol = &p->pTab->aCol[iIdx]; - if( pCol->iDflt>0 ){ - if( p->apDflt==0 ){ - int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; - p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); - if( p->apDflt==0 ) goto preupdate_old_out; - } - if( p->apDflt[iIdx]==0 ){ - sqlite3_value *pVal = 0; - Expr *pDflt; - assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); - pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; - rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); - if( rc==SQLITE_OK && pVal==0 ){ - rc = SQLITE_CORRUPT_BKPT; + pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; + if( iIdx>=p->pUnpacked->nField ){ + /* This occurs when the table has been extended using ALTER TABLE + ** ADD COLUMN. The value to return is the default value of the column. */ + Column *pCol = &p->pTab->aCol[iIdx]; + if( pCol->iDflt>0 ){ + if( p->apDflt==0 ){ + int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); + if( p->apDflt==0 ) goto preupdate_old_out; + } + if( p->apDflt[iIdx]==0 ){ + sqlite3_value *pVal = 0; + Expr *pDflt; + assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); + pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; + rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); + if( rc==SQLITE_OK && pVal==0 ){ + rc = SQLITE_CORRUPT_BKPT; + } + p->apDflt[iIdx] = pVal; } - p->apDflt[iIdx] = pVal; + *ppValue = p->apDflt[iIdx]; + }else{ + *ppValue = (sqlite3_value *)columnNullValue(); + } + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pMem); } - *ppValue = p->apDflt[iIdx]; - }else{ - *ppValue = (sqlite3_value *)columnNullValue(); - } - }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ - if( pMem->flags & (MEM_Int|MEM_IntReal) ){ - testcase( pMem->flags & MEM_Int ); - testcase( pMem->flags & MEM_IntReal ); - sqlite3VdbeMemRealify(pMem); } } @@ -99645,9 +99691,11 @@ case OP_OpenEphemeral: { /* ncycle */ } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + assert( p->apCsr[pOp->p1]==pCx ); if( rc ){ assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); sqlite3BtreeClose(pCx->ub.pBtx); + p->apCsr[pOp->p1] = 0; /* Not required; helps with static analysis */ }else{ assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); } @@ -111722,7 +111770,7 @@ static int codeCompare( p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); - sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); + sqlite3VdbeChangeP5(pParse->pVdbe, (u16)p5); return addr; } @@ -113889,7 +113937,7 @@ static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){ ** (4a) pExpr must come from an ON clause.. ** (4b) and specifically the ON clause associated with the LEFT JOIN. ** -** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** (5) If pSrc is the right operand of a LEFT JOIN or the left ** operand of a RIGHT JOIN, then pExpr must be from the WHERE ** clause, not an ON clause. ** @@ -114528,6 +114576,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( if( aiMap ) aiMap[i] = j; } + assert( nExpr>0 && nExpr<BMS ); assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); if( colUsed==(MASKBIT(nExpr)-1) ){ /* If we reach this point, that means the index pIdx is usable */ @@ -117423,16 +117472,23 @@ SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,i ** same as that currently bound to variable pVar, non-zero is returned. ** Otherwise, if the values are not the same or if pExpr is not a simple ** SQL value, zero is returned. +** +** If the SQLITE_EnableQPSG flag is set on the database connection, then +** this routine always returns false. */ -static int exprCompareVariable( +static SQLITE_NOINLINE int exprCompareVariable( const Parse *pParse, const Expr *pVar, const Expr *pExpr ){ - int res = 0; + int res = 2; int iVar; sqlite3_value *pL, *pR = 0; + if( pExpr->op==TK_VARIABLE && pVar->iColumn==pExpr->iColumn ){ + return 0; + } + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2; sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); if( pR ){ iVar = pVar->iColumn; @@ -117442,12 +117498,11 @@ static int exprCompareVariable( if( sqlite3_value_type(pL)==SQLITE_TEXT ){ sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */ } - res = 0==sqlite3MemCompare(pL, pR, 0); + res = sqlite3MemCompare(pL, pR, 0) ? 2 : 0; } sqlite3ValueFree(pR); sqlite3ValueFree(pL); } - return res; } @@ -117473,12 +117528,10 @@ static int exprCompareVariable( ** just might result in some slightly slower code. But returning ** an incorrect 0 or 1 could lead to a malfunction. ** -** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in -** pParse->pReprepare can be matched against literals in pB. The -** pParse->pVdbe->expmask bitmask is updated for each variable referenced. -** If pParse is NULL (the normal case) then any TK_VARIABLE term in -** Argument pParse should normally be NULL. If it is not NULL and pA or -** pB causes a return value of 2. +** If pParse is not NULL and SQLITE_EnableQPSG is off then TK_VARIABLE +** terms in pA with bindings in pParse->pReprepare can be matched against +** literals in pB. The pParse->pVdbe->expmask bitmask is updated for +** each variable referenced. */ SQLITE_PRIVATE int sqlite3ExprCompare( const Parse *pParse, @@ -117490,8 +117543,8 @@ SQLITE_PRIVATE int sqlite3ExprCompare( if( pA==0 || pB==0 ){ return pB==pA ? 0 : 2; } - if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){ - return 0; + if( pParse && pA->op==TK_VARIABLE ){ + return exprCompareVariable(pParse, pA, pB); } combinedFlags = pA->flags | pB->flags; if( combinedFlags & EP_IntValue ){ @@ -117686,18 +117739,70 @@ static int exprImpliesNotNull( return 0; } +/* +** Return true if the boolean value of the expression is always either +** FALSE or NULL. +*/ +static int sqlite3ExprIsNotTrue(Expr *pExpr){ + int v; + if( pExpr->op==TK_NULL ) return 1; + if( pExpr->op==TK_TRUEFALSE && sqlite3ExprTruthValue(pExpr)==0 ) return 1; + v = 1; + if( sqlite3ExprIsInteger(pExpr, &v, 0) && v==0 ) return 1; + return 0; +} + +/* +** Return true if the expression is one of the following: +** +** CASE WHEN x THEN y END +** CASE WHEN x THEN y ELSE NULL END +** CASE WHEN x THEN y ELSE false END +** iif(x,y) +** iif(x,y,NULL) +** iif(x,y,false) +*/ +static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){ + ExprList *pList; + if( pExpr->op==TK_FUNCTION ){ + const char *z = pExpr->u.zToken; + FuncDef *pDef; + if( (z[0]!='i' && z[0]!='I') ) return 0; + if( pExpr->x.pList==0 ) return 0; + pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 ) return 0; +#else + if( NEVER(pDef==0) ) return 0; +#endif + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0; + if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0; + }else if( pExpr->op==TK_CASE ){ + if( pExpr->pLeft!=0 ) return 0; + }else{ + return 0; + } + pList = pExpr->x.pList; + assert( pList!=0 ); + if( pList->nExpr==2 ) return 1; + if( pList->nExpr==3 && sqlite3ExprIsNotTrue(pList->a[2].pExpr) ) return 1; + return 0; +} + /* ** Return true if we can prove the pE2 will always be true if pE1 is ** true. Return false if we cannot complete the proof or if pE2 might ** be false. Examples: ** -** pE1: x==5 pE2: x==5 Result: true -** pE1: x>0 pE2: x==5 Result: false -** pE1: x=21 pE2: x=21 OR y=43 Result: true -** pE1: x!=123 pE2: x IS NOT NULL Result: true -** pE1: x!=?1 pE2: x IS NOT NULL Result: true -** pE1: x IS NULL pE2: x IS NOT NULL Result: false -** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: iif(x,y) pE2: x Result: true +** PE1: iif(x,y,0) pE2: x Result: true ** ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has ** Expr.iTable<0 then assume a table number given by iTab. @@ -117731,6 +117836,9 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr( ){ return 1; } + if( sqlite3ExprIsIIF(pParse->db, pE1) ){ + return sqlite3ExprImpliesExpr(pParse,pE1->x.pList->a[0].pExpr,pE2,iTab); + } return 0; } @@ -123449,15 +123557,6 @@ static void attachFunc( sqlite3BtreeLeaveAll(db); assert( zErrDyn==0 || rc!=SQLITE_OK ); } -#ifdef SQLITE_USER_AUTHENTICATION - if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){ - u8 newAuth = 0; - rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); - if( newAuth<db->auth.authLevel ){ - rc = SQLITE_AUTH_USER; - } - } -#endif if( rc ){ if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ int iDb = db->nDb - 1; @@ -123955,11 +124054,7 @@ SQLITE_PRIVATE int sqlite3AuthReadCol( int rc; /* Auth callback return code */ if( db->init.busy ) return SQLITE_OK; - rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext); if( rc==SQLITE_DENY ){ char *z = sqlite3_mprintf("%s.%s", zTab, zCol); if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); @@ -124066,11 +124161,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( testcase( zArg3==0 ); testcase( pParse->zAuthContext==0 ); - rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); + rc = db->xAuth(db->pAuthArg,code,zArg1,zArg2,zArg3,pParse->zAuthContext); if( rc==SQLITE_DENY ){ sqlite3ErrorMsg(pParse, "not authorized"); pParse->rc = SQLITE_AUTH; @@ -124306,17 +124397,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } sqlite3VdbeAddOp0(v, OP_Halt); -#if SQLITE_USER_AUTHENTICATION && !defined(SQLITE_OMIT_SHARED_CACHE) - if( pParse->nTableLock>0 && db->init.busy==0 ){ - sqlite3UserAuthInit(db); - if( db->auth.authLevel<UAUTH_User ){ - sqlite3ErrorMsg(pParse, "user not authenticated"); - pParse->rc = SQLITE_AUTH_USER; - return; - } - } -#endif - /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a @@ -124445,16 +124525,6 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ pParse->nested--; } -#if SQLITE_USER_AUTHENTICATION -/* -** Return TRUE if zTable is the name of the system table that stores the -** list of users and their access credentials. -*/ -SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){ - return sqlite3_stricmp(zTable, "sqlite_user")==0; -} -#endif - /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -124473,13 +124543,6 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha /* All mutexes are required for schema access. Make sure we hold them. */ assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); -#if SQLITE_USER_AUTHENTICATION - /* Only the admin user is allowed to know that the sqlite_user table - ** exists */ - if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){ - return 0; - } -#endif if( zDatabase ){ for(i=0; i<db->nDb; i++){ if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break; @@ -128194,9 +128257,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex( if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && db->init.busy==0 && pTblName!=0 -#if SQLITE_USER_AUTHENTICATION - && sqlite3UserAuthTable(pTab->zName)==0 -#endif ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; @@ -132094,7 +132154,6 @@ static void substrFunc( int len; int p0type; i64 p1, p2; - int negP2 = 0; assert( argc==3 || argc==2 ); if( sqlite3_value_type(argv[1])==SQLITE_NULL @@ -132103,7 +132162,7 @@ static void substrFunc( return; } p0type = sqlite3_value_type(argv[0]); - p1 = sqlite3_value_int(argv[1]); + p1 = sqlite3_value_int64(argv[1]); if( p0type==SQLITE_BLOB ){ len = sqlite3_value_bytes(argv[0]); z = sqlite3_value_blob(argv[0]); @@ -132128,19 +132187,18 @@ static void substrFunc( if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */ #endif if( argc==3 ){ - p2 = sqlite3_value_int(argv[2]); - if( p2<0 ){ - p2 = -p2; - negP2 = 1; - } + p2 = sqlite3_value_int64(argv[2]); }else{ p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; } if( p1<0 ){ p1 += len; if( p1<0 ){ - p2 += p1; - if( p2<0 ) p2 = 0; + if( p2<0 ){ + p2 = 0; + }else{ + p2 += p1; + } p1 = 0; } }else if( p1>0 ){ @@ -132148,12 +132206,13 @@ static void substrFunc( }else if( p2>0 ){ p2--; } - if( negP2 ){ - p1 -= p2; - if( p1<0 ){ - p2 += p1; - p1 = 0; + if( p2<0 ){ + if( p2<-p1 ){ + p2 = p1; + }else{ + p2 = -p2; } + p1 -= p2; } assert( p1>=0 && p2>=0 ); if( p0type!=SQLITE_BLOB ){ @@ -132167,9 +132226,11 @@ static void substrFunc( sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, SQLITE_UTF8); }else{ - if( p1+p2>len ){ + if( p1>=len ){ + p1 = p2 = 0; + }else if( p2>len-p1 ){ p2 = len-p1; - if( p2<0 ) p2 = 0; + assert( p2>0 ); } sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); } @@ -132180,13 +132241,13 @@ static void substrFunc( */ #ifndef SQLITE_OMIT_FLOATING_POINT static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - int n = 0; + i64 n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; - n = sqlite3_value_int(argv[1]); + n = sqlite3_value_int64(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } @@ -132201,7 +132262,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ - zBuf = sqlite3_mprintf("%!.*f",n,r); + zBuf = sqlite3_mprintf("%!.*f",(int)n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; @@ -134549,9 +134610,6 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ SFUNCTION(load_extension, 1, 0, 0, loadExt ), SFUNCTION(load_extension, 2, 0, 0, loadExt ), #endif -#if SQLITE_USER_AUTHENTICATION - FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), -#endif #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), @@ -134688,7 +134746,10 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ FUNCTION(sign, 1, 0, 0, signFunc ), INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), + INLINE_FUNC(iif, 2, INLINEFUNC_iif, 0 ), INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), + INLINE_FUNC(if, 2, INLINEFUNC_iif, 0 ), + INLINE_FUNC(if, 3, INLINEFUNC_iif, 0 ), }; #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); @@ -143272,12 +143333,6 @@ SQLITE_PRIVATE void sqlite3Pragma( ** in auto-commit mode. */ mask &= ~(SQLITE_ForeignKeys); } -#if SQLITE_USER_AUTHENTICATION - if( db->auth.authLevel==UAUTH_User ){ - /* Do not allow non-admin users to modify the schema arbitrarily */ - mask &= ~(SQLITE_WriteSchema); - } -#endif if( sqlite3GetBoolean(zRight, 0) ){ if( (mask & SQLITE_WriteSchema)==0 @@ -143413,7 +143468,8 @@ SQLITE_PRIVATE void sqlite3Pragma( char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName); if( zSql ){ sqlite3_stmt *pDummy = 0; - (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0); + (void)sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_DONT_LOG, + &pDummy, 0); (void)sqlite3_finalize(pDummy); sqlite3DbFree(db, zSql); } @@ -143894,7 +143950,7 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Do the b-tree integrity checks */ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); - sqlite3VdbeChangeP5(v, (u8)i); + sqlite3VdbeChangeP5(v, (u16)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), @@ -145515,14 +145571,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl #else encoding = SQLITE_UTF8; #endif - if( db->nVdbeActive>0 && encoding!=ENC(db) - && (db->mDbFlags & DBFLAG_Vacuum)==0 - ){ - rc = SQLITE_LOCKED; - goto initone_error_out; - }else{ - sqlite3SetTextEncoding(db, encoding); - } + sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ @@ -150230,32 +150279,32 @@ static Expr *substExpr( if( pSubst->isOuterJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } - if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ - sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, - pExpr->flags & (EP_OuterON|EP_InnerON)); - } - sqlite3ExprDelete(db, pExpr); - pExpr = pNew; - if( pExpr->op==TK_TRUEFALSE ){ - pExpr->u.iValue = sqlite3ExprTruthValue(pExpr); - pExpr->op = TK_INTEGER; - ExprSetProperty(pExpr, EP_IntValue); + if( pNew->op==TK_TRUEFALSE ){ + pNew->u.iValue = sqlite3ExprTruthValue(pNew); + pNew->op = TK_INTEGER; + ExprSetProperty(pNew, EP_IntValue); } /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ { - CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pNew); CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pSubst->pCList->a[iColumn].pExpr ); - if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){ - pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + if( pNat!=pColl || (pNew->op!=TK_COLUMN && pNew->op!=TK_COLLATE) ){ + pNew = sqlite3ExprAddCollateString(pSubst->pParse, pNew, (pColl ? pColl->zName : "BINARY") ); } } - ExprClearProperty(pExpr, EP_Collate); + ExprClearProperty(pNew, EP_Collate); + if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, + pExpr->flags & (EP_OuterON|EP_InnerON)); + } + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; } } }else{ @@ -150992,6 +151041,7 @@ static int flattenSubquery( /* Transfer the FROM clause terms from the subquery into the ** outer query. */ + iNewParent = pSubSrc->a[0].iCursor; for(i=0; i<nSubSrc; i++){ SrcItem *pItem = &pSrc->a[i+iFrom]; assert( pItem->fg.isTabFunc==0 ); @@ -151001,7 +151051,6 @@ static int flattenSubquery( if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); *pItem = pSubSrc->a[i]; pItem->fg.jointype |= ltorj; - iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].fg.jointype &= JT_LTORJ; @@ -151041,6 +151090,7 @@ static int flattenSubquery( pWhere = pSub->pWhere; pSub->pWhere = 0; if( isOuterJoin>0 ){ + assert( pSubSrc->nSrc==1 ); sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON); } if( pWhere ){ @@ -153144,7 +153194,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, iTop); sqlite3ReleaseTempRange(pParse, regAgg, nArg); @@ -153307,7 +153357,7 @@ static void updateAccumulator( } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); } if( addrNext ){ @@ -154140,7 +154190,7 @@ SQLITE_PRIVATE int sqlite3Select( #endif assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); }else{ - TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); + TREETRACE(0x4000,pParse,p,("WHERE-clause push-down not possible\n")); } /* Convert unused result columns of the subquery into simple NULL @@ -156702,7 +156752,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ - sqlite3VdbeChangeP5(v, (u8)bRecursive); + sqlite3VdbeChangeP5(v, (u16)bRecursive); } } @@ -160941,9 +160991,17 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( const WhereInfo *pWInfo, /* WHERE clause */ const WhereLevel *pLevel /* Bloom filter on this level */ ); +SQLITE_PRIVATE void sqlite3WhereAddExplainText( + Parse *pParse, /* Parse context */ + int addr, + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +); #else # define sqlite3WhereExplainOneScan(u,v,w,x) 0 # define sqlite3WhereExplainBloomFilter(u,v,w) 0 +# define sqlite3WhereAddExplainText(u,v,w,x,y) #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS SQLITE_PRIVATE void sqlite3WhereAddScanStatus( @@ -161145,38 +161203,38 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ } /* -** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN -** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG -** was defined at compile-time. If it is not a no-op, a single OP_Explain -** opcode is added to the output to describe the table scan strategy in pLevel. -** -** If an OP_Explain opcode is added to the VM, its address is returned. -** Otherwise, if no OP_Explain is coded, zero is returned. +** This function sets the P4 value of an existing OP_Explain opcode to +** text describing the loop in pLevel. If the OP_Explain opcode already has +** a P4 value, it is freed before it is overwritten. */ -SQLITE_PRIVATE int sqlite3WhereExplainOneScan( +SQLITE_PRIVATE void sqlite3WhereAddExplainText( Parse *pParse, /* Parse context */ + int addr, /* Address of OP_Explain opcode */ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ - int ret = 0; #if !defined(SQLITE_DEBUG) if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) #endif { + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr); + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; - Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ WhereLoop *pLoop; /* The controlling WhereLoop object */ u32 flags; /* Flags that describe this loop */ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) char *zMsg; /* Text to add to EQP output */ +#endif StrAccum str; /* EQP output string */ char zBuf[100]; /* Initial space for EQP output string */ + if( db->mallocFailed ) return; + pLoop = pLevel->pWLoop; flags = pLoop->wsFlags; - if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0; isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) @@ -161200,7 +161258,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; }else if( flags & WHERE_AUTO_INDEX ){ zFmt = "AUTOMATIC COVERING INDEX"; - }else if( flags & WHERE_IDX_ONLY ){ + }else if( flags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ zFmt = "COVERING INDEX %s"; }else{ zFmt = "INDEX %s"; @@ -161252,11 +161310,50 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( sqlite3_str_append(&str, " (~1 row)", 9); } #endif +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) zMsg = sqlite3StrAccumFinish(&str); sqlite3ExplainBreakpoint("",zMsg); - ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), - pParse->addrExplain, pLoop->rRun, - zMsg, P4_DYNAMIC); +#endif + + assert( pOp->opcode==OP_Explain ); + assert( pOp->p4type==P4_DYNAMIC || pOp->p4.z==0 ); + sqlite3DbFree(db, pOp->p4.z); + pOp->p4type = P4_DYNAMIC; + pOp->p4.z = sqlite3StrAccumFinish(&str); + } +} + + +/* +** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN +** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG +** was defined at compile-time. If it is not a no-op, a single OP_Explain +** opcode is added to the output to describe the table scan strategy in pLevel. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ + int ret = 0; +#if !defined(SQLITE_DEBUG) + if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + if( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + ){ + Vdbe *v = pParse->pVdbe; + int addr = sqlite3VdbeCurrentAddr(v); + ret = sqlite3VdbeAddOp3( + v, OP_Explain, addr, pParse->addrExplain, pLevel->pWLoop->rRun + ); + sqlite3WhereAddExplainText(pParse, addr, pTabList, pLevel, wctrlFlags); + } } return ret; } @@ -161355,9 +161452,10 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( } }else{ int addr; + VdbeOp *pOp; assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; - VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); + pOp = sqlite3VdbeGetOp(v, addr-1); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); @@ -161610,6 +161708,7 @@ static Expr *removeUnindexableInClauseTerms( pNew->pLeft->x.pList = pLhs; } pSelect->pEList = pRhs; + pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */ if( pLhs && pLhs->nExpr==1 ){ /* Take care here not to generate a TK_VECTOR containing only a ** single value. Since the parser never creates such a vector, some @@ -166684,7 +166783,7 @@ static int constraintCompatibleWithOuterJoin( return 0; } if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 - && ExprHasProperty(pTerm->pExpr, EP_InnerON) + && NEVER(ExprHasProperty(pTerm->pExpr, EP_InnerON)) ){ return 0; } @@ -166705,6 +166804,11 @@ static int constraintCompatibleWithOuterJoin( ** more than 20, then return false. ** ** 3. If no disqualifying conditions above are found, return true. +** +** 2025-01-03: I experimented with a new rule that returns false if the +** the datatype of the column is "BOOLEAN". This did not improve +** performance on any queries at hand, but it did burn CPU cycles, so the +** idea was not committed. */ static SQLITE_NOINLINE int columnIsGoodIndexCandidate( const Table *pTab, @@ -168177,7 +168281,7 @@ static int whereInScanEst( #endif /* SQLITE_ENABLE_STAT4 */ -#ifdef WHERETRACE_ENABLED +#if defined(WHERETRACE_ENABLED) || defined(SQLITE_DEBUG) /* ** Print the content of a WhereTerm object */ @@ -168221,6 +168325,9 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } +SQLITE_PRIVATE void sqlite3ShowWhereTerm(WhereTerm *pTerm){ + sqlite3WhereTermPrint(pTerm, 0); +} #endif #ifdef WHERETRACE_ENABLED @@ -169407,7 +169514,6 @@ static int whereUsablePartialIndex( if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0; pWhere = pWhere->pRight; } - if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ Expr *pExpr; pExpr = pTerm->pExpr; @@ -172074,7 +172180,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( } if( hasRightJoin && ExprHasProperty(pTerm->pExpr, EP_InnerON) - && pTerm->pExpr->w.iJoin==pItem->iCursor + && NEVER(pTerm->pExpr->w.iJoin==pItem->iCursor) ){ break; /* restriction (5) */ } @@ -172994,6 +173100,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; sqlite3VdbePrintOp(0, pc, pOp); + sqlite3ShowWhereTerm(0); /* So compiler won't complain about unused func */ } #endif @@ -173293,14 +173400,28 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); - }else{ - /* Unable to translate the table reference into an index - ** reference. Verify that this is harmless - that the - ** table being referenced really is open. - */ + }else if( pLoop->wsFlags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ if( pLoop->wsFlags & WHERE_IDX_ONLY ){ + /* An error. pLoop is supposed to be a covering index loop, + ** and yet the VM code refers to a column of the table that + ** is not part of the index. */ sqlite3ErrorMsg(pParse, "internal query planner error"); pParse->rc = SQLITE_INTERNAL; + }else{ + /* The WHERE_EXPRIDX flag is set by the planner when it is likely + ** that pLoop is a covering index loop, but it is not possible + ** to be 100% sure. In this case, any OP_Explain opcode + ** corresponding to this loop describes the index as a "COVERING + ** INDEX". But, pOp proves that pLoop is not actually a covering + ** index loop. So clear the WHERE_EXPRIDX flag and rewrite the + ** text that accompanies the OP_Explain opcode, if any. */ + pLoop->wsFlags &= ~WHERE_EXPRIDX; + sqlite3WhereAddExplainText(pParse, + pLevel->addrBody-1, + pTabList, + pLevel, + pWInfo->wctrlFlags + ); } } }else if( pOp->opcode==OP_Rowid ){ @@ -175008,6 +175129,7 @@ static void windowAggStep( int regArg; int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); int i; + int addrIf = 0; assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); @@ -175024,6 +175146,18 @@ static void windowAggStep( } regArg = reg; + if( pWin->pFilter ){ + int regTmp; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); + assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regTmp); + } + if( pMWin->regStartRowid==0 && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) @@ -175043,25 +175177,13 @@ static void windowAggStep( } sqlite3VdbeJumpHere(v, addrIsNull); }else if( pWin->regApp ){ + assert( pWin->pFilter==0 ); assert( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ); assert( bInverse==0 || bInverse==1 ); sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); }else if( pFunc->xSFunc!=noopStepFunc ){ - int addrIf = 0; - if( pWin->pFilter ){ - int regTmp; - assert( ExprUseXList(pWin->pOwner) ); - assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); - assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); - regTmp = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); - addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); - VdbeCoverage(v); - sqlite3ReleaseTempReg(pParse, regTmp); - } - if( pWin->bExprArgs ){ int iOp = sqlite3VdbeCurrentAddr(v); int iEnd; @@ -175088,12 +175210,13 @@ static void windowAggStep( sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeChangeP5(v, (u16)nArg); if( pWin->bExprArgs ){ sqlite3ReleaseTempRange(pParse, regArg, nArg); } - if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } + + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } } @@ -176520,6 +176643,13 @@ struct TrigEvent { int a; IdList * b; }; struct FrameBound { int eType; Expr *pExpr; }; +/* +** Generate a syntax error +*/ +static void parserSyntaxError(Parse *pParse, Token *p){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", p); +} + /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. @@ -180483,7 +180613,11 @@ static YYACTIONTYPE yy_reduce( case 89: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy599, &dest); + if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0 + || sqlite3ReadSchema(pParse)==SQLITE_OK + ){ + sqlite3Select(pParse, yymsp[0].minor.yy599, &dest); + } sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy599); } break; @@ -180955,7 +181089,7 @@ static YYACTIONTYPE yy_reduce( Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/ assert( t.n>=2 ); if( pParse->nested==0 ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); + parserSyntaxError(pParse, &t); yymsp[0].minor.yy66 = 0; }else{ yymsp[0].minor.yy66 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); @@ -181813,7 +181947,7 @@ static void yy_syntax_error( UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ if( TOKEN.z[0] ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + parserSyntaxError(pParse, &TOKEN); }else{ sqlite3ErrorMsg(pParse, "incomplete input"); } @@ -183311,7 +183445,9 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ if( pParse->zErrMsg==0 ){ pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); } - sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){ + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + } nErr++; } pParse->zTail = zSql; @@ -185302,10 +185438,6 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ sqlite3ValueFree(db->pErr); sqlite3CloseExtensions(db); -#if SQLITE_USER_AUTHENTICATION - sqlite3_free(db->auth.zAuthUser); - sqlite3_free(db->auth.zAuthPW); -#endif db->eOpenState = SQLITE_STATE_ERROR; @@ -186922,8 +187054,8 @@ static const int aHardLimit[] = { #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif -#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127 -# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127 +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>32767 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 32767 #endif #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 # error SQLITE_MAX_ATTACHED must be between 0 and 125 @@ -186990,8 +187122,8 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ if( newLimit>=0 ){ /* IMP: R-52476-28732 */ if( newLimit>aHardLimit[limitId] ){ newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ - }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){ - newLimit = 1; + }else if( newLimit<SQLITE_MIN_LENGTH && limitId==SQLITE_LIMIT_LENGTH ){ + newLimit = SQLITE_MIN_LENGTH; } db->aLimit[limitId] = newLimit; } @@ -188414,7 +188546,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ /* Invoke these debugging routines so that the compiler does not ** issue "defined but not used" warnings. */ if( x==9999 ){ - sqlite3ShowExpr(0); sqlite3ShowExpr(0); sqlite3ShowExprList(0); sqlite3ShowIdList(0); @@ -192846,10 +192977,15 @@ static int fts3PoslistPhraseMerge( if( *p1==POS_COLUMN ){ p1++; p1 += fts3GetVarint32(p1, &iCol1); + /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN + ** entry, so this is actually end-of-doclist. */ + if( iCol1==0 ) return 0; } if( *p2==POS_COLUMN ){ p2++; p2 += fts3GetVarint32(p2, &iCol2); + /* As above, iCol2==0 indicates corruption. */ + if( iCol2==0 ) return 0; } while( 1 ){ @@ -196020,7 +196156,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ nTmp += p->pRight->pPhrase->doclist.nList; } nTmp += p->pPhrase->doclist.nList; - aTmp = sqlite3_malloc64(nTmp*2); + aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX); if( !aTmp ){ *pRc = SQLITE_NOMEM; res = 0; @@ -196671,7 +196807,7 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ } #endif -#if !SQLITE_CORE +#if !defined(SQLITE_CORE) /* ** Initialize API pointer table, if required. */ @@ -197573,10 +197709,11 @@ static int getNextString( Fts3PhraseToken *pToken; p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); - if( !p ) goto no_mem; - zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); - if( !zTemp ) goto no_mem; + if( !zTemp || !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } assert( nToken==ii ); pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; @@ -197591,9 +197728,6 @@ static int getNextString( nToken = ii+1; } } - - pModule->xClose(pCursor); - pCursor = 0; } if( rc==SQLITE_DONE ){ @@ -197601,7 +197735,10 @@ static int getNextString( char *zBuf = 0; p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); - if( !p ) goto no_mem; + if( !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); p->eType = FTSQUERY_PHRASE; p->pPhrase = (Fts3Phrase *)&p[1]; @@ -197609,11 +197746,9 @@ static int getNextString( p->pPhrase->nToken = nToken; zBuf = (char *)&p->pPhrase->aToken[nToken]; + assert( nTemp==0 || zTemp ); if( zTemp ){ memcpy(zBuf, zTemp, nTemp); - sqlite3_free(zTemp); - }else{ - assert( nTemp==0 ); } for(jj=0; jj<p->pPhrase->nToken; jj++){ @@ -197623,17 +197758,17 @@ static int getNextString( rc = SQLITE_OK; } - *ppExpr = p; - return rc; -no_mem: - + getnextstring_out: if( pCursor ){ pModule->xClose(pCursor); } sqlite3_free(zTemp); - sqlite3_free(p); - *ppExpr = 0; - return SQLITE_NOMEM; + if( rc!=SQLITE_OK ){ + sqlite3_free(p); + p = 0; + } + *ppExpr = p; + return rc; } /* @@ -223968,8 +224103,8 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ sqlite3_str_append(pOut, "}", 1); } errCode = sqlite3_str_errcode(pOut); - sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free); sqlite3_result_error_code(ctx, errCode); + sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free); } /* This routine implements an SQL function that returns the "depth" parameter @@ -226485,7 +226620,7 @@ SQLITE_API int sqlite3_rtree_query_callback( ); } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif @@ -227076,7 +227211,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ return rc; } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif @@ -234674,6 +234809,24 @@ static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ return SQLITE_OK; } +/* +** Open write transactions. Since we do not know in advance which database +** files will be written by the sqlite_dbpage virtual table, start a write +** transaction on them all. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int dbpageBeginTrans(DbpageTable *pTab){ + sqlite3 *db = pTab->db; + int rc = SQLITE_OK; + int i; + for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ) rc = sqlite3BtreeBeginTrans(pBt, 1, 0); + } + return rc; +} + static int dbpageUpdate( sqlite3_vtab *pVtab, int argc, @@ -234741,6 +234894,12 @@ static int dbpageUpdate( goto update_fail; } } + + if( dbpageBeginTrans(pTab)!=SQLITE_OK ){ + zErr = "failed to open transaction"; + goto update_fail; + } + pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ @@ -234750,6 +234909,8 @@ static int dbpageUpdate( memcpy(aPage, pData, szPage); pTab->pgnoTrunc = 0; } + }else{ + pTab->pgnoTrunc = 0; } sqlite3PagerUnref(pDbPage); return rc; @@ -234760,18 +234921,8 @@ static int dbpageUpdate( return SQLITE_ERROR; } -/* Since we do not know in advance which database files will be -** written by the sqlite_dbpage virtual table, start a write transaction -** on them all. -*/ static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; - sqlite3 *db = pTab->db; - int i; - for(i=0; i<db->nDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); - } pTab->pgnoTrunc = 0; return SQLITE_OK; } @@ -234783,7 +234934,11 @@ static int dbpageSync(sqlite3_vtab *pVtab){ if( pTab->pgnoTrunc>0 ){ Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt; Pager *pPager = sqlite3BtreePager(pBt); - sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); + sqlite3BtreeEnter(pBt); + if( pTab->pgnoTrunc<sqlite3BtreeLastPage(pBt) ){ + sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); + } + sqlite3BtreeLeave(pBt); } pTab->pgnoTrunc = 0; return SQLITE_OK; @@ -234803,7 +234958,7 @@ static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){ */ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ static sqlite3_module dbpage_module = { - 0, /* iVersion */ + 2, /* iVersion */ dbpageConnect, /* xCreate */ dbpageConnect, /* xConnect */ dbpageBestIndex, /* xBestIndex */ @@ -240122,12 +240277,12 @@ static int sessionChangesetApply( } } } - sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); - }else{ + } + if( rc!=SQLITE_OK ){ sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); } @@ -241377,7 +241532,27 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ /************** End of sqlite3session.c **************************************/ /************** Begin file fts5.c ********************************************/ - +/* +** This, the "fts5.c" source file, is a composite file that is itself +** assembled from the following files: +** +** fts5.h +** fts5Int.h +** fts5parse.h <--- Generated from fts5parse.y by Lemon +** fts5parse.c <--- Generated from fts5parse.y by Lemon +** fts5_aux.c +** fts5_buffer.c +** fts5_config.c +** fts5_expr.c +** fts5_hash.c +** fts5_index.c +** fts5_main.c +** fts5_storage.c +** fts5_tokenize.c +** fts5_unicode2.c +** fts5_varint.c +** fts5_vocab.c +*/ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) @@ -241387,6 +241562,12 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ # undef NDEBUG #endif +#ifdef HAVE_STDINT_H +/* #include <stdint.h> */ +#endif +#ifdef HAVE_INTTYPES_H +/* #include <inttypes.h> */ +#endif /* ** 2014 May 31 ** @@ -241687,14 +241868,29 @@ struct Fts5PhraseIter { ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, ** output variable (*ppToken) is set to point to a buffer containing the ** matching document token, and (*pnToken) to the size of that buffer in -** bytes. This API is not available if the specified token matches a -** prefix query term. In that case both output variables are always set -** to 0. +** bytes. ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. ** @@ -242376,7 +242572,8 @@ struct Fts5Config { char *zRank; /* Name of rank function */ char *zRankArgs; /* Arguments to rank function */ int bSecureDelete; /* 'secure-delete' */ - int nDeleteMerge; /* 'deletemerge' */ + int nDeleteMerge; /* 'deletemerge' */ + int bPrefixInsttoken; /* 'prefix-insttoken' */ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ char **pzErrmsg; @@ -242633,7 +242830,14 @@ static int sqlite3Fts5StructureTest(Fts5Index*, void*); /* ** Used by xInstToken(): */ -static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*); +static int sqlite3Fts5IterToken( + Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, + i64 iRowid, + int iCol, + int iOff, + const char **ppOut, int *pnOut +); /* ** Insert or remove data to or from the index. Each time a document is @@ -246847,6 +247051,19 @@ static int sqlite3Fts5ConfigSetValue( }else{ pConfig->bSecureDelete = (bVal ? 1 : 0); } + } + + else if( 0==sqlite3_stricmp(zKey, "insttoken") ){ + int bVal = -1; + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + bVal = sqlite3_value_int(pVal); + } + if( bVal<0 ){ + *pbBadkey = 1; + }else{ + pConfig->bPrefixInsttoken = (bVal ? 1 : 0); + } + }else{ *pbBadkey = 1; } @@ -249982,7 +250199,7 @@ static int fts5ExprPopulatePoslistsCb( int rc = sqlite3Fts5PoslistWriterAppend( &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff ); - if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){ + if( rc==SQLITE_OK && (pExpr->pConfig->bTokendata || pT->bPrefix) ){ int iCol = p->iOff>>32; int iTokOff = p->iOff & 0x7FFFFFFF; rc = sqlite3Fts5IndexIterWriteTokendata( @@ -250175,15 +250392,14 @@ static int sqlite3Fts5ExprInstToken( return SQLITE_RANGE; } pTerm = &pPhrase->aTerm[iToken]; - if( pTerm->bPrefix==0 ){ - if( pExpr->pConfig->bTokendata ){ - rc = sqlite3Fts5IterToken( - pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut - ); - }else{ - *ppOut = pTerm->pTerm; - *pnOut = pTerm->nFullTerm; - } + if( pExpr->pConfig->bTokendata || pTerm->bPrefix ){ + rc = sqlite3Fts5IterToken( + pTerm->pIter, pTerm->pTerm, pTerm->nQueryTerm, + iRowid, iCol, iOff+iToken, ppOut, pnOut + ); + }else{ + *ppOut = pTerm->pTerm; + *pnOut = pTerm->nFullTerm; } return rc; } @@ -251686,9 +251902,13 @@ static int fts5IndexPrepareStmt( ){ if( p->rc==SQLITE_OK ){ if( zSql ){ - p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, + int rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB, ppStmt, 0); + /* If this prepare() call fails with SQLITE_ERROR, then one of the + ** %_idx or %_data tables has been removed or modified. Call this + ** corruption. */ + p->rc = (rc==SQLITE_ERROR ? SQLITE_CORRUPT : rc); }else{ p->rc = SQLITE_NOMEM; } @@ -256268,6 +256488,24 @@ static void fts5FlushSecureDelete( const int f = FTS5INDEX_QUERY_SKIPHASH; Fts5Iter *pIter = 0; /* Used to find term instance */ + /* If the version number has not been set to SECUREDELETE, do so now. */ + if( p->pConfig->iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ + Fts5Config *pConfig = p->pConfig; + sqlite3_stmt *pStmt = 0; + fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf( + "REPLACE INTO %Q.'%q_config' VALUES ('version', %d)", + pConfig->zDb, pConfig->zName, FTS5_CURRENT_VERSION_SECUREDELETE + )); + if( p->rc==SQLITE_OK ){ + int rc; + sqlite3_step(pStmt); + rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK ) p->rc = rc; + pConfig->iCookie++; + pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; + } + } + fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); if( fts5MultiIterEof(p, pIter)==0 ){ i64 iThis = fts5MultiIterRowid(pIter); @@ -256998,6 +257236,383 @@ static void fts5MergePrefixLists( *p1 = out; } + +/* +** Iterate through a range of entries in the FTS index, invoking the xVisit +** callback for each of them. +** +** Parameter pToken points to an nToken buffer containing an FTS index term +** (i.e. a document term with the preceding 1 byte index identifier - +** FTS5_MAIN_PREFIX or similar). If bPrefix is true, then the call visits +** all entries for terms that have pToken/nToken as a prefix. If bPrefix +** is false, then only entries with pToken/nToken as the entire key are +** visited. +** +** If the current table is a tokendata=1 table, then if bPrefix is true then +** each index term is treated separately. However, if bPrefix is false, then +** all index terms corresponding to pToken/nToken are collapsed into a single +** term before the callback is invoked. +** +** The callback invoked for each entry visited is specified by paramter xVisit. +** Each time it is invoked, it is passed a pointer to the Fts5Index object, +** a copy of the 7th paramter to this function (pCtx) and a pointer to the +** iterator that indicates the current entry. If the current entry is the +** first with a new term (i.e. different from that of the previous entry, +** including the very first term), then the final two parameters are passed +** a pointer to the term and its size in bytes, respectively. If the current +** entry is not the first associated with its term, these two parameters +** are passed 0. +** +** If parameter pColset is not NULL, then it is used to filter entries before +** the callback is invoked. +*/ +static int fts5VisitEntries( + Fts5Index *p, /* Fts5 index object */ + Fts5Colset *pColset, /* Columns filter to apply, or NULL */ + u8 *pToken, /* Buffer containing token */ + int nToken, /* Size of buffer pToken in bytes */ + int bPrefix, /* True for a prefix scan */ + void (*xVisit)(Fts5Index*, void *pCtx, Fts5Iter *pIter, const u8*, int), + void *pCtx /* Passed as second argument to xVisit() */ +){ + const int flags = (bPrefix ? FTS5INDEX_QUERY_SCAN : 0) + | FTS5INDEX_QUERY_SKIPEMPTY + | FTS5INDEX_QUERY_NOOUTPUT; + Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ + int bNewTerm = 1; + Fts5Structure *pStruct = fts5StructureRead(p); + + fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for( /* no-op */ ; + fts5MultiIterEof(p, p1)==0; + fts5MultiIterNext2(p, p1, &bNewTerm) + ){ + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + int nNew = 0; + const u8 *pNew = 0; + + p1->xSetOutputs(p1, pSeg); + if( p->rc ) break; + + if( bNewTerm ){ + nNew = pSeg->term.n; + pNew = pSeg->term.p; + if( nNew<nToken || memcmp(pToken, pNew, nToken) ) break; + } + + xVisit(p, pCtx, p1, pNew, nNew); + } + fts5MultiIterFree(p1); + + fts5StructureRelease(pStruct); + return p->rc; +} + + +/* +** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an +** array of these for each row it visits (so all iRowid fields are the same). +** Or, for an iterator used by an "ORDER BY rank" query, it accumulates an +** array of these for the entire query (in which case iRowid fields may take +** a variety of values). +** +** Each instance in the array indicates the iterator (and therefore term) +** associated with position iPos of rowid iRowid. This is used by the +** xInstToken() API. +** +** iRowid: +** Rowid for the current entry. +** +** iPos: +** Position of current entry within row. In the usual ((iCol<<32)+iOff) +** format (e.g. see macros FTS5_POS2COLUMN() and FTS5_POS2OFFSET()). +** +** iIter: +** If the Fts5TokenDataIter iterator that the entry is part of is +** actually an iterator (i.e. with nIter>0, not just a container for +** Fts5TokenDataMap structures), then this variable is an index into +** the apIter[] array. The corresponding term is that which the iterator +** at apIter[iIter] currently points to. +** +** Or, if the Fts5TokenDataIter iterator is just a container object +** (nIter==0), then iIter is an index into the term.p[] buffer where +** the term is stored. +** +** nByte: +** In the case where iIter is an index into term.p[], this variable +** is the size of the term in bytes. If iIter is an index into apIter[], +** this variable is unused. +*/ +struct Fts5TokenDataMap { + i64 iRowid; /* Row this token is located in */ + i64 iPos; /* Position of token */ + int iIter; /* Iterator token was read from */ + int nByte; /* Length of token in bytes (or 0) */ +}; + +/* +** An object used to supplement Fts5Iter for tokendata=1 iterators. +** +** This object serves two purposes. The first is as a container for an array +** of Fts5TokenDataMap structures, which are used to find the token required +** when the xInstToken() API is used. This is done by the nMapAlloc, nMap and +** aMap[] variables. +*/ +struct Fts5TokenDataIter { + int nMapAlloc; /* Allocated size of aMap[] in entries */ + int nMap; /* Number of valid entries in aMap[] */ + Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */ + + /* The following are used for prefix-queries only. */ + Fts5Buffer terms; + + /* The following are used for other full-token tokendata queries only. */ + int nIter; + int nIterAlloc; + Fts5PoslistReader *aPoslistReader; + int *aPoslistToIter; + Fts5Iter *apIter[1]; +}; + +/* +** The two input arrays - a1[] and a2[] - are in sorted order. This function +** merges the two arrays together and writes the result to output array +** aOut[]. aOut[] is guaranteed to be large enough to hold the result. +** +** Duplicate entries are copied into the output. So the size of the output +** array is always (n1+n2) entries. +*/ +static void fts5TokendataMerge( + Fts5TokenDataMap *a1, int n1, /* Input array 1 */ + Fts5TokenDataMap *a2, int n2, /* Input array 2 */ + Fts5TokenDataMap *aOut /* Output array */ +){ + int i1 = 0; + int i2 = 0; + + assert( n1>=0 && n2>=0 ); + while( i1<n1 || i2<n2 ){ + Fts5TokenDataMap *pOut = &aOut[i1+i2]; + if( i2>=n2 || (i1<n1 && ( + a1[i1].iRowid<a2[i2].iRowid + || (a1[i1].iRowid==a2[i2].iRowid && a1[i1].iPos<=a2[i2].iPos) + ))){ + memcpy(pOut, &a1[i1], sizeof(Fts5TokenDataMap)); + i1++; + }else{ + memcpy(pOut, &a2[i2], sizeof(Fts5TokenDataMap)); + i2++; + } + } +} + + +/* +** Append a mapping to the token-map belonging to object pT. +*/ +static void fts5TokendataIterAppendMap( + Fts5Index *p, + Fts5TokenDataIter *pT, + int iIter, + int nByte, + i64 iRowid, + i64 iPos +){ + if( p->rc==SQLITE_OK ){ + if( pT->nMap==pT->nMapAlloc ){ + int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; + int nAlloc = nNew * sizeof(Fts5TokenDataMap); + Fts5TokenDataMap *aNew; + + aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc); + if( aNew==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pT->aMap[pT->nMap].iRowid = iRowid; + pT->aMap[pT->nMap].iPos = iPos; + pT->aMap[pT->nMap].iIter = iIter; + pT->aMap[pT->nMap].nByte = nByte; + pT->nMap++; + } +} + +/* +** Sort the contents of the pT->aMap[] array. +** +** The sorting algorithm requries a malloc(). If this fails, an error code +** is left in Fts5Index.rc before returning. +*/ +static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ + Fts5TokenDataMap *aTmp = 0; + int nByte = pT->nMap * sizeof(Fts5TokenDataMap); + + aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( aTmp ){ + Fts5TokenDataMap *a1 = pT->aMap; + Fts5TokenDataMap *a2 = aTmp; + i64 nHalf; + + for(nHalf=1; nHalf<pT->nMap; nHalf=nHalf*2){ + int i1; + for(i1=0; i1<pT->nMap; i1+=(nHalf*2)){ + int n1 = MIN(nHalf, pT->nMap-i1); + int n2 = MIN(nHalf, pT->nMap-i1-n1); + fts5TokendataMerge(&a1[i1], n1, &a1[i1+n1], n2, &a2[i1]); + } + SWAPVAL(Fts5TokenDataMap*, a1, a2); + } + + if( a1!=pT->aMap ){ + memcpy(pT->aMap, a1, pT->nMap*sizeof(Fts5TokenDataMap)); + } + sqlite3_free(aTmp); + +#ifdef SQLITE_DEBUG + { + int ii; + for(ii=1; ii<pT->nMap; ii++){ + Fts5TokenDataMap *p1 = &pT->aMap[ii-1]; + Fts5TokenDataMap *p2 = &pT->aMap[ii]; + assert( p1->iRowid<p2->iRowid + || (p1->iRowid==p2->iRowid && p1->iPos<=p2->iPos) + ); + } + } +#endif + } +} + +/* +** Delete an Fts5TokenDataIter structure and its contents. +*/ +static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ + if( pSet ){ + int ii; + for(ii=0; ii<pSet->nIter; ii++){ + fts5MultiIterFree(pSet->apIter[ii]); + } + fts5BufferFree(&pSet->terms); + sqlite3_free(pSet->aPoslistReader); + sqlite3_free(pSet->aMap); + sqlite3_free(pSet); + } +} + + +/* +** fts5VisitEntries() context object used by fts5SetupPrefixIterTokendata() +** to pass data to prefixIterSetupTokendataCb(). +*/ +typedef struct TokendataSetupCtx TokendataSetupCtx; +struct TokendataSetupCtx { + Fts5TokenDataIter *pT; /* Object being populated with mappings */ + int iTermOff; /* Offset of current term in terms.p[] */ + int nTermByte; /* Size of current term in bytes */ +}; + +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIterTokendata(). This +** callback adds an entry to the Fts5TokenDataIter.aMap[] array for each +** position in the current position-list. It doesn't matter that some of +** these may be out of order - they will be sorted later. +*/ +static void prefixIterSetupTokendataCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + TokendataSetupCtx *pSetup = (TokendataSetupCtx*)pCtx; + int iPosOff = 0; + i64 iPos = 0; + + if( pNew ){ + pSetup->nTermByte = nNew-1; + pSetup->iTermOff = pSetup->pT->terms.n; + fts5BufferAppendBlob(&p->rc, &pSetup->pT->terms, nNew-1, pNew+1); + } + + while( 0==sqlite3Fts5PoslistNext64( + p1->base.pData, p1->base.nData, &iPosOff, &iPos + ) ){ + fts5TokendataIterAppendMap(p, + pSetup->pT, pSetup->iTermOff, pSetup->nTermByte, p1->base.iRowid, iPos + ); + } +} + + +/* +** Context object passed by fts5SetupPrefixIter() to fts5VisitEntries(). +*/ +typedef struct PrefixSetupCtx PrefixSetupCtx; +struct PrefixSetupCtx { + void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); + void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); + i64 iLastRowid; + int nMerge; + Fts5Buffer *aBuf; + int nBuf; + Fts5Buffer doclist; + TokendataSetupCtx *pTokendata; +}; + +/* +** fts5VisitEntries() callback used by fts5SetupPrefixIter() +*/ +static void prefixIterSetupCb( + Fts5Index *p, + void *pCtx, + Fts5Iter *p1, + const u8 *pNew, + int nNew +){ + PrefixSetupCtx *pSetup = (PrefixSetupCtx*)pCtx; + const int nMerge = pSetup->nMerge; + + if( p1->base.nData>0 ){ + if( p1->base.iRowid<=pSetup->iLastRowid && pSetup->doclist.n>0 ){ + int i; + for(i=0; p->rc==SQLITE_OK && pSetup->doclist.n; i++){ + int i1 = i*nMerge; + int iStore; + assert( i1+nMerge<=pSetup->nBuf ); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + if( pSetup->aBuf[iStore].n==0 ){ + fts5BufferSwap(&pSetup->doclist, &pSetup->aBuf[iStore]); + fts5BufferZero(&pSetup->doclist); + break; + } + } + if( iStore==i1+nMerge ){ + pSetup->xMerge(p, &pSetup->doclist, nMerge, &pSetup->aBuf[i1]); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + fts5BufferZero(&pSetup->aBuf[iStore]); + } + } + } + pSetup->iLastRowid = 0; + } + + pSetup->xAppend( + p, (u64)p1->base.iRowid-(u64)pSetup->iLastRowid, p1, &pSetup->doclist + ); + pSetup->iLastRowid = p1->base.iRowid; + } + + if( pSetup->pTokendata ){ + prefixIterSetupTokendataCb(p, (void*)pSetup->pTokendata, p1, pNew, nNew); + } +} + static void fts5SetupPrefixIter( Fts5Index *p, /* Index to read from */ int bDesc, /* True for "ORDER BY rowid DESC" */ @@ -257008,38 +257623,41 @@ static void fts5SetupPrefixIter( Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; - Fts5Buffer *aBuf; - int nBuf = 32; - int nMerge = 1; + PrefixSetupCtx s; + TokendataSetupCtx s2; + + memset(&s, 0, sizeof(s)); + memset(&s2, 0, sizeof(s2)); + + s.nMerge = 1; + s.iLastRowid = 0; + s.nBuf = 32; + if( iIdx==0 + && p->pConfig->eDetail==FTS5_DETAIL_FULL + && p->pConfig->bPrefixInsttoken + ){ + s.pTokendata = &s2; + s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT)); + } - void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); - void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ - xMerge = fts5MergeRowidLists; - xAppend = fts5AppendRowid; + s.xMerge = fts5MergeRowidLists; + s.xAppend = fts5AppendRowid; }else{ - nMerge = FTS5_MERGE_NLIST-1; - nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ - xMerge = fts5MergePrefixLists; - xAppend = fts5AppendPoslist; + s.nMerge = FTS5_MERGE_NLIST-1; + s.nBuf = s.nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ + s.xMerge = fts5MergePrefixLists; + s.xAppend = fts5AppendPoslist; } - aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); + s.aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*s.nBuf); pStruct = fts5StructureRead(p); - assert( p->rc!=SQLITE_OK || (aBuf && pStruct) ); + assert( p->rc!=SQLITE_OK || (s.aBuf && pStruct) ); if( p->rc==SQLITE_OK ){ - const int flags = FTS5INDEX_QUERY_SCAN - | FTS5INDEX_QUERY_SKIPEMPTY - | FTS5INDEX_QUERY_NOOUTPUT; + void *pCtx = (void*)&s; int i; - i64 iLastRowid = 0; - Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; - Fts5Buffer doclist; - int bNewTerm = 1; - - memset(&doclist, 0, sizeof(doclist)); /* If iIdx is non-zero, then it is the number of a prefix-index for ** prefixes 1 character longer than the prefix being queried for. That @@ -257047,94 +257665,45 @@ static void fts5SetupPrefixIter( ** corresponding to the prefix itself. That one is extracted from the ** main term index here. */ if( iIdx!=0 ){ - int dummy = 0; - const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; pToken[0] = FTS5_MAIN_PREFIX; - fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); - for(; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &dummy) - ){ - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - p1->xSetOutputs(p1, pSeg); - if( p1->base.nData ){ - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); - iLastRowid = p1->base.iRowid; - } - } - fts5MultiIterFree(p1); + fts5VisitEntries(p, pColset, pToken, nToken, 0, prefixIterSetupCb, pCtx); } pToken[0] = FTS5_MAIN_PREFIX + iIdx; - fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); - fts5IterSetOutputCb(&p->rc, p1); + fts5VisitEntries(p, pColset, pToken, nToken, 1, prefixIterSetupCb, pCtx); - for( /* no-op */ ; - fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext2(p, p1, &bNewTerm) - ){ - Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; - int nTerm = pSeg->term.n; - const u8 *pTerm = pSeg->term.p; - p1->xSetOutputs(p1, pSeg); - - assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 ); - if( bNewTerm ){ - if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break; - } - - if( p1->base.nData==0 ) continue; - if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ - for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - int i1 = i*nMerge; - int iStore; - assert( i1+nMerge<=nBuf ); - for(iStore=i1; iStore<i1+nMerge; iStore++){ - if( aBuf[iStore].n==0 ){ - fts5BufferSwap(&doclist, &aBuf[iStore]); - fts5BufferZero(&doclist); - break; - } - } - if( iStore==i1+nMerge ){ - xMerge(p, &doclist, nMerge, &aBuf[i1]); - for(iStore=i1; iStore<i1+nMerge; iStore++){ - fts5BufferZero(&aBuf[iStore]); - } - } - } - iLastRowid = 0; - } - - xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); - iLastRowid = p1->base.iRowid; - } - - assert( (nBuf%nMerge)==0 ); - for(i=0; i<nBuf; i+=nMerge){ + assert( (s.nBuf%s.nMerge)==0 ); + for(i=0; i<s.nBuf; i+=s.nMerge){ int iFree; if( p->rc==SQLITE_OK ){ - xMerge(p, &doclist, nMerge, &aBuf[i]); + s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]); } - for(iFree=i; iFree<i+nMerge; iFree++){ - fts5BufferFree(&aBuf[iFree]); + for(iFree=i; iFree<i+s.nMerge; iFree++){ + fts5BufferFree(&s.aBuf[iFree]); } } - fts5MultiIterFree(p1); - pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING); + pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING); + assert( pData!=0 || p->rc!=SQLITE_OK ); if( pData ){ pData->p = (u8*)&pData[1]; - pData->nn = pData->szLeaf = doclist.n; - if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n); + pData->nn = pData->szLeaf = s.doclist.n; + if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n); fts5MultiIterNew2(p, pData, bDesc, ppIter); } - fts5BufferFree(&doclist); + + assert( (*ppIter)!=0 || p->rc!=SQLITE_OK ); + if( p->rc==SQLITE_OK && s.pTokendata ){ + fts5TokendataIterSortMap(p, s2.pT); + (*ppIter)->pTokenDataIter = s2.pT; + s2.pT = 0; + } } + fts5TokendataIterDelete(s2.pT); + fts5BufferFree(&s.doclist); fts5StructureRelease(pStruct); - sqlite3_free(aBuf); + sqlite3_free(s.aBuf); } @@ -257388,38 +257957,6 @@ static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ pSeg->pLeaf = 0; } -/* -** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an -** array of these for each row it visits. Or, for an iterator used by an -** "ORDER BY rank" query, it accumulates an array of these for the entire -** query. -** -** Each instance in the array indicates the iterator (and therefore term) -** associated with position iPos of rowid iRowid. This is used by the -** xInstToken() API. -*/ -struct Fts5TokenDataMap { - i64 iRowid; /* Row this token is located in */ - i64 iPos; /* Position of token */ - int iIter; /* Iterator token was read from */ -}; - -/* -** An object used to supplement Fts5Iter for tokendata=1 iterators. -*/ -struct Fts5TokenDataIter { - int nIter; - int nIterAlloc; - - int nMap; - int nMapAlloc; - Fts5TokenDataMap *aMap; - - Fts5PoslistReader *aPoslistReader; - int *aPoslistToIter; - Fts5Iter *apIter[1]; -}; - /* ** This function appends iterator pAppend to Fts5TokenDataIter pIn and ** returns the result. @@ -257456,54 +257993,6 @@ static Fts5TokenDataIter *fts5AppendTokendataIter( return pRet; } -/* -** Delete an Fts5TokenDataIter structure and its contents. -*/ -static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ - if( pSet ){ - int ii; - for(ii=0; ii<pSet->nIter; ii++){ - fts5MultiIterFree(pSet->apIter[ii]); - } - sqlite3_free(pSet->aPoslistReader); - sqlite3_free(pSet->aMap); - sqlite3_free(pSet); - } -} - -/* -** Append a mapping to the token-map belonging to object pT. -*/ -static void fts5TokendataIterAppendMap( - Fts5Index *p, - Fts5TokenDataIter *pT, - int iIter, - i64 iRowid, - i64 iPos -){ - if( p->rc==SQLITE_OK ){ - if( pT->nMap==pT->nMapAlloc ){ - int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; - int nByte = nNew * sizeof(Fts5TokenDataMap); - Fts5TokenDataMap *aNew; - - aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte); - if( aNew==0 ){ - p->rc = SQLITE_NOMEM; - return; - } - - pT->aMap = aNew; - pT->nMapAlloc = nNew; - } - - pT->aMap[pT->nMap].iRowid = iRowid; - pT->aMap[pT->nMap].iPos = iPos; - pT->aMap[pT->nMap].iIter = iIter; - pT->nMap++; - } -} - /* ** The iterator passed as the only argument must be a tokendata=1 iterator ** (pIter->pTokenDataIter!=0). This function sets the iterator output @@ -257544,7 +258033,7 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ pIter->base.iRowid = iRowid; if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){ - fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1); + fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, 0, iRowid, -1); }else if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){ int nReader = 0; @@ -257797,6 +258286,7 @@ static Fts5Iter *fts5SetupTokendataIter( pRet = fts5MultiIterAlloc(p, 0); } if( pRet ){ + pRet->nSeg = 0; pRet->pTokenDataIter = pSet; if( pSet ){ fts5IterSetOutputsTokendata(pRet); @@ -257812,7 +258302,6 @@ static Fts5Iter *fts5SetupTokendataIter( return pRet; } - /* ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. @@ -257835,8 +258324,14 @@ static int sqlite3Fts5IndexQuery( int iIdx = 0; /* Index to search */ int iPrefixIdx = 0; /* +1 prefix index */ int bTokendata = pConfig->bTokendata; + assert( buf.p!=0 ); if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); + /* The NOTOKENDATA flag is set when each token in a tokendata=1 table + ** should be treated individually, instead of merging all those with + ** a common prefix into a single entry. This is used, for example, by + ** queries performed as part of an integrity-check, or by the fts5vocab + ** module. */ if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){ bTokendata = 0; } @@ -257867,7 +258362,7 @@ static int sqlite3Fts5IndexQuery( } if( bTokendata && iIdx==0 ){ - buf.p[0] = '0'; + buf.p[0] = FTS5_MAIN_PREFIX; pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset); }else if( iIdx<=pConfig->nPrefix ){ /* Straight index lookup */ @@ -257880,7 +258375,7 @@ static int sqlite3Fts5IndexQuery( fts5StructureRelease(pStruct); } }else{ - /* Scan multiple terms in the main index */ + /* Scan multiple terms in the main index for a prefix query. */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); if( pRet==0 ){ @@ -257916,7 +258411,8 @@ static int sqlite3Fts5IndexQuery( static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); - if( pIter->pTokenDataIter ){ + if( pIter->nSeg==0 ){ + assert( pIter->pTokenDataIter ); fts5TokendataIterNext(pIter, 0, 0); }else{ fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); @@ -257953,7 +258449,8 @@ static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ */ static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - if( pIter->pTokenDataIter ){ + if( pIter->nSeg==0 ){ + assert( pIter->pTokenDataIter ); fts5TokendataIterNext(pIter, 1, iMatch); }else{ fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); @@ -257972,14 +258469,61 @@ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return (z ? &z[1] : 0); } +/* +** pIter is a prefix query. This function populates pIter->pTokenDataIter +** with an Fts5TokenDataIter object containing mappings for all rows +** matched by the query. +*/ +static int fts5SetupPrefixIterTokendata( + Fts5Iter *pIter, + const char *pToken, /* Token prefix to search for */ + int nToken /* Size of pToken in bytes */ +){ + Fts5Index *p = pIter->pIndex; + Fts5Buffer token = {0, 0, 0}; + TokendataSetupCtx ctx; + + memset(&ctx, 0, sizeof(ctx)); + + fts5BufferGrow(&p->rc, &token, nToken+1); + assert( token.p!=0 || p->rc!=SQLITE_OK ); + ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT)); + + if( p->rc==SQLITE_OK ){ + + /* Fill in the token prefix to search for */ + token.p[0] = FTS5_MAIN_PREFIX; + memcpy(&token.p[1], pToken, nToken); + token.n = nToken+1; + + fts5VisitEntries( + p, 0, token.p, token.n, 1, prefixIterSetupTokendataCb, (void*)&ctx + ); + + fts5TokendataIterSortMap(p, ctx.pT); + } + + if( p->rc==SQLITE_OK ){ + pIter->pTokenDataIter = ctx.pT; + }else{ + fts5TokendataIterDelete(ctx.pT); + } + fts5BufferFree(&token); + + return fts5IndexReturn(p); +} + /* ** This is used by xInstToken() to access the token at offset iOff, column ** iCol of row iRowid. The token is returned via output variables *ppOut ** and *pnOut. The iterator passed as the first argument must be a tokendata=1 ** iterator (pIter->pTokenDataIter!=0). +** +** pToken/nToken: */ static int sqlite3Fts5IterToken( Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, i64 iRowid, int iCol, int iOff, @@ -257987,13 +258531,22 @@ static int sqlite3Fts5IterToken( ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5TokenDataIter *pT = pIter->pTokenDataIter; - Fts5TokenDataMap *aMap = pT->aMap; i64 iPos = (((i64)iCol)<<32) + iOff; - + Fts5TokenDataMap *aMap = 0; int i1 = 0; - int i2 = pT->nMap; + int i2 = 0; int iTest = 0; + assert( pT || (pToken && pIter->nSeg>0) ); + if( pT==0 ){ + int rc = fts5SetupPrefixIterTokendata(pIter, pToken, nToken); + if( rc!=SQLITE_OK ) return rc; + pT = pIter->pTokenDataIter; + } + + i2 = pT->nMap; + aMap = pT->aMap; + while( i2>i1 ){ iTest = (i1 + i2) / 2; @@ -258016,9 +258569,15 @@ static int sqlite3Fts5IterToken( } if( i2>i1 ){ - Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; - *ppOut = (const char*)pMap->aSeg[0].term.p+1; - *pnOut = pMap->aSeg[0].term.n-1; + if( pIter->nSeg==0 ){ + Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; + *ppOut = (const char*)pMap->aSeg[0].term.p+1; + *pnOut = pMap->aSeg[0].term.n-1; + }else{ + Fts5TokenDataMap *p = &aMap[iTest]; + *ppOut = (const char*)&pT->terms.p[p->iIter]; + *pnOut = aMap[iTest].nByte; + } } return SQLITE_OK; @@ -258030,7 +258589,9 @@ static int sqlite3Fts5IterToken( */ static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - if( pIter && pIter->pTokenDataIter ){ + if( pIter && pIter->pTokenDataIter + && (pIter->nSeg==0 || pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_FULL) + ){ pIter->pTokenDataIter->nMap = 0; } } @@ -258050,17 +258611,29 @@ static int sqlite3Fts5IndexIterWriteTokendata( Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5TokenDataIter *pT = pIter->pTokenDataIter; Fts5Index *p = pIter->pIndex; - int ii; + i64 iPos = (((i64)iCol)<<32) + iOff; assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); - assert( pIter->pTokenDataIter ); - - for(ii=0; ii<pT->nIter; ii++){ - Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; - if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; - } - if( ii<pT->nIter ){ - fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff); + assert( pIter->pTokenDataIter || pIter->nSeg>0 ); + if( pIter->nSeg>0 ){ + /* This is a prefix term iterator. */ + if( pT==0 ){ + pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); + pIter->pTokenDataIter = pT; + } + if( pT ){ + fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos); + fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken); + } + }else{ + int ii; + for(ii=0; ii<pT->nIter; ii++){ + Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; + if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; + } + if( ii<pT->nIter ){ + fts5TokendataIterAppendMap(p, pT, ii, 0, iRowid, iPos); + } } return fts5IndexReturn(p); } @@ -259965,6 +260538,7 @@ struct Fts5Global { #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr )) #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr)) +#define FTS5_INSTTOKEN_SUBTYPE 73 /* ** Each auxiliary function registered with the FTS5 module is represented @@ -260504,6 +261078,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an ** unusable plan. Return SQLITE_CONSTRAINT. */ + idxStr[iIdxStr] = 0; return SQLITE_CONSTRAINT; }else{ if( iCol==nCol+1 ){ @@ -261289,6 +261864,7 @@ static int fts5FilterMethod( sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; + int bPrefixInsttoken = pConfig->bPrefixInsttoken; int i; int iIdxStr = 0; Fts5Expr *pExpr = 0; @@ -261324,6 +261900,9 @@ static int fts5FilterMethod( rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset); if( rc!=SQLITE_OK ) goto filter_out; if( zText==0 ) zText = ""; + if( sqlite3_value_subtype(apVal[i])==FTS5_INSTTOKEN_SUBTYPE ){ + pConfig->bPrefixInsttoken = 1; + } iCol = 0; do{ @@ -261464,6 +262043,7 @@ static int fts5FilterMethod( filter_out: sqlite3Fts5ExprFree(pExpr); pConfig->pzErrmsg = pzErrmsg; + pConfig->bPrefixInsttoken = bPrefixInsttoken; return rc; } @@ -261766,7 +262346,6 @@ static int fts5UpdateMethod( Fts5Config *pConfig = pTab->p.pConfig; int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ - int bUpdateOrDelete = 0; /* A transaction must be open when this is called. */ assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); @@ -261778,7 +262357,7 @@ static int fts5UpdateMethod( ); assert( pTab->p.pConfig->pzErrmsg==0 ); if( pConfig->pgsz==0 ){ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie); if( rc!=SQLITE_OK ) return rc; } @@ -261803,7 +262382,6 @@ static int fts5UpdateMethod( rc = SQLITE_ERROR; }else{ rc = fts5SpecialDelete(pTab, apVal); - bUpdateOrDelete = 1; } }else{ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); @@ -261840,7 +262418,6 @@ static int fts5UpdateMethod( }else{ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0); - bUpdateOrDelete = 1; } } @@ -261868,7 +262445,6 @@ static int fts5UpdateMethod( if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); - bUpdateOrDelete = 1; } fts5StorageInsert(&rc, pTab, apVal, pRowid); } @@ -261922,23 +262498,8 @@ static int fts5UpdateMethod( rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); fts5StorageInsert(&rc, pTab, apVal, pRowid); } - bUpdateOrDelete = 1; sqlite3Fts5StorageReleaseDeleteRow(pStorage); } - - } - } - - if( rc==SQLITE_OK - && bUpdateOrDelete - && pConfig->bSecureDelete - && pConfig->iVersion==FTS5_CURRENT_VERSION - ){ - rc = sqlite3Fts5StorageConfigValue( - pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE - ); - if( rc==SQLITE_OK ){ - pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; } } @@ -261991,6 +262552,7 @@ static int fts5RollbackMethod(sqlite3_vtab *pVtab){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0); rc = sqlite3Fts5StorageRollback(pTab->pStorage); + pTab->p.pConfig->pgsz = 0; return rc; } @@ -263459,7 +264021,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e84010", -1, SQLITE_TRANSIENT); } /* @@ -263523,6 +264085,20 @@ static void fts5LocaleFunc( } } +/* +** Implementation of fts5_insttoken() function. +*/ +static void fts5InsttokenFunc( + sqlite3_context *pCtx, /* Function call context */ + int nArg, /* Number of args */ + sqlite3_value **apArg /* Function arguments */ +){ + assert( nArg==1 ); + (void)nArg; + sqlite3_result_value(pCtx, apArg[0]); + sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE); +} + /* ** Return true if zName is the extension on one of the shadow tables used ** by this module. @@ -263652,10 +264228,17 @@ static int fts5Init(sqlite3 *db){ if( rc==SQLITE_OK ){ rc = sqlite3_create_function( db, "fts5_locale", 2, - SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE|SQLITE_SUBTYPE, p, fts5LocaleFunc, 0, 0 ); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function( + db, "fts5_insttoken", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + p, fts5InsttokenFunc, 0, 0 + ); + } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file @@ -263919,6 +264502,11 @@ static int fts5StorageGetStmt( if( rc!=SQLITE_OK && pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); } + if( rc==SQLITE_ERROR && eStmt>FTS5_STMT_LOOKUP2 && eStmt<FTS5_STMT_SCAN ){ + /* One of the internal tables - not the %_content table - is missing. + ** This counts as a corrupted table. */ + rc = SQLITE_CORRUPT; + } } } @@ -266580,8 +267168,8 @@ static int fts5TriTokenize( char *zOut = aBuf; int ii; const unsigned char *zIn = (const unsigned char*)pText; - const unsigned char *zEof = &zIn[nText]; - u32 iCode; + const unsigned char *zEof = (zIn ? &zIn[nText] : 0); + u32 iCode = 0; int aStart[3]; /* Input offset of each character in aBuf[] */ UNUSED_PARAM(unusedFlags); @@ -266590,8 +267178,8 @@ static int fts5TriTokenize( for(ii=0; ii<3; ii++){ do { aStart[ii] = zIn - (const unsigned char*)pText; + if( zIn>=zEof ) return SQLITE_OK; READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) return SQLITE_OK; if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); }while( iCode==0 ); WRITE_UTF8(zOut, iCode); @@ -266612,8 +267200,11 @@ static int fts5TriTokenize( /* Read characters from the input up until the first non-diacritic */ do { iNext = zIn - (const unsigned char*)pText; + if( zIn>=zEof ){ + iCode = 0; + break; + } READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); }while( iCode==0 ); @@ -268650,7 +269241,7 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ } - +/* Here ends the fts5.c composite file. */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */ /************** End of fts5.c ************************************************/ @@ -269223,4 +269814,5 @@ void libsql_wasm_free_msg_buf(char *err_msg_buf) { /************** End of wasmedge_bindings.c ***********************************/ /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } +#endif /* SQLITE_AMALGAMATION */ /************************** End of sqlite3.c ******************************/ diff --git a/libsql-ffi/bundled/src/sqlite3.h b/libsql-ffi/bundled/src/sqlite3.h index 77de0af6c3..d7711ed77f 100644 --- a/libsql-ffi/bundled/src/sqlite3.h +++ b/libsql-ffi/bundled/src/sqlite3.h @@ -149,9 +149,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.47.0" -#define SQLITE_VERSION_NUMBER 3047000 -#define SQLITE_SOURCE_ID "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82alt1" +#define SQLITE_VERSION "3.48.0" +#define SQLITE_VERSION_NUMBER 3048000 +#define SQLITE_SOURCE_ID "2025-01-14 11:05:00 d2fe6b05f38d9d7cd78c5d252e99ac59f1aea071d669830c1ffe4e8966e8alt1" #define LIBSQL_VERSION "0.2.3" @@ -659,6 +659,13 @@ SQLITE_API int sqlite3_exec( ** filesystem supports doing multiple write operations atomically when those ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. +** +** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read +** from the database file in amounts that are not a multiple of the +** page size and that do not begin at a page boundary. Without this +** property, SQLite is careful to only do full-page reads and write +** on aligned pages, with the one exception that it will do a sub-page +** read of the first page to access the database header. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -675,6 +682,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 #define SQLITE_IOCAP_IMMUTABLE 0x00002000 #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 +#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 /* ** CAPI3REF: File Locking Levels @@ -821,6 +829,7 @@ struct sqlite3_file { ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] ** <li> [SQLITE_IOCAP_IMMUTABLE] ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] +** <li> [SQLITE_IOCAP_SUBPAGE_READ] ** </ul> ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of @@ -1105,6 +1114,11 @@ struct sqlite3_io_methods { ** pointed to by the pArg argument. This capability is used during testing ** and only needs to be supported when SQLITE_TEST is defined. ** +** <li>[[SQLITE_FCNTL_NULL_IO]] +** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor +** or file handle for the [sqlite3_file] object such that it will no longer +** read or write to the database file. +** ** <li>[[SQLITE_FCNTL_WAL_BLOCK]] ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might ** be advantageous to block on the next WAL lock if the lock is not immediately @@ -1258,6 +1272,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 +#define SQLITE_FCNTL_NULL_IO 43 // libSQL extension #define SQLITE_FCNTL_WAL_METHODS_POINTER 129 @@ -2649,10 +2664,14 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** The two functions are identical except for the type of the return value -** and that if the number of rows modified by the most recent INSERT, UPDATE +** and that if the number of rows modified by the most recent INSERT, UPDATE, ** or DELETE is greater than the maximum value supported by type "int", then ** the return value of sqlite3_changes() is undefined. ^Executing any other ** type of SQL statement does not modify the value returned by these functions. +** For the purposes of this interface, a CREATE TABLE AS SELECT statement +** does not count as an INSERT, UPDATE or DELETE statement and hence the rows +** added to the new table by the CREATE TABLE AS SELECT statement are not +** counted. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], @@ -4246,11 +4265,22 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler ** to return an error (error code SQLITE_ERROR) if the statement uses ** any virtual tables. +** +** [[SQLITE_PREPARE_DONT_LOG]] <dt>SQLITE_PREPARE_DONT_LOG</dt> +** <dd>The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler +** errors from being sent to the error log defined by +** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test +** compiles to see if some SQL syntax is well-formed, without generating +** messages on the global error log when it is not. If the test compile +** fails, the sqlite3_prepare_v3() call returns the same error indications +** with or without this flag; it just omits the call to [sqlite3_log()] that +** logs the error. ** </dl> */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 #define SQLITE_PREPARE_NO_VTAB 0x04 +#define SQLITE_PREPARE_DONT_LOG 0x10 /* ** CAPI3REF: Compiling An SQL Statement @@ -11055,7 +11085,7 @@ SQLITE_API int sqlite3_deserialize( #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif -#endif /* SQLITE3_H */ +/* #endif for SQLITE3_H will be added by mksqlite3.tcl */ /******** Begin file sqlite3rtree.h *********/ /* @@ -13306,14 +13336,29 @@ struct Fts5PhraseIter { ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, ** output variable (*ppToken) is set to point to a buffer containing the ** matching document token, and (*pnToken) to the size of that buffer in -** bytes. This API is not available if the specified token matches a -** prefix query term. In that case both output variables are always set -** to 0. +** bytes. ** ** The output text is not a copy of the document text that was tokenized. ** It is the output of the tokenizer module. For tokendata=1 tables, this ** includes any embedded 0x00 and trailing data. ** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. ** @@ -14102,3 +14147,4 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *); #endif //LIBSQL_ENABLE_WASM_RUNTIME /******** End of wasm_bindings.h *********/ +#endif /* SQLITE3_H */ From c7e917b30c55f65209490c4a278e3bfcca5874c1 Mon Sep 17 00:00:00 2001 From: Pekka Enberg <penberg@iki.fi> Date: Thu, 28 May 2026 13:16:30 +0300 Subject: [PATCH 521/522] libsql-sqlite3: Restore libsql-specific build targets in autosetup Adopting upstream 3.48.0's autosetup wholesale (commit bcd6013d8a) lost the libsql-specific targets the old autotools Makefile.in provided. CI PR #2243 surfaced two: * Makefile CI (./configure --enable-wasm-runtime-dynamic) failed with "Unknown option --wasm-runtime-dynamic". The flag was never wired into the new auto.def. * Extensions Tests (`make libsql`) and the Wasm CI step (`make liblibsql_install`, `make rusttestwasm`) failed with "No rule to make target 'libsql'". All of those targets were Makefile.in-only and were not present in upstream's main.mk. Restore them so the CI workflows in .github/workflows/sqlite3.yml and .github/workflows/extensions-test.yml work again. == auto.def == Adds two flags: --enable-wasm-runtime -> defines OPT_WASM_RUNTIME = y --enable-wasm-runtime-dynamic -> defines OPT_WASM_RUNTIME = d otherwise OPT_WASM_RUNTIME defaults to n. Mirrors the y/d/n switch the old Makefile.in used. == Makefile.in == Reads @OPT_WASM_RUNTIME@ into the make variable OPT_WASM_RUNTIME and includes the new libsql.mk after main.mk. == libsql.mk (new) == libsql-specific targets, kept in a separate file so the upstream Makefile.in / main.mk diff stays minimal: * libsql$(T.exe): byte-identical copy of sqlite3$(T.exe). * liblibsql.LIB / liblibsql.SO: copies of libsqlite3.LIB / libsqlite3.SO (the old build literally relinked LIBOBJ twice under two names; the copy here avoids paying for the second link). * libsql.pc: generated from libsql.pc.in via sed (autotools used config.status for this; we do it inline). * liblibsql_wasm: `cargo build --release --lib` in crates/wasmtime-bindings/. The cargo target dir is discovered via `cargo metadata` rather than hard-coded (the old Makefile.in's $(WBTOP)/../target/release/ assumption breaks if cargo workspaces resolve to a different target directory, e.g. when CARGO_TARGET_DIR is set). * liblibsql_wasm_install, liblibsql_install, lib_install: install rules, gated on $(ENABLE_STATIC) / $(ENABLE_SHARED) to match main.mk's install-so / install-lib pattern. * libsqlapi, testlibsql, rusttest, rusttestwasm: pass-through to cargo against crates/ and test/rust_suite/. OPT_WASM_RUNTIME y vs d vs n drives OPT_WASM_RUNTIME_LIBRARY_TARGET / OPT_STATIC_LIBLIBSQL_WASM exactly as the old Makefile.in did, so liblibsql_install in --enable-wasm-runtime-dynamic mode pulls in liblibsql_wasm_install. Verified locally with --enable-wasm-runtime-dynamic: make libsql -> OK make liblibsql_install DESTDIR=/tmp/x -> installs liblibsql.{a,so} and liblibsql_wasm.{a,so*} make test -> 0 errors out of 331057 tests make rusttestwasm -> 24 passed; 0 failed cd ext/crr && make loadable && make test -> all suites Success --- libsql-sqlite3/Makefile.in | 5 ++ libsql-sqlite3/auto.def | 14 ++++ libsql-sqlite3/libsql.mk | 145 +++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 libsql-sqlite3/libsql.mk diff --git a/libsql-sqlite3/Makefile.in b/libsql-sqlite3/Makefile.in index 5b17c0e426..f5f1826e88 100644 --- a/libsql-sqlite3/Makefile.in +++ b/libsql-sqlite3/Makefile.in @@ -335,4 +335,9 @@ distclean: distclean-autosetup version-info$(T.exe): $(TOP)/tool/version-info.c Makefile sqlite3.h $(T.link) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c +# libsql Wasm UDF runtime mode (y = static, d = dynamic, n = off). +# Set by configure from --enable-wasm-runtime / --enable-wasm-runtime-dynamic. +OPT_WASM_RUNTIME = @OPT_WASM_RUNTIME@ + include $(TOP)/main.mk +include $(TOP)/libsql.mk diff --git a/libsql-sqlite3/auto.def b/libsql-sqlite3/auto.def index c9aa0cb9d1..11ab38576e 100644 --- a/libsql-sqlite3/auto.def +++ b/libsql-sqlite3/auto.def @@ -184,6 +184,8 @@ set flags { with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build} with-emsdk:=auto => {Top-most dir of the Emscripten SDK installation. Default = EMSDK env var.} + wasm-runtime => {Enable the libsql WebAssembly UDF runtime, statically linked (sets OPT_WASM_RUNTIME=y)} + wasm-runtime-dynamic => {Enable the libsql WebAssembly UDF runtime, dynamically linked (sets OPT_WASM_RUNTIME=d)} # </alternative-builds> # <developer> # Note that using the --debug/--enable-debug flag here requires patching @@ -516,6 +518,18 @@ proj-define-for-opt test-status TSTRNNR_OPTS \ proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \ "Use #line macros in the amalgamation:" +# libsql Wasm UDF runtime: --enable-wasm-runtime / --enable-wasm-runtime-dynamic +# map to the legacy OPT_WASM_RUNTIME = y / d switch read by main.mk. +if {[proj-opt-truthy wasm-runtime-dynamic]} { + define OPT_WASM_RUNTIME d + msg-result "libsql Wasm UDF runtime: dynamic" +} elseif {[proj-opt-truthy wasm-runtime]} { + define OPT_WASM_RUNTIME y + msg-result "libsql Wasm UDF runtime: static" +} else { + define OPT_WASM_RUNTIME n +} + msg-checking "SQLITE_DEBUG build? " proj-if-opt-truthy debug { define SQLITE_DEBUG 1 diff --git a/libsql-sqlite3/libsql.mk b/libsql-sqlite3/libsql.mk new file mode 100644 index 0000000000..76df4726a7 --- /dev/null +++ b/libsql-sqlite3/libsql.mk @@ -0,0 +1,145 @@ +#!/usr/bin/make +# +# libsql-specific build targets that live alongside upstream's main.mk. +# Loaded from Makefile.in after main.mk so all of main.mk's variables +# (libsqlite3.LIB, libsqlite3.SO, install-dir.lib, T.exe, etc.) are +# defined. +# +# Provides: +# - libsql$(T.exe) alias for the sqlite3 shell binary +# - liblibsql.LIB / liblibsql.SO aliases for libsqlite3 +# - libsql.pc pkg-config file +# - liblibsql_wasm cargo-built libsql wasm UDF runtime +# - liblibsql_install install liblibsql.{a,so} to libdir +# - liblibsql_wasm_install install liblibsql_wasm.{a,so} to libdir +# - lib_install libsqlite3 install + liblibsql_install +# - libsqlapi / testlibsql cargo invocations against the libsql crates +# - rusttest / rusttestwasm cargo invocations against test/rust_suite + +# Path to the libsql Rust workspace and the wasm-bindings crate. +APITOP = $(TOP)/crates +WBTOP = $(TOP)/crates/wasmtime-bindings +WBSRC = $(WBTOP)/src/lib.rs + +# Wire OPT_WASM_RUNTIME (y/d/n from configure) into the legacy target +# selectors used below. +ifeq ($(OPT_WASM_RUNTIME),y) +OPT_WASM_RUNTIME_LIBRARY_TARGET = liblibsql_wasm +OPT_WASM_RUNTIME_INSTALL_TARGET = liblibsql_wasm_install +OPT_STATIC_LIBLIBSQL_WASM = $(TOP)/.libs/liblibsql_wasm.a +else ifeq ($(OPT_WASM_RUNTIME),d) +OPT_WASM_RUNTIME_LIBRARY_TARGET = liblibsql_wasm +OPT_WASM_RUNTIME_INSTALL_TARGET = liblibsql_wasm_install +OPT_STATIC_LIBLIBSQL_WASM = +TLIBS += -L$(WBTOP)/../target/release -llibsql_wasm +else +OPT_WASM_RUNTIME_LIBRARY_TARGET = +OPT_WASM_RUNTIME_INSTALL_TARGET = +OPT_STATIC_LIBLIBSQL_WASM = +endif + +# +# libsql shell binary: cheaply alias the upstream sqlite3 binary. +# +libsql$(T.exe): sqlite3$(T.exe) + cp $< $@ +all: libsql$(T.exe) + +# +# liblibsql.a / liblibsql.so are byte-identical copies of libsqlite3. +# We copy rather than symlink so that DESTDIR-based installs (used by CI) +# do not depend on the link target resolving inside the staging tree. +# +liblibsql.LIB = liblibsql$(T.lib) +liblibsql.SO = liblibsql$(T.dll) + +$(liblibsql.LIB): $(libsqlite3.LIB) + cp $< $@ +$(liblibsql.LIB)-1: $(liblibsql.LIB) +$(liblibsql.LIB)-0 $(liblibsql.LIB)-: + +$(liblibsql.SO): $(libsqlite3.SO) + cp $< $@ +$(liblibsql.SO)-1: $(liblibsql.SO) +$(liblibsql.SO)-0 $(liblibsql.SO)-: + +liblibsql.la: $(liblibsql.LIB)-$(ENABLE_STATIC) $(liblibsql.SO)-$(ENABLE_SHARED) +all: liblibsql.la + +# +# libsql.pc - generated from libsql.pc.in, same idea as sqlite3.pc. +# +libsql.pc: $(TOP)/libsql.pc.in Makefile + sed -e 's,@prefix@,$(prefix),g' \ + -e 's,@exec_prefix@,$(exec_prefix),g' \ + -e 's,@libdir@,$(libdir),g' \ + -e 's,@includedir@,$(includedir),g' \ + -e 's,@PACKAGE_VERSION@,$(PACKAGE_VERSION),g' \ + $(TOP)/libsql.pc.in > $@ + +# +# libsql wasm UDF runtime: built by cargo in crates/wasmtime-bindings. +# cargo's target directory depends on whether CARGO_TARGET_DIR is set in +# the environment and on which Cargo.toml above us declares the +# workspace, so query it from cargo rather than hard-coding a path. +# +liblibsql_wasm: $(WBSRC) + cd $(WBTOP) && cargo build --release --lib + mkdir -p $(TOP)/.libs + cargo_target_dir=$$(cd $(WBTOP) && cargo metadata --no-deps --format-version 1 \ + | sed -n 's/.*"target_directory":"\([^"]*\)".*/\1/p'); \ + cp $$cargo_target_dir/release/liblibsql_wasm.* $(TOP)/.libs/ + +# +# Installation. +# +liblibsql_wasm_install: liblibsql_wasm + $(INSTALL) -d $(DESTDIR)$(libdir) + $(INSTALL) -m 0644 $(TOP)/.libs/liblibsql_wasm.so $(DESTDIR)$(libdir)/liblibsql_wasm.so.0.0 + $(INSTALL) -m 0644 $(TOP)/.libs/liblibsql_wasm.a $(DESTDIR)$(libdir)/liblibsql_wasm.a + ln -fs $(DESTDIR)$(libdir)/liblibsql_wasm.so.0.0 $(DESTDIR)$(libdir)/liblibsql_wasm.so.0 + ln -fs $(DESTDIR)$(libdir)/liblibsql_wasm.so.0.0 $(DESTDIR)$(libdir)/liblibsql_wasm.so + +liblibsql_install-1: $(install-dir.lib) $(liblibsql.LIB) + $(INSTALL.noexec) $(liblibsql.LIB) $(DESTDIR)$(libdir) +liblibsql_install-0 liblibsql_install-: + +liblibsql_install-so-1: $(install-dir.lib) $(liblibsql.SO) + $(INSTALL) $(liblibsql.SO) $(DESTDIR)$(libdir) +liblibsql_install-so-0 liblibsql_install-so-: + +liblibsql_install: \ + liblibsql_install-$(ENABLE_STATIC) \ + liblibsql_install-so-$(ENABLE_SHARED) \ + $(OPT_WASM_RUNTIME_INSTALL_TARGET) + +lib_install: install-lib install-so liblibsql_install + +# +# Rust test targets (run against the in-tree libsql/libsqlite3). +# +libsqlapi: sqlite3.h + cd $(APITOP) && LIBSQL_SRC_DIR=$(TOP) cargo test --all --release --lib + +testlibsql: sqlite3.h + cd $(APITOP) && LIBSQL_SRC_DIR=$(TOP) \ + cargo test --all --all-targets --all-features && \ + cargo test --all --doc --all-features && \ + cargo install cargo-hack && cargo hack check --each-feature --no-dev-deps + +rusttest: sqlite3.h $(liblibsql.LIB) $(liblibsql.SO) + ( cd test/rust_suite; \ + SQLITE3_STATIC=1 SQLITE3_INCLUDE_DIR=$(TOP) \ + LD_LIBRARY_PATH=$(TOP) SQLITE3_LIB_DIR=$(TOP) \ + cargo test ) + +rusttestwasm: sqlite3.h $(liblibsql.LIB) $(liblibsql.SO) liblibsql_wasm + ( cd test/rust_suite; \ + SQLITE3_STATIC=1 SQLITE3_INCLUDE_DIR=$(TOP) \ + LD_LIBRARY_PATH=$(TOP) SQLITE3_LIB_DIR=$(TOP) \ + cargo test --features wasm,udf ) + +clean: clean-libsql +clean-libsql: + rm -f libsql$(T.exe) liblibsql$(T.lib) liblibsql$(T.dll) libsql.pc + rm -rf $(TOP)/.libs From 9c2f99925ddcafd29fccfe309b8682abd582db44 Mon Sep 17 00:00:00 2001 From: Pekka Enberg <penberg@iki.fi> Date: Thu, 28 May 2026 14:22:55 +0300 Subject: [PATCH 522/522] libsql-ffi: Update bundled SQLite to 3.48.0 --- libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c | 2 ++ libsql-ffi/bundled/src/sqlite3.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c index adff2331b5..63002f663c 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c @@ -22,8 +22,10 @@ ** ** .fossil-settings/empty-dirs ** .fossil-settings/ignore-glob +** Makefile.in ** Makefile.msc ** README.md +** auto.def ** doc/compile-for-windows.md ** doc/jsonb.md ** doc/trusted-schema.md diff --git a/libsql-ffi/bundled/src/sqlite3.c b/libsql-ffi/bundled/src/sqlite3.c index adff2331b5..63002f663c 100644 --- a/libsql-ffi/bundled/src/sqlite3.c +++ b/libsql-ffi/bundled/src/sqlite3.c @@ -22,8 +22,10 @@ ** ** .fossil-settings/empty-dirs ** .fossil-settings/ignore-glob +** Makefile.in ** Makefile.msc ** README.md +** auto.def ** doc/compile-for-windows.md ** doc/jsonb.md ** doc/trusted-schema.md